Panel Stack Splitter(PSS)を使ってfoobar2000のスキンを作るときに、PSSスクリプトをどう書いていったらいいのかを解説します。
解説の仕方を悩んだのですが、解説用に作ったスキンのPSSスクリプトを、機能ごとに説明していく形を取ります。
ダウンロード
実用性を考えて作っていないので、間違えてメイン環境に上書きしないようにしてください。
コードの説明
Splitter Settings > Scriptタブのコードを上から順番に説明していきます。PSSに加えて、Title formatting(TF)の知識がないと、ちょっと難しいかも知れません。
スキンで使用しているTFと関数
調べるときに役に立つかと思って抜き出してみました。
// TF Functions $puts $get $strcmp $left $if $if3 $ifequal $or $add $sub $div // TF Fields %isplaying% %ispaused% %path% %playback_time_remaining_seconds%
// PSS Functions $init_ps_glogal $set_ps_glogal $gradientrect $drawrect $textbutton $font $movepanel_c $showpanel_c $imageabs // PSS Fields %ps_width% %ps_height% %ps_foobar2000_path% %ps_playback_order%
TFは関数が11、変数が4種類。PSSは関数が9、変数が4種類。多いのか少ないのかわかりませんが、これだけ理解すればこの程度のスキンは作ることができる、とも考えられるでしょうか。
http://tnetsixenon.xrea.jp/title_formatting.html
Variables
$init_ps_global(panel,0) $init_ps_global(bgnum,0)
ここから本題に入ります。このコードは、$init_ps_global関数を使って、変数を定義しています。表示中のパネルを別のパネルに切り替えるなどの、スイッチを作るときによく使います。例えば、1行目のpanel変数は、PANEL-2ボタンが押されたときは1になり、PANEL-1ボタンが押されたときは0になります。
Constant
$puts(white,255-255-255-255)
$putsはPSSの関数ではなくTFです。$putsは定数を定義する関数になります。値が変化する変数に対して、定数は値が変化しません。基本的に、スクリプト中に何度も出てくる式や座標などに使われます。後で座標などの値を変更したくなったときに、スクリプト中に散らばっている値を一々変更する手間がなくなるので、大変有用です。このスキンでは、ややこしくなるので1つしか使っていませんが、本来はもっとガッツリ使います。
Background
$if($strcmp(%bgnum%,0), $set_ps_global(bgcol1,153-0-255-255) $set_ps_global(bgcol2,108-0-158-255) ) $if($strcmp(%bgnum%,1), $set_ps_global(bgcol1,255-0-102-255) $set_ps_global(bgcol2,158-0-50-255) ) $if($strcmp(%bgnum%,2), $set_ps_global(bgcol1,255-153-0-255) $set_ps_global(bgcol2,158-108-0-255) )
このコードは、変数bgnumが0、1、2の時それぞれに、変数bgcol1とbgcol2を定義するというコードです。背景のグラデーションの色を指定している箇所なので、カラーコードを変更すれば背景の色も変わります。%bgnum%のように、変数を呼び出すときは%変数名%を使います。Variablesの項で$init_ps_global関数を使って変数を定義していましたが、このように$set_ps_globalを使って定義することもできます。
$gradientrect(0,0,%ps_width%,$sub(%ps_height%,100),%bgcol1%,%bgcol2%)
$gradientrectは、グラデーションで塗りつぶした矩形を描画する関数です。上で定義した変数bgcol1とbgcol2をここで使用しています。
ちなみに、$gradientrectを使わずに$drawrectにするとベタ塗りの背景に、$drawimageなどの画像表示関数にすると画像を背景に表示することができます。
$drawrect(0,0,%ps_width%,%ps_height%,0-0-0-255,0-0-0-255) $drawrect(0,0,%ps_width%,%ps_height%,255-255-255-255,255-255-255-255)
Dummy Button
$textbutton(,,,,,,,)
PSSには、起動時にボタンがマウスオン状態になってしまうバグがあります。このコードは、そのバグを回避するためのコードです。致命的なバグではありませんので無くてもいいと思います。このコードは、スクリプト中でボタン関数を使用する前であれば、どこに記述しても効果があります。
Playback Order Buttons
$font(Calibri,9,Bold)
$fontは、$drawtextや$textbuttonなどの文字列を表示する関数の、書体を設定する関数です。以降、違う書体を使う場合は、再度設定し直す必要があります。
$if($stricmp($left(%ps_playback_order%,7),'Default'),$textbutton($sub(%ps_width%,100),0,100,16,'Default','Default',COMMAND:'Playback/Order/Repeat (track)';REFRESH,fontcolor:255-255-255-255 brushcolor:0-0-0-255,fontcolor:255-255-255-255 brushcolor:0-0-0-255)) $if($stricmp($left(%ps_playback_order%,14),'Repeat (track)'),$textbutton($sub(%ps_width%,100),0,100,16,'Repeat (track)','Repeat (track)',COMMAND:'Playback/Order/Repeat (playlist)';REFRESH,fontcolor:255-255-255-255 brushcolor:0-0-0-255,fontcolor:255-255-255-255 brushcolor:0-0-0-255)) $if($stricmp($left(%ps_playback_order%,17),'Repeat (playlist)'),$textbutton($sub(%ps_width%,100),0,100,16,'Repeat (playlist)','Repeat (playlist)',COMMAND:'Playback/Order/Random';REFRESH,fontcolor:255-255-255-255 brushcolor:0-0-0-255,fontcolor:255-255-255-255 brushcolor:0-0-0-255)) $if($stricmp($left(%ps_playback_order%,6),'Random'),$textbutton($sub(%ps_width%,100),0,100,16,'Random','Random',COMMAND:'Playback/Order/Shuffle (tracks)';REFRESH,fontcolor:255-255-255-255 brushcolor:0-0-0-255,fontcolor:255-255-255-255 brushcolor:0-0-0-255)) $if($stricmp($left(%ps_playback_order%,16),'Shuffle (tracks)'),$textbutton($sub(%ps_width%,100),0,100,16,'Shuffle (tracks)','Shuffle (tracks)',COMMAND:'Playback/Order/Shuffle (albums)';REFRESH,fontcolor:255-255-255-255 brushcolor:0-0-0-255,fontcolor:255-255-255-255 brushcolor:0-0-0-255)) $if($stricmp($left(%ps_playback_order%,16),'Shuffle (albums)'),$textbutton($sub(%ps_width%,100),0,100,16,'Shuffle (albums)','Shuffle (albums)',COMMAND:'Playback/Order/Shuffle (folders)';REFRESH,fontcolor:255-255-255-255 brushcolor:0-0-0-255,fontcolor:255-255-255-255 brushcolor:0-0-0-255)) $if($stricmp($left(%ps_playback_order%,17),'Shuffle (folders)'),$textbutton($sub(%ps_width%,100),0,100,16,'Shuffle (folders)','Shuffle (folders)',COMMAND:'Playback/Order/Default';REFRESH,fontcolor:255-255-255-255 brushcolor:0-0-0-255,fontcolor:255-255-255-255 brushcolor:0-0-0-255))
よくスキンで使われているオーダー切り替えボタンのコードです。このコードは座標や色を変更すればコピペで使えます。
Preferences Button
$font(Webdings,9)
違う書体を使うので再度設定します。
$textbutton(10,10,20,20,'c','g',COMMAND:'File/Preferences',fontcolor:$get(white) brushcolor:0-0-0-0,fontcolor:$get(white) brushcolor:0-0-0-0)
プレイヤー左上にある四角のボタンです。このスキンはメニューバーを表示していないので、あった方がいいかと思い付けてみました。PSSはメニューの各項目をコマンドで呼び出すことはできますが、メニューそのものを表示することはできません。
説明用に作ったスキンなので別にメニューやツールバーを表示してもいいのですが、ない方がスキンっぽく見えるんですよね。もっといえば、UI Hacksでウィンドウフレームも非表示にすると更にスキンっぽくなります。(スキンっぽいって何だろう)
Background Change Buttons
$font(Segoe UI Black,12)
書体の再設定です。
$textbutton(10,$div($sub(%ps_height%,140),2),20,20,$ifequal(%bgnum%,0,'●','◌'),$ifequal(%bgnum%,0,'●','●'),SETGLOBAL:bgnum:0;REFRESH,fontcolor:$get(white) brushcolor:0-0-0-0,fontcolor:$get(white) brushcolor:0-0-0-0) $textbutton(10,$div($sub(%ps_height%,100),2),20,20,$ifequal(%bgnum%,1,'●','◌'),$ifequal(%bgnum%,1,'●','●'),SETGLOBAL:bgnum:1;REFRESH,fontcolor:$get(white) brushcolor:0-0-0-0,fontcolor:$get(white) brushcolor:0-0-0-0) $textbutton(10,$div($sub(%ps_height%,60),2),20,20,$ifequal(%bgnum%,2,'●','◌'),$ifequal(%bgnum%,2,'●','●'),SETGLOBAL:bgnum:2;REFRESH,fontcolor:$get(white) brushcolor:0-0-0-0,fontcolor:$get(white) brushcolor:0-0-0-0)
プレイヤー左中央の背景切り替えボタンのコードです。選択中の背景に対応するボタンは黒丸、それ以外は白丸を表示するために、テキストの値に条件式を突っ込んでいます。このように、関数内で条件式を使うことで、多少は複雑な処理も行うことができるようになります。コマンドのREFRESHは、何か表示が変更される処理には必須です。フォントカラーの$getは、前述の定数を呼び出すための関数になります。
Backgroundの項で出た$if($strcmp(%bgnum%,0),)と$ifequal(%bgnum%,0,,)は、値を文字列として解釈するか、数値として解釈するかの違いがありますが、同じ働きをするようです。本当なら文字列と数値で使い分けるのがセオリーなのだと思いますが、私はthenの処理だけの場合は$if、elseの処理も必要な場合は$ifequalを使うようにしています。($if文は$if(cond,then)という書き方ができるため)
Playback Buttons
$font(Webdings,12)
また書体の再設定です。
$textbutton($sub(%ps_width%,30),$sub(%ps_height%,130),20,20,'4','4',COMMAND:'Playback/Play',fontcolor:$get(white),fontcolor:200-200-200-255) $textbutton($sub(%ps_width%,60),$sub(%ps_height%,130),20,20,'9','9',COMMAND:'Playback/Previous',fontcolor:$get(white),fontcolor:200-200-200-255) $textbutton($sub(%ps_width%,90),$sub(%ps_height%,130),20,20,';',';',COMMAND:'Playback/Pause',fontcolor:$get(white),fontcolor:200-200-200-255) $textbutton($sub(%ps_width%,30),$sub(%ps_height%,160),20,20,':',':',COMMAND:'Playback/Next',fontcolor:$get(white),fontcolor:200-200-200-255) $textbutton($sub(%ps_width%,30),$sub(%ps_height%,190),20,20,'<','<',COMMAND:'Playback/Stop',fontcolor:$get(white),fontcolor:200-200-200-255)
再生ボタンや停止ボタンなどのプレイバックボタンを表示するコードになります。$textbuttonよりも$imagebuttonが使われることが多いですが、これもよく使われるコードです。
Panel Change Buttons Background
$drawrect(0,$sub(%ps_height%,100),%ps_width%,56,70-70-70-255,70-70-70-255)
$drawrectはベタ塗りの矩形を描画する関数です。このコードは、PANEL-1、PANEL-2と表示されている、パネル切り替えボタンの下地部分ですが、ボタン自体は透明で、この矩形の上に透明のボタンが重なっています。
Panel Change Buttons Indicator
$if($strcmp(%panel%,0), $drawrect(0,$sub(%ps_height%,100),$div(%ps_width%,2),1,$get(white),$get(white)) ) $if($strcmp(%panel%,1), $drawrect($div(%ps_width%,2),$sub(%ps_height%,100),$div(%ps_width%,2),1,$get(white),$get(white)) )
パネル切り替えボタンのインジケーターのコードです。panel変数の値によってX座標を変更します。このコードを1行にまとめると下記のようになります。
$drawrect($ifequal(%panel%,0,0,$div(%ps_width%,2)),$sub(%ps_height%,100),$div(%ps_width%,2),1,$get(white),$get(white))
$drawrectは矩形の内側と枠で、高さは2が最低のような気がしますが、高さを1にすると1ピクセルで表示してくれます。(たぶん値が1だと枠は表示されていない)
Panel Change Buttons
$font(Consolas,12)
書体の再設定。
$textbutton(0,$sub(%ps_height%,100),$div(%ps_width%,2),56,'PANEL-1','PANEL-1',SETGLOBAL:panel:0;REFRESH,fontcolor:$get(white) brushcolor:0-0-0-0,fontcolor:$get(white) brushcolor:0-0-0-30) $textbutton($div(%ps_width%,2),$sub(%ps_height%,100),$div(%ps_width%,2),56,'PANEL-2','PANEL-2',SETGLOBAL:panel:1;REFRESH,fontcolor:$get(white) brushcolor:0-0-0-0,fontcolor:$get(white) brushcolor:0-0-0-30)
前述した透明のボタンのコードです。
PSSのボタンは、通常の表示とマウスオン時の表示しか設定することができないので、現在どのパネルが表示されているか、何番の背景が表示されているのか、ボタンの見た目で選択状態を確認することができないため、所謂タブを作りたいようなときは別途処理を追加する必要があり、このように若干ややこしいことになってしまいます。
Underbar Background
$drawrect(0,$sub(%ps_height%,40),%ps_width%,40,50-50-50-255,50-50-50-255)
ベタ塗りの矩形描画関数です。位置的には、プレイヤー最下部の濃いグレーの箇所になります。この部分も矩形の上に透明のパネルを重ねています。
Panel Area
$movepanel_c(yts,40,40,$sub($div(%ps_width%,2),40),40) $movepanel_c(jsplaylist,40,80,$sub($div(%ps_width%,2),40),$sub(%ps_height%,220)) $movepanel_c(ytv,$div(%ps_width%,2),40,$sub($div(%ps_width%,2),40),$sub(%ps_height%,180)) $movepanel_c(ls3,40,40,$sub(%ps_width%,80),$sub(%ps_height%,180)) $movepanel_c(seekbar,0,$sub(%ps_height%,44),%ps_width%,4) $movepanel_c(st,40,$sub(%ps_height%,40),$sub(%ps_width%,80),40) $movepanel_c(shpeck,$sub(%ps_width%,36),$sub(%ps_height%,36),32,32)
各パネルの表示位置や領域を指定するコードです。ボタンや背景などの装飾は無しで、単にタイル状にパネルを表示したいだけなら、このコードだけで済みます。
Splitter Settings > Panellistでも同じことができるのですが、後で値を変更したくなったときに非常に手間です。断然スクリプトでやった方が楽だと思います。
また、シークバーを別のプラグインに変更する場合を例に取ると、既存のシークバーパネルを削除し新しいシークバーパネルを追加したら、あとはCaptionを同じseekbarとすれば変更が完了します。私はPanellistでは、Caption決めとForced layoutのチェックだけしか行いません。
Panel Display State
$if($strcmp(%panel%,0), $showpanel_c(ls3,0) $showpanel_c(ytv,1) $showpanel_c(yts,1) $showpanel_c(jsplaylist,1) ) $if($strcmp(%panel%,1), $showpanel_c(ytv,0) $showpanel_c(yts,0) $showpanel_c(jsplaylist,0) $drawrect(40,40,$sub(%ps_width%,80),$sub(%ps_height%,180),0-0-0-20,0-0-0-20) $showpanel_c(ls3,1) )
各パネルの表示状態を指定するコードになります。複数のパネルを切り替えるスキンでは、このように変数を使います。全てのパネルの表示/非表示状態を指定しないと、不具合が起こりやすいです。
たくさんのパネルを表示しようとすると、表示状態を指定するのが大変なので、PSSにPSSを重ねたくなることがあると思います。私も以前は重ねていたのですが、これをやると色々と弊害が生じるので、できるだけ重ねないようにすることをおすすめします。
途中に入っている$drawrectは歌詞表示の下地です。ここも矩形の上に、背景を透明にしたLyric Show Panel 3を重ねています。背景を透過させたスキンは、このように背景を透明にできるパネルを上に重ねると作ることができます。
余談ですが、恐らくバグだと思いますが、$drawrectは内側と枠の色を同じにしても枠が少し濃くなるようです。
Cover
$if($or(%isplaying%,%ispaused%), $if3($imageabs(4,$sub(%ps_height%,36),32,32,%path%,artreader,),$imageabs(4,$sub(%ps_height%,36),32,32,%ps_foobar2000_path%\user-components\foo_jscript_panel\samples\jsplaylist-mod\images\nocover.png)) , $imageabs(4,$sub(%ps_height%,36),32,32,%ps_foobar2000_path%\user-components\foo_jscript_panel\samples\jsplaylist-mod\images\logo.png) )
プレイヤー左下のアルバムアート表示のコードです。ここは$if文の中に$if3文が入っているので、最初は理解しにくいと思います。処理的には、再生中か一時停止中ならアルバムアートを表示し、該当する画像がなかったら代替画像を表示。再生中でも一時停止中でもない(となると停止時になる)場合にはロゴ画像を表示するという処理です。$imageabs関数が、画像を表示すると共に真偽値も返すという性質を利用しています。このコードも画像のパスや座標などを変更すれば流用できます
Auto Change Background
$if($strcmp(%playback_time_remaining_seconds%,1), $ifequal(%bgnum%,2,$set_ps_global(bgnum,0),$set_ps_global(bgnum,$add(%bgnum%,1))))
このコードはPer Secondタブにあります。次の曲に変わったときに背景を変更するコードです。残り時間1秒になったら、変数bgnumの値を1変更するという処理を行います。秒単位での条件なのでPer Secondタブに記述する必要があります。(説明書の90-92行目を参照)2行目のコードは、変数bgnumを0->1->2->0と回すためのコードです。
応用
コードを改変してみます。
背景を増やす
$if($strcmp(%bgnum%,0), $set_ps_global(bgcol1,153-0-255-255) $set_ps_global(bgcol2,108-0-158-255) ) $if($strcmp(%bgnum%,1), $set_ps_global(bgcol1,255-0-102-255) $set_ps_global(bgcol2,158-0-50-255) ) $if($strcmp(%bgnum%,2), $set_ps_global(bgcol1,255-153-0-255) $set_ps_global(bgcol2,158-108-0-255) ) $if($strcmp(%bgnum%,3), $set_ps_global(bgcol1,102-255-0-255) $set_ps_global(bgcol2,50-158-0-255) ) $if($strcmp(%bgnum%,4), $set_ps_global(bgcol1,25-0-255-255) $set_ps_global(bgcol2,29-0-158-255) )
Backgroundの項で、変数bgnumが3のときの色と、4のときの色を追加します。(背景を2種類増やす場合)
$textbutton(10,$div($sub(%ps_height%,180),2),20,20,$ifequal(%bgnum%,0,'●','◌'),$ifequal(%bgnum%,0,'●','●'),SETGLOBAL:bgnum:0;REFRESH,fontcolor:$get(white) brushcolor:0-0-0-0,fontcolor:$get(white) brushcolor:0-0-0-0) $textbutton(10,$div($sub(%ps_height%,140),2),20,20,$ifequal(%bgnum%,1,'●','◌'),$ifequal(%bgnum%,1,'●','●'),SETGLOBAL:bgnum:1;REFRESH,fontcolor:$get(white) brushcolor:0-0-0-0,fontcolor:$get(white) brushcolor:0-0-0-0) $textbutton(10,$div($sub(%ps_height%,100),2),20,20,$ifequal(%bgnum%,2,'●','◌'),$ifequal(%bgnum%,2,'●','●'),SETGLOBAL:bgnum:2;REFRESH,fontcolor:$get(white) brushcolor:0-0-0-0,fontcolor:$get(white) brushcolor:0-0-0-0) $textbutton(10,$div($sub(%ps_height%,60),2),20,20,$ifequal(%bgnum%,3,'●','◌'),$ifequal(%bgnum%,3,'●','●'),SETGLOBAL:bgnum:3;REFRESH,fontcolor:$get(white) brushcolor:0-0-0-0,fontcolor:$get(white) brushcolor:0-0-0-0) $textbutton(10,$div($sub(%ps_height%,20),2),20,20,$ifequal(%bgnum%,4,'●','◌'),$ifequal(%bgnum%,4,'●','●'),SETGLOBAL:bgnum:4;REFRESH,fontcolor:$get(white) brushcolor:0-0-0-0,fontcolor:$get(white) brushcolor:0-0-0-0)
Background Change Buttonsの項で、変数bgnumを3にするボタンと、4にするボタンを追加します。
$if($strcmp(%playback_time_remaining_seconds%,1), $ifequal(%bgnum%,4,$set_ps_global(bgnum,0),$set_ps_global(bgnum,$add(%bgnum%,1))))
Auto Change Backgroundの項で、変数bgnumが、0->1->2->3->4->0と回るようにコードを変更します。
下部の黒い部分は、本来パネル切り替えボタンとかが表示されている部分です。何も色を指定しないと、BehaviourタブのChange colourで選択した色が表示されます。(Custom background colourにチェックが入っている必要があります)隣のDefault fontボタンで選択した書体は、$font関数で書体を指定しなかった場合に表示されます。
定数に入れられる値
$puts(command,COMMAND:'File/Preferences') $textbutton(15,15,15,15,'c','g',$get(command),fontcolor:$get(white) brushcolor:0-0-0-0,fontcolor:$get(white) brushcolor:0-0-0-0)
こんな感じで、定数にはコマンドも入ります。意味はないですが、%ps_playback_order%なんかも定数に入ります。コンマが含まれるとダメなので関数は入りません。私は$subとか$divとかの式をよく定数にします。
解説用スキンのリンクが?
返信削除ご報告ありがとうございます。
削除リンクを修正しました。
ササビー様
返信削除解説用とは言え、シンプルでありながらYoutube動画にも対応しており素敵なスキンですね。
UI Hacks追加と、解説していただいたBackground Colorの追加だけで楽しませていただいております。
PSSスクリプトは私には敷居が高いですが、モディファイ用に勉強にさせていただきます。
いつもコメントありがとうございます。
削除PSSスクリプトに興味を持ってもらえたら幸いです。
foobar2000が動画も再生できるようになったと誤解されそうなので、あんまり動画パネルを含めない方がよさそうな気はするのですが、制作中の環境にプレイリストやライブラリを読ませることを出来るだけしたくないので、動画を流していることが多いんです。そういう事情で動画パネルが含まれています。ちなみに、このスキンを作るまで知らなかったのですが、動画パネルはマウススクロールでボリューム調整が出来ます。なのでボリュームバーは付けていません。
このコメントは投稿者によって削除されました。
削除Youtube再生機能はZetroMODに実装していただいて以来、大変重宝しております。Youtube Search機能はなくても再生ができるだけでもありがたいです。外さないでください。
削除マウススクロールでのボリューム調整は便利なのでZetroMODでも常用していました。PANEL-2でのボリューム調整はPageUPとPageDownにKeyboard Shortcutを設定しておりますで問題ありません。UI HacksでFrame styleもNo Borderにしてさらにシンプルにして、終了はタスクバーからしています。