Br3tt

WSH Tabbed Playlist Manager v3.3.0

Nov 13th, 2011
3,008
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // ==PREPROCESSOR==
  2. // @name "WSH Tabbed Playlist Manager"
  3. // @version "3.3.0"
  4. // @author "Br3tt aka Falstaff >> http://br3tt.deviantart.com"
  5. // @feature "dragdrop"
  6. // ==/PREPROCESSOR==
  7.  
  8. // [Requirements]
  9. // * foobar2000 v1.1 or better  >> http://foobar2000.org
  10. // * WSH panel Mod v1.5.2 or better  >> http://http://code.google.com/p/foo-wsh-panel-mod/downloads/list
  11. // [/Requirements]
  12.  
  13. //=================================================// General declarations
  14. // Used in window.SetCursor()
  15. // {{
  16. IDC_ARROW = 32512;
  17. IDC_HAND = 32649;
  18. // }}
  19.  
  20. // Use with GdiDrawText()
  21. // {{
  22. var DT_LEFT = 0x00000000;
  23. var DT_RIGHT = 0x00000002;
  24. var DT_TOP = 0x00000000;
  25. var DT_CENTER = 0x00000001;
  26. var DT_VCENTER = 0x00000004;
  27. var DT_WORDBREAK = 0x00000010;
  28. var DT_SINGLELINE = 0x00000020;
  29. var DT_CALCRECT = 0x00000400;
  30. var DT_NOPREFIX = 0x00000800;
  31. var DT_EDITCONTROL = 0x00002000;
  32. var DT_END_ELLIPSIS = 0x00008000;
  33. // }}
  34. // Keyboard Flags & Tools
  35. // {{
  36. var VK_BACK = 0x08;
  37. var VK_RETURN = 0x0D;
  38. var VK_SHIFT = 0x10;
  39. var VK_CONTROL = 0x11;
  40. var VK_ALT = 0x12;
  41. var VK_ESCAPE = 0x1B;
  42. var VK_PGUP = 0x21;
  43. var VK_PGDN = 0x22;
  44. var VK_END = 0x23;
  45. var VK_HOME = 0x24;
  46. var VK_LEFT = 0x25;
  47. var VK_UP = 0x26;
  48. var VK_RIGHT = 0x27;
  49. var VK_DOWN = 0x28;
  50. var VK_INSERT = 0x2D;
  51. var VK_DELETE = 0x2E;
  52. var KMask = {
  53.     none: 0,
  54.     ctrl: 1,
  55.     shift: 2,
  56.     ctrlshift: 3,
  57.     ctrlalt: 4,
  58.     ctrlaltshift: 5,
  59.     alt: 6
  60. };
  61. function GetKeyboardMask() {
  62.     var c = utils.IsKeyPressed(VK_CONTROL) ? true : false;
  63.     var a = utils.IsKeyPressed(VK_ALT) ? true : false;
  64.     var s = utils.IsKeyPressed(VK_SHIFT) ? true : false;
  65.     var ret = KMask.none;
  66.     if (c && !a && !s) ret = KMask.ctrl;
  67.     if (!c && !a && s) ret = KMask.shift;
  68.     if (c && !a && s) ret = KMask.ctrlshift;
  69.     if (c && a && !s) ret = KMask.ctrlalt;
  70.     if (c && a && s) ret = KMask.ctrlaltshift;
  71.     if (!c && a && !s) ret = KMask.alt;
  72.     return ret;
  73. }
  74. // }}
  75. // Used in window.GetColorCUI()
  76. // {{
  77. ColorTypeCUI = {
  78.     text: 0,
  79.     selection_text: 1,
  80.     inactive_selection_text: 2,
  81.     background: 3,
  82.     selection_background: 4,
  83.     inactive_selection_background: 5,
  84.     active_item_frame: 6
  85. };
  86. // Used in window.GetFontCUI()
  87. FontTypeCUI = {
  88.     items: 0,
  89.     labels: 1
  90. };
  91. // Used in window.GetColorDUI()
  92. ColorTypeDUI = {
  93.     text: 0,
  94.     background: 1,
  95.     highlight: 2,
  96.     selection: 3
  97. };
  98. // Used in window.GetFontDUI()
  99. FontTypeDUI = {
  100.     defaults: 0,
  101.     tabs: 1,
  102.     lists: 2,
  103.     playlists: 3,
  104.     statusbar: 4,
  105.     console: 5
  106. };
  107. // }}
  108.  
  109. // Used in gr.DrawString()
  110. // {{
  111. function StringFormat() {
  112.     var h_align = 0, v_align = 0, trimming = 0, flags = 0;
  113.     switch (arguments.length) {
  114.      case 3:
  115.         trimming = arguments[2];
  116.      case 2:
  117.         v_align = arguments[1];
  118.      case 1:
  119.         h_align = arguments[0];
  120.         break;
  121.      default:
  122.         return 0;
  123.     }
  124.     return ((h_align << 28) | (v_align << 24) | (trimming << 20) | flags);
  125. }
  126. StringAlignment = {Near: 0, Centre: 1, Far: 2};
  127. var lt_stringformat = StringFormat(StringAlignment.Near, StringAlignment.Near);
  128. var ct_stringformat = StringFormat(StringAlignment.Centre, StringAlignment.Near);
  129. var rt_stringformat = StringFormat(StringAlignment.Far, StringAlignment.Near);
  130. var lc_stringformat = StringFormat(StringAlignment.Near, StringAlignment.Centre);
  131. var cc_stringformat = StringFormat(StringAlignment.Centre, StringAlignment.Centre);
  132. var rc_stringformat = StringFormat(StringAlignment.Far, StringAlignment.Centre);
  133. var lb_stringformat = StringFormat(StringAlignment.Near, StringAlignment.Far);
  134. var cb_stringformat = StringFormat(StringAlignment.Centre, StringAlignment.Far);
  135. var rb_stringformat = StringFormat(StringAlignment.Far, StringAlignment.Far);
  136. // }}
  137.  
  138. // Used everywhere!
  139. // {{
  140. function RGB(r, g, b) {
  141.     return (0xff000000 | (r << 16) | (g << 8) | (b))
  142. }
  143. function RGBA(r, g, b, a) {
  144.     return ((a << 24) | (r << 16) | (g << 8) | (b))
  145. }
  146. // }}
  147.  
  148. // VB wrapper
  149. // {{
  150. var vb = {};
  151. vb.Function = function (func) {
  152.     return function () {
  153.         return vb.Function.eval.call(this, func, arguments);
  154.     }
  155. };
  156. vb.Function.eval = function (func) {
  157.     var args = Array.prototype.slice.call(arguments[1]);
  158.     for (var i=0;i<args.length;i++) {
  159.         if (typeof args[i] != 'string') continue;
  160.         args[i] = '"' + args[i].replace(/"/g, '" + Chr(34) + "') + '"';
  161.     }
  162.     var vbe;
  163.     vbe = new ActiveXObject('ScriptControl');
  164.     vbe.Language = 'VBScript';
  165.     return vbe.eval(func + '(' + args.join(', ') + ')');
  166. };
  167. var InputBox = vb.Function('InputBox');
  168. var MsgBox = vb.Function('MsgBox');
  169. // }}
  170.  
  171. //=================================================// Button object
  172. ButtonStates = {normal: 0, hover: 1, down: 2};
  173. button = function (normal, hover, down) {
  174.     this.img = Array(normal, hover, down);
  175.     this.w = this.img[0].Width;
  176.     this.h = this.img[0].Height;
  177.     this.state = ButtonStates.normal;
  178.     this.draw = function (gr, x, y, alpha) {
  179.         this.x = x;
  180.         this.y = y;
  181.         this.img[this.state] && gr.DrawImage(this.img[this.state], this.x, this.y, this.w, this.h, 0, 0, this.w, this.h, 0, alpha);
  182.     }
  183.     this.display_context_menu = function (x, y, id) {}
  184.     this.repaint = function () {
  185.         window.RepaintRect(this.x, this.y, this.w, this.h);
  186.     }
  187.     this.checkstate = function (event, x, y) {
  188.         this.ishover = (x > this.x && x < this.x + this.w - 1 && y > this.y && y < this.y + this.h - 1);
  189.         this.old = this.state;
  190.         switch (event) {
  191.          case "down":
  192.             switch(this.state) {
  193.              case ButtonStates.normal:
  194.              case ButtonStates.hover:
  195.                 this.state = this.ishover ? ButtonStates.down : ButtonStates.normal;
  196.                 break;
  197.             }
  198.             break;
  199.          case "up":
  200.             this.state = this.ishover ? ButtonStates.hover : ButtonStates.normal;
  201.             break;
  202.          case "right":
  203.              if(this.ishover) this.display_context_menu(x, y, id);
  204.              break;
  205.          case "move":
  206.             switch(this.state) {
  207.              case ButtonStates.normal:
  208.              case ButtonStates.hover:
  209.                 this.state = this.ishover ? ButtonStates.hover : ButtonStates.normal;
  210.                 break;
  211.             }
  212.             break;
  213.          case "leave":
  214.             this.state = this.isdown ? ButtonStates.down : ButtonStates.normal;
  215.             break;
  216.         }
  217.         if(this.state!=this.old) this.repaint();
  218.         return this.state;
  219.     }
  220. };
  221.  
  222. //=================================================// Global Variables
  223. var g_instancetype = window.InstanceType;
  224. var g_textcolor;
  225. var g_textcolor_sel;
  226. var g_textcolor_hl;
  227. var g_backcolor;
  228.  
  229. var top_tab_margin = window.GetProperty("_Top tabs margin", 2);
  230. var inter_tab_margin = window.GetProperty("_Inter tabs margin", 2);
  231.  
  232. var background_colour = {};
  233. var label_colour = {};
  234.  
  235. //=================================================// Images
  236. var close_img_off, close_img_ov, autoplaylist_marker_off, autoplaylist_marker_on;
  237. var newtab_img_off, newtab_img_ov, newpl_img_off, newpl_img_ov;
  238. var plmenu1_img_off, plmenu1_img_ov, plmenu2_img_off, plmenu2_img_ov;
  239. var scroll_left_img_off, scroll_left_img_ov, scroll_right_img_off, scroll_right_img_off;
  240.  
  241. //=================================================// OBJECT tab
  242. var bt_w = 18;
  243.  
  244. tab_CONST = {
  245.     width: 60,
  246.     min_width: 70,
  247.     max_width: 100,
  248.     height: 26,
  249.     pad_top: 0,
  250.     pad_left: 2,
  251.     pad_left_default: 2,
  252.     pad_right: bt_w*2,
  253.     scroll: false,
  254.     scroll_step: 40,
  255.     pos: 0
  256. };
  257.  
  258. panel = {
  259.     custom_textcolor: window.GetProperty("*USER.custom.text.color.normal", "RGB(240,240,240)"),
  260.     custom_textcolor_selection: window.GetProperty("*USER.custom.text.color.selection", "RGB(64,128,250)"),
  261.     custom_textcolor_highlight: window.GetProperty("*USER.custom.text.color.highlight", "RGB(64,128,250)"),
  262.     custom_backcolor: window.GetProperty("*USER.custom.background.color", "RGB(0,0,0)"),
  263.     custom_colors: window.GetProperty("SYSTEM.panel.custom.colors", false)
  264. };
  265.  
  266. TabStates = {
  267.     normal: 0,
  268.     hover: 1,
  269.     active: 2
  270. };
  271.  
  272. tab = function () {
  273.     this.create = function(label, id) {
  274.         if (typeof this.tabname == "undefined") {
  275.             this.label = label;
  276.             this.id = id;
  277.             if (fb.ActivePlaylist == id) {
  278.                 this.state = TabStates.active;
  279.             } else {
  280.                 this.state = TabStates.normal;
  281.             }
  282.             this.x = 0;
  283.             this.y = 0;
  284.             this.w = 0;
  285.             this.h = 0;
  286.             this.colour_text = RGB(0, 0, 0);
  287.             this.colour_bg = RGB(240, 240, 240);
  288.             // creating the close tab button of this sheet
  289.             this.bt_close = new button(close_img_off, close_img_ov, close_img_ov);
  290.         }
  291.     }
  292.     this.draw = function (gr, x, y, alpha) {
  293.         var delta_move = 0;
  294.         this.w = tab_CONST.width;
  295.         this.h = tab_CONST.height;
  296.         this.x = tab_CONST.pos + tab_CONST.pad_left + (this.w + 0) * this.id;
  297.         this.y = y;
  298.         // set delta on mouse drag to move items to their new place preview
  299.         if(g_drag) {
  300.             if(this.x+this.w>mouse_x && this.id < g_drag_source_id) {
  301.                 delta_move = mytab[g_drag_source_id].w;
  302.             }
  303.             if(this.x<mouse_x && this.id > g_drag_source_id) {
  304.                 delta_move = mytab[g_drag_source_id].w * -1;
  305.             }
  306.         }
  307.         // set colours
  308.         switch (this.state) {
  309.          case TabStates.normal:
  310.             this.label_colour = label_colour.normal;
  311.             this.bg_colour_1 = background_colour.normal;
  312.             break;
  313.          case TabStates.hover:
  314.             if(g_drag) {
  315.                 this.label_colour = label_colour.hover;
  316.                 this.bg_colour_1 = background_colour.hover;
  317.             } else {
  318.                 this.label_colour = label_colour.hover;
  319.                 this.bg_colour_1 = background_colour.hover;
  320.             }
  321.             break;
  322.          case TabStates.active:
  323.             this.label_colour = label_colour.active;
  324.             this.bg_colour_1 = background_colour.active;
  325.             break;
  326.         }
  327.        
  328.         if(!g_drag || (g_drag && this.id!=g_drag_source_id)) {
  329.             if(this.x+delta_move > tab_CONST.pad_left-tab_CONST.width && x < ww-tab_CONST.pad_right) {
  330.                 // Drawing a tab
  331.                 if(this.state==TabStates.active){
  332.                     gr.FillSolidRect(this.x+delta_move, this.y+this.h-1, this.w, 1, g_backcolor);
  333.                     gr.FillSolidRect(this.x+delta_move, this.y+this.h-1, this.w, 1, RGBA(0,0,0,50));
  334.                     gr.FillSolidRect(this.x+delta_move-1, this.y+top_tab_margin-1, this.w - inter_tab_margin+2, this.h+5+1, g_textcolor&0x55ffffff);
  335.                     gr.FillSolidRect(this.x+delta_move-1, this.y+top_tab_margin-1, this.w - inter_tab_margin+2, this.h+5+1, RGBA(255,255,255,50));
  336.                     gr.FillSolidRect(this.x+delta_move, this.y+top_tab_margin, this.w - inter_tab_margin, this.h+5, this.bg_colour_1);
  337.                     gr.FillGradRect(this.x+delta_move, this.y+top_tab_margin, this.w - inter_tab_margin, this.h+5, 90, 0, g_textcolor&0x35ffffff, 1.0);
  338.                     gr.GdiDrawText(this.label, g_font_headers, g_backcolor, this.x + 6 + delta_move, this.y + top_tab_margin - 0, this.w - 21 - inter_tab_margin, this.h-top_tab_margin, DT_NOPREFIX | DT_CALCRECT | DT_VCENTER | DT_END_ELLIPSIS);
  339.                     gr.GdiDrawText(this.label, g_font_headers, this.label_colour, this.x + 6 + delta_move, this.y + top_tab_margin - 1, this.w - 21 - inter_tab_margin, this.h-top_tab_margin, DT_NOPREFIX | DT_CALCRECT | DT_VCENTER | DT_END_ELLIPSIS);
  340.                 } else {
  341.                     gr.FillSolidRect(this.x+delta_move, this.y+top_tab_margin, this.w - inter_tab_margin, this.h+5-1, g_backcolor);
  342.                     gr.FillSolidRect(this.x+delta_move, this.y+top_tab_margin, this.w - inter_tab_margin, this.h+5-1, g_textcolor&0xaaffffff);
  343.                     gr.FillSolidRect(this.x+delta_move+1, this.y+top_tab_margin+1, this.w - inter_tab_margin-2, this.h+5-1, g_backcolor);
  344.                     gr.FillSolidRect(this.x+delta_move+1, this.y+top_tab_margin+1, this.w - inter_tab_margin-2, this.h+5-1, background_colour.normal);
  345.                     if(this.state==TabStates.normal){
  346.                         gr.FillGradRect(this.x+delta_move+1, this.y+top_tab_margin+1, this.w - inter_tab_margin-2, this.h+5-1, 90, g_backcolor&0x55ffffff, background_colour.normal, 1.0);
  347.                     } else {
  348.                         gr.FillGradRect(this.x+delta_move+1, this.y+top_tab_margin+1, this.w - inter_tab_margin-2, this.h+5-1, 90, background_colour.normal, g_backcolor&0x55ffffff, 1.0);
  349.                     }
  350.                     gr.FillSolidRect(this.x+delta_move, this.y+this.h-2, this.w - inter_tab_margin, 1, RGBA(0,0,0,80));
  351.                     gr.FillSolidRect(this.x+delta_move, this.y+this.h-3, this.w - inter_tab_margin, 1, RGBA(0,0,0,30));
  352.                     gr.FillSolidRect(this.x+delta_move, this.y+this.h-4, this.w - inter_tab_margin, 1, RGBA(0,0,0,10));
  353.                     gr.FillSolidRect(this.x+delta_move, this.y+this.h-1, this.w, 1, g_backcolor);
  354.                     gr.FillSolidRect(this.x+delta_move, this.y+this.h-1, this.w, 1, RGBA(0,0,0,50));
  355.                     gr.GdiDrawText(this.label, g_font_headers, g_textcolor, this.x + 6 + delta_move, this.y + top_tab_margin - 0, this.w - 20 - inter_tab_margin, this.h-top_tab_margin, DT_NOPREFIX | DT_CALCRECT | DT_VCENTER | DT_END_ELLIPSIS);
  356.                     gr.GdiDrawText(this.label, g_font_headers, this.label_colour, this.x + 6 + delta_move, this.y + top_tab_margin - 1, this.w - 20 - inter_tab_margin, this.h-top_tab_margin, DT_NOPREFIX | DT_CALCRECT | DT_VCENTER | DT_END_ELLIPSIS);
  357.                 }
  358.                 // Drawing the close tab button in the tab (only is there are more than 1 sheet !)
  359.                 this.bt_close.draw(gr, Math.floor(this.x + this.w - 14 - inter_tab_margin + delta_move), this.y + top_tab_margin + 2, 255, "");
  360.                 // autoplaylist mark
  361.                 if(fb.IsAutoPlaylist(this.id)) {
  362.                     /*
  363.                     if(this.state!=TabStates.active){
  364.                         gr.FillSolidRect(Math.ceil(this.x+delta_move), this.y+top_tab_margin, 5, 6, g_backcolor);
  365.                         gr.FillSolidRect(Math.ceil(this.x+delta_move), this.y+top_tab_margin, 5, 6, RGBA(0,0,0,10));
  366.                         gr.DrawImage(autoplaylist_marker_off, Math.ceil(this.x+delta_move), this.y+top_tab_margin, autoplaylist_marker_off.Width, autoplaylist_marker_off.Height, 0, 0, autoplaylist_marker_off.Width, autoplaylist_marker_off.Height, 0, 255);
  367.                     } else {
  368.                         gr.FillSolidRect(Math.ceil(this.x+delta_move-1), this.y+top_tab_margin-1, 6, 7, g_backcolor);
  369.                         gr.FillSolidRect(Math.ceil(this.x+delta_move-1), this.y+top_tab_margin-1, 6, 7, RGBA(0,0,0,10));
  370.                         gr.DrawImage(autoplaylist_marker_on, Math.ceil(this.x+delta_move-1), this.y+top_tab_margin-1, autoplaylist_marker_on.Width, autoplaylist_marker_on.Height, 0, 0, autoplaylist_marker_on.Width, autoplaylist_marker_on.Height, 0, 255);
  371.                     }
  372.                     */
  373.                 }
  374.             }
  375.         }
  376.         // draw the dragged item
  377.         if(g_drag) {
  378.             // Drawing a tab
  379.             try {
  380.                 gr.FillSolidRect(mouse_x-mytab[g_drag_source_id].w/2-1, this.y+top_tab_margin-1, this.w - inter_tab_margin+2, this.h+5+1, g_backcolor&0x77ffffff);
  381.                 gr.DrawRect(mouse_x-mytab[g_drag_source_id].w/2-0, this.y+top_tab_margin-1, this.w - inter_tab_margin+0, this.h+5+1, 1.0, g_textcolor&0x55ffffff);
  382.                 gr.GdiDrawText(mytab[g_drag_source_id].label, g_font_headers, g_backcolor, mouse_x - mytab[g_drag_source_id].w/2 + 7, this.y + top_tab_margin - 0, this.w - 13 - inter_tab_margin, this.h-top_tab_margin, DT_NOPREFIX | DT_CALCRECT | DT_VCENTER | DT_END_ELLIPSIS);
  383.                 gr.GdiDrawText(mytab[g_drag_source_id].label, g_font_headers, label_colour.active, mouse_x - mytab[g_drag_source_id].w/2 + 7, this.y + top_tab_margin - 1, this.w - 13 - inter_tab_margin, this.h-top_tab_margin, DT_NOPREFIX | DT_CALCRECT | DT_VCENTER | DT_END_ELLIPSIS);
  384.                 // autoplaylist mark
  385.                 if(fb.IsAutoPlaylist(mytab[g_drag_source_id].id)) {}
  386.             } catch(e) {}
  387.         }
  388.     }
  389.  
  390.     this.checkstate = function (event, x, y, id) {
  391.         this.ishover = ((x>tab_CONST.pad_left && x<ww-tab_CONST.pad_right ) && x > this.x && x < this.x + this.w && y > this.y && y < this.y + this.h)?true:false;
  392.         this.ishoverX = ((x>tab_CONST.pad_left && x<ww-tab_CONST.pad_right) && x > this.x && x < this.x + this.w)?true:false;
  393.         switch (event) {
  394.         case "down":
  395.             switch(this.state) {
  396.             case TabStates.normal:
  397.                 break;
  398.             case TabStates.hover:
  399.                 if(this.ishover) {
  400.                     for(i=0;i<mytab.length;i++) {
  401.                         mytab[i].state = TabStates.normal;
  402.                     }
  403.                     g_drag_source_id = this.id;
  404.                     this.state = TabStates.active;
  405.                     window.Repaint();
  406.                 }
  407.                 break;
  408.             case TabStates.active:
  409.                 g_drag_source_id = this.id;
  410.                 break;
  411.             }
  412.             break;
  413.         case "right":
  414.             if(this.ishover) {
  415.                 playlist_context_menu(x, y, this.id);
  416.             }
  417.             break;
  418.         case "up":
  419.             switch(this.state) {
  420.             case TabStates.normal:
  421.                 break;
  422.             case TabStates.hover:
  423.                 if(g_drag && this.id!=g_drag_source_id) {
  424.                     fb.MovePlaylist(g_drag_source_id, this.id);
  425.                     fb.ActivePlaylist = this.id;
  426.                     refresh_playlists();
  427.                     window.Repaint();
  428.                 }
  429.                 break;
  430.             case TabStates.active:
  431.                 fb.ActivePlaylist = this.id;
  432.                 break;
  433.             }
  434.             g_drag && window.Repaint();
  435.             break;
  436.         case "move":
  437.             switch(this.state) {
  438.             case TabStates.normal:
  439.                 if(g_drag) {
  440.                     if(this.ishoverX) {
  441.                         this.state = TabStates.hover;
  442.                         window.Repaint();
  443.                     }
  444.                 } else {
  445.                     if(this.ishover) {
  446.                         this.state = TabStates.hover;
  447.                         window.Repaint();
  448.                     }
  449.                 }
  450.                 break;
  451.             case TabStates.hover:
  452.                 if(g_drag) {
  453.                     if(!this.ishoverX) {
  454.                         this.state = TabStates.normal;
  455.                         window.Repaint();
  456.                     }
  457.                 } else {
  458.                     if(!this.ishover) {
  459.                         this.state = TabStates.normal;
  460.                         window.Repaint();
  461.                     }
  462.                 }
  463.                 break;
  464.             case TabStates.active:
  465.                 break;
  466.             }
  467.             if(this.ishover) {
  468.                 if(g_handles!=null) {
  469.                     var insert_index = fb.PlaylistItemCount(this.id);
  470.                     plman.InsertPlaylistItems(this.id, insert_index, g_handles, false);
  471.                 }
  472.                 g_handles = null;
  473.             }
  474.             break;
  475.         case "leave":
  476.             if(fb.ActivePlaylist != this.id) {
  477.                 this.state = TabStates.normal;
  478.                 window.Repaint();
  479.             }
  480.             break;
  481.         }
  482.         return this.state;
  483.     }
  484. };
  485.  
  486. //=================================================// Tools
  487. function RGB(r, g, b) {
  488.     return (0xff000000 | (r << 16) | (g << 8) | (b))
  489. }
  490.  
  491. function RGBA(r, g, b, a) {
  492.     return ((a << 24) | (r << 16) | (g << 8) | (b))
  493. }
  494.  
  495. //=================================================// Global Variables
  496. // Buttons global variables
  497. var mybutton = Array();
  498. var buttons_padx = 0;
  499. var buttons_pady = 0;
  500.  
  501. // Tabs global variables
  502. var mytab = Array(new tab);
  503. var g_tooltip = window.CreateTooltip();
  504. var g_font_headers = null;
  505.  
  506. // Common global variables
  507. var ww = 0;
  508. var wh = 0;
  509. var mouse_x;
  510. var mouse_y;
  511. var show_tooltip;
  512. var hand;
  513. var g_left_click = 0;
  514. var g_drag = false;
  515. var g_drag_source_id;
  516. var g_scrollitems_delta = 0;
  517. var g_scrollitems_timer = false;
  518. var new_pl = false;
  519. var timer_new_pl = false;
  520. var previous_active_pl = 0;
  521.  
  522. // WSH drag and drop globals
  523. var g_handles = null;
  524.  
  525. //==========================================================================/ on_size
  526. function on_size() {
  527.     if (!window.Width || !window.Height) return;
  528.     if(g_instancetype == 0) { // CUI
  529.         window.MinWidth = 200;
  530.         window.MinHeight = tab_CONST.height+5;  
  531.     } else if(g_instancetype == 1) { // DUI
  532.         window.MinWidth = 200;
  533.         window.MinHeight = tab_CONST.height+5;
  534.         window.MaxHeight = tab_CONST.height+5;
  535.     }
  536.    
  537.     ww = window.Width;
  538.     wh = window.Height;
  539.    
  540.     if(ww==0 && wh==0) return true;
  541.  
  542.     get_font();
  543.     get_colors();
  544.     refresh_buttons();
  545.     refresh_playlists();
  546. }
  547.  
  548. //==========================================================================/ on_paint
  549. function on_paint(gr) {
  550.     var i;
  551.    
  552.     previous_active_pl = fb.ActivePlaylist;
  553.    
  554.     // draw panel background
  555.     gr.FillSolidRect(0, 0, ww, wh, g_backcolor);
  556.     gr.FillSolidRect(0, 0, ww, tab_CONST.height, RGBA(255,255,255,19));
  557.     //gr.FillGradRect(0, tab_CONST.height-5, ww, 4, 90, 0, RGBA(0,0,0,40), 1.0);
  558.     gr.FillSolidRect(0, tab_CONST.height-2, ww, 1, RGBA(0,0,0,30));
  559.    
  560.     gr.FillSolidRect(0, tab_CONST.height-1, ww, 1, g_backcolor);
  561.     gr.FillSolidRect(0, tab_CONST.height-1, ww, 1, RGBA(0,0,0,50));
  562.    
  563.     // if no scroll tabs, add playlist button have to be draw under the tabs
  564.     if(!tab_CONST.scroll && !g_drag) {
  565.         mybutton[0].draw(gr, tab_CONST.pos + tab_CONST.pad_left + (mytab.length * (tab_CONST.width + 0)), tab_CONST.pad_top, 255);
  566.     }
  567.    
  568.     // draw the tabs
  569.     for (i=0; i < mytab.length; i++) {
  570.         mytab[i].draw(gr, 0, tab_CONST.pad_top, 255);
  571.     }
  572.    
  573.     // draw undertab background
  574.     gr.FillSolidRect(0, tab_CONST.height+tab_CONST.pad_top, ww, wh-tab_CONST.height, g_backcolor);
  575.     gr.FillSolidRect(0, tab_CONST.height+tab_CONST.pad_top, ww, wh-tab_CONST.height, g_textcolor&0x25ffffff);
  576.    
  577.     gr.FillGradRect(0, tab_CONST.height+tab_CONST.pad_top-1, ww, wh-tab_CONST.height+1, 90, 0, g_backcolor);
  578.    
  579.     //draw buttons
  580.     for (i = 0; i < mybutton.length; i++) {
  581.         switch (i) {
  582.         case 0:
  583.             // Add a new playlist
  584.             if(tab_CONST.scroll) {
  585.                 if (tab_CONST.scroll) {
  586.                     mybutton[i].draw(gr, ww - bt_w*2, tab_CONST.pad_top, 255);
  587.                 } else {
  588.                     mybutton[i].draw(gr, tab_CONST.pos + tab_CONST.pad_left + (mytab.length * (tab_CONST.width + 0)), tab_CONST.pad_top, 255);
  589.                 }
  590.             }
  591.             break;
  592.         case 1:
  593.             if (!tab_CONST.scroll) gr.FillGradRect(ww - bt_w - 3, tab_CONST.pad_top, 6, tab_CONST.height, 0, 0, RGB(0,0,0), 1.0);
  594.             mybutton[i].draw(gr, ww - bt_w, tab_CONST.pad_top, 255);
  595.             break;
  596.         case 2:
  597.             if (tab_CONST.scroll) {
  598.                 gr.FillGradRect(bt_w-4, tab_CONST.pad_top, 6, tab_CONST.height, 0, RGB(0,0,0), 0, 1.0);
  599.                 mybutton[i].draw(gr, 0, tab_CONST.pad_top, 255);
  600.             }
  601.             break;
  602.         case 3:
  603.             if (tab_CONST.scroll) {
  604.                 gr.FillGradRect(ww - bt_w*3 - 3, tab_CONST.pad_top, 6, tab_CONST.height, 0, 0, RGB(0,0,0), 1.0);
  605.                 mybutton[i].draw(gr, ww - bt_w*3, tab_CONST.pad_top, 255);
  606.             }
  607.             break;
  608.         }
  609.     }
  610. }
  611.  
  612. //==========================================================================/ playlists_changed
  613. function on_playlists_changed() {
  614.     var prev_total_pl = mytab.length;
  615.     refresh_playlists();
  616.     if(prev_total_pl<fb.PlaylistCount) {
  617.         new_pl = true;
  618.         if(!timer_new_pl) {
  619.             timer_new_pl = window.SetTimeout(function() {
  620.                 fb.ActivePlaylist = mytab.length-1;
  621.                 if(tab_CONST.scroll) {
  622.                     scroll_to_right_limit();
  623.                 } else {
  624.                     window.Repaint();
  625.                 }
  626.                 timer_new_pl = false;
  627.             }, 10);
  628.         }
  629.     }
  630.     window.Repaint();
  631. }
  632.  
  633. function on_playlist_switch() {
  634.     refresh_playlists();
  635.     window.Repaint();
  636. }
  637.  
  638. //==========================================================================/ lbtn_down
  639. function on_mouse_lbtn_down(x, y) {
  640.     var i;
  641.    
  642.     for (i = 0; i < mybutton.length; i++) {
  643.         mybutton[i].checkstate("down", x, y, i);
  644.     }
  645.  
  646.     if (x > tab_CONST.pad_left && x < ww - tab_CONST.pad_right) {
  647.         for (i=0; i < mytab.length; i++) {
  648.             if(mytab[i].bt_close.checkstate("down", x, y, i)!=ButtonStates.down) {
  649.                 mytab[i].checkstate("down", x, y, i);
  650.                 if(mytab[i].ishover) g_left_click = 1;
  651.             }
  652.         }
  653.     }
  654. }
  655.  
  656. function on_mouse_lbtn_dblclk(x, y, mask) {
  657.     on_mouse_lbtn_down(x, y);
  658. }
  659.  
  660. //==========================================================================/ lbtn_up
  661. function on_mouse_lbtn_up(x, y) {
  662.     var i;
  663.     var j;
  664.     var active_pl;
  665.     var nb_pl;
  666.     var top_refresh_columns_width = 0;
  667.     new_pl = false;
  668.    
  669.     g_left_click = 0;
  670.  
  671.     // buttons actions
  672.     if(!g_drag) {
  673.         for (i = 0; i < mybutton.length; i++) {
  674.             switch (i) {
  675.             case 0:
  676.                 if (mybutton[i].checkstate("up", x, y, i) == ButtonStates.hover) {
  677.                     fb.CreatePlaylist(mytab.length, "");
  678.                     new_pl = true;
  679.                     if(!timer_new_pl) {
  680.                         timer_new_pl = window.SetTimeout(function() {
  681.                             fb.ActivePlaylist = mytab.length-1;
  682.                             if(tab_CONST.scroll) {
  683.                                 scroll_to_right_limit();
  684.                             } else {
  685.                                 window.Repaint();
  686.                             }
  687.                             timer_new_pl = false;
  688.                         }, 10);
  689.                     }
  690.                 }
  691.                 break;
  692.             case 1:
  693.                 if (mybutton[i].checkstate("up", x, y, i) == ButtonStates.hover) {
  694.                     playlist_command_menu(x, y, i);
  695.                 }
  696.                 break;
  697.             case 2:
  698.                 if (mybutton[i].checkstate("up", x, y, i) == ButtonStates.hover) {
  699.                     on_mouse_wheel(1);
  700.                 }
  701.                 break;
  702.             case 3:
  703.                 if (mybutton[i].checkstate("up", x, y, i) == ButtonStates.hover) {
  704.                     on_mouse_wheel(-1);
  705.                 }
  706.                 break;
  707.             }
  708.         }
  709.     } else {
  710.         window.Repaint();
  711.     }
  712.  
  713.     for (i=0; i < mytab.length; i++) {
  714.         if (mytab[i].bt_close.checkstate("up", x, y, i) == ButtonStates.hover) {
  715.             active_pl = fb.ActivePlaylist;
  716.             nb_pl = mytab.length;
  717.             mytab.splice(i,1);
  718.             fb.RemovePlaylist(i);
  719.             if (i == active_pl) {
  720.                 if (nb_pl > 1) {
  721.                     if(i == nb_pl - 1) {
  722.                         fb.ActivePlaylist = i - 1;
  723.                     } else {
  724.                         fb.ActivePlaylist = active_pl;
  725.                     }
  726.                 }
  727.             }
  728.             if (tab_CONST.scroll) {
  729.                 tab_CONST.pos = tab_CONST.pos < tab_CONST.min_width * -1 ? tab_CONST.pos + tab_CONST.min_width + 0 : tab_CONST.pos;
  730.             } else {
  731.                 tab_CONST.pos = 0;
  732.             }
  733.             refresh_playlists();
  734.         } else {
  735.             mytab[i].checkstate("up", x, y, i);
  736.         }
  737.     }
  738.        
  739.     g_drag = false;
  740. }
  741.  
  742. //==========================================================================/ mouse_move
  743. function on_mouse_move(x, y) {
  744.     var i;
  745.    
  746.     if(!g_drag && x==mouse_x && y==mouse_y) return true;
  747.    
  748.     g_drag = (g_left_click>2)?true:false;
  749.     if(g_left_click>0) g_left_click++;
  750.    
  751.     hand = false;
  752.     if(!g_drag) {
  753.         for (i=0; i < mybutton.length; i++) {
  754.             mybutton[i].checkstate("move", x, y, i);
  755.             if(mybutton[i].ishover == true) hand = true;
  756.         }
  757.     }
  758.  
  759.     if (x > 0 && x < ww) {
  760.         show_tooltip = false;
  761.         for (i=0; i < mytab.length; i++) {
  762.             mytab[i].checkstate("move", x, y, i);
  763.             if(mytab[i].ishover) {
  764.                 show_tooltip = true;
  765.                 var total_item = fb.PlaylistItemCount(i);
  766.                 total_item = (total_item>1?" - ["+total_item+" items]":(total_item>0?" [1 item]":" [no item]"));
  767.                 if(g_tooltip.Text != mytab[i].label+total_item) {
  768.                     g_tooltip.Deactivate();
  769.                     g_tooltip.Text = mytab[i].label+total_item;
  770.                 }
  771.             }
  772.             if (x > tab_CONST.pad_left && x < ww - tab_CONST.pad_right) {
  773.                 mytab[i].bt_close.checkstate("move", x, y, i);
  774.                 if(mytab[i].bt_close.ishover) hand=true;
  775.             } else {
  776.                 mytab[i].bt_close.state = ButtonStates.normal;
  777.                 mytab[i].bt_close.repaint();
  778.             }
  779.         }
  780.         if(show_tooltip) {
  781.             g_tooltip.Activate();
  782.         } else {
  783.             g_tooltip.Deactivate();
  784.             g_tooltip.Text="";
  785.         }
  786.     } else {
  787.         g_tooltip.Deactivate();
  788.         g_tooltip.Text="";
  789.     }
  790.    
  791.     // tab item scroll on mouse drag item over boundaries
  792.     if((g_drag && !g_scrollitems_timer) || elp_dragging) {
  793.         if(tab_CONST.scroll && x<tab_CONST.pad_left) {
  794.             g_scrollitems_delta = 1;
  795.             if(elp_dragging) {
  796.                 on_mouse_wheel(g_scrollitems_delta);
  797.                 window.Repaint();
  798.             } else {              
  799.                 g_scrollitems_timer = window.SetTimeout(function() {
  800.                     on_mouse_wheel(g_scrollitems_delta);
  801.                     g_scrollitems_timer = false;
  802.                     window.Repaint();
  803.                     // if drag on, we call again mouse_move to check if scroll item is still invoked or not
  804.                     if(g_drag || elp_dragging) on_mouse_move(mouse_x, mouse_y);
  805.                 }, 80);
  806.             }
  807.         } else if (tab_CONST.scroll && x>ww-tab_CONST.pad_right) {
  808.             g_scrollitems_delta = -1;
  809.             if(elp_dragging) {
  810.                 on_mouse_wheel(g_scrollitems_delta);
  811.                 window.Repaint();
  812.             } else {
  813.                 g_scrollitems_timer = window.SetTimeout(function() {
  814.                     on_mouse_wheel(g_scrollitems_delta);
  815.                     g_scrollitems_timer = false;
  816.                     window.Repaint();
  817.                     // if drag on, we call again mouse_move to check if scroll item is still invoked or not
  818.                     if(g_drag || elp_dragging) on_mouse_move(mouse_x, mouse_y);
  819.                 }, 80);
  820.             }
  821.         } else {
  822.             // timer reset if no more scroll invoked
  823.             g_scrollitems_timer && window.ClearTimeout(g_scrollitems_timer);
  824.             g_scrollitems_timer = false;
  825.             // repaint action when no scroll invoked
  826.             window.Repaint();
  827.         }
  828.     }
  829.     // when drag stop, timer is to reset
  830.     if(!g_drag && !elp_dragging) {
  831.         g_scrollitems_timer && window.ClearTimeout(g_scrollitems_timer);
  832.         g_scrollitems_timer = false;
  833.     }
  834.  
  835.     var mouseCursor = hand?IDC_HAND:IDC_ARROW;
  836.     window.SetCursor(mouseCursor);
  837.    
  838.     g_handles = null;
  839.  
  840.     mouse_x = x;
  841.     mouse_y = y;
  842. }
  843.  
  844. //==========================================================================/ mouse_leave
  845. function on_mouse_leave() {
  846.     var i;
  847.     for (i = 0; i < mybutton.length; i++) {
  848.         mybutton[i].checkstate("leave", 0, 0, i);
  849.     }
  850.  
  851.     for (i = 0; i < mytab.length; i++) {
  852.         mytab[i].checkstate("leave", 0, 0, i);
  853.         mytab[i].bt_close.checkstate("leave", 0, 0, i);
  854.     }
  855.     g_tooltip.Text="";
  856. }
  857.  
  858. function on_font_changed() {
  859.     get_font();
  860.     window.Repaint();
  861. }
  862.  
  863. function on_colors_changed() {
  864.     get_colors();
  865.     refresh_buttons();
  866.     refresh_playlists();
  867.     window.Repaint();
  868. }
  869.  
  870. // ===============================================================================/ playlist context menu
  871. function playlist_context_menu(x, y, id) {
  872.     var MF_SEPARATOR = 0x00000800;
  873.     var MF_STRING = 0x00000000;
  874.     var _menu = window.CreatePopupMenu();
  875.     var idx;
  876.  
  877.     _menu.AppendMenuItem(MF_STRING, 1, "Rename this playlist");
  878.     if(fb.IsAutoPlaylist(id) && mytab[id].label.substring(0,13)!="#Quicksearch*") _menu.AppendMenuItem(MF_STRING, 3, "Edit Autoplaylist Properties");
  879.     idx = _menu.TrackPopupMenu(x, y);
  880.     switch (idx) {
  881.     case 1:
  882.         var playlistname = InputBox("Rename the playlist: "+mytab[id].label, "Rename a playlist", mytab[id].label);
  883.         if(!playlistname || playlistname == "") playlistname = mytab[id].label;
  884.         if (playlistname.length > 1 || (playlistname.length == 1 && (playlistname >= "a" && playlistname <= "z") || (playlistname >= "A" && playlistname <= "Z") || (playlistname >= "0" && playlistname <= "9"))) {
  885.             mytab[id].label = playlistname;
  886.             fb.RenamePlaylist(id, playlistname);
  887.             window.Repaint();
  888.         }
  889.         break;
  890.     case 2:
  891.         break;
  892.     case 3:
  893.         fb.ShowAutoPlaylistUI(id);
  894.         break;
  895.     }
  896.     _menu.Dispose();
  897.     return true;
  898. }
  899.  
  900. // ===============================================================================/ playlist command menu
  901. function playlist_command_menu(x, y, id) {
  902.     var MF_SEPARATOR = 0x00000800;
  903.     var MF_STRING = 0x00000000;
  904.     var _menu = window.CreatePopupMenu();
  905.     var idx;
  906.     var ind;
  907.  
  908.     ind=fb.ActivePlaylist;
  909.  
  910.     _menu.AppendMenuItem(MF_STRING, 1, "Show active playlist tab");
  911.     _menu.AppendMenuItem(MF_SEPARATOR, 0, "");
  912.     _menu.AppendMenuItem(MF_STRING, 2, "Rename the active Playlist");
  913.     _menu.AppendMenuItem(MF_STRING, 3, "Save the active Playlist");
  914.     _menu.AppendMenuItem(MF_STRING, 4, "Load a Playlist");
  915.     _menu.AppendMenuItem(MF_STRING, 5, "Open Playlist Manager");
  916.     idx = _menu.TrackPopupMenu(x, y);
  917.     switch (idx) {
  918.     case 1:
  919.         show_active_playlist();
  920.         break;
  921.     case 2:
  922.         playlistname = InputBox("Rename the playlist: "+mytab[ind].label, "Rename a playlist", mytab[ind].label);
  923.         if(!playlistname || playlistname == "") playlistname = mytab[ind].label;
  924.         if (playlistname.length > 1 || (playlistname.length == 1 && (playlistname >= "a" && playlistname <= "z") || (playlistname >= "A" && playlistname <= "Z") || (playlistname >= "0" && playlistname <= "9"))) {
  925.             mytab[ind].label = playlistname;
  926.             fb.RenamePlaylist(ind, playlistname);
  927.             window.Repaint();
  928.         }
  929.         break;
  930.     case 3:
  931.         fb.RunMainMenuCommand("File/Save Playlist...");
  932.         break;
  933.     case 4:
  934.         fb.RunMainMenuCommand("File/Load Playlist...");
  935.         break;
  936.     case 5:
  937.         fb.RunMainMenuCommand("View/Playlist Manager");
  938.         break;
  939.     }
  940.     _menu.Dispose();
  941.     return true;
  942. }
  943.  
  944. //==========================================================================/ refresh_playlists
  945. function refresh_playlists() {
  946.     var i;
  947.    
  948.     tab_CONST.scroll = false;
  949.     tab_CONST.pad_left = tab_CONST.pad_left_default;
  950.     tab_CONST.pad_right = bt_w*2;
  951.  
  952.     // reset array
  953.     mytab.splice(0, mytab.length);
  954.  
  955.     // init of the tabs (one tab per playlist found)
  956.     for (i=0; i < fb.PlaylistCount; i++) {
  957.         mytab.push(new tab);
  958.         mytab[i].create(fb.GetPlaylistName(i), i);
  959.     }
  960.    
  961.     var free_width = ww - tab_CONST.pad_left - tab_CONST.pad_right;
  962.    
  963.     tab_CONST.width = free_width / mytab.length;
  964.    
  965.     // force tab width to the minimal width if smaller (then horizontal scroll will be activated!)
  966.     if (tab_CONST.width < tab_CONST.min_width) {
  967.         tab_CONST.scroll = true;
  968.         tab_CONST.pad_left = bt_w + 2;
  969.         tab_CONST.pad_right = bt_w*3 - inter_tab_margin*0;
  970.         tab_CONST.width = tab_CONST.min_width;
  971.     } else {
  972.         tab_CONST.pos = 0;
  973.         tab_CONST.scroll = false;
  974.         tab_CONST.pad_left = tab_CONST.pad_left_default ;
  975.         tab_CONST.pad_right = bt_w*2;
  976.         if(tab_CONST.width > tab_CONST.max_width) tab_CONST.width = tab_CONST.max_width;
  977.     }
  978.    
  979.     check_all_buttons();
  980. }
  981.  
  982. //==========================================================================/ rbtn_down
  983. function on_mouse_rbtn_down(x, y) {
  984.     var i;
  985.     if (x > tab_CONST.pad_left && x < ww - tab_CONST.pad_right) {
  986.         for (i = 0; i < mytab.length; i++) {
  987.             mytab[i].checkstate("right", x, y, i);
  988.         }
  989.     }
  990. }
  991.  
  992. //==========================================================================/ mouse_wheel
  993. function on_mouse_wheel(delta) {
  994.     var i;
  995.     var ex_pos = tab_CONST.pos;
  996.    
  997.     var total_area = tab_CONST.width * mytab.length;
  998.     var visible_area = ww - tab_CONST.pad_left - tab_CONST.pad_right;
  999.    
  1000.     if (total_area > visible_area) {
  1001.         var delta_area_right = total_area - visible_area + tab_CONST.pos;
  1002.         var scroll_area_right = delta_area_right>=tab_CONST.scroll_step?tab_CONST.scroll_step:delta_area_right;
  1003.         var delta_area_left = tab_CONST.pos * -1;
  1004.         var scroll_area_left = delta_area_left>=tab_CONST.scroll_step?tab_CONST.scroll_step:delta_area_left;
  1005.  
  1006.         if (delta < 0) {
  1007.             tab_CONST.pos = tab_CONST.pos - scroll_area_right;
  1008.         } else {
  1009.             tab_CONST.pos = tab_CONST.pos + scroll_area_left;
  1010.         }
  1011.                
  1012.     } else {
  1013.         tab_CONST.scroll = false;
  1014.         tab_CONST.pos = 0;
  1015.     }
  1016.    
  1017.     on_mouse_move(mouse_x, mouse_y);
  1018.  
  1019.     window.Repaint();
  1020. }
  1021.  
  1022. function scroll_to_right_limit() {
  1023.     var total_area = tab_CONST.width * mytab.length+1;
  1024.     var visible_area = ww - tab_CONST.pad_left - tab_CONST.pad_right;
  1025.     tab_CONST.pos = 0 - (total_area - visible_area);
  1026.     tab_CONST.pos++;
  1027.     window.Repaint();
  1028. }
  1029.  
  1030. function show_active_playlist() {
  1031.     var visible_area = ww - tab_CONST.pad_left - tab_CONST.pad_right;
  1032.     if(tab_CONST.scroll) {
  1033.         if(mytab[fb.ActivePlaylist].x < tab_CONST.pad_left) {
  1034.             tab_CONST.pos += mytab[fb.ActivePlaylist].x*-1 + tab_CONST.pad_left;
  1035.         }
  1036.         if(mytab[fb.ActivePlaylist].x+tab_CONST.width > ww-tab_CONST.pad_right) {
  1037.             tab_CONST.pos -= (mytab[fb.ActivePlaylist].x - visible_area + tab_CONST.pad_right + 08);
  1038.         }        
  1039.            
  1040.     }
  1041.     window.Repaint();
  1042. }
  1043.  
  1044. //=================================================// Keyboard Callbacks
  1045. function on_key_up(vkey) {
  1046. }
  1047.  
  1048. function on_key_down(vkey) {
  1049.     var mask = GetKeyboardMask();
  1050.     var focus_id;
  1051.    
  1052.     if (mask == KMask.none) {
  1053.         switch (vkey) {
  1054.         case VK_END:
  1055.             if(tab_CONST.scroll) {
  1056.                 tab_CONST.pos = 0 - ((mytab.length*tab_CONST.width) - (ww-tab_CONST.pad_left-tab_CONST.pad_right));
  1057.                 window.Repaint();
  1058.             }
  1059.             break;
  1060.         case VK_HOME:
  1061.             if(tab_CONST.scroll) {
  1062.                 tab_CONST.pos = 0;
  1063.                 window.Repaint();
  1064.             }
  1065.             break;
  1066.         }
  1067.     } else {
  1068.         switch(mask) {
  1069.             case KMask.ctrl:
  1070.                 if(vkey==65) { // CTRL+A
  1071.                     fb.RunMainMenuCommand("Edit/Select all");
  1072.                     window.Repaint();
  1073.                 }
  1074.                 if(vkey==70) { // CTRL+F
  1075.                     fb.RunMainMenuCommand("Edit/Search");
  1076.                 }
  1077.                 if(vkey==78) { // CTRL+N
  1078.                     fb.RunMainMenuCommand("File/New playlist");
  1079.                 }
  1080.                 if(vkey==79) { // CTRL+O
  1081.                     fb.RunMainMenuCommand("File/Open...");
  1082.                 }
  1083.                 if(vkey==80) { // CTRL+P
  1084.                     fb.RunMainMenuCommand("File/Preferences");
  1085.                 }
  1086.                 if(vkey==83) { // CTRL+S
  1087.                     fb.RunMainMenuCommand("File/Save playlist...");
  1088.                 }
  1089.                 break;
  1090.             case KMask.alt:
  1091.                 if(vkey==65) { // ALT+A
  1092.                     fb.RunMainMenuCommand("View/Always on Top");
  1093.                 }
  1094.                 break;
  1095.         }
  1096.     }
  1097. }
  1098.  
  1099. function on_notify_data(name, info) {
  1100.     switch(name) {
  1101.         case "WSH_playlist_drag_drop": // send from a WSH playlist panel to simulate a drag and drop feature
  1102.             g_handles = info;
  1103.             break;
  1104.     }
  1105. }
  1106.  
  1107. //=================================================// Drag'n'Drop Callbacks
  1108. var elp_dragging = false;
  1109.  
  1110. function on_drag_enter() {
  1111.     elp_dragging = true;
  1112. }
  1113.  
  1114. function on_drag_leave() {
  1115.     elp_dragging = false;
  1116. }
  1117.  
  1118. function on_drag_over(action, x, y, mask) {
  1119.     on_mouse_move(x, y);
  1120. }
  1121.  
  1122. function GetIDfromXpos(x) {
  1123.     var idx = Math.floor((x - tab_CONST.pos - tab_CONST.pad_left) / tab_CONST.width);
  1124.     return idx;
  1125. }
  1126.  
  1127. function on_drag_drop(action, x, y, mask) {
  1128.     elp_dragging = false;
  1129.     var idx = GetIDfromXpos(x);
  1130.     // We are going to process the dropped items to a playlist
  1131.     action.ToPlaylist();
  1132.     action.Playlist = idx;
  1133.     action.ToSelect = false;
  1134. }
  1135.  
  1136. function check_all_buttons() {
  1137.     if(tab_CONST.scroll) {
  1138.         mybutton[0] = new button(newpl_img_off, newpl_img_ov, newpl_img_ov);
  1139.     } else {
  1140.         mybutton[0] = new button(newtab_img_off, newtab_img_ov, newtab_img_ov);
  1141.     }
  1142.    
  1143.     if(tab_CONST.scroll) {
  1144.         mybutton[1] = new button(plmenu1_img_off, plmenu1_img_ov, plmenu1_img_ov);
  1145.     } else {
  1146.         mybutton[1] = new button(plmenu2_img_off, plmenu2_img_ov, plmenu2_img_ov);
  1147.     }
  1148.    
  1149.     mybutton[2] = new button(scroll_left_img_off, scroll_left_img_ov, scroll_left_img_ov);
  1150.     mybutton[3] = new button(scroll_right_img_off, scroll_right_img_ov, scroll_right_img_ov);
  1151. }
  1152.  
  1153. //=================================================// Draw buttons
  1154. function refresh_buttons() {
  1155.     var i;
  1156.     var gb;
  1157.     var gui_font;
  1158.  
  1159.     // ***
  1160.  
  1161.     newtab_img_off = gdi.CreateImage(bt_w, tab_CONST.height);
  1162.     gb = newtab_img_off.GetGraphics();
  1163.     gb.FillSolidRect(0, top_tab_margin, newtab_img_off.Width, newtab_img_off.Height+5-top_tab_margin, g_backcolor);
  1164.     gb.FillSolidRect(0, top_tab_margin, newtab_img_off.Width, newtab_img_off.Height+5-top_tab_margin, g_textcolor&0xaaffffff);
  1165.     gb.FillSolidRect(1, top_tab_margin+1, newtab_img_off.Width-2, newtab_img_off.Height+5-top_tab_margin-1, g_backcolor);
  1166.     gb.FillSolidRect(1, top_tab_margin+1, newtab_img_off.Width-2, newtab_img_off.Height+5-top_tab_margin-1, background_colour.normal);
  1167.     gb.FillGradRect(1, top_tab_margin+1, newtab_img_off.Width-2, newtab_img_off.Height+5-top_tab_margin-1, 90, g_backcolor&0x55ffffff, background_colour.normal, 1.0);
  1168.     gb.FillSolidRect(0, newtab_img_off.Height-2, newtab_img_off.Width, 1, RGBA(0,0,0,80));
  1169.     gb.FillSolidRect(0, newtab_img_off.Height-3, newtab_img_off.Width, 1, RGBA(0,0,0,30));
  1170.     gb.FillSolidRect(0, newtab_img_off.Height-4, newtab_img_off.Width, 1, RGBA(0,0,0,10));
  1171.     gb.FillSolidRect(0, newtab_img_off.Height-1, newtab_img_off.Width, 1, g_backcolor);
  1172.     gb.FillSolidRect(0, newtab_img_off.Height-1, newtab_img_off.Width, 1, RGBA(0,0,0,50));
  1173.     gui_font = gdi.Font("guifx v2 transports", 12, 0);
  1174.     gb.SetTextRenderingHint(3);
  1175.     gb.DrawString("=", gui_font, g_textcolor, 0, top_tab_margin-1, newtab_img_off.Width, newtab_img_off.Height-top_tab_margin, cc_stringformat);
  1176.     gb.DrawString("=", gui_font, label_colour.normal, 0, top_tab_margin-2, newtab_img_off.Width, newtab_img_off.Height-top_tab_margin, cc_stringformat);
  1177.     newtab_img_off.ReleaseGraphics(gb);
  1178.  
  1179.     newtab_img_ov = gdi.CreateImage(bt_w, tab_CONST.height);
  1180.     gb = newtab_img_ov.GetGraphics();
  1181.     gb.FillSolidRect(0, 1, newtab_img_ov.Width, newtab_img_ov.Height+5-1, g_backcolor);
  1182.     gb.FillSolidRect(0, 1, newtab_img_ov.Width, newtab_img_ov.Height+5-1, g_textcolor&0xaaffffff);
  1183.     gb.FillSolidRect(1, 2, newtab_img_ov.Width-2, newtab_img_ov.Height+5-2, g_backcolor);
  1184.     gb.FillSolidRect(1, 2, newtab_img_ov.Width-2, newtab_img_ov.Height+5-2, background_colour.normal);
  1185.     gb.FillGradRect(1, 2, newtab_img_ov.Width-2, newtab_img_ov.Height+5-2, 90, background_colour.normal, g_backcolor&0x55ffffff, 1.0);
  1186.     gb.FillSolidRect(0, newtab_img_ov.Height-2, newtab_img_ov.Width, 1, RGBA(0,0,0,80));
  1187.     gb.FillSolidRect(0, newtab_img_ov.Height-3, newtab_img_ov.Width, 1, RGBA(0,0,0,30));
  1188.     gb.FillSolidRect(0, newtab_img_ov.Height-4, newtab_img_ov.Width, 1, RGBA(0,0,0,10));
  1189.     gb.FillSolidRect(0, newtab_img_ov.Height-1, newtab_img_ov.Width, 1, g_backcolor);
  1190.     gb.FillSolidRect(0, newtab_img_ov.Height-1, newtab_img_ov.Width, 1, RGBA(0,0,0,50));  
  1191.     gui_font = gdi.Font("guifx v2 transports", 14, 0);
  1192.     gb.SetTextRenderingHint(3);
  1193.     gb.DrawString("=", gui_font, g_textcolor, 0, top_tab_margin-1, newtab_img_ov.Width, newtab_img_ov.Height-top_tab_margin, cc_stringformat);
  1194.     gb.DrawString("=", gui_font, label_colour.hover, 0, top_tab_margin-2, newtab_img_ov.Width, newtab_img_ov.Height-top_tab_margin, cc_stringformat);
  1195.     newtab_img_ov.ReleaseGraphics(gb);
  1196.  
  1197.     newpl_img_off = gdi.CreateImage(bt_w, tab_CONST.height);
  1198.     gb = newpl_img_off.GetGraphics();
  1199.     gb.FillSolidRect(0, 0, newpl_img_off.Width, newpl_img_off.Height, g_backcolor);
  1200.     gb.FillGradRect(0, 0, newpl_img_off.Width, newpl_img_off.Height, 90, 0, g_textcolor&0x28ffffff, 1.0);
  1201.     gui_font = gdi.Font("guifx v2 transports", 12, 0);
  1202.     gb.SetTextRenderingHint(3);
  1203.     gb.DrawString("=", gui_font, g_textcolor&0x55ffffff, 0, top_tab_margin+5, newpl_img_off.Width, newpl_img_off.Height, ct_stringformat);
  1204.     newpl_img_off.ReleaseGraphics(gb);
  1205.  
  1206.     newpl_img_ov = gdi.CreateImage(bt_w, tab_CONST.height);
  1207.     gb = newpl_img_ov.GetGraphics();
  1208.     gb.FillSolidRect(0, 0, newpl_img_ov.Width, newpl_img_ov.Height, g_backcolor);
  1209.     gb.FillGradRect(0, 0, newpl_img_ov.Width, newpl_img_ov.Height, 90, 0, g_textcolor&0x28ffffff, 1.0);
  1210.     gui_font = gdi.Font("guifx v2 transports", 14, 0);
  1211.     gb.SetTextRenderingHint(3);
  1212.     gb.DrawString("=", gui_font, g_textcolor, 0, top_tab_margin+4, newpl_img_ov.Width, newpl_img_ov.Height, ct_stringformat);
  1213.     newpl_img_ov.ReleaseGraphics(gb);
  1214.  
  1215.     // ***
  1216.  
  1217.     plmenu2_img_off = gdi.CreateImage(bt_w, tab_CONST.height);
  1218.     gb = plmenu2_img_off.GetGraphics();
  1219.     gb.FillSolidRect(0, 0, plmenu2_img_off.Width, plmenu2_img_off.Height, g_backcolor);
  1220.     gb.FillGradRect(0, 0, plmenu2_img_off.Width, plmenu2_img_off.Height, 90, 0, g_textcolor&0x28ffffff, 1.0);
  1221.     gb.FillGradRect(0, 0, 1, plmenu2_img_off.Height, 90, RGBA(0,0,0,0), RGBA(255,255,255,75), 0.5);
  1222.     gui_font = gdi.Font("guifx v2 transports", 13, 0);
  1223.     gb.SetTextRenderingHint(5);
  1224.     gb.DrawString("s", gui_font, g_textcolor&0x55ffffff, 0, top_tab_margin+5, plmenu2_img_off.Width, plmenu2_img_off.Height+20, ct_stringformat);
  1225.     plmenu2_img_off.ReleaseGraphics(gb);
  1226.  
  1227.     plmenu2_img_ov = gdi.CreateImage(bt_w, tab_CONST.height);
  1228.     gb = plmenu2_img_ov.GetGraphics();
  1229.     gb.FillSolidRect(0, 0, plmenu2_img_ov.Width, plmenu2_img_ov.Height, g_backcolor);
  1230.     gb.FillGradRect(0, 0, plmenu2_img_ov.Width, plmenu2_img_ov.Height, 90, 0, g_textcolor&0x28ffffff, 1.0);
  1231.     gb.FillGradRect(0, 0, 1, plmenu2_img_off.Height, 90, RGBA(0,0,0,0), RGBA(255,255,255,75), 0.5);
  1232.     gui_font = gdi.Font("guifx v2 transports", 13, 0);
  1233.     gb.SetTextRenderingHint(5);
  1234.     gb.DrawString("s", gui_font, g_textcolor, 0, top_tab_margin+5, plmenu2_img_ov.Width, plmenu2_img_ov.Height, ct_stringformat);
  1235.     plmenu2_img_ov.ReleaseGraphics(gb);
  1236.  
  1237.     plmenu1_img_off = gdi.CreateImage(bt_w, tab_CONST.height);
  1238.     gb = plmenu1_img_off.GetGraphics();
  1239.     gb.FillSolidRect(0, 0, plmenu1_img_off.Width, plmenu1_img_off.Height, g_backcolor);
  1240.     gb.FillGradRect(0, 0, plmenu1_img_off.Width, plmenu1_img_off.Height, 90, 0, g_textcolor&0x28ffffff, 1.0);
  1241.     gui_font = gdi.Font("guifx v2 transports", 13, 0);
  1242.     gb.SetTextRenderingHint(5);
  1243.     gb.DrawString("s", gui_font, g_textcolor&0x55ffffff, 0, top_tab_margin+5, plmenu1_img_off.Width, plmenu1_img_off.Height+20, ct_stringformat);
  1244.     plmenu1_img_off.ReleaseGraphics(gb);
  1245.  
  1246.     plmenu1_img_ov = gdi.CreateImage(bt_w, tab_CONST.height);
  1247.     gb = plmenu1_img_ov.GetGraphics();
  1248.     gb.FillSolidRect(0, 0, plmenu1_img_ov.Width, plmenu1_img_ov.Height, g_backcolor);
  1249.     gb.FillGradRect(0, 0, plmenu1_img_ov.Width, plmenu1_img_ov.Height, 90, 0, g_textcolor&0x28ffffff, 1.0);
  1250.     gui_font = gdi.Font("guifx v2 transports", 13, 0);
  1251.     gb.SetTextRenderingHint(5);
  1252.     gb.DrawString("s", gui_font, g_textcolor, 0, top_tab_margin+5, plmenu1_img_ov.Width, plmenu1_img_ov.Height, ct_stringformat);
  1253.     plmenu1_img_ov.ReleaseGraphics(gb);
  1254.  
  1255.     // ***
  1256.  
  1257.     scroll_left_img_off = gdi.CreateImage(bt_w, tab_CONST.height);
  1258.     gb = scroll_left_img_off.GetGraphics();
  1259.     gb.FillSolidRect(0, 0, scroll_left_img_off.Width, scroll_left_img_off.Height, g_backcolor);
  1260.     gb.FillGradRect(0, 0, scroll_left_img_off.Width, scroll_left_img_off.Height, 90, 0, g_textcolor&0x28ffffff, 1.0);
  1261.     gb.FillGradRect(scroll_left_img_off.Width-1, 0, 1, scroll_left_img_off.Height, 90, RGBA(0,0,0,0), RGBA(255,255,255,75), 0.5);
  1262.     gui_font = gdi.Font("guifx v2 transports", 14, 0);
  1263.     gb.SetTextRenderingHint(5);
  1264.     gb.DrawString("<", gui_font, g_textcolor&0x55ffffff, 0, top_tab_margin+4, scroll_left_img_off.Width, scroll_left_img_off.Height, ct_stringformat);
  1265.     scroll_left_img_off.ReleaseGraphics(gb);
  1266.  
  1267.     scroll_left_img_ov = gdi.CreateImage(bt_w, tab_CONST.height);
  1268.     gb = scroll_left_img_ov.GetGraphics();
  1269.     gb.FillSolidRect(0, 0, scroll_left_img_ov.Width, scroll_left_img_ov.Height, g_backcolor);
  1270.     gb.FillGradRect(0, 0, scroll_left_img_ov.Width, scroll_left_img_ov.Height, 90, 0, g_textcolor&0x28ffffff, 1.0);
  1271.     gb.FillGradRect(scroll_left_img_off.Width-1, 0, 1, scroll_left_img_off.Height, 90, RGBA(0,0,0,0), RGBA(255,255,255,75), 0.5);
  1272.     gui_font = gdi.Font("guifx v2 transports", 14, 0);
  1273.     gb.SetTextRenderingHint(5);
  1274.     gb.DrawString("<", gui_font, g_textcolor, -1, top_tab_margin+4, scroll_left_img_ov.Width, scroll_left_img_ov.Height, ct_stringformat);
  1275.     scroll_left_img_ov.ReleaseGraphics(gb);
  1276.  
  1277.     scroll_right_img_off = gdi.CreateImage(bt_w, tab_CONST.height);
  1278.     gb = scroll_right_img_off.GetGraphics();
  1279.     gb.FillSolidRect(0, 0, scroll_right_img_off.Width, scroll_right_img_off.Height, g_backcolor);
  1280.     gb.FillGradRect(0, 0, scroll_right_img_off.Width, scroll_right_img_off.Height, 90, 0, g_textcolor&0x28ffffff, 1.0);
  1281.     gb.FillGradRect(0, 0, 1, scroll_left_img_off.Height, 90, RGBA(0,0,0,0), RGBA(255,255,255,75), 0.5);
  1282.     gui_font = gdi.Font("guifx v2 transports", 14, 0);
  1283.     gb.SetTextRenderingHint(5);
  1284.     gb.DrawString(">", gui_font, g_textcolor&0x55ffffff, 0, top_tab_margin+4, scroll_right_img_off.Width, scroll_right_img_off.Height, ct_stringformat);
  1285.     scroll_right_img_off.ReleaseGraphics(gb);
  1286.  
  1287.     scroll_right_img_ov = gdi.CreateImage(bt_w, tab_CONST.height);
  1288.     gb = scroll_right_img_ov.GetGraphics();
  1289.     gb.FillSolidRect(0, 0, scroll_right_img_ov.Width, scroll_right_img_ov.Height, g_backcolor);
  1290.     gb.FillGradRect(0, 0, scroll_right_img_ov.Width, scroll_right_img_ov.Height, 90, 0, g_textcolor&0x28ffffff, 1.0);
  1291.     gb.FillGradRect(0, 0, 1, scroll_left_img_off.Height, 90, RGBA(0,0,0,0), RGBA(255,255,255,75), 0.5);
  1292.     gui_font = gdi.Font("guifx v2 transports", 14, 0);
  1293.     gb.SetTextRenderingHint(5);
  1294.     gb.DrawString(">", gui_font, g_textcolor, 1, top_tab_margin+4, scroll_right_img_ov.Width, scroll_right_img_ov.Height, ct_stringformat);
  1295.     scroll_right_img_ov.ReleaseGraphics(gb);
  1296.  
  1297.     // ***
  1298.  
  1299.     close_img_off = gdi.CreateImage(12, 12);
  1300.     gb = close_img_off.GetGraphics();
  1301.     gb.SetSmoothingMode(2);
  1302.     //gb.FillEllipse(0, 0, 11, 11, background_colour.normal);
  1303.     gb.FillRoundRect(1, 1, 9, 9, 1, 1, background_colour.normal);
  1304.     gb.DrawLine(3, 3, 8, 8, 1.0, label_colour.normal);
  1305.     gb.DrawLine(8, 3, 3, 8, 1.0, label_colour.normal);
  1306.     close_img_off.ReleaseGraphics(gb);
  1307.  
  1308.     close_img_ov = gdi.CreateImage(12, 12);
  1309.     gb = close_img_ov.GetGraphics();
  1310.     gb.SetSmoothingMode(2);
  1311.     //gb.FillEllipse(0, 0, 11, 11, RGB(210, 050, 050));
  1312.     gb.FillRoundRect(1, 1, 9, 9, 1, 1, RGB(210, 050, 050));
  1313.     gb.DrawLine(3, 3, 8, 8, 1.0, RGB(240, 240, 240));
  1314.     gb.DrawLine(8, 3, 3, 8, 1.0, RGB(240, 240, 240));
  1315.     close_img_ov.ReleaseGraphics(gb);
  1316.    
  1317.     // ***
  1318.  
  1319.     autoplaylist_marker_off = gdi.CreateImage(7, 7);
  1320.     gb = autoplaylist_marker_off.GetGraphics();
  1321.     gb.SetSmoothingMode(2);
  1322.     //gb.FillSolidRect(0, 0, 6, 7, g_backcolor);
  1323.     var points = Array(0,4, 4,0, 4,5, 0,5);
  1324.     gb.FillPolygon(g_textcolor, 0, points);
  1325.     gb.FillPolygon(RGBA(255,255,255,50), 0, points);
  1326.     gb.DrawPolygon(g_textcolor&0xbbffffff, 1.0, points);
  1327.     gb.DrawPolygon(RGBA(255,255,255,50), 1.0, points);
  1328.     gb.DrawLine(0,6,5,6,1.0,RGBA(0,0,0,100));
  1329.     gb.DrawLine(5,0,5,5,1.0,RGBA(0,0,0,100));
  1330.     autoplaylist_marker_off.ReleaseGraphics(gb);
  1331.  
  1332.     autoplaylist_marker_on = gdi.CreateImage(8, 8);
  1333.     gb = autoplaylist_marker_on.GetGraphics();
  1334.     gb.SetSmoothingMode(2);
  1335.     //gb.FillSolidRect(0, 0, 6, 7, g_backcolor);
  1336.     var points = Array(0,5, 5,0, 5,6, 0,6);
  1337.     gb.FillPolygon(g_backcolor, 0, points);
  1338.     gb.DrawPolygon(RGBA(255,255,255,50), 1.0, points);
  1339.     gb.DrawPolygon(g_textcolor&0x25ffffff, 1.0, points);
  1340.     gb.DrawLine(0,7,6,7,1.0,RGBA(0,0,0,75));
  1341.     gb.DrawLine(6,0,6,6,1.0,RGBA(0,0,0,75));
  1342.     autoplaylist_marker_on.ReleaseGraphics(gb);
  1343.  
  1344.     // initialize button's attributs
  1345.     for (i = 0; i < 4; i++) {
  1346.         switch (i) {
  1347.         case 0: // add new playlist button
  1348.             mybutton.push(new button(newtab_img_off, newtab_img_ov, newtab_img_ov));
  1349.             break;
  1350.         case 1: // menu
  1351.             if(tab_CONST.scroll) {
  1352.                 mybutton.push(new button(plmenu1_img_off, plmenu1_img_ov, plmenu1_img_ov));
  1353.             } else {
  1354.                 mybutton.push(new button(plmenu2_img_off, plmenu2_img_ov, plmenu2_img_ov));
  1355.             }
  1356.             break;
  1357.         case 2: // scroll left
  1358.             mybutton.push(new button(scroll_left_img_off, scroll_left_img_ov, scroll_left_img_ov));
  1359.             break;
  1360.         case 3: // scroll right
  1361.             mybutton.push(new button(scroll_right_img_off, scroll_right_img_ov, scroll_right_img_ov));
  1362.             break;
  1363.         }
  1364.     }
  1365.     CollectGarbage();
  1366. }
  1367.  
  1368. //==========================================================================/ on_mouse_right_button
  1369. function on_mouse_rbtn_up(x, y) {
  1370.     //return true;
  1371. }
  1372.  
  1373. //==========================================================================/ Get Colors & Fonts
  1374. function get_colors() {
  1375.     if(g_instancetype == 0) { // CUI
  1376.         g_textcolor = window.GetColorCUI(ColorTypeCUI.text);
  1377.         g_textcolor_sel = window.GetColorCUI(ColorTypeCUI.selection_text);
  1378.         g_textcolor_hl = window.GetColorCUI(ColorTypeCUI.active_item_frame);
  1379.         g_backcolor = window.GetColorCUI(ColorTypeCUI.background);
  1380.     } else if(g_instancetype == 1) { // DUI
  1381.         g_textcolor = window.GetColorDUI(ColorTypeDUI.text);
  1382.         g_textcolor_sel = window.GetColorDUI(ColorTypeDUI.selection);
  1383.         g_textcolor_hl = window.GetColorDUI(ColorTypeDUI.highlight);
  1384.         g_backcolor = window.GetColorDUI(ColorTypeDUI.background);
  1385.     };
  1386.    
  1387.     // Custom colors set in Properties of the panel
  1388.     if(panel.custom_colors) {
  1389.         try{
  1390.             if(panel.custom_textcolor.length>0) g_textcolor = eval(panel.custom_textcolor);
  1391.             if(panel.custom_textcolor_selection.length>0) {
  1392.                 g_textcolor_sel = eval(panel.custom_textcolor_selection);
  1393.                 g_backcolor_sel = g_textcolor_sel;
  1394.             };
  1395.             if(panel.custom_backcolor.length>0) g_backcolor = eval(panel.custom_backcolor);
  1396.             if(panel.custom_textcolor_highlight.length>0) g_textcolor_hl = eval(panel.custom_textcolor_highlight);
  1397.         } catch(e) {};
  1398.     };
  1399.    
  1400.     background_colour.normal = g_textcolor&0xbbffffff;
  1401.     background_colour.hover = g_textcolor&0xbccfffff;
  1402.     background_colour.active = g_backcolor;
  1403.     background_colour.drag = g_backcolor;
  1404.     label_colour.normal = g_backcolor;
  1405.     label_colour.hover = g_backcolor&0xeeffffff;
  1406.     label_colour.active = g_textcolor&0xeeffffff;
  1407.     label_colour.drag = g_textcolor&0xeeffffff;
  1408. }
  1409.  
  1410. function get_font() {
  1411.     if (g_instancetype == 0) { // CUI
  1412.         g_font_headers = window.GetFontCUI(FontTypeCUI.labels);
  1413.     } else if (g_instancetype == 1) { // DUI
  1414.         g_font_headers = window.GetFontDUI(FontTypeDUI.tabs);
  1415.     }
  1416. }
RAW Paste Data