Advertisement
danielkza

WSH Ratings Panel

Mar 11th, 2012
367
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Helper function for DrawString() and MeasureString()
  2. // args: h_align, v_align, trimming, flags
  3. function StringFormat() {
  4.     var h_align = 0, v_align = 0, trimming = 0, flags = 0;
  5.     switch (arguments.length)
  6.     {
  7.     // fall-thru
  8.     case 4:
  9.         flags = arguments[3];
  10.     case 3:
  11.         trimming = arguments[2];
  12.     case 2:
  13.         v_align = arguments[1];
  14.     case 1:
  15.         h_align = arguments[0];
  16.         break;
  17.     default:
  18.         return 0;
  19.     }
  20.     return ((h_align << 28) | (v_align << 24) | (trimming << 20) | flags);
  21. };
  22.  
  23. StringFormatFlags = {
  24.     DirectionRightToLeft: 0x00000001,
  25.     DirectionVertical: 0x00000002,
  26.     NoFitBlackBox: 0x00000004,
  27.     DisplayFormatControl: 0x00000020,
  28.     NoFontFallback: 0x00000400,
  29.     MeasureTrailingSpaces: 0x00000800,
  30.     NoWrap: 0x00001000,
  31.     LineLimit: 0x00002000,
  32.     NoClip: 0x00004000
  33. };
  34.  
  35. // Used in gdi.Font(), can be combined
  36. // For more information, see: http://msdn.microsoft.com/en-us/library/ms534124(VS.85).aspx
  37. FontStyle = {
  38.     Regular: 0,
  39.     Bold: 1,
  40.     Italic: 2,
  41.     BoldItalic: 3,
  42.     Underline: 4,
  43.     Strikeout: 8
  44. };
  45.  
  46. // h_align/v_align:
  47. // http://msdn.microsoft.com/en-us/library/ms534177(VS.85).aspx
  48. StringAlignment = {
  49.     Near: 0,
  50.     Center: 1,
  51.     Far: 2
  52. };
  53.  
  54. SmoothingMode = {
  55.     Invalid: -1,
  56.     Default: 0,
  57.     HighSpeed: 1,
  58.     HighQuality: 2,
  59.     None: 3,
  60.     AntiAlias: 4
  61. };
  62.  
  63. // Used in window.GetColorCUI()
  64. ColorTypeCUI = {
  65.     text: 0,
  66.     selection_text: 1,
  67.     inactive_selection_text: 2,
  68.     background: 3,
  69.     selection_background: 4,
  70.     inactive_selection_background: 5,
  71.     active_item_frame: 6
  72. };
  73.  
  74. // Used in window.GetFontCUI()
  75. FontTypeCUI = {
  76.     items: 0,
  77.     labels: 1
  78. };
  79.  
  80.  
  81. // Used in window.GetColorDUI()
  82. ColorTypeDUI = {
  83.     text: 0,
  84.     background: 1,
  85.     highlight: 2,
  86.     selection: 3
  87. };
  88.  
  89. // Used in window.GetFontDUI()
  90. FontTypeDUI = {
  91.     defaults: 0,
  92.     tabs: 1,
  93.     lists: 2,
  94.     playlists: 3,
  95.     statusbar: 4,
  96.     console: 5
  97. };
  98.  
  99. String.prototype.repeat = function( num ) {
  100.     return new Array( num + 1 ).join( this );
  101. }
  102.  
  103. function RGB(r, g, b) {
  104.     return (0xff000000 | (r << 16) | (g << 8) | (b));
  105. }
  106.  
  107. function setAlpha(color, a) {
  108.     return ((color & 0x00ffffff) | (a << 24));
  109. }
  110.  
  111. function colorBlend(colors, weights)
  112. {
  113.     var r = 0, g = 0, b = 0;
  114.     var totalWeight = 0.0;
  115.    
  116.     for(var i = 0; i < Math.min(colors.length, weights.length); i++) {
  117.         weight = weights[i];
  118.         color = colors[i];
  119.        
  120.         totalWeight += weight;
  121.  
  122.         r += ((color >> 16) & 0xff) * weight;
  123.         g += ((color >> 8) & 0xff) * weight;
  124.         b += ((color) & 0xff) * weight;
  125.     }
  126.  
  127.     return RGB(r / totalWeight, g / totalWeight, b / totalWeight);
  128. }
  129.  
  130. // ===================================================================== //
  131.  
  132. RatingChar = {
  133.     Filled: window.GetProperty("rating.filledChar", '★') || '★',
  134.     Unfilled: window.GetProperty("rating.unfilledChar", '☆') || '☆'
  135. };
  136.  
  137. // ===================================================================== //
  138.  
  139. g_ratingTF = fb.TitleFormat("%rating%");
  140. function getCurRating()
  141. {
  142.     return parseInt(g_ratingTF.Eval()) || 0;
  143. };
  144.  
  145. g_updateTextPending = false;
  146. function updateText(repaint)
  147. {
  148.     g_updateTextPending = true;
  149.     if(repaint)
  150.         window.Repaint();
  151. };
  152.  
  153. function rect(x, y, w, h)
  154. {
  155.     function pick(arg, def) {
  156.         return (typeof arg == 'undefined' ? def : arg);
  157.     }
  158.  
  159.     this.x = pick(x, 0);
  160.     this.y = pick(y, 0);
  161.     this.w = pick(w, 0);
  162.     this.h = pick(h, 0);
  163.    
  164.     this.check = function(x, y)
  165.     {
  166.         return x >= this.x && x < this.x + this.w
  167.             && y >= this.y && y < this.y + this.h;
  168.     }
  169. };
  170.  
  171. function textPartsCreate()
  172. {
  173.     var rating = getCurRating();
  174.    
  175.     var hoverCount = g_curRegion + 1;
  176.     var filledCount = Math.max(0, rating - hoverCount);
  177.     var UnfilledCount = Math.max(0, 5 - hoverCount - filledCount);
  178.    
  179.     var textParts = [];
  180.     for(i = 0; i < hoverCount; i++)
  181.         textParts.push({text: RatingChar.Filled, color: g_textHighlightColor});
  182.    
  183.     for(i = 0; i < filledCount; i++)
  184.         textParts.push({text: RatingChar.Filled, color: g_textColor});
  185.    
  186.     for(i = 0; i < UnfilledCount; i++)
  187.         textParts.push({text: RatingChar.Unfilled, color: g_textColor});
  188.  
  189.     return textParts;
  190. };
  191.  
  192. function textPartsMeasureWidth(textParts, gr, width, height, textFlags)
  193. {
  194.     var totalWidth = 0;
  195.    
  196.     for(var i = 0; i < textParts.length; i++)
  197.     {
  198.         var textPart = textParts[i];
  199.            
  200.         var measure = gr.MeasureString(textPart.text, g_font,
  201.             0, 0, width, height,
  202.             textFlags);
  203.    
  204.         totalWidth += measure.Width;
  205.     }
  206.    
  207.     return totalWidth;
  208. };
  209.  
  210. function textPartsDraw(textParts, gr, x, y, width, height, textFlags)
  211. {
  212.     var regions = [];
  213.     var rating = getCurRating();
  214.    
  215.     for(var i = 0; i < textParts.length; i++)
  216.     {
  217.         var textPart = textParts[i];
  218.        
  219.         var glowAlpha = (rating == 0 || i < rating) ? g_textGlowAlpha : 0;
  220.         var textStyle = gdi.CreateStyleTextRender();
  221.         textStyle.GlowText(textPart.color, setAlpha(g_textHighlightColor, glowAlpha), 4);
  222.        
  223.         textStyle.renderStringRect(gr, textPart.text, g_font,
  224.             x, y, width, height,
  225.             textFlags);
  226.        
  227.         var measure = gr.MeasureString(textPart.text, g_font,
  228.             x, y, width, height,
  229.             textFlags);
  230.            
  231.         var region = new rect(measure.x, measure.y, measure.Width, measure.Height);
  232.         regions.push(region);
  233.    
  234.         x += measure.Width;
  235.     }
  236.    
  237.     return regions;
  238. };
  239.  
  240.  
  241. // ===================================================================== //
  242.  
  243. g_textGlowAlpha = 0;
  244. g_textGlowTimer = 0;
  245.  
  246. function applyTextGlow()
  247. {
  248.     g_textGlowAlpha = 200;
  249.    
  250.     if(g_textGlowTimer)
  251.         window.ClearInterval(g_textGlowTimer);
  252.        
  253.     g_textGlowTimer = window.SetInterval(function() {
  254.         g_textGlowAlpha -= 20;
  255.         if(g_textGlowAlpha <= 0) {
  256.             g_textGlowAlpha = 0;
  257.             window.ClearInterval(g_textGlowTimer);
  258.             g_textGlowTimer = 0;
  259.         }
  260.         window.Repaint();
  261.     }, 50.0);
  262.    
  263.     window.Repaint();
  264. };
  265.  
  266. g_textParts = null;
  267. g_textPartsWidth = null;
  268.  
  269. g_ratingRegions = [];
  270. g_curRegion = -1;
  271.  
  272. g_textAlignmentX = (function() {
  273.     switch(window.GetProperty("text.align.x", "center")) {
  274.         case "left":
  275.             return StringAlignment.Near;
  276.         case "right":
  277.             return StringAlignment.Far;
  278.     }
  279.     return StringAlignment.Center;
  280. })();
  281.    
  282. g_textAlignmentY = (function() {
  283.     switch(window.GetProperty("text.align.y", "center")) {
  284.         case "top":
  285.             return StringAlignment.Near;
  286.         case "bottom":
  287.             return StringAlignment.Far;
  288.     }
  289.     return StringAlignment.Center;
  290. })();
  291.  
  292. function on_paint(gr)
  293. {
  294.     if(g_updateTextPending) {
  295.         g_textParts = textPartsCreate();
  296.         g_textPartsWidth = textPartsMeasureWidth(g_textParts, gr,
  297.             window.Width, window.Height,
  298.             StringFormat(StringAlignment.Near, StringAlignment.Near,
  299.                          0, StringFormatFlags.NoWrap));
  300.  
  301.         g_updateTextPending = false;
  302.     }
  303.    
  304.     gr.SetSmoothingMode(SmoothingMode.HighQuality);
  305.    
  306.     var startX;
  307.     switch(g_textAlignmentX) {
  308.         case StringAlignment.Near:
  309.             startX = 0;
  310.             break;
  311.         case StringAlignment.Center:
  312.             startX = (window.Width - g_textPartsWidth) / 2;
  313.             break;
  314.         case StringAlignment.Far:
  315.             startX = window.Width - g_textPartsWidth;
  316.     }
  317.    
  318.     g_ratingRegions = textPartsDraw(g_textParts, gr,
  319.         startX, 0, g_textPartsWidth, window.Height,
  320.         StringFormat(StringAlignment.Near, g_textAlignmentY,
  321.                      0, StringFormatFlags.NoWrap));
  322. };
  323.  
  324. // ===================================================================== //
  325.  
  326. function on_mouse_move(x, y)
  327. {
  328.     var newRegion = -1;
  329.     for(var i = 0; i < g_ratingRegions.length; i++)
  330.     {
  331.         region = g_ratingRegions[i];
  332.         if(region.check(x, y)) {
  333.             newRegion = i;
  334.             break;
  335.         }
  336.     }
  337.    
  338.     if(newRegion != g_curRegion)
  339.     {
  340.         updateText(true);
  341.     }
  342.    
  343.     g_curRegion = newRegion;
  344. };
  345.  
  346. function on_mouse_leave()
  347. {
  348.     if(g_curRegion != -1) {
  349.         g_curRegion = -1;
  350.         updateText(true);
  351.     }
  352. };
  353.  
  354. function on_mouse_lbtn_up(x, y, mask)
  355. {
  356.     var newRegion = -1;
  357.     for(var i = 0; i < g_ratingRegions.length; i++)
  358.     {
  359.         region = g_ratingRegions[i];
  360.         if(region.check(x, y)) {
  361.             newRegion = i;
  362.             break;
  363.         }
  364.     }
  365.    
  366.     if(newRegion == -1)
  367.         return;
  368.        
  369.     var newRating = newRegion + 1;
  370.     var oldRating = getCurRating();
  371.    
  372.     if(newRating != oldRating) {
  373.         fb.RunContextCommand("Playback Statistics/Rating/" + newRating);
  374.         applyTextGlow();
  375.     }
  376. };
  377.  
  378. // ===================================================================== //
  379.  
  380. g_cachedRating = -1;
  381.  
  382. function on_playback_new_track(metadb)
  383. {
  384.     updateText(false);
  385.     applyTextGlow();
  386.  
  387.     g_cachedRating = getCurRating();
  388. };
  389.  
  390. function on_playback_stop(reason)
  391. {
  392.     if(reason != 2) { // starting another
  393.         updateText(false);
  394.         applyTextGlow();
  395.     }
  396.    
  397.     g_cachedRating = -1;
  398. };
  399.  
  400. function on_playback_edited(metadb)
  401. {
  402.     var newRating = getCurRating();
  403.     if(g_cachedRating == -1 || g_cachedRating != newRating) {
  404.         updateText(false);
  405.         applyTextGlow();
  406.        
  407.         g_cachedRating = newRating;
  408.     }
  409. };
  410.  
  411. // ===================================================================== //
  412.  
  413. function on_font_changed()
  414. {
  415.     var origFont = window.InstanceType ?
  416.         window.GetFontDUI(FontTypeDUI.defaults) :
  417.         window.GetFontCUI(FontTypeCUI.labels);
  418.    
  419.     var origSize = 10, origName = "Segoe UI";
  420.        
  421.     if(origFont) {
  422.         origSize = origFont.size;
  423.         origName = origFont.Name;
  424.     }
  425.    
  426.     var size = window.GetProperty("font.size", "") || origSize;
  427.     var name = window.GetProperty("font.face", "") || origName;
  428.     var dpi = window.GetProperty("font.dpi", "") || 96;
  429.        
  430.     g_font = gdi.Font(name, size * dpi / 72.0, FontStyle.regular);
  431.    
  432.     updateText(true);
  433. };
  434.  
  435. function on_colors_changed()
  436. {
  437.     if(window.instanceType) {
  438.         g_textColor = window.getColorDUI(ColorTypeDUI.text);
  439.         g_backGroundColor = window.GetColorDUI(ColorTypeDUI.background);
  440.         g_textHighlightColor = window.GetColorDUI(ColorTypeDUI.highlight);
  441.     } else {
  442.         g_textColor = window.GetColorCUI(ColorTypeCUI.text);
  443.         g_backGroundColor = window.GetColorCUI(ColorTypeCUI.background);
  444.         g_textHighlightColor = colorBlend([g_textColor, g_backGroundColor], [60, 40]);
  445.     }
  446.     window.Repaint();
  447. };
  448.  
  449. (function init()
  450. {
  451.     on_font_changed();
  452.     on_colors_changed();
  453. })();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement