summaryrefslogtreecommitdiff
path: root/plugins/Watrack/kolframe
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/Watrack/kolframe')
-rw-r--r--plugins/Watrack/kolframe/frm.rc84
-rw-r--r--plugins/Watrack/kolframe/frm.resbin0 -> 3032 bytes
-rw-r--r--plugins/Watrack/kolframe/frm_data.inc37
-rw-r--r--plugins/Watrack/kolframe/frm_designer.inc164
-rw-r--r--plugins/Watrack/kolframe/frm_dlg1.inc283
-rw-r--r--plugins/Watrack/kolframe/frm_dlg2.inc172
-rw-r--r--plugins/Watrack/kolframe/frm_frame.inc497
-rw-r--r--plugins/Watrack/kolframe/frm_icogroup.inc115
-rw-r--r--plugins/Watrack/kolframe/frm_rc.inc56
-rw-r--r--plugins/Watrack/kolframe/frm_text.inc90
-rw-r--r--plugins/Watrack/kolframe/frm_trackbar.inc229
-rw-r--r--plugins/Watrack/kolframe/frm_vars.inc80
-rw-r--r--plugins/Watrack/kolframe/i_bitmap.inc290
-rw-r--r--plugins/Watrack/kolframe/kolframe.pas327
14 files changed, 2424 insertions, 0 deletions
diff --git a/plugins/Watrack/kolframe/frm.rc b/plugins/Watrack/kolframe/frm.rc
new file mode 100644
index 0000000000..50180b4b53
--- /dev/null
+++ b/plugins/Watrack/kolframe/frm.rc
@@ -0,0 +1,84 @@
+#include "frm_rc.inc"
+
+LANGUAGE 0,0
+
+FRAME DIALOGEX 0, 0, 304, 226, 0
+STYLE DS_SETFONT | WS_CHILD | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0
+{
+ AUTOCHECKBOX "Use buttons gap" , IDC_BTNGAP , 3, 44, 146, 14, BS_VCENTER | BS_MULTILINE | BS_NOTIFY
+
+ LTEXT "Frame refresh time", -1, 47, 2, 100, 14, SS_CENTERIMAGE
+ EDITTEXT IDC_TIMER , 3, 3, 40, 12, ES_RIGHT | ES_NUMBER
+
+ AUTOCHECKBOX "Hide when no player", IDC_HIDEFRAMEPLAYER, 3, 16, 146, 14, BS_VCENTER | BS_MULTILINE | BS_NOTIFY
+ AUTOCHECKBOX "Hide when no music" , IDC_HIDEFRAMEMUSIC , 3, 30, 146, 14, BS_VCENTER | BS_MULTILINE | BS_NOTIFY
+
+ AUTOCHECKBOX "Show info in the frame" , IDC_SHOWTEXT , 155, 2, 144, 14, BS_VCENTER | BS_MULTILINE | BS_NOTIFY | BS_RIGHT | BS_LEFTTEXT
+ AUTOCHECKBOX "Show controls in the frame", IDC_SHOWCTRLS, 155, 16, 144, 14, BS_VCENTER | BS_MULTILINE | BS_NOTIFY | BS_RIGHT | BS_LEFTTEXT
+ AUTOCHECKBOX "Show volume controls" , IDC_SHOWVOLUM, 155, 30, 144, 14, BS_VCENTER | BS_MULTILINE | BS_NOTIFY | BS_RIGHT | BS_LEFTTEXT
+ AUTOCHECKBOX "Show trackbar" , IDC_SHOWBAR , 155, 44, 144, 14, BS_VCENTER | BS_MULTILINE | BS_NOTIFY | BS_RIGHT | BS_LEFTTEXT
+
+ AUTOCHECKBOX "Use Picture",IDC_FRMUSEPIC,3,65,91,14,BS_VCENTER | BS_MULTILINE | BS_NOTIFY
+ EDITTEXT IDC_FRMBKPIC, 96, 65, 185, 14
+ PUSHBUTTON "...", IDC_FRMPICBTN, 284, 65, 16, 14
+
+ GROUPBOX "Picture transform", -1, 2, 82, 298, 59
+ AUTOCHECKBOX "Center horizontally" , IDC_CENTERX , 6, 91, 96, 16, BS_VCENTER | BS_MULTILINE | BS_NOTIFY
+ AUTOCHECKBOX "Center vertically" , IDC_CENTERY , 6, 107, 96, 16, BS_VCENTER | BS_MULTILINE | BS_NOTIFY
+ AUTOCHECKBOX "Bottom" , IDC_BOTTOM , 6, 123, 96, 16, BS_VCENTER | BS_MULTILINE | BS_NOTIFY
+ AUTOCHECKBOX "Tile horizontally" , IDC_TILEX , 104, 91, 96, 16, BS_VCENTER | BS_MULTILINE | BS_NOTIFY
+ AUTOCHECKBOX "Tile vertically" , IDC_TILEY , 104, 107, 96, 16, BS_VCENTER | BS_MULTILINE | BS_NOTIFY
+ AUTOCHECKBOX "Right" , IDC_RIGHT , 104, 123, 96, 16, BS_VCENTER | BS_MULTILINE | BS_NOTIFY
+ AUTOCHECKBOX "Stretch to width" , IDC_STRETCHX, 202, 91, 96, 16, BS_VCENTER | BS_MULTILINE | BS_NOTIFY
+ AUTOCHECKBOX "Stretch to height" , IDC_STRETCHY, 202, 107, 96, 16, BS_VCENTER | BS_MULTILINE | BS_NOTIFY
+ AUTOCHECKBOX "Stretch proportionally", IDC_PROP , 202, 123, 96, 16, BS_VCENTER | BS_MULTILINE | BS_NOTIFY
+
+ CTEXT "Cover padding", -1, 6, 152, 142, 14, SS_CENTERIMAGE
+ EDITTEXT IDC_PADDING_TOP , 64, 168, 24, 14, ES_RIGHT | ES_NUMBER
+ EDITTEXT IDC_PADDING_LEFT , 50, 184, 24, 14, ES_RIGHT | ES_NUMBER
+ EDITTEXT IDC_PADDING_RIGHT , 78, 184, 24, 14, ES_RIGHT | ES_NUMBER
+ EDITTEXT IDC_PADDING_BOTTOM, 64, 200, 24, 14, ES_RIGHT | ES_NUMBER
+
+ AUTOCHECKBOX "Manual element placement", IDC_MANUALPLACE, 155,144,144,16, BS_VCENTER | BS_MULTILINE | BS_RIGHT | BS_LEFTTEXT
+
+// TBS_TOOLTIPS
+ CONTROL "",IDC_FRMALPHA,"msctls_trackbar32", TBS_BOTTOM|TBS_NOTICKS|$100,160,168,68,11
+ LTEXT "Alpha",-1,230,168,75,11, SS_CENTERIMAGE
+
+ CONTROL "",IDC_FRMCOLOR, "ColourPicker", WS_TABSTOP, 162, 181, 14, 14
+ LTEXT "Background color",-1,178,181,126,14, SS_CENTERIMAGE
+
+ AUTOCHECKBOX "Use cover instead of picture", IDC_USECOVER, 155, 196, 142, 16, BS_VCENTER | BS_MULTILINE | BS_NOTIFY
+}
+
+FRAME2 DIALOGEX 0, 0, 304, 226, 0
+STYLE DS_SETFONT | WS_CHILD | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0
+{
+ PUSHBUTTON "Choose font...", IDC_FRMFONT, 84, 90, 64, 12
+
+ GROUPBOX "Text effect",-1,154,6,142,76
+ AUTORADIOBUTTON "Cut", IDC_EFF_CUT , 158, 16, 136, 12, NOT WS_TABSTOP
+ AUTORADIOBUTTON "Wrap", IDC_EFF_WRAP, 158, 28, 136, 12, NOT WS_TABSTOP
+ AUTORADIOBUTTON "Roll", IDC_EFF_ROLL, 158, 40, 136, 12, NOT WS_TABSTOP
+ AUTORADIOBUTTON "PingPong", IDC_EFF_PONG, 158, 52, 136, 12, NOT WS_TABSTOP
+ AUTOCHECKBOX "Align text to center", IDC_ALCENTER, 158, 66, 136, 12, BS_VCENTER | BS_MULTILINE | BS_NOTIFY
+
+ GROUPBOX "Text movement", -1, 6, 6, 142, 76, WS_TABSTOP
+ LTEXT "Text rotation speed (1-20)", -1, 32, 17, 114, 12, SS_CENTERIMAGE
+ LTEXT "Scroll step" , -1, 32, 33, 114, 12, SS_CENTERIMAGE
+ LTEXT "Scroll gap" , -1, 32, 49, 114, 12, SS_CENTERIMAGE
+// LTEXT "Minimum scroll tail" , -1, 32, 65, 114, 12, SS_CENTERIMAGE
+ EDITTEXT IDC_TIMER , 10, 17, 20, 12, ES_RIGHT | ES_NUMBER
+ EDITTEXT IDC_ROLLSTEP, 10, 33, 20, 12, ES_RIGHT | ES_NUMBER
+ EDITTEXT IDC_ROLLGAP , 10, 49, 20, 12, ES_RIGHT | ES_NUMBER
+// EDITTEXT IDC_ROLLTAIL, 10, 65, 20, 12, ES_RIGHT | ES_NUMBER
+
+ CONTROL "M" ,IDC_MACRO_HELP ,"MButtonClass",WS_TABSTOP,284,156,16,16,$18000000
+ RTEXT "Frame Text", -1 , 4, 163, 274, 10
+ EDITTEXT IDC_FRAME_TEXT , 4, 174, 296, 48,
+ ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN
+}
diff --git a/plugins/Watrack/kolframe/frm.res b/plugins/Watrack/kolframe/frm.res
new file mode 100644
index 0000000000..b978cdb07e
--- /dev/null
+++ b/plugins/Watrack/kolframe/frm.res
Binary files differ
diff --git a/plugins/Watrack/kolframe/frm_data.inc b/plugins/Watrack/kolframe/frm_data.inc
new file mode 100644
index 0000000000..52535d15b2
--- /dev/null
+++ b/plugins/Watrack/kolframe/frm_data.inc
@@ -0,0 +1,37 @@
+{Frame data}
+
+const
+ //show controls
+ scButtons = $0001;
+ scTrackBar = $0002;
+ scText = $0004;
+ scVolume = $0008;
+ scGap = $0010;
+ scAll = $000F;
+
+ ppLeft = 0;
+ ppRight = 1;
+ //effects
+ effCut = 0;
+ effWrap = 1;
+ effRoll = 2;
+ effPong = 3;
+
+ // Back bitmap mode
+ frbkCenterX = $0001;
+ frbkCenterY = $0002;
+ frbkCenter = frbkCenterX or frbkCenterY;
+ frbkTileX = $0004;
+ frbkTileY = $0008;
+ frbkTile = frbkTileX or frbkTileY;
+ frbkStretchX = $0010;
+ frbkStretchY = $0020;
+ frbkStretch = frbkStretchX or frbkStretchY;
+ frbkProportional = $0040;
+ frbkBottom = $0080;
+ frbkRight = $0100;
+
+const
+ numbuttons = 7;
+ VolBtnDist = 6;
+ BtnGap = 3;
diff --git a/plugins/Watrack/kolframe/frm_designer.inc b/plugins/Watrack/kolframe/frm_designer.inc
new file mode 100644
index 0000000000..f12c01f05d
--- /dev/null
+++ b/plugins/Watrack/kolframe/frm_designer.inc
@@ -0,0 +1,164 @@
+{Frame designer}
+const
+ // trackbar
+ opt_tbleft :pAnsiChar='frame/designer/trackbar/left';
+ opt_tbtop :pAnsiChar='frame/designer/trackbar/top';
+ opt_tbwidth :pAnsiChar='frame/designer/trackbar/width';
+ opt_tbheight:pAnsiChar='frame/designer/trackbar/height';
+ // text block
+ opt_tleft :pAnsiChar='frame/designer/text/left';
+ opt_ttop :pAnsiChar='frame/designer/text/top';
+ opt_twidth :pAnsiChar='frame/designer/text/width';
+ opt_theight :pAnsiChar='frame/designer/text/height';
+ // buttons (with number)
+ opt_bleft :pAnsiChar='frame/designer/buttons/left';
+ opt_btop :pAnsiChar='frame/designer/buttons/top';
+
+procedure TWATFrame.DesignerSaveSettings;
+var
+ i:integer;
+ D:PWATFrameData;
+ lleft,ltop:array [0..63] of AnsiChar;
+ pleft,ptop:PAnsiChar;
+begin
+ D:=CustomData;
+ if D.TrackBar<>nil then
+ begin
+ DBWriteWord(0,PluginShort,opt_tbleft ,D.Trackbar.Left);
+ DBWriteWord(0,PluginShort,opt_tbtop ,D.Trackbar.Top);
+ DBWriteWord(0,PluginShort,opt_tbwidth ,D.Trackbar.Width);
+ DBWriteWord(0,PluginShort,opt_tbheight,D.Trackbar.Height);
+ end;
+
+ if D.TextBlock<>nil then
+ begin
+ DBWriteWord(0,PluginShort,opt_tleft ,D.TextBlock.Left);
+ DBWriteWord(0,PluginShort,opt_ttop ,D.TextBlock.Top);
+ DBWriteWord(0,PluginShort,opt_twidth ,D.TextBlock.Width);
+ DBWriteWord(0,PluginShort,opt_theight,D.TextBlock.Height);
+ end;
+
+ if (D.ShowControls and scButtons)<>0 then
+ begin
+ if D.btnarray[0]<>nil then
+ begin
+ pleft:=StrCopyE(lleft,opt_bleft);
+ ptop :=StrCopyE(ltop ,opt_btop);
+ for i:=0 to HIGH(D.btnarray) do
+ begin
+ IntToStr(pleft,i); DBWriteWord(0,PluginShort,lleft,D.btnarray[i].Left);
+ IntToStr(ptop ,i); DBWriteWord(0,PluginShort,ltop ,D.btnarray[i].Top);
+ end;
+ end;
+ end;
+end;
+
+procedure TWATFrame.DesignerLoadSettings;
+var
+ i:integer;
+ D:PWATFrameData;
+ lleft,ltop:array [0..63] of AnsiChar;
+ pleft,ptop:PAnsiChar;
+ for_check:integer;
+begin
+ D:=CustomData;
+
+ if (D.TrackBar<>nil) and
+ ((D.ShowControls and scTrackbar)<>0) and
+ ((D.Loaded and scTrackbar)=0) then
+ begin
+ D.Loaded:=D.Loaded or scTrackbar;
+ for_check:=DBReadWord(0,PluginShort,opt_tbwidth);
+ if for_check<>0 then
+ begin
+ D.Trackbar.SetPosition(
+ DBReadWord(0,PluginShort,opt_tbleft),
+ DBReadWord(0,PluginShort,opt_tbtop));
+ D.Trackbar.SetSize(
+ for_check,
+ {18}DBReadWord(0,PluginShort,opt_tbheight));
+ end;
+ end;
+
+ if (D.TextBlock<>nil) and
+ ((D.ShowControls and scText)<>0) and
+ ((D.Loaded and scText)=0) then
+ begin
+ D.Loaded:=D.Loaded or scText;
+ for_check:=DBReadWord(0,PluginShort,opt_twidth);
+ if for_check<>0 then
+ begin
+ D.TextBlock.SetPosition(
+ DBReadWord(0,PluginShort,opt_tleft),
+ DBReadWord(0,PluginShort,opt_ttop));
+ D.TextBlock.SetSize(
+ for_check,
+ DBReadWord(0,PluginShort,opt_theight));
+ end;
+ end;
+
+ if ((D.ShowControls and scButtons)<>0) and
+ ((D.Loaded and scButtons)=0) then
+ begin
+ if D.btnarray[0]<>nil then
+ begin
+ D.Loaded:=D.Loaded or scButtons;
+ pleft:=StrCopyE(lleft,opt_bleft);
+ pleft^:='0'; (pleft+1)^:=#0;
+ for_check:=SmallInt(DBReadWord(0,PluginShort,lleft,word(-1)));
+ if for_check>=0 then
+ begin
+ ptop :=StrCopyE(ltop,opt_btop);
+ for i:=0 to HIGH(D.btnarray) do
+ begin
+ IntToStr(pleft,i);
+ IntToStr(ptop ,i);
+ D.btnarray[i].SetPosition(
+ DBReadWord(0,PluginShort,lleft,word(-1)),
+ DBReadWord(0,PluginShort,ltop ,word(-1)));
+ end;
+ end;
+ end;
+ end;
+end;
+
+procedure TWATFrame.CreateDesigner(Sender:PControl;var Mouse:TMouseEventData);
+var
+ D:PWATFrameData;
+begin
+ D:=CustomData;
+ if not D.ManualPlacement then exit;
+
+ if D.Designer=nil then
+ D.Designer:=NewDesigner(@self);
+
+ if not D.Designer.Active then
+ begin
+ // Trackbar
+ if D.Trackbar<>nil then
+ begin
+ D.Trackbar.Anchor(false,false,false,false);
+ D.Designer.Connect('Trackbar',D.Trackbar);
+ end;
+ // TextBlock
+ if D.TextBlock<>nil then
+ begin
+ D.TextBlock.Anchor(false,false,false,false);
+ D.Designer.Connect('Panel',D.TextBlock);
+ end;
+ // Icons
+ if (D.ShowControls and scButtons)<>0 then MakeButtonsDesigner;
+
+ D.Designer.Active:=true;
+ end
+ else
+ begin
+ D.Designer.Active:=False;
+
+ DesignerSaveSettings;
+ if D.Trackbar <>nil then D.Designer.Disconnect(D.Trackbar);
+ if D.TextBlock<>nil then D.Designer.Disconnect(D.TextBlock);
+ if (D.ShowControls and scButtons)<>0 then FreeButtonsDesigner;
+ Sender.Update;
+ end;
+end;
diff --git a/plugins/Watrack/kolframe/frm_dlg1.inc b/plugins/Watrack/kolframe/frm_dlg1.inc
new file mode 100644
index 0000000000..19f590af66
--- /dev/null
+++ b/plugins/Watrack/kolframe/frm_dlg1.inc
@@ -0,0 +1,283 @@
+{Frame}
+const
+ FSC_BACKGROUND = 1;
+ FSC_BEHAVIOUR = 2;
+ FSC_SHOW = 4;
+// FSC_ALPHA = 8;
+
+function MakePicFilter:PWideChar;
+var
+ buf:array [0..255] of WideChar;
+ size:integer;
+ pc:pWideChar;
+begin
+ FillChar(buf,SizeOf(buf),0);
+ pc:=StrCopyEW(StrCopyEW(buf,TranslateW('All Bitmaps')),' (*.bmp;*.jpg;*.gif;*.png)');
+ pc:=StrCopyEW(pc+1,'*.BMP;*.RLE;*.JPG;*.JPEG;*.GIF;*.PNG');
+ size:=(pc+2-@buf)*SizeOf(WideChar);
+ mGetMem(result,size);
+ move(buf,result^,size);
+end;
+
+procedure SwitchBk(Dialog:hwnd);
+var
+ en:boolean;
+begin
+ en:=IsDlgButtonChecked(Dialog,IDC_FRMUSEPIC)<>BST_UNCHECKED;
+ EnableWindow(GetDlgItem(Dialog,IDC_FRMBKPIC ),en);
+ EnableWindow(GetDlgItem(Dialog,IDC_FRMPICBTN),en);
+ EnableWindow(GetDlgItem(Dialog,IDC_CENTERX ),en);
+ EnableWindow(GetDlgItem(Dialog,IDC_CENTERY ),en);
+ EnableWindow(GetDlgItem(Dialog,IDC_TILEX ),en);
+ EnableWindow(GetDlgItem(Dialog,IDC_TILEY ),en);
+ EnableWindow(GetDlgItem(Dialog,IDC_STRETCHX ),en);
+ EnableWindow(GetDlgItem(Dialog,IDC_STRETCHY ),en);
+ EnableWindow(GetDlgItem(Dialog,IDC_PROP ),en);
+ EnableWindow(GetDlgItem(Dialog,IDC_BOTTOM ),en);
+ EnableWindow(GetDlgItem(Dialog,IDC_RIGHT ),en);
+ EnableWindow(GetDlgItem(Dialog,IDC_USECOVER ),en);
+end;
+
+function FrameViewDlg(Dialog:HWnd; hMessage,wParam,lParam:DWord):integer; stdcall;
+const
+ DlgInited:boolean=false;
+var
+ tmp:cardinal;
+ buf1:PAnsiChar;
+ buf:PAnsiChar;
+ p:PAnsiChar;
+ tmpb:longbool;
+ pcw,tmpPicName:pWideChar;
+ D:PWATFrameData;
+begin
+ result:=0;
+ case hMessage of
+ WM_INITDIALOG: begin
+ DlgInited:=false;
+
+ TranslateDialogDefault(Dialog);
+ D:=FrameCtrl.CustomData;
+
+ SendDlgItemMessage(Dialog,IDC_FRMALPHA,TBM_SETRANGE,0,MAKELONG(0,255));
+ SendDlgItemMessage(Dialog,IDC_FRMALPHA,TBM_SETPOS,1,D.FrmAlpha);
+
+ if (D.ShowControls and scButtons )<>0 then CheckDlgButton(Dialog,IDC_SHOWCTRLS,BST_CHECKED);
+ if (D.ShowControls and scTrackBar)<>0 then CheckDlgButton(Dialog,IDC_SHOWBAR ,BST_CHECKED);
+ if (D.ShowControls and scText )<>0 then CheckDlgButton(Dialog,IDC_SHOWTEXT ,BST_CHECKED);
+ if (D.ShowControls and scVolume )<>0 then CheckDlgButton(Dialog,IDC_SHOWVOLUM,BST_CHECKED);
+ if (D.ShowControls and scGap )<>0 then CheckDlgButton(Dialog,IDC_BTNGAP ,BST_CHECKED);
+
+ MakeHint(Dialog,IDC_MANUALPLACE,
+ 'Use manual frame elements placement. Doubleclick on free space to start designer.');
+ CheckDlgButton(Dialog,IDC_MANUALPLACE,ORD(D.ManualPlacement));
+
+ CheckDlgButton(Dialog,IDC_HIDEFRAMEPLAYER,ORD(D.HideNoPlayer));
+ CheckDlgButton(Dialog,IDC_HIDEFRAMEMUSIC ,ORD(D.HideNoMusic));
+ EnableWindow(GetDlgItem(Dialog,IDC_HIDEFRAMEMUSIC),D.HideNoPlayer);
+
+ SendDlgItemMessage(Dialog,IDC_FRMCOLOR,CPM_SETCOLOUR,0,D.BkColor);
+ SendDlgItemMessage(Dialog,IDC_FRMCOLOR,CPM_SETDEFAULTCOLOUR,0,GetSysColor(COLOR_BTNFACE));
+ SetDlgItemInt(Dialog,IDC_FRMCOLOR,D.BkColor,false);
+
+ if D.UseBkPicture then
+ CheckDlgButton(Dialog,IDC_FRMUSEPIC,ORD(D.UseBkPicture));
+ if D.BkDefFile=nil then
+ p:=''
+ else
+ p:=D.BkDefFile;
+ SetDlgItemTextA(Dialog,IDC_FRMBKPIC,p);
+ CheckDlgButton(Dialog,IDC_USECOVER,ORD(D.UseCover));
+
+ tmp:=D.UpdInterval;
+ if (tmp>=1000) and (tmp mod 1000=0) then
+ tmp:=tmp div 1000;
+ SetDlgItemInt(Dialog,IDC_TIMER,tmp,false);
+
+ SetDlgItemInt(Dialog,IDC_PADDING_LEFT ,D.padding.left ,false);
+ SetDlgItemInt(Dialog,IDC_PADDING_TOP ,D.padding.top ,false);
+ SetDlgItemInt(Dialog,IDC_PADDING_RIGHT ,D.padding.right ,false);
+ SetDlgItemInt(Dialog,IDC_PADDING_BOTTOM,D.padding.bottom,false);
+
+ if (D.BkMode and frbkCenterX )<>0 then CheckDlgButton(Dialog,IDC_CENTERX ,BST_CHECKED);
+ if (D.BkMode and frbkCenterY )<>0 then CheckDlgButton(Dialog,IDC_CENTERY ,BST_CHECKED);
+ if (D.BkMode and frbkTileX )<>0 then CheckDlgButton(Dialog,IDC_TILEX ,BST_CHECKED);
+ if (D.BkMode and frbkTileY )<>0 then CheckDlgButton(Dialog,IDC_TILEY ,BST_CHECKED);
+ if (D.BkMode and frbkStretchX )<>0 then CheckDlgButton(Dialog,IDC_STRETCHX,BST_CHECKED);
+ if (D.BkMode and frbkStretchY )<>0 then CheckDlgButton(Dialog,IDC_STRETCHY,BST_CHECKED);
+ if (D.BkMode and frbkProportional)<>0 then CheckDlgButton(Dialog,IDC_PROP ,BST_CHECKED);
+ if (D.BkMode and frbkBottom )<>0 then CheckDlgButton(Dialog,IDC_BOTTOM ,BST_CHECKED);
+ if (D.BkMode and frbkRight )<>0 then CheckDlgButton(Dialog,IDC_RIGHT ,BST_CHECKED);
+
+ SwitchBk(Dialog);
+
+ DlgInited:=true;
+ end;
+
+ WM_HSCROLL: begin
+ if DlgInited then
+ SendMessage(GetParent(Dialog),PSM_CHANGED,0,0);
+ end;
+
+ WM_COMMAND: begin
+ if (wParam shr 16)=BN_CLICKED then
+ begin
+ case LoWord(wParam) of
+ IDC_HIDEFRAMEPLAYER: begin
+ EnableWindow(GetDlgItem(Dialog,IDC_HIDEFRAMEMUSIC),
+ IsDlgButtonChecked(Dialog,IDC_HIDEFRAMEPLAYER)<>BST_UNCHECKED);
+ end;
+
+ IDC_FRMUSEPIC: begin
+ SwitchBk(Dialog);
+ end;
+
+ IDC_FRMPICBTN: begin
+ pcw:=MakePicFilter;
+ tmpPicName:=GetDlgText(Dialog,IDC_FRMBKPIC);
+ mGetMem(buf,1024);
+ if ShowDlgW(pWideChar(buf),tmpPicName,pcw) then
+ SetDlgItemTextW(Dialog,IDC_FRMBKPIC,pWideChar(buf));
+ mFreeMem(buf);
+ mFreeMem(tmpPicName);
+ mFreeMem(pcw);
+ end;
+ end;
+ end;
+
+ if DlgInited then
+ if ((wParam shr 16)=BN_CLICKED) or
+ ((wParam shr 16)=EN_CHANGE) or
+ ((wParam shr 16)=CPN_COLOURCHANGED) then
+ begin
+ SendMessage(GetParent(Dialog),PSM_CHANGED,0,0);
+ end;
+ end;
+
+ WM_NOTIFY: begin
+ if integer(PNMHdr(lParam)^.code)=PSN_APPLY then
+ begin
+ D:=FrameCtrl.CustomData;
+ // Alpha channel
+ tmp:=SendDlgItemMessage(Dialog,IDC_FRMALPHA,TBM_GETPOS,0,0);
+ if tmp<>Cardinal(D.FrmAlpha) then
+ begin
+ D.FrmAlpha:=tmp;
+ if D.FrameId>=0 then
+ FrameCtrl.SetAlpha(D.FrmAlpha);
+ end;
+
+ // show/hide controls
+ tmp:=0;
+ if IsDlgButtonChecked(Dialog,IDC_SHOWCTRLS)<>BST_UNCHECKED then tmp:=tmp or scButtons;
+ if IsDlgButtonChecked(Dialog,IDC_SHOWBAR )<>BST_UNCHECKED then tmp:=tmp or scTrackBar;
+ if IsDlgButtonChecked(Dialog,IDC_SHOWTEXT )<>BST_UNCHECKED then tmp:=tmp or scText;
+ if IsDlgButtonChecked(Dialog,IDC_SHOWVOLUM)<>BST_UNCHECKED then tmp:=tmp or scVolume;
+ if IsDlgButtonChecked(Dialog,IDC_BTNGAP )<>BST_UNCHECKED then tmp:=tmp or scGap;
+ D.ShowControls:=tmp;
+
+ tmp:=IsDlgButtonChecked(Dialog,IDC_MANUALPLACE);
+ // From Auto to Manual = keep position
+ if (tmp<>BST_UNCHECKED) and not D.ManualPlacement then D.Loaded:=$FFFF;
+ D.ManualPlacement:=tmp<>BST_UNCHECKED;
+
+ // Frame background
+ tmpb:=IsDlgButtonChecked(Dialog,IDC_USECOVER)<>BST_UNCHECKED;
+ if tmpb<>D.UseCover then
+ begin
+ D.UseCover:=tmpb;
+ end;
+ tmpb:=IsDlgButtonChecked(Dialog,IDC_FRMUSEPIC)<>BST_UNCHECKED;
+ if tmpb<>D.UseBkPicture then
+ begin
+ D.UseBkPicture:=tmpb;
+ end;
+ tmp:=SendDlgItemMessage(Dialog,IDC_FRMCOLOR,CPM_GETCOLOUR,0,0);
+ if tmp<>D.BkColor then
+ begin
+ D.BkColor:=tmp;
+ end;
+
+ mGetMem(buf1,1024{*SizeOf(WideChar)});
+ buf1^:=#0;
+ buf:=GetDlgText(Dialog,IDC_FRMBKPIC,true);
+ CallService(MS_UTILS_PATHTORELATIVE,dword(buf),dword(buf1));
+ if StrCmp(buf1,D.BkDefFile)<>0 then
+ begin
+ mFreeMem(D.BkDefFile);
+ StrDup(D.BkDefFile,buf1);
+ end;
+ mFreeMem(buf);
+ mFreeMem(buf1);
+
+ // Picture effects
+ tmp:=0;
+ if IsDlgButtonchecked(Dialog,IDC_CENTERX )<>BST_UNCHECKED then tmp:=tmp or frbkCenterX;
+ if IsDlgButtonchecked(Dialog,IDC_CENTERY )<>BST_UNCHECKED then tmp:=tmp or frbkCenterY;
+ if IsDlgButtonchecked(Dialog,IDC_BOTTOM )<>BST_UNCHECKED then tmp:=tmp or frbkBottom;
+ if IsDlgButtonchecked(Dialog,IDC_RIGHT )<>BST_UNCHECKED then tmp:=tmp or frbkRight;
+ if IsDlgButtonchecked(Dialog,IDC_TILEX )<>BST_UNCHECKED then tmp:=tmp or frbkTileX;
+ if IsDlgButtonchecked(Dialog,IDC_TILEY )<>BST_UNCHECKED then tmp:=tmp or frbkTileY;
+ if IsDlgButtonchecked(Dialog,IDC_STRETCHX)<>BST_UNCHECKED then tmp:=tmp or frbkStretchX;
+ if IsDlgButtonchecked(Dialog,IDC_STRETCHY)<>BST_UNCHECKED then tmp:=tmp or frbkStretchY;
+ if IsDlgButtonchecked(Dialog,IDC_PROP )<>BST_UNCHECKED then tmp:=tmp or frbkProportional;
+
+ if tmp<>D.BkMode then
+ begin
+ D.BkMode:=tmp;
+ end;
+
+ // Hide frame option
+ tmpb :=IsDlgButtonChecked(Dialog,IDC_HIDEFRAMEPLAYER)<>BST_UNCHECKED;
+ if tmpb<>D.HideNoPlayer then
+ begin
+ D.HideNoPlayer:=tmpb;
+ end;
+ tmpb:=IsDlgButtonChecked(Dialog,IDC_HIDEFRAMEMUSIC)<>BST_UNCHECKED;
+ if tmpb<>D.HideNoMusic then
+ begin
+ D.HideNoMusic:=tmpb;
+ end;
+
+ // Padding
+ tmp:=GetDlgItemInt(Dialog,IDC_PADDING_LEFT,tmpb,false);
+ if integer(tmp)<>D.padding.left then
+ begin
+ D.padding.left:=tmp;
+ end;
+ tmp:=GetDlgItemInt(Dialog,IDC_PADDING_TOP,tmpb,false);
+ if integer(tmp)<>D.padding.top then
+ begin
+ D.padding.top:=tmp;
+ end;
+ tmp:=GetDlgItemInt(Dialog,IDC_PADDING_RIGHT,tmpb,false);
+ if integer(tmp)<>D.padding.right then
+ begin
+ D.padding.right:=tmp;
+ end;
+ tmp:=GetDlgItemInt(Dialog,IDC_PADDING_BOTTOM,tmpb,false);
+ if integer(tmp)<>D.padding.bottom then
+ begin
+ D.padding.bottom:=tmp;
+ end;
+
+ tmp:=GetDlgItemInt(Dialog,IDC_TIMER,tmpb,false);
+ if tmp>0 then
+ begin
+ if tmp<100 then
+ tmp:=tmp*1000;
+ if tmp<200 then
+ tmp:=200;
+ end;
+
+ if tmp<>D.UpdInterval then
+ begin
+ D.UpdInterval:=tmp;
+ end;
+
+ FrameCtrl.SaveSettings;
+ end;
+ end;
+ else
+ {result:=}DefWindowProc(Dialog,hMessage,wParam,lParam);
+ end;
+end;
diff --git a/plugins/Watrack/kolframe/frm_dlg2.inc b/plugins/Watrack/kolframe/frm_dlg2.inc
new file mode 100644
index 0000000000..6325e05fcd
--- /dev/null
+++ b/plugins/Watrack/kolframe/frm_dlg2.inc
@@ -0,0 +1,172 @@
+{Frame text}
+const
+ MaxTxtScrollSpeed = 20;
+
+function FrameTextDlg(Dialog:HWnd; hMessage,wParam,lParam:DWord):integer; stdcall;
+const
+ DlgInited :boolean=false;
+ TemplateChanged:Boolean=false;
+var
+ tmp,tmp1:integer;
+ tmpb:longbool;
+ pcf:TCHOOSEFONT;
+ lf:LOGFONTW;
+begin
+ result:=0;
+
+ case hMessage of
+ WM_DESTROY: begin
+ // new - if Apply, old - if cancel
+ if FrameCtrl<>nil then // for case when FrameCtrl was destryed already
+ if PWATFrameData(FrameCtrl.CustomData).TextBlock<>nil then
+ PWATFrameData(FrameCtrl.CustomData).TextBlock.FontData:=TextLF;
+ end;
+
+ WM_INITDIALOG: begin
+ DlgInited:=false;
+ TranslateDialogDefault(Dialog);
+ with PWATFrameData(FrameCtrl.CustomData).TextBlock^ do
+ begin
+ case LoByte(Effects) of
+ effWrap: tmp:=IDC_EFF_WRAP;
+ effRoll: tmp:=IDC_EFF_ROLL;
+ effPong: tmp:=IDC_EFF_PONG;
+ else // like effCut
+ tmp:=IDC_EFF_CUT;
+ end;
+ CheckDlgButton(Dialog,tmp,BST_CHECKED);
+
+ SetDlgItemInt(Dialog,IDC_TIMER,UpdateTime,false);
+
+ SetDlgItemInt(Dialog,IDC_ROLLSTEP,RollStep,false);
+ SetDlgItemInt(Dialog,IDC_ROLLGAP ,RollGap ,false);
+ // SetDlgItemInt(Dialog,IDC_ROLLTAIL,RollTail,false);
+
+ CheckDlgButton(Dialog,IDC_ALCENTER,ord((Effects and effCenter)<>0));
+
+ SetDlgItemTextW(Dialog,IDC_FRAME_TEXT,PWATFrameData(FrameCtrl.CustomData).Template);
+ end;
+
+ SendDlgItemMessage(Dialog,IDC_MACRO_HELP,BM_SETIMAGE,IMAGE_ICON,
+ CallService(MS_SKIN_LOADICON,SKINICON_OTHER_HELP,0));
+
+ TemplateChanged:=false;
+ DlgInited:=true;
+ end;
+
+ WM_COMMAND: begin
+ case (wParam shr 16) of
+ EN_CHANGE: begin
+ if Loword(wParam)=IDC_FRAME_TEXT then
+ TemplateChanged:=True;
+ end;
+
+ BN_CLICKED: begin
+ case LoWord(wParam) of
+ IDC_MACRO_HELP: CallService(MS_WAT_MACROHELP,Dialog,0);
+ IDC_FRMFONT: begin
+ with PWATFrameData(FrameCtrl.CustomData).TextBlock^ do
+ begin
+ lf:=FontData;
+ // lf:=TextLF;
+ FillChar(pcf,sizeOf(pcf),0);
+ with pcf do
+ begin
+ lStructSize:=SizeOf(pcf);
+ lpLogFont:=@lf;
+ Flags:=CF_EFFECTS+CF_FORCEFONTEXIST+CF_LIMITSIZE+CF_NOVERTFONTS+
+ CF_SCREENFONTS+CF_INITTOLOGFONTSTRUCT;
+ rgbColors:=TextColor;
+ nSizeMin:=6;
+ nSizeMax:=32;
+ end;
+ if ChooseFont(pcf) then
+ begin
+ FontData:=lf; // paint directly
+ TextColor:=pcf.rgbColors;
+ SendMessage(GetParent(Dialog),PSM_CHANGED,0,0);
+ end
+ else
+ exit;
+ end;
+ end;
+ end;
+ end;
+ end;
+
+ if DlgInited then
+ case wParam shr 16 of
+ BN_CLICKED,
+ EN_CHANGE: begin
+ SendMessage(GetParent(Dialog),PSM_CHANGED,0,0);
+ end;
+ end;
+ end;
+
+ WM_NOTIFY: begin
+ if integer(PNMHdr(lParam)^.code)=PSN_APPLY then
+ begin
+// redraw:=false;
+ with PWATFrameData(FrameCtrl.CustomData).TextBlock^ do
+ begin
+ tmp:=GetDlgItemInt(Dialog,IDC_TIMER,tmpb,false);
+ if tmp>MaxTxtScrollSpeed then
+ tmp:=MaxTxtScrollSpeed;
+
+ if tmp<>UpdateTime then
+ begin
+ UpdateTime:=tmp;
+{
+ if UpdTimer<>0 then
+ KillTimer(FrameWnd,UpdTimer);
+ if (UpdInterval>0) and (FrameWnd<>0) then
+ UpdTimer:=SetTimer(FrameWnd,TMR_TEXT,(MaxTxtScrollSpeed+1-UpdInterval)*100,nil)
+ else
+ UpdTimer:=0;
+}
+ end;
+
+ // Text effects
+ if IsDlgButtonChecked(Dialog,IDC_EFF_CUT )<>BST_UNCHECKED then tmp:=effCut
+ else if IsDlgButtonChecked(Dialog,IDC_EFF_WRAP)<>BST_UNCHECKED then tmp:=effWrap
+ else if IsDlgButtonChecked(Dialog,IDC_EFF_ROLL)<>BST_UNCHECKED then tmp:=effRoll
+ else if IsDlgButtonChecked(Dialog,IDC_EFF_PONG)<>BST_UNCHECKED then tmp:=effPong;
+ if IsDlgButtonChecked(Dialog,IDC_ALCENTER)<>BST_UNCHECKED then
+ tmp:=tmp or effCenter;
+ Effects:=tmp;
+
+ tmp1:=GetDlgItemInt(Dialog,IDC_ROLLSTEP,tmpb,false);
+ if tmp1<>RollStep then
+ begin
+ RollStep:=tmp1;
+ end;
+ tmp1:=GetDlgItemInt(Dialog,IDC_ROLLGAP ,tmpb,false);
+ if tmp1<>RollGap then
+ begin
+ RollGap:=tmp1;
+ end;
+ {
+ tmp1:=GetDlgItemInt(Dialog,IDC_ROLLTAIL,tmpb,false);
+ if tmp1<>RollTail then
+ begin
+ RollTail:=tmp1;
+ end;
+ }
+
+ if TemplateChanged then
+ begin
+ mFreeMem(PWATFrameData(FrameCtrl.CustomData).Template);
+ PWATFrameData(FrameCtrl.CustomData).Template:=GetDlgText(Dialog,IDC_FRAME_TEXT);
+ end;
+
+ TextLF:=FontData; // OK - saving for future?
+
+ SaveTextSettings(TemplateChanged);
+ TemplateChanged:=false;
+ end;
+ end;
+ end;
+ else
+ {result:=}DefWindowProc(Dialog,hMessage,wParam,lParam);
+ end;
+end;
diff --git a/plugins/Watrack/kolframe/frm_frame.inc b/plugins/Watrack/kolframe/frm_frame.inc
new file mode 100644
index 0000000000..8c3034327c
--- /dev/null
+++ b/plugins/Watrack/kolframe/frm_frame.inc
@@ -0,0 +1,497 @@
+{Frame + background}
+
+const
+ WS_EX_LAYERED = $00080000;
+
+function SetLayeredWindowAttributes(Hwnd: THandle; crKey: COLORREF; bAlpha: Byte; dwFlags: DWORD): Boolean; stdcall;
+ external user32 name 'SetLayeredWindowAttributes';
+
+const
+ defFrameText = '%artist% - %title%';
+
+const
+// opt_HiddenByMe:PAnsiChar = 'frame/hiddenbyme';
+ opt_ShowCtrls :PAnsiChar = 'frame/showcontrols';
+ opt_FrmUsePic :PAnsiChar = 'frame/frmusepic';
+ opt_FrmUseCvr :PAnsiChar = 'frame/frmusecover';
+ opt_FrmBkColor:PAnsiChar = 'frame/frmbkcolor';
+ opt_FrmBkPic :PAnsiChar = 'frame/frmbkpic';
+ opt_FrmBkMode :PAnsiChar = 'frame/frmbkmode';
+ opt_FrmAlpha :PAnsiChar = 'frame/frmalpha';
+ opt_HideFrameM:PAnsiChar = 'frame/hideframem';
+ opt_HideFrameP:PAnsiChar = 'frame/hideframep';
+ opt_FrmTimer :PAnsiChar = 'frame/frametimer';
+ opt_PadLeft :PAnsiChar = 'frame/paddingleft';
+ opt_PadTop :PAnsiChar = 'frame/paddingtop';
+ opt_PadRight :PAnsiChar = 'frame/paddingright';
+ opt_PadBottom :PAnsiChar = 'frame/paddingbottom';
+ opt_Manual :PAnsiChar = 'frame/manualplacement';
+
+procedure TWATFrame.ResetFrame;
+var
+ D:PWATFrameData;
+begin
+ D:=CustomData;
+ if D.Trackbar <>nil then ResetTrackbar(D.Trackbar);
+ if D.TextBlock<>nil then D.TextBlock.BlockText:=nil;
+// frame back to default
+ RefreshPicture(nil);
+end;
+
+procedure FrameTimerProc(wnd:HWND;uMsg:uint;idEvent:uint_ptr;dwTime:dword); stdcall;
+var
+ psi:pSongInfo;
+ D:PWATFrameData;
+begin
+ D:=FrameCtrl.CustomData;
+
+ if IsFrameHidden(D.FrameId) then
+ begin
+ if not D.wasHidden then
+ begin
+ D.wasHidden:=true;
+ D.TextBlock.UpdateTime:=0;
+ end;
+ exit;
+ end
+ else if D.wasHidden and (D.TextBlock.UpdateTime=0) then
+ begin
+ D.wasHidden:=false;
+ if (D.ShowControls and scText)<>0 then
+ D.TextBlock.UpdateTime:=DBReadWord(0,PluginShort,opt_TxtTimer,10);
+ end;
+
+ if D.Trackbar<>nil then
+ begin
+ if (CallService(MS_WAT_GETMUSICINFO,WAT_INF_CHANGES,dword(@psi))<>WAT_PLS_NOTFOUND) then
+ begin
+ SetTrackBarPosition(D.Trackbar,(psi^.time*1000) div D.UpdInterval)
+ end;
+ end;
+
+ UpdateTextBlock(D,false); // false - check for %percent%/%time%
+
+ FrameCtrl.Update;
+end;
+
+procedure TWATFrame.AdjustFrame;
+var
+ h:integer;
+ D:PWATFrameData;
+begin
+ D:=CustomData;
+
+ if D.ManualPlacement then
+ begin
+ if D.Trackbar <>nil then D.Trackbar .Anchor(false,false,false,false);
+ if D.TextBlock<>nil then D.TextBlock.Anchor(false,false,false,false);
+ DesignerLoadSettings;
+ exit;
+ end;
+
+ h:=Height; // or need to get FRAME height
+
+ if D.Trackbar<>nil then
+ begin
+ D.Trackbar.SetSize(Width-16,18);
+ dec(h,D.Trackbar.Height);
+ D.Trackbar.SetPosition(8,h);
+ D.Trackbar.Anchor(true,false,true,true);
+ end;
+
+ if (D.ShowControls and scButtons)<>0 then
+ begin
+ AdjustButtons(h-16-BtnGap);
+ dec(h,16+2*BtnGap);
+ end;
+
+ if D.TextBlock<>nil then
+ begin
+ D.TextBlock.Top :=awkTextPad;
+ D.TextBlock.Height:=h-D.TextBlock.Top;
+ D.TextBlock.Anchor(true,true,true,true);
+ end;
+end;
+
+procedure TWATFrame.SaveSettings;
+var
+ D:PWATFrameData;
+begin
+ D:=CustomData;
+ DBWriteByte (0,PluginShort,opt_Manual ,ord(D.ManualPlacement));
+ DBWriteByte (0,PluginShort,opt_HideFrameM,ord(D.HideNoMusic));
+ DBWriteByte (0,PluginShort,opt_HideFrameP,ord(D.HideNoPlayer));
+ DBWriteByte (0,PluginShort,opt_FrmUsePic ,ord(D.UseBkPicture));
+ DBWriteByte (0,PluginShort,opt_FrmUseCvr ,ord(D.UseCover));
+ DBWriteDWord (0,PluginShort,opt_FrmBkColor,D.BkColor);
+ DBWriteWord (0,PluginShort,opt_FrmBkMode ,D.BkMode);
+ DBWriteDWord (0,PluginShort,opt_ShowCtrls ,D.ShowControls);
+ DBWriteByte (0,PluginShort,opt_FrmAlpha ,D.FrmAlpha);
+ DBWriteWord (0,PluginShort,opt_FrmTimer ,D.UpdInterval);
+ DBWriteWord (0,PluginShort,opt_PadLeft ,D.padding.left);
+ DBWriteWord (0,PluginShort,opt_PadTop ,D.padding.top);
+ DBWriteWord (0,PluginShort,opt_PadRight ,D.padding.right);
+ DBWriteWord (0,PluginShort,opt_PadBottom ,D.padding.bottom);
+ DBWriteString(0,PluginShort,opt_FrmBkPic ,D.BkDefFile);
+
+ CheckControls;
+ AdjustFrame;
+ RefreshPicture;
+ InvalidateRect(FrameCtrl.GetWindowHandle,nil,true);
+ FrameCtrl.Update;
+
+ if D.UpdTimer<>0 then // FrameWnd MUST be present
+ begin
+ KillTimer(0,D.UpdTimer);
+ D.UpdTimer:=0;
+ end;
+ if D.UpdInterval>0 then
+ begin
+ D.UpdTimer:=SetTimer(0,0,D.UpdInterval,@FrameTimerProc);
+ end;
+end;
+
+procedure TWATFrame.LoadSettings;
+var
+ D:PWATFrameData;
+begin
+ D:=CustomData;
+ D.ManualPlacement:=DBReadByte (0,PluginShort,opt_Manual ,0)<>0;
+ D.HideNoMusic :=DBReadByte (0,PluginShort,opt_HideFrameM,0)<>0;
+ D.HideNoPlayer :=DBReadByte (0,PluginShort,opt_HideFrameP,0)<>0;
+ D.UseBkPicture :=DBReadByte (0,PluginShort,opt_FrmUsePic ,0)<>0;
+ D.UseCover :=DBReadByte (0,PluginShort,opt_FrmUseCvr ,0)<>0;
+ D.BkColor :=DBReadDWord(0,PluginShort,opt_FrmBkColor,$00E0E0E0);
+ D.BkMode :=DBReadWord (0,PluginShort,opt_FrmBkMode ,frbkCenter);
+ D.ShowControls :=DBReadDWord(0,PluginShort,opt_ShowCtrls ,scAll);
+ D.FrmAlpha :=DBReadByte (0,PluginShort,opt_FrmAlpha ,255);
+
+ D.UpdInterval:=DBReadWord(0,PluginShort,opt_FrmTimer,200);
+ if D.UpdInterval<100 then
+ D.UpdInterval:=D.UpdInterval*1000;
+
+ D.padding.left :=DBReadWord(0,PluginShort,opt_PadLeft ,0);
+ D.padding.top :=DBReadWord(0,PluginShort,opt_PadTop ,0);
+ D.padding.right :=DBReadWord(0,PluginShort,opt_PadRight ,0);
+ D.padding.bottom:=DBReadWord(0,PluginShort,opt_PadBottom,0);
+
+ D.BkDefFile:=DBReadString(0,PluginShort,opt_FrmBkPic,nil);
+ //!!!! saving NOT in TextBlock
+ D.Template:=DBReadUnicode(0,PluginShort,opt_FrameText,DefFrameText);
+end;
+
+{$include i_bitmap.inc}
+
+procedure TWATFrame.SetAlpha(value:integer);
+const
+ LWA_COLORKEY = $00000001;
+ LWA_ALPHA = $00000002;
+var
+ wnd:HWND;
+ x:cardinal;
+begin
+ if IsFrameFloated(PWATFrameData(CustomData).FrameId) then
+ begin
+ wnd:=GetParent(FrameCtrl.GetWindowHandle);
+ x:=GetWindowLongW(wnd,GWL_EXSTYLE);
+ if value<>255 then
+ begin
+ if (x and WS_EX_LAYERED)=0 then
+ SetWindowLongW(wnd,GWL_EXSTYLE,x or WS_EX_LAYERED);
+ SetLayeredWindowAttributes(wnd,0,value,LWA_ALPHA);
+ end
+ else if (x and WS_EX_LAYERED)<>0 then
+ SetWindowLongW(wnd,GWL_EXSTYLE,x and not WS_EX_LAYERED);
+ end;
+end;
+
+procedure TWATFrame.FrameResize(Sender: PObj);
+var
+ tmpBmp:HBITMAP;
+ D:PWATFrameData;
+begin
+ D:=CustomData;
+ if D.BkDC<>0 then
+ begin
+ tmpBmp:=GetCurrentObject(D.BkDC,OBJ_BITMAP);
+ DeleteDC(D.BkDC);
+ D.BkDC:=0;
+ DeleteObject(tmpBmp);
+ end;
+ AdjustFrame;
+end;
+
+procedure BkTimerProc(wnd:HWND;uMsg:uint;idEvent:uint_ptr;dwTime:dword); stdcall;
+var
+ D:PWATFrameData;
+begin
+ D:=FrameCtrl.CustomData;
+ KillTimer(0,D.BkTimer);
+ D.BkTimer:=0;
+ DeleteObject(D.BkBitmap);
+ D.BkBitmap:=0;
+end;
+
+procedure TWATFrame.RefreshPicture(cover:PAnsiChar=nil);
+var
+ D:PWATFrameData;
+begin
+ D:=CustomData;
+ if D.BkBitmap<>0 then
+ BkTimerProc(0,0,0,0); // remove old picture
+
+ FrameResize(nil); // clear frame bitmap buffer
+
+ if D.UseBkPicture then
+ D.BkBitmap:=LoadBkPicture(cover,true,D.BkDefFile);
+
+ if D.BkBitmap=HBITMAP(-1) then // same file
+ D.BkBitmap:=0;
+ Update;
+end;
+
+procedure TWATFrame.Paint(Sender: PControl; DC: HDC);
+var
+ rc: TRect;
+ br:HBRUSH;
+ D:PWATFrameData;
+begin
+ D:=CustomData;
+ GetClientRect(Sender.Handle,rc);
+ if D.UseBkPicture then
+ begin
+ if D.BkDC=0 then
+ begin
+ if D.BkBitmap=0 then
+ begin
+ if (D.BkFile<>nil) and (D.BkFile^<>#0) then
+ D.BkBitmap:=CallService(MS_UTILS_LOADBITMAP,0,dword(D.BkFile));
+ end;
+
+ if D.BkBitmap<>0 then
+ begin
+ PreparePicture(dc,rc);
+ D.BkTimer:=SetTimer(0,0,10000,@BkTimerProc);
+ end;
+ end;
+ if D.BkDC<>0 then
+ begin
+ BitBlt(dc,rc.left,rc.top,rc.right-rc.left,rc.bottom-rc.top,
+ D.BkDC,rc.left,rc.top,SRCCOPY);
+ exit;
+ end;
+ end;
+
+ InflateRect(rc,1,1);
+ br:=CreateSolidBrush(D.BkColor);
+ FillRect(dc,rc,br);
+ DeleteObject(br);
+end;
+
+// JUST LOAD picture, no matter, which transforms
+// Backname = from settings, Covername = from data (higher priority)
+// -1 - same file, 0 - can't load, other - new bitmap
+function TWATFrame.LoadBkPicture(CoverFName:PAnsiChar;check:boolean=false;
+ BackFName:PAnsiChar=nil):integer;
+var
+ tmpstr:PAnsiChar;
+ D:PWATFrameData;
+begin
+ result:=0;
+ D:=CustomData;
+
+ // check the same file, ie only 'next pic'
+ if (CoverFName<>nil) and (CoverFName^<>#0) then
+ begin
+ if check and (StrCmp(CoverFName,D.BkFile)=0) then
+ begin
+ result:=-1;
+ Exit;
+ end;
+
+ result:=CallService(MS_UTILS_LOADBITMAP,0,dword(CoverFName));
+ if result<>0 then
+ begin
+ mFreeMem(D.BkFile);
+ StrDup(D.BkFile,CoverFName);
+ Exit;
+ end;
+ end;
+
+ if (BackFName<>nil) and (BackFName^<>#0) then
+ begin
+ tmpstr:=ParseVarString(BackFName);
+ if (tmpstr<>nil) and (tmpstr^<>#0) then
+ begin
+ if (not check) or (StrCmp(tmpstr,D.BkFile)<>0) then
+ begin
+ result:=CallService(MS_UTILS_LOADBITMAP,0,dword(tmpstr));
+ if result<>0 then
+ begin
+ mFreeMem(D.BkFile);
+ StrDup(D.BkFile,tmpstr);
+ end;
+ end
+ else
+ result:=-1;
+ end;
+ mFreeMem(tmpstr);
+ end;
+end;
+
+procedure TWATFrame.ClearBitmapData;
+var
+ D:PWATFrameData;
+ tmpBmp:HBITMAP;
+begin
+ D:=CustomData;
+
+ if D.BkTimer<>0 then
+ begin
+ KillTimer(0,D.BkTimer);
+ D.BkTimer:=0;
+ end;
+ if D.BkDC<>0 then
+ begin
+ tmpBmp:=GetCurrentObject(D.BkDC,OBJ_BITMAP);
+ DeleteDC(D.BkDC);
+ D.BkDC:=0;
+ DeleteObject(tmpBmp);
+ end;
+ if D.BkBitmap<>0 then
+ begin
+ DeleteObject(D.BkBitmap);
+ D.BkBitmap:=0;
+ end;
+ mFreeMem(D.BkFile);
+end;
+
+procedure TWATFrame.MyDestroy(sender:PObj);
+var
+ D:PWATFrameData;
+begin
+ D:=CustomData;
+ if D.UpdTimer<>0 then
+ begin
+ KillTimer(0,D.UpdTimer);
+ D.UpdTimer:=0;
+ end;
+
+ mFreeMem(D.Template);
+ mFreeMem(D.BkDefFile);
+ ClearBitmapData;
+
+ if D.Designer<>nil then
+ begin
+ D.Designer.Free;
+ D.Designer:=nil;
+ end;
+
+end;
+
+procedure TWATFrame.RefreshAllFrameIcons;
+var
+ D:PWATFrameData;
+begin
+ D:=CustomData;
+ if (D.ShowControls and scButtons)<>0 then RefreshButtonIcons;
+ if D.Trackbar<>nil then RefreshTrackbarIcons(D.Trackbar);
+end;
+
+procedure TWATFrame.CheckControls;
+var
+ D:PWATFrameData;
+ psi:pSongInfo;
+begin
+ D:=CustomData;
+
+ if (D.ShowControls and scTrackBar)<>0 then
+ begin
+ if D.Trackbar=nil then
+ begin
+ RegisterButtonIcons;
+ D.Trackbar:=MakeNewTrackbar(@self);
+ // for case when TB creating after track start (fastest way)
+ // can use (CallService(MS_WAT_GETMUSICINFO,WAT_INF_CHANGES,dword(@psi))<>WAT_PLS_NOTFOUND)
+ psi:=pointer(CallService(MS_WAT_RETURNGLOBAL,WAT_INF_UNICODE,1));
+ TrackbarSetRange(D.Trackbar,D.UpdInterval,psi^.total);
+ end;
+ end
+ else if D.Trackbar<>nil then
+ begin
+ D.Trackbar.Free;
+ D.Trackbar:=nil;
+ end;
+
+ if (D.ShowControls and scButtons)<>0 then
+ begin
+ if D.btnarray[0]=nil then
+ begin
+ if RegisterButtonIcons then
+ MakeNewButtonGroup;
+ end
+ end
+ else if D.btnarray[0]<>nil then
+ FreeButtons;
+{
+ if (D.ShowControls and scText)<>0 then
+ begin
+}
+ if D.TextBlock=nil then
+ begin
+ D.TextBlock:=MakeTextBlock(@self,D.BkColor);
+ end;
+
+ if (D.ShowControls and scText)<>0 then
+ D.TextBlock.UpdateTime:=DBReadWord(0,PluginShort,opt_TxtTimer,10);
+{
+ end
+ else if D.TextBlock<>nil then
+ begin
+ D.TextBlock.Free;
+ D.TextBlock:=nil;
+ end;
+}
+ if D.UseBkPicture then
+ begin
+ D.BkBitmap:=LoadBkPicture(nil,true,D.BkDefFile);
+ if D.BkBitmap=HBITMAP(-1) then
+ D.BkBitmap:=0;
+ end
+ else
+ ClearBitmapData;
+end;
+
+function CreateFrameWindow(parent:HWND):THANDLE;
+var
+ D:PWATFrameData;
+begin
+ result:=0;
+
+ FrameCtrl:=PWATFrame(NewAlienPanel(parent,esNone));
+ if FrameCtrl<>nil then
+ begin
+ GetMem (D ,SizeOf(TWATFrameData));
+ FillChar(D^,SizeOf(TWATFrameData),0); // clear all including buttons
+ with FrameCtrl^ do
+ begin
+ CustomData:=D;
+ LoadSettings;
+
+ result:=GetWindowHandle;
+
+ CheckControls;
+
+ MinWidth :=80;
+ MinHeight:=30;
+
+ OnPaint :=FrameCtrl.Paint;
+ OnResize :=FrameCtrl.FrameResize;
+// OnMouseDown :=TOnMouse(MakeMethod(nil, @MouseDown));
+ OnMouseDblClk:=FrameCtrl.CreateDesigner;
+ end;
+ FrameCtrl.OnDestroy:=FrameCtrl.MyDestroy;
+// theoretically, must get Resize here.... or after
+// FrameCtrl.AdjustFrame;
+ end;
+end;
diff --git a/plugins/Watrack/kolframe/frm_icogroup.inc b/plugins/Watrack/kolframe/frm_icogroup.inc
new file mode 100644
index 0000000000..2b6e9de6f9
--- /dev/null
+++ b/plugins/Watrack/kolframe/frm_icogroup.inc
@@ -0,0 +1,115 @@
+{Panel = group of icons}
+
+procedure TWATFrame.AdjustButtons(atop:integer);
+var
+ i,lWidth,lOffs,gap:integer;
+ lleft:integer;
+ D:PWATFrameData;
+begin
+ D:=CustomData;
+
+ if D.btnarray[0]=nil then exit;
+
+ if (D.ShowControls and scGap)<>0 then
+ gap:=BtnGap
+ else
+ gap:=0;
+
+ D.btnarray[0].Visible:=(D.ShowControls and scVolume)<>0;
+ D.btnarray[1].Visible:=(D.ShowControls and scVolume)<>0;
+
+ lWidth:=(Length(D.btnarray)-2)*(16+gap)-gap;
+ if (D.ShowControls and scVolume)<>0 then
+ Inc(lWidth, VolBtnDist+2*(16+gap));
+ lLeft:=(Width-lWidth) div 2;
+
+ lOffs:=0;
+ if (D.ShowControls and scVolume)<>0 then
+ begin
+ D.btnarray[0].Left:=lleft+lOffs;
+ D.btnarray[0].Top :=atop;
+ Inc(lOffs,16+gap);
+ D.btnarray[1].Left:=lleft+lOffs;
+ D.btnarray[1].Top :=atop;
+ Inc(lOffs,16+gap+VolBtnDist);
+ end;
+
+ for i:=2 to HIGH(D.btnarray) do
+ begin
+ D.btnarray[i].Left:=lleft+lOffs;
+ D.btnarray[i].Top :=atop;
+ Inc(lOffs,16+gap);
+ end;
+
+end;
+
+procedure TWATFrame.RefreshButtonIcons;
+var
+ i:integer;
+ D:PWATFrameData;
+begin
+ D:=CustomData;
+
+ if D.btnarray[0]<>nil then exit;
+
+ for i:=0 to HIGH(D.btnarray) do
+ D.btnarray[i].RefreshIcon;
+end;
+
+procedure TWATFrame.FreeButtonsDesigner;
+var
+ i:integer;
+ D:PWATFrameData;
+begin
+ D:=CustomData;
+
+ if D.btnarray[0]<>nil then exit;
+
+ for i:=0 to HIGH(D.btnarray) do
+ D.Designer.Disconnect(D.btnarray[i]);
+end;
+
+procedure TWATFrame.MakeButtonsDesigner;
+var
+ i:integer;
+ D:PWATFrameData;
+begin
+ D:=CustomData;
+
+ if D.btnarray[0]<>nil then exit;
+
+ for i:=0 to HIGH(D.btnarray) do
+ D.Designer.Connect('Button',D.btnarray[i],DESIGNER_NORESIZE);
+end;
+
+procedure TWATFrame.FreeButtons;
+var
+ i:integer;
+ D:PWATFrameData;
+begin
+ D:=CustomData;
+
+ if D.btnarray[0]<>nil then exit;
+
+ for i:=0 to HIGH(D.btnarray) do
+ begin
+ D.btnarray[i].Free;
+ D.btnarray[i]:=nil;
+ end;
+end;
+
+procedure TWATFrame.MakeNewButtonGroup;
+var
+ D:PWATFrameData;
+begin
+ D:=CustomData;
+
+ D.btnarray[0]:=CreateIcoButton(@self,waticons.GetIcon,DoAction,WAT_CTRL_VOLDN,300);
+ D.btnarray[1]:=CreateIcoButton(@self,waticons.GetIcon,DoAction,WAT_CTRL_VOLUP,300);
+ D.btnarray[2]:=CreateIcoButton(@self,waticons.GetIcon,DoAction,WAT_CTRL_PREV,2000);
+ D.btnarray[3]:=CreateIcoButton(@self,waticons.GetIcon,DoAction,WAT_CTRL_PLAY);
+ D.btnarray[4]:=CreateIcoButton(@self,waticons.GetIcon,DoAction,WAT_CTRL_PAUSE);
+ D.btnarray[5]:=CreateIcoButton(@self,waticons.GetIcon,DoAction,WAT_CTRL_STOP);
+ D.btnarray[6]:=CreateIcoButton(@self,waticons.GetIcon,DoAction,WAT_CTRL_NEXT,2000);
+end;
+
diff --git a/plugins/Watrack/kolframe/frm_rc.inc b/plugins/Watrack/kolframe/frm_rc.inc
new file mode 100644
index 0000000000..25ac437b3b
--- /dev/null
+++ b/plugins/Watrack/kolframe/frm_rc.inc
@@ -0,0 +1,56 @@
+{DLG 5 - frame}
+const
+ IDC_HELP_FORMAT = 1025;
+ IDC_HELP_COLOR = 1026;
+ IDC_HELP_VARIABLES = 1027;
+const
+ IDC_TIMER = 1028;
+ IDC_SHOWCTRLS = 1032;
+ IDC_SHOWTEXT = 1033;
+ IDC_SHOWVOLUM = 1034;
+ IDC_FRMCOLOR = 1036;
+ IDC_FRMUSEPIC = 1037;
+ IDC_FRMBKPIC = 1038;
+ IDC_FRMPICBTN = 1039;
+ IDC_CENTERX = 1040;
+ IDC_CENTERY = 1041;
+ IDC_TILEX = 1042;
+ IDC_TILEY = 1043;
+ IDC_STRETCHX = 1044;
+ IDC_STRETCHY = 1045;
+ IDC_PROP = 1046;
+ IDC_BOTTOM = 1047;
+ IDC_RIGHT = 1048;
+ IDC_FRMALPHA = 1049;
+ IDC_TRACKBAR = 1050;
+ IDC_BTNGAP = 1051;
+ IDC_SHOWBAR = 1052;
+ IDC_USECOVER = 1053;
+
+ IDC_HIDEFRAMEMUSIC = 1054;
+ IDC_HIDEFRAMEPLAYER = 1055;
+
+ IDC_PADDING_LEFT = 1056;
+ IDC_PADDING_TOP = 1057;
+ IDC_PADDING_RIGHT = 1058;
+ IDC_PADDING_BOTTOM = 1059;
+
+ IDC_MANUALPLACE = 1060;
+
+{DLG 51 - frame 2}
+ IDC_FRMTXT = 1031;
+ IDC_EFF_CUT = 1032;
+ IDC_EFF_WRAP = 1033;
+ IDC_EFF_ROLL = 1034;
+ IDC_EFF_PONG = 1035;
+ IDC_ROLLSTEP = 1036;
+ IDC_ROLLGAP = 1037;
+// IDC_ROLLTAIL = 1038;
+ IDC_ALCENTER = 1039;
+ IDC_FRMFONT = 1040;
+
+ IDC_FRAME_TEXT = 1041;
+ IDC_MACRO_HELP = 1042;
+
+{Frame}
+ IDC_FRM_POS = 1032;
diff --git a/plugins/Watrack/kolframe/frm_text.inc b/plugins/Watrack/kolframe/frm_text.inc
new file mode 100644
index 0000000000..66c00a1b2b
--- /dev/null
+++ b/plugins/Watrack/kolframe/frm_text.inc
@@ -0,0 +1,90 @@
+{Text}
+
+const
+ TextLF:TLOGFONTW = (
+ lfHeight :-10;
+ lfWidth :0;
+ lfEscapement :0;
+ lfOrientation :0;
+ lfWeight :FW_DONTCARE;
+ lfItalic :0;
+ lfUnderline :0;
+ lfStrikeOut :0;
+ lfCharSet :DEFAULT_CHARSET;
+ lfOutPrecision :OUT_DEFAULT_PRECIS;
+ lfClipPrecision :CLIP_DEFAULT_PRECIS;
+ lfQuality :DEFAULT_QUALITY;
+ lfPitchAndFamily:DEFAULT_PITCH or FF_DONTCARE{;
+ lfFaceName :#0});
+
+const
+ opt_FrmTxtClr :PAnsiChar = 'frame/frametextcolor';
+ opt_FrmFont :PAnsiChar = 'frame/framefont';
+ opt_FrmEffect :PAnsiChar = 'frame/txteffect';
+ opt_RollStep :PAnsiChar = 'frame/rollstep';
+ opt_RollGap :PAnsiChar = 'frame/rollgap';
+// opt_RollTail :PAnsiChar = 'frame/rolltail';
+ opt_AlgnCenter:PAnsiChar = 'frame/aligncenter';
+ opt_TxtTimer :PAnsiChar = 'frame/texttimer';
+ opt_FrameText :PAnsiChar = 'frame/frametext';
+
+procedure UpdateTextBlock(D:PWATFrameData;force:boolean);
+var
+ tmp:pWideChar;
+begin
+ if (D.ShowControls and scText)=0 then exit;
+ if D.TextBlock=nil then exit;
+
+ if not force then
+ begin
+ if (StrPosW(D.Template,'%percent%')=nil) and
+ (StrPosW(D.Template,'%time%' )=nil) then // need to |remake
+ exit;
+ end;
+ tmp:=pWideChar(CallService(MS_WAT_REPLACETEXT,0,dword(D.Template)));
+ D.TextBlock.BlockText:=tmp;
+ mFreeMem(tmp);
+end;
+
+procedure SaveTextSettings(withtemplate:boolean);
+var
+ D:PWATFrameData;
+begin
+ D:=FrameCtrl.CustomData;
+ if D.TextBlock=nil then exit;
+
+// DBWriteByte (0,PluginShort,opt_RollTail ,RollTail);
+ DBWriteDWord(0,PluginShort,opt_FrmTxtClr,D.TextBlock.TextColor); // reaction on chunk?
+ DBWriteByte (0,PluginShort,opt_RollStep ,D.TextBlock.RollStep);
+ DBWriteByte (0,PluginShort,opt_RollGap ,D.TextBlock.RollGap);
+ DBWriteWord (0,PluginShort,opt_FrmEffect,D.TextBlock.Effects);
+ DBWriteWord (0,PluginShort,opt_TxtTimer ,D.TextBlock.UpdateTime);
+
+ DBWriteStruct(0,PluginShort,opt_FrmFont,@TextLF,SizeOf(TLOGFONT));
+
+ if withtemplate then
+ begin
+ DBWriteUnicode(0,PluginShort,opt_FrameText,D.Template);
+ UpdateTextBlock(D,true);
+ end;
+end;
+
+procedure LoadTextSettings(TB:pTextBlock);
+begin
+ if TB=nil then exit;
+// RollTail :=DBReadByte (0,PluginShort,opt_RollTail ,20);
+ TB.RollStep :=DBReadByte (0,PluginShort,opt_RollStep ,2);
+ TB.RollGap :=DBReadByte (0,PluginShort,opt_RollGap ,16);
+ TB.TextColor :=DBReadDWord(0,PluginShort,opt_FrmTxtClr,0);
+ TB.Effects :=DBReadWord (0,PluginShort,opt_FrmEffect,effCut or effCenter);
+ DBReadStruct(0,PluginShort,opt_FrmFont,@TextLF,SizeOf(TextLF));
+ TB.FontData :=TextLF;
+ TB.UpdateTime:=DBReadWord (0,PluginShort,opt_TxtTimer ,10);
+end;
+
+function MakeTextBlock(AOwner:PControl;BkColor:TCOLORREF):pTextBlock;
+begin
+ result:=MakeNewTextBlock(AOwner,BkColor);
+// result.OnMouseDown:=TOnMouse(MakeMethod(nil, @MouseDown));
+ LoadTextSettings(result);
+end;
diff --git a/plugins/Watrack/kolframe/frm_trackbar.inc b/plugins/Watrack/kolframe/frm_trackbar.inc
new file mode 100644
index 0000000000..d6e08c56a7
--- /dev/null
+++ b/plugins/Watrack/kolframe/frm_trackbar.inc
@@ -0,0 +1,229 @@
+{Trackbar}
+type
+ pAWKTrackbar = ^tAWKTrackbar;
+ tAWKTrackbar = object(TObj)
+ total:integer;
+ UpdInterval:integer;
+ OldMouseDown,
+ OldMouseUp:TOnMouse;
+
+ procedure CtrlResize(Sender: PObj);
+ procedure Erase(Sender: PControl; DC: HDC);
+ procedure Paint(Sender: PControl; DC: HDC);
+ procedure Scroll(Sender:PTrackbar; Code:Integer);
+ procedure PressButton (Sender: PControl;var Mouse: TMouseEventData);
+ procedure UnPressButton(Sender: PControl;var Mouse: TMouseEventData);
+ procedure DragButton (Sender: PControl;var Mouse: TMouseEventData);
+ end;
+
+procedure ResetTrackbar(Trackbar:PControl);
+begin
+ if Trackbar=nil then exit;
+
+ with pTrackbar(Trackbar)^ do
+ begin
+ RangeMin:=0;
+ RangeMax:=0;
+ Position:=0;
+ end;
+end;
+
+procedure TrackbarSetRange(Trackbar:PTrackbar;timer:integer;total:integer=-1);
+var
+ D:pAWKTrackbar;
+ lpercent:real;
+begin
+ if Trackbar=nil then exit;
+
+ with Trackbar^ do
+ begin
+ D:=pointer(CustomObj);
+ if total<0 then // changing timer only
+ begin
+ total:=D.total;
+ if RangeMax>0 then
+ lpercent:=position/RangeMax
+ else
+ lpercent:=0;
+ end
+ else // for new track
+ begin
+ D.total:=total;
+ lpercent:=0;
+ end;
+ D.UpdInterval:=timer;
+ total:=(total*1000) div timer;
+ RangeMax:=total;
+ LineSize:=total div 100;
+ PageSize:=total div 10;
+ Position:=round(lpercent*total);
+ end;
+end;
+
+procedure SetTrackbarPosition(Trackbar:PTrackbar;pos:integer);
+begin
+ if Trackbar=nil then exit;
+//?? if Sender.ChildCount=0 then exit;
+ if pIcoButton(Trackbar.Children[0]).State<>AST_PRESSED then
+ Trackbar.Position:=pos;
+
+ Trackbar.Update;
+end;
+
+function CoordToPos(Trackbar:PTrackbar;x:integer):integer;
+var
+ range:integer;
+ rmin,rmax:integer;
+ offsetthumb,width:integer;
+ rc:TRect;
+begin
+ result:=0;
+ if Trackbar=nil then exit;
+
+ rmin:=Trackbar.RangeMin;
+ rmax:=Trackbar.RangeMax;
+ range:=rmax-rmin; // logic width
+
+ offsetthumb:=Trackbar.ThumbLen div 2;
+
+ rc:=Trackbar.ChannelRect;
+ width:= (rc.right-rc.left)-(offsetthumb*2)-1;
+ result:=(range*(x-rc.left-offsetthumb)) div width;
+
+ inc(result,rmin);
+ if result>rmax then
+ result:=rmax
+ else if result<rmin then
+ result:=rmin;
+end;
+
+procedure tAWKTrackbar.PressButton(Sender: PControl;var Mouse: TMouseEventData);
+begin
+ pAWKTrackbar(Sender.Parent.CustomObj).OldMouseDown(Sender,Mouse);
+
+ pIcoButton(Sender)^.Action:=PTrackbar(Sender.Parent).Position;
+end;
+
+procedure tAWKTrackbar.UnPressButton(Sender: PControl;var Mouse: TMouseEventData);
+begin
+ pAWKTrackbar(Sender.Parent.CustomObj).OldMouseUp(Sender,Mouse);
+
+ CallService(MS_WAT_PRESSBUTTON,WAT_CTRL_SEEK,
+ pIcoButton(Sender)^.Action*pAWKTrackbar(Sender.Parent.CustomObj).UpdInterval div 1000);
+ pIcoButton(Sender)^.Action:=-1;
+end;
+
+procedure tAWKTrackbar.DragButton(Sender: PControl;var Mouse: TMouseEventData);
+var
+ pos:integer;
+begin
+ with pIcoButton(Sender)^ do
+ if State=AST_PRESSED then
+ begin
+ pos:=CoordToPos(PTrackbar(Sender.Parent),Sender.Left+Mouse.X);
+ if Action<>pos then
+ begin
+ Action:=pos;
+ PTrackbar(Sender.Parent).Position:=pos;
+ end;
+ end;
+end;
+
+procedure tAWKTrackbar.Scroll(Sender:PTrackbar; Code:Integer);
+begin
+ if code=TB_ENDTRACK then
+ begin
+ CallService(MS_WAT_PRESSBUTTON,WAT_CTRL_SEEK,
+ Sender.Position*pAWKTrackbar(Sender.CustomObj).UpdInterval div 1000);
+ end;
+end;
+
+procedure tAWKTrackbar.CtrlResize(Sender: PObj);
+var
+ tmp:integer;
+begin
+ tmp:=PControl(Sender).Parent.Width-16;
+ if (PTrackbar(Sender)^.Width)>tmp then
+ PTrackbar(Sender)^.Width:=tmp;
+ //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ // need to move slider here
+// PControl(Sender).Update;
+end;
+
+procedure tAWKTrackbar.Erase(Sender: PControl; DC: HDC);
+begin
+// Sender.Parent.Update;
+end;
+
+procedure tAWKTrackbar.Paint(Sender: PControl; DC: HDC);
+var
+ rc, rc1:TRECT;
+ w:integer;
+begin
+ SendMessage(Sender.Handle,TBM_GETTHUMBRECT,0,dword(@rc));
+
+ w:=rc.right-rc.left;
+ if w<>16 then
+ rc.left:=rc.left+(w div 2)-8;
+
+ copyRect(rc1,Sender.BoundsRect);
+ rc1.Right :=rc1.Right-rc1.Left-8;
+ rc1.Left :=4;
+ rc1.Top :=7{((rc1.Bottom-rc1.Top) div 2)-2};
+ rc1.Bottom:=rc1.Top+4;
+ DrawEdge(DC,rc1,EDGE_SUNKEN,BF_RECT or BF_ADJUST);
+ if Sender.ChildCount>0 then
+ Sender.Children[0].Left:=rc.Left
+ else
+ begin
+ rc.right:=rc.left+8;
+ DrawFrameControl(DC,rc,DFC_BUTTON,DFCS_BUTTONPUSH);
+ end;
+end;
+
+procedure RefreshTrackbarIcons(Owner:PControl);
+begin
+ if Owner.ChildCount>0 then
+ pIcoButton(Owner.Children[0]).RefreshIcon;
+end;
+
+function MakeNewTrackBar(AOwner:PControl):PTrackbar;
+var
+ D:pAWKTrackbar;
+ btn:pIcoButton;
+begin
+ New(D, Create);
+ result:=NewTrackbar(AOwner,[trbNoTicks,trbBoth,trbNoBorder],D.Scroll);
+
+ with result^ do
+ begin
+ Transparent:=true;
+ CustomObj:=D;
+ SetSize(AOwner.Width-16,18);
+ SetPosition({AOwner.Left+}8,{AOwner.Top+}AOwner.Height-18);
+ Anchor(true,false,true,true);
+ ThumbLen:=16;
+
+ RangeMin:=0;
+ RangeMax:=100;
+
+ btn:=CreateIcoButton(result,GetIcon,DoAction,WAT_CTRL_SEEK);
+
+ if btn<>nil then
+ begin
+ btn.ResetEvent(idx_fOnClick);
+ D.OldMouseDown:=btn.OnMouseDown;
+ btn.OnMouseDown:=D.PressButton;
+ D.OldMouseUp:=btn.OnMouseUp;
+ btn.OnMouseUp :=D.UnPressButton;
+ btn.OnMouseMove:=D.DragButton;
+ end;
+
+ OnResize :=D.CtrlResize;
+ OnEraseBkGnd:=D.Erase;
+ OnPaint :=D.Paint;
+
+// OnScroll :=D.Scroll;
+ end;
+
+end;
diff --git a/plugins/Watrack/kolframe/frm_vars.inc b/plugins/Watrack/kolframe/frm_vars.inc
new file mode 100644
index 0000000000..88dd71f0d1
--- /dev/null
+++ b/plugins/Watrack/kolframe/frm_vars.inc
@@ -0,0 +1,80 @@
+{Frame variables}
+var
+ sic,
+ PlStatusHook:cardinal;
+
+ HiddenByMe:bool;
+
+ FrameHeight:dword;
+
+type
+ PWATFrameData = ^TWATFrameData;
+ TWATFrameData = record
+ BkDC :HDC; // "buffer" DC and associated bitmap
+ BkBitmap :HBITMAP; // original bitmap
+ BkFile :PAnsiChar; // original bitmap filename
+ BkDefFile :PAnsiChar; // default background picture filename
+ BkMode :cardinal;
+ BkTimer :cardinal; // timer to free original picture buffer
+ BkColor :TCOLORREF;
+ padding :TRect;
+
+ ShowControls:dword;
+ UseBkPicture:bool;
+ UseCover :bool;
+ HideNoMusic :bool;
+ HideNoPlayer:bool;
+
+ WasHidden :bool;
+ // not sure what will keep here
+ FrameId :integer;
+ FrmAlpha :integer;
+ UpdInterval :cardinal;
+ UpdTimer :cardinal;
+
+ Template :PWideChar;
+
+ Trackbar :PTrackbar;
+ TextBlock:PTextBlock;
+
+ // Designer section
+ Designer :PDesigner;
+ ManualPlacement:bool;
+ Loaded :dword;
+
+ btnarray:array [0..numbuttons-1] of pIcoButton;
+ end;
+
+ PWATFrame = ^TWATFrame;
+ TWATFrame = object(TControl)
+ procedure Paint(Sender: PControl; DC: HDC);
+ procedure FrameResize(Sender: PObj);
+ procedure RefreshAllFrameIcons;
+ procedure ResetFrame;
+
+ procedure CreateDesigner(Sender:PControl;var Mouse:TMouseEventData);
+ procedure DesignerSaveSettings;
+ procedure DesignerLoadSettings;
+
+ procedure PreparePicture(dc:HDC;rc:TRECT);
+ function LoadBkPicture(CoverFName:PAnsiChar;check:boolean=false;
+ BackFName:PAnsiChar=nil):integer;
+ procedure SaveSettings;
+ procedure LoadSettings;
+ procedure CheckControls;
+ procedure SetAlpha(value:integer);
+ procedure RefreshPicture(cover:PAnsiChar=nil);
+ procedure ClearBitmapData;
+ procedure AdjustFrame;
+ procedure MyDestroy(Sender:PObj);
+
+ procedure AdjustButtons(atop:integer);
+ procedure RefreshButtonIcons;
+ procedure FreeButtonsDesigner;
+ procedure MakeButtonsDesigner;
+ procedure FreeButtons;
+ procedure MakeNewButtonGroup;
+ end;
+
+var
+ FrameCtrl:PWATFrame;
diff --git a/plugins/Watrack/kolframe/i_bitmap.inc b/plugins/Watrack/kolframe/i_bitmap.inc
new file mode 100644
index 0000000000..bee15fdda7
--- /dev/null
+++ b/plugins/Watrack/kolframe/i_bitmap.inc
@@ -0,0 +1,290 @@
+{}
+procedure CalcRect(var src,dst:TRECT;mode:dword);
+var
+ dh, dw:integer;
+begin
+ if (Mode and frbkStretch)=frbkStretch then
+ begin
+ if (Mode and frbkProportional)<>0 then
+ begin
+ if (dst.right*src.bottom)>(src.right*dst.bottom) then
+ begin
+ dh:=dst.bottom;
+ dw:=dh*src.right div src.bottom
+ end
+ else
+ begin
+ dw:=dst.right;
+ dh:=dw*src.bottom div src.right;
+ end;
+ end
+ else
+ begin
+ dw:=dst.right;
+ dh:=dst.bottom;
+ end;
+ end
+ else if (Mode and frbkStretchX)<>0 then
+ begin
+ dw:=dst.right;
+ if (Mode and frbkProportional)<>0 then
+ dh:=dw*src.bottom div src.right
+ else
+ dh:=src.bottom;
+ end
+ else if (Mode and frbkStretchY)<>0 then
+ begin
+ dh:=dst.bottom;
+ if (Mode and frbkProportional)<>0 then
+ dw:=dh*src.right div src.bottom
+ else
+ dw:=src.right;
+ end
+ else
+ begin
+ dw:=src.right;
+ dh:=src.bottom;
+ end;
+
+ if (Mode and frbkBottom)<>0 then
+ begin
+ if dh<=dst.bottom then
+ begin
+ dst.top:=(dst.bottom-dh);
+ end
+ else
+ begin
+ src.top:=(dh-dst.bottom);
+ dh:=dst.bottom;
+ src.bottom:=src.top+dh;
+ end;
+ end;
+
+ if (Mode and frbkRight)<>0 then
+ begin
+ if dw<=dst.right then
+ begin
+ dst.left:=(dst.right-dw);
+ end
+ else
+ begin
+ src.left:=(dw-dst.right);
+ dw:=dst.right;
+ src.right:=src.left+dw;
+ end;
+ end;
+
+ if (Mode and frbkCenterX)<>0 then
+ begin
+ if dw<=dst.right then
+ begin
+ dst.left:=(dst.right-dw) div 2;
+ end
+ else
+ begin
+ src.left:=(dw-dst.right) div 2;
+ dw:=dst.right;
+ src.right:=src.left+dw;
+ end;
+ end;
+
+ if (Mode and frbkCenterY)<>0 then
+ begin
+ if dh<=dst.bottom then
+ begin
+ dst.top:=(dst.bottom-dh) div 2;
+ end
+ else
+ begin
+ src.top:=(dh-dst.bottom) div 2;
+ dh:=dst.bottom;
+ src.bottom:=src.top+dh;
+ end;
+ end;
+ dst.right:=dst.left+dw;
+ dst.bottom:=dst.top+dh;
+end;
+
+function CreateDIB32(dc:HDC;w,h:integer):HBITMAP;
+var
+ pt:pointer;
+ bi:TBITMAPINFO;
+begin
+ FillChar(bi,SizeOf(TBITMAPINFO),0);
+ bi.bmiHeader.biSize :=SizeOf(TBITMAPINFOHEADER);
+ bi.bmiHeader.biWidth :=w;
+ bi.bmiHeader.biHeight :=h;
+ bi.bmiHeader.biPlanes :=1;
+ bi.bmiHeader.biBitCount:=32;
+ result:=CreateDIBSection(dc,bi,DIB_RGB_COLORS,pt,0,0);
+end;
+
+procedure PreMultiplyChanells(hbmp:HBITMAP);
+type
+ tPixel=array [0..3] of Byte;
+var
+ bmp:windows.TBITMAP;
+ flag:bool;
+ pBitmapBits:PByte;
+ Len:dword;
+ bh,bw,y,x,z:integer;
+ pPixel:^tPixel;
+ alpha:dword;
+//f:THANDLE;
+begin
+ GetObject(hbmp,SizeOf(bmp),@bmp);
+ bh:=bmp.bmHeight;
+ bw:=bmp.bmWidth;
+ z:=bw*4;
+ Len:=bh*z;
+
+ mGetMem(pBitmapBits,Len);
+ GetBitmapBits(hbmp,Len,pBitmapBits);
+ flag:=true;
+ for y:=0 to bh-1 do
+ begin
+ pointer(pPixel):=PAnsiChar(pBitmapBits)+z*y;
+
+ for x:=0 to bw-1 do
+ begin
+ if pPixel^[3]<>0 then
+ flag:=false
+ else
+ pPixel^[3]:=255;
+ inc(pByte(pPixel),4);
+ end
+ end;
+
+ if not flag then
+ begin
+ GetBitmapBits(hbmp,Len,pBitmapBits); // alpha not changed
+ for y:=0 to bh-1 do
+ begin
+ pointer(pPixel):=PAnsiChar(pBitmapBits)+z*y;
+
+ for x:=0 to bw-1 do
+ begin
+ alpha:=pPixel^[3];
+ if alpha<255 then
+ begin
+ pPixel^[0]:=dword(pPixel^[0])*alpha div 255;
+ pPixel^[1]:=dword(pPixel^[1])*alpha div 255;
+ pPixel^[2]:=dword(pPixel^[2])*alpha div 255;
+ end;
+ inc(pByte(pPixel),4);
+ end
+ end;
+ end;
+ SetBitmapBits(hbmp,Len,pBitmapBits);
+ mFreeMem(pBitmapBits);
+end;
+
+function FixBitmap(dc:HDC;var hBmp:HBITMAP):HBITMAP;
+var
+ dc24,dc32:HDC;
+ hBitmap32,obmp24,obmp32:HBITMAP;
+ bmpInfo:windows.TBITMAP;
+begin
+ GetObject(hBmp,SizeOf(bmpInfo),@bmpInfo);
+ if bmpInfo.bmBitsPixel<>32 then
+ begin
+ dc32:=CreateCompatibleDC(dc);
+ dc24:=CreateCompatibleDC(dc);
+ hBitmap32:=CreateDIB32(dc,bmpInfo.bmWidth,bmpInfo.bmHeight);
+ obmp24:=SelectObject(dc24,hBmp);
+ obmp32:=SelectObject(dc32,hBitmap32);
+ BitBlt(dc32,0,0,bmpInfo.bmWidth,bmpInfo.bmHeight,dc24,0,0,SRCCOPY);
+ DeleteObject(SelectObject(dc24,obmp24));
+ SelectObject(dc32,obmp32);
+ DeleteDC(dc24);
+ DeleteDC(dc32);
+ hBmp:=hBitmap32;
+ end;
+ PreMultiplyChanells(hBmp);
+ result:=hBmp;
+end;
+
+procedure TWATFrame.PreparePicture(dc:HDC;rc:TRECT);
+var
+ bmpinfo:windows.TBITMAP;
+ src,dst:TRECT;
+ x,y,w,h,dh:integer;
+ br:HBRUSH;
+ hdcbmp:HDC;
+ bf:BLENDFUNCTION;
+ hOld:THANDLE;
+ D:PWATFrameData;
+begin
+ D:=CustomData;
+ D.BkDC:=CreateCompatibleDC(dc);
+
+ FixBitmap(dc,D.BkBitmap);
+
+ DeleteObject(SelectObject(D.BkDC,CreateDIB32(dc,rc.right-rc.left,rc.bottom-rc.top)));
+
+ //fill empty space by BK color
+ br:=CreateSolidBrush(D.BkColor);
+ FillRect(D.BkDC,rc,br);
+ DeleteObject(br);
+
+ CopyRect(dst,rc);
+ hdcbmp:=CreateCompatibleDC(D.BkDC);
+ GetObject(D.BkBitmap,SizeOf(bmpinfo),@bmpinfo);
+ hOld:=SelectObject(hdcbmp,D.BkBitmap);
+
+ SetRect(src,0,0,bmpinfo.bmWidth,bmpinfo.bmHeight);
+
+ if (D.padding.top+D.padding.bottom)<(dst.bottom-dst.top) then
+ dec(dst.bottom,D.padding.top+D.padding.bottom);
+ if (D.padding.left+D.padding.right)<(dst.right-dst.left) then
+ dec(dst.right,D.padding.left+D.padding.right);
+
+ CalcRect(src,dst,D.BkMode); // calculate final picture rect
+
+ w:=1;
+ if (D.BkMode and frbkTileX)<>0 then
+ begin
+ x:=dst.right;
+ while x<rc.right do
+ begin
+ inc(w);
+ inc(x,dst.right);
+ end;
+ end;
+ h:=1;
+ if (D.BkMode and frbkTileY)<>0 then
+ begin
+ y:=dst.bottom;
+ while y<rc.bottom do
+ begin
+ inc(h);
+ inc(y,dst.bottom);
+ end;
+ end;
+
+ bf.BlendOp :=AC_SRC_OVER;
+ bf.BlendFlags :=0;
+ bf.SourceConstantAlpha:=255;
+ bf.AlphaFormat :=1; // AC_SRC_ALPHA introduced in delphi 7
+
+ x:=dst.left+D.padding.left;
+ if x<dst.right then
+ while w>0 do
+ begin
+ dh:=h;
+ y:=dst.top+D.padding.top;
+ if y<dst.bottom then
+ while dh>0 do
+ begin
+ Windows.AlphaBlend(D.BkDC,x,y,dst.right-dst.left,dst.bottom-dst.top,
+ hdcbmp,src.left,src.top,src.right-src.left,src.bottom-src.top,bf);
+ inc(y,dst.bottom);
+ dec(dh);
+ end;
+ inc(x,dst.right);
+ dec(w);
+ end;
+
+ SelectObject(hdcbmp,hOld);
+ DeleteDC(hdcbmp);
+end;
diff --git a/plugins/Watrack/kolframe/kolframe.pas b/plugins/Watrack/kolframe/kolframe.pas
new file mode 100644
index 0000000000..615991d810
--- /dev/null
+++ b/plugins/Watrack/kolframe/kolframe.pas
@@ -0,0 +1,327 @@
+{CList frame}
+unit KOLFrame;
+
+interface
+
+implementation
+
+uses windows,kol,commdlg,messages,common,commctrl, KOLCCtrls,
+ wat_api,wrapper,global,m_api,dbsettings,waticons,mirutils,
+ icobuttons,textblock,kolsizer;
+
+{$R frm.res}
+
+{$include frm_data.inc}
+{$include frm_vars.inc}
+
+procedure MouseDown(DummySelf, Sender:PControl;var Mouse:TMouseEventData);
+var
+ wnd:HWND;
+begin
+ wnd:=GetParent(Sender.GetWindowHandle);
+ SendMessage(wnd,WM_SYSCOMMAND,
+ SC_MOVE or HTCAPTION,MAKELPARAM(Mouse.x,Mouse.y));
+end;
+
+// ---------------- frame functions ----------------
+
+procedure SetFrameTitle(title:pointer;icon:HICON;addflag:integer=FO_UNICODETEXT);
+var
+ D:PWATFrameData;
+begin
+ D:=FrameCtrl.CustomData;
+ CallService(MS_CLIST_FRAMES_SETFRAMEOPTIONS,
+ (D.FrameId shl 16)+FO_TBNAME+addflag,dword(title));
+ CallService(MS_CLIST_FRAMES_SETFRAMEOPTIONS,(D.FrameId shl 16)+FO_ICON,icon);
+ CallService(MS_CLIST_FRAMES_UPDATEFRAME,D.FrameId,FU_TBREDRAW);
+end;
+
+// -----------------------
+
+function IsFrameMinimized(FrameId:integer):bool;
+begin
+ result:=(CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS,
+ (FrameId shl 16)+FO_FLAGS,0) and F_UNCOLLAPSED)=0;
+end;
+
+function IsFrameFloated(FrameId:integer):bool;
+begin
+ result:=CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS,
+ (FrameId shl 16)+FO_FLOATING,0)>0;
+end;
+
+function IsFrameHidden(FrameId:integer):bool;
+begin
+ result:=(CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS,
+ (FrameId shl 16)+FO_FLAGS,0) and F_VISIBLE)=0;
+end;
+
+procedure HideFrame(FrameId:integer);
+begin
+ if not IsFrameHidden(FrameId) then
+ begin
+ CallService(MS_CLIST_FRAMES_SHFRAME,FrameId,0);
+ HiddenByMe:=true;
+ end;
+end;
+
+function ShowFrame(FrameId:integer):integer;
+begin
+ result:=0;
+ if IsFrameHidden(FrameId) then
+ if HiddenByMe then
+ begin
+ CallService(MS_CLIST_FRAMES_SHFRAME,FrameId,0);
+ HiddenByMe:=false;
+ end
+ else
+ result:=1;
+end;
+
+{$include frm_rc.inc}
+{$include frm_icogroup.inc}
+{$include frm_trackbar.inc}
+{$include frm_text.inc}
+{$include frm_frame.inc}
+{$include frm_designer.inc}
+
+{$include frm_dlg1.inc}
+{$include frm_dlg2.inc}
+
+// ---------------- basic frame functions ----------------
+
+function NewPlStatus(wParam:WPARAM;lParam:LPARAM):int;cdecl;
+const
+ needToChange:boolean=true;
+var
+ bufw:array [0..511] of WideChar;
+// FrameWnd:HWND;
+ Cover:pAnsiChar;
+ D:PWATFrameData;
+begin
+ result:=0;
+// FrameWnd:=FrameCtrl.Form.GetWindowHandle;
+ D:=FrameCtrl.CustomData;
+
+ case wParam of
+ WAT_EVENT_PLAYERSTATUS: begin
+ case Integer(loword(lParam)) of
+ WAT_PLS_NORMAL : exit;
+ WAT_PLS_NOMUSIC : begin
+ if D.HideNoMusic then
+ HideFrame(D.FrameId)
+ else
+ ShowFrame(D.FrameId); // if was hidden with "no player"
+ end;
+ WAT_PLS_NOTFOUND: begin
+ if D.HideNoPlayer then
+ HideFrame(D.FrameId);
+
+ SetFrameTitle(PluginShort,0,0); // frame update code there
+ end;
+ end;
+ FrameCtrl.ResetFrame;
+ end;
+
+ WAT_EVENT_NEWTRACK: begin
+ // cover
+ if D.UseCover then
+ if (pSongInfo(lParam)^.Cover<>nil) and (pSongInfo(lParam)^.Cover^<>#0) then
+ begin
+ GetShortPathNameW(pSongInfo(lParam)^.Cover,bufw,SizeOf(bufw));
+ WideToAnsi(bufw,Cover);
+ FrameCtrl.RefreshPicture(Cover);
+ mFreeMem(Cover);
+ end;
+
+ // trackbar
+ TrackbarSetRange(D.Trackbar,D.UpdInterval,pSongInfo(lParam)^.total);
+
+ if (D.UpdTimer=0) and (D.UpdInterval>0) then
+ D.UpdTimer:=SetTimer(0,0,D.UpdInterval,@FrameTimerProc);
+
+ // text
+ UpdateTextBlock(D,true);
+
+ ShowFrame(D.FrameId);
+ end;
+
+ WAT_EVENT_NEWPLAYER: begin
+ SetFrameTitle(pSongInfo(lParam)^.player,pSongInfo(lParam)^.icon);
+ // new player must call "no music" at least, so we have chance to show frame
+ end;
+
+ WAT_EVENT_PLUGINSTATUS: begin
+ case lParam of
+ dsEnabled: begin
+ ShowFrame(D.FrameId);
+ // plus - start frame and text timers
+ if D.UpdInterval>0 then
+ D.UpdTimer:=SetTimer(0,0,D.UpdInterval,@FrameTimerProc);
+ end;
+
+ dsPermanent: begin
+ HideFrame(D.FrameId);
+
+ // plus - stop frame and text timers
+ if D.UpdTimer<>0 then
+ begin
+ KillTimer(0,D.UpdTimer);
+ D.UpdTimer:=0;
+ end;
+ end;
+ end;
+ end;
+ end;
+end;
+
+function IconChanged(wParam:WPARAM;lParam:LPARAM):int;cdecl;
+begin
+ result:=0;
+ if PWATFrameData(FrameCtrl.CustomData).FrameId<>0 then
+ begin
+ FrameCtrl.RefreshAllFrameIcons;
+ ShowWindow(FrameCtrl.GetWindowHandle,SW_HIDE);
+ ShowWindow(FrameCtrl.GetWindowHandle,SW_SHOW);
+ end;
+end;
+
+//??const opt_FrmHeight :PAnsiChar = 'frame/frmheight';
+
+function CreateFrame(parent:HWND):boolean;
+var
+ CLFrame:TCLISTFrame;
+ rc:TRECT;
+ FrameWnd:HWND;
+begin
+ result:=false;
+ if ServiceExists(MS_CLIST_FRAMES_ADDFRAME)=0 then
+ exit;
+
+ if parent=0 then
+ parent:=CallService(MS_CLUI_GETHWND,0,0);
+
+ FrameWnd:=CreateFrameWindow(parent);
+
+ if FrameWnd<>0 then
+ begin
+ FillChar(CLFrame,SizeOf(CLFrame),0);
+ with CLFrame do
+ begin
+ cbSize :=SizeOf(CLFrame);
+ hWnd :=FrameWnd;
+ hIcon :=0;
+ align :=alTop;
+ GetClientRect(FrameWnd,rc);
+//?? height :=DBReadWord(0,PluginShort,opt_FrmHeight,rc.bottom-rc.top);
+ Flags :=0;//{F_VISIBLE or} F_SHOWTB;
+ name.a :=PluginShort;
+ TBName.a:=PluginShort;
+ end;
+ FrameHeight:=CLFrame.height;
+
+ PWATFrameData(FrameCtrl.CustomData).FrameId:=CallService(MS_CLIST_FRAMES_ADDFRAME,dword(@CLFrame),0);
+ if PWATFrameData(FrameCtrl.CustomData).FrameId>=0 then
+ begin
+ plStatusHook:=HookEvent(ME_WAT_NEWSTATUS,@NewPlStatus);
+ end;
+ end;
+ result:=FrameWnd<>0;
+end;
+
+procedure DestroyFrame;
+var
+ id:Integer;
+begin
+ if (FrameCtrl<>nil) and (PWATFrameData(FrameCtrl.CustomData).FrameId>=0) then
+ begin
+ UnhookEvent(plStatusHook);
+
+ id:=PWATFrameData(FrameCtrl.CustomData).FrameId;
+ FrameCtrl.Free;
+ FrameCtrl:=nil;
+ CallService(MS_CLIST_FRAMES_REMOVEFRAME,Id,0);
+ end;
+end;
+
+const
+ opt_ModStatus:PAnsiChar = 'module/frame';
+
+function GetModStatus:integer;
+begin
+ result:=DBReadByte(0,PluginShort,opt_ModStatus,1);
+end;
+
+procedure SetModStatus(stat:integer);
+begin
+ DBWriteByte(0,PluginShort,opt_modStatus,stat);
+end;
+
+// ---------------- base interface procedures ----------------
+
+function InitProc(aGetStatus:boolean=false):integer;
+begin
+ FrameCtrl:=nil;
+ result:=0;
+ if aGetStatus then
+ begin
+ if GetModStatus=0 then
+ exit;
+ end
+ else
+ SetModStatus(1);
+
+ result:=ord(CreateFrame(0));
+ if result<>0 then
+ sic:=HookEvent(ME_SKIN2_ICONSCHANGED,@IconChanged);
+end;
+
+procedure DeInitProc(aSetDisable:boolean);
+begin
+ if aSetDisable then
+ SetModStatus(0);
+
+ if sic<>0 then UnhookEvent(sic);
+ sic:=0;
+ DestroyFrame;
+end;
+
+function AddOptionsPage(var tmpl:pAnsiChar;var proc:pointer;var name:PAnsiChar):integer;
+const
+ count:integer=2;
+begin
+ if count=0 then
+ count:=2;
+ if count=2 then
+ begin
+ tmpl:='FRAME';
+ proc:=@FrameViewDlg;
+ name:='Frame (main)';
+ end
+ else
+ begin
+ tmpl:='FRAME2';
+ proc:=@FrameTextDlg;
+ name:='Frame (text)';
+ end;
+
+ dec(count);
+ result:=count;
+end;
+
+var
+ Frame:twModule;
+
+procedure Init;
+begin
+ Frame.Next :=ModuleLink;
+ Frame.Init :=@InitProc;
+ Frame.DeInit :=@DeInitProc;
+ Frame.AddOption :=@AddOptionsPage;
+ Frame.ModuleName:='Frame';
+ ModuleLink :=@Frame;
+end;
+
+begin
+ Init;
+end.