Skip to main content

Notice

Please note that most of the software linked on this forum is likely to be safe to use. If you are unsure, feel free to ask in the relevant topics, or send a private message to an administrator or moderator. To help curb the problems of false positives, or in the event that you do find actual malware, you can contribute through the article linked here.
Topic: HTPC Fullscreen panels II (Read 145748 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

HTPC Fullscreen panels II

Reply #75
Hello odjo
I'm a happy user of WSHtpc02. It's just about perfect for my htpc use, thanks a lot for it.
Now I'm about to move and my new htpc display will be a large plasma TV.
Plasmas don't like static content (burn-in) and use quite some energy (black screen = low energy consumption, white screen = lots).
So I have a problem with WSHtpc02.

The perfect solution would be like:
20 seconds in and out of every song same look as WSHtpc02. then fade to black. fade in the cover at random size at a random
position within the screen after maybe 20 seconds for 10 seconds, fade out. possibly move the cover and display for a longer
time.
then do the same with the artist picture (shrinked), so that either black screen, cover or artist is showing, and WSHtpc02 around 40 seconds
between songs.
Also it would be great if 'ok' from the remote would bring back WSHtpc02 for 20 seconds.

Goal is, to save energy and screen life, but still use WSHtpc02.

Alternative for the screen saving time:
circle artist00 - artist10 pictures, fade in and out, alternate with black screen plus current info bar and cover but at random height.
Maybe easier to code?

Unfortunatly I can't code but maybe you feel challenged?
Thanks for considering!

HTPC Fullscreen panels II

Reply #76
I spent a little time modding WSHtpc02 and i thought i would share my work. 


Image 1- while playing


Image 2- while stopped


You can replace the wallpaper with one of you own choosing by putting it in the image folder and naming it bg.jpg. 


required files
need WSH Panel Mod latest version

This is mark2003's examples just set it up in default directions included
http://dl.dropbox.com/u/22801321/samples.zip

This is the wallpaper shown and the txt file and goes here  %foobar path%/images/bg.jpg
http://dl.dropbox.com/u/6670204/htpcv1.0.7z

HTPC Fullscreen panels II

Reply #77
Update: WSHtpc03 v0.5



Changes to WSHtpc03 v0.1:
  • WMP-ish layout
  • Does not need artist art
  • Cool symbols (no more boring circles) for rating, mood and play count (all optional)
  • Displays much more information (album, genre, playback order) without looking crowded

Download
[attachment=6124:WSHtpc03_0.5.zip]
Installation
Copy the file bg.jpg to %Foobar2000ProfilePath%/images/WSHtpc03/bg.jpg.
(This folder is either located in c:/Users/YourName/Appdata/Roaming/foobar2000 or in the installation directory for portable version.)
Add a WSH Panel to your configuration.
Copy the contents of the text file to the panel's configuration window.
Hit Ok.


Hello, I have been using your fullscreen configs for wuite some time now, thanks for an amazing effort. What I miss in these WSH configs, is to display the cover in a nice and shiny CD case. How would I go about doing this, as I am not a coder? Is it possible to have this in a WSH panel like this one, within DUI? Thanks for any help and all best.
In the province of the mind, there are no limits.



HTPC Fullscreen panels II

Reply #80
I wanted to say a big THANKS to you odjo for this beautiful panel.
Great work!
I'd humbly second SatFloyd's request for some kind of effect to fade out (or turn off completely) the screen after a certain time, and turn it on again on new song, because it would be a real energy saver for a TV screen.
Thanks a lot!

HTPC Fullscreen panels II

Reply #81
Just a suggestion:
Another enhancement I'd love would be some kind of function to auto-rotate all the jpg's in the album's folder...
I'd try to do it myself if I had any knowledge of wsh panels but anyway... be sure that really thankful for the panels just as they are now!

HTPC Fullscreen panels II

Reply #82
What do you mean by "auto-rotate"?

Concerning the requests for fading/energy saving options: After over a year with WSHtpc03, I'm beginning to get bored with it. WSHtpc04 is on the way, but has no definite release date yet ("when it's done").

HTPC Fullscreen panels II

Reply #83
i guess Chipicui means cycle through all images in a folder at an interval of so many seconds. i have a similar feature in my own scripts.

mine works like this.

-read all images into an array using utils.glob on a folder path/file mask
-create a new array of image objects from these file paths
-display the first image
-after a set interval, increment the value of the current image by one.
-remeber to handle reaching the end of the array by going back to 0.

HTPC Fullscreen panels II

Reply #84
Thanks marc2003 for your explanation! ... that's exactly what I meant to say
And thanks again ojdo for taking the time to create a new HTPC panel... if it's half as nice as the ones you already did it'll be beautiful.

HTPC Fullscreen panels II

Reply #85
New release: WSHtpc04 v0.1
  • Configurable tag grid
  • Dynamically switches between informative (tags) and decorative (album art only) views
  • Clickable progress bar
Globbing of image files is not implemented yet, but planned for v0.2.





Download
[attachment=6767:WSHtpc04_0.1.zip]
Installation instructions and my older configurations (WSHtpc01-03) can be found here.

HTPC Fullscreen panels II

Reply #86
Bugfix update: WSHtpc04 v0.1.1
I should have waited one day with the release...
  • Fixed: Wrong timer handling caused constant repainting of the whole panel, greatly decreasing FPS.
[attachment=6768:WSHtpc04_0.1.1.zip]

HTPC Fullscreen panels II

Reply #87
a few issues with this....

-it's spamming the console (line 357: fb.trace(my_timer); )

-crashes on resize

Code: [Select]
'shadow_image' is null or not an object
File: <main>
Ln: 465, Col: 5
<source text only available at compile time>


also i don't understand the logic for displaying the full image or track details. it seems random and changes when seeking????

HTPC Fullscreen panels II

Reply #88
Quote
Crash in createDropShadow()

Strange, this is unmodified code from WSHtpc03, working for me over a year without crash. In the next release, the function won't be called in on_size anymore - that never was a good idea anyway. Please report if the version below behaves as it should

also i don't understand the logic for displaying the full image or track details. it seems random and changes when seeking????

Logic behind big/small: Album art is is big, except
  • at start or end of track (first/last 30 playback seconds)
  • when a tag has changed (for 5 real time seconds)
Do you have other suggestions? The tag change event is essential, at least for me. However, I could make it configurable. This is my first adventure with timer events, so please be patient
While I explain the logic, I see where the problem is: tags should be displayed for the first ~15-30 real time seconds of a song, without respect to seeking. I haven't noticed that the current behaviour is annoying because I rarely seek. This behaviour is changed in 0.1.3.

Download
[attachment=6770:WSHtpc04_0.1.3.zip]Fixed: fb.trace spams console
Fix (?): createDropShadow no longer called in on_size
Change: timer behaviour now more predictable and configurable (see pref["t_start"] and pref["t_tag"]).

HTPC Fullscreen panels II

Reply #89
sorry i forgot about this. tested and working fine.

Quote
I see where the problem is: tags should be displayed for the first ~15-30 real time seconds of a song, without respect to seeking. I haven't noticed that the current behaviour is annoying because I rarely seek. This behaviour is changed in 0.1.3.


this makes much more sense now.

 

HTPC Fullscreen panels II

Reply #90
New version 0.2.0. Changes from 0.1.3:
  • new option: display "globbed" images on rotation OR (old behaviour) front cover from album art reader.
  • mouse interaction: click on album for play/pause, click on right/left border for next/prev song; click on progress bar for seeking
Download
[attachment=6771:WSHtpc04_0.2.0.zip]

HTPC Fullscreen panels II

Reply #91
New version 0.2.0. Changes from 0.1.3:
  • new option: display "globbed" images on rotation OR (old behaviour) front cover from album art reader.
  • mouse interaction: click on album for play/pause, click on right/left border for next/prev song; click on progress bar for seeking
Download
[attachment=6771:WSHtpc04_0.2.0.zip]

Thank you, working perfectly
I'm just missing CD Jewel Case..... pls consider to attach it again

HTPC Fullscreen panels II

Reply #92
I'm just missing CD Jewel Case..... pls consider to attach it again
Sorry, I won't do that - I'm done with jewel cases, as a growing part of my music collection never got released on physical medium. Anyway, it's just adding two or three lines of code to the panel's on_paint function. You might want to try adding the code yourself:

1. Search or prepare a set of jewel case images. Usually two: one for the case border and a transparent reflection image.
2. Search for the two sections beginning with if (albumart) in the on_paint function. Locate the line that draws the image itself: gr.DrawImage(albumart, [...]). Just before that line, add an identical line that paints the jewel case. (Search for bg_image to see how to create an image object that can be drawn by DrawImage.) After the albumart line, add a copy that draws the reflection imge.
3. Play around with the positional function arguments (the ones using albumart_size
  • or aa_size
  • ) until you get the placement right. A bit of pen-and-paper arithmetic and measuring out the exact image dimensions in a graphics application might help.
    4. Enjoy your own, custom made now playing panel!

HTPC Fullscreen panels II

Reply #93
Thank you for this. I am really going to try customizing, and come back with results. All best.
In the province of the mind, there are no limits.

HTPC Fullscreen panels II

Reply #94
Not as easy as I thought :-) I have two great images for the jewel case and the gloss, which I have used for a long time with your HTPC07.

I would like to use only the "extended" version of the panel, with the tag information on the left and the cover art in a jewel case on the right.

As I understand up untill now:

Here:

Code: [Select]
// BACKGROUND IMAGE
pref["bg_image"] = fb.ProfilePath+"images/WSHtpc04/diagonal-stripes.png";

I have to create two more entries for the jewel case and gloss images.

Code: [Select]
pref["bg_image"] = fb.ProfilePath+"images/WSHtpc04/case.png";
pref["bg_image"] = fb.ProfilePath+"images/WSHtpc04/gloss.png";

Here:

Code: [Select]
// INIT
// ALBUM ART
var albumart      = null;                        // albumart image
var albumart_size = new Array(0,0,0,0);          // position (big image)
var aa_size       = new Array(0,0,0,0);          // position (small image)
var image_bg      = gdi.Image(pref["bg_image"]); // background image

I have to create two more entries for the jewel case and gloss, but can I name them bg_jewel and bg_gloss?

Code: [Select]
var jewel_bg      = gdi.Image(pref["bg_jewel"]); // cd case
var gloss_bg      = gdi.Image(pref["bg_gloss"]); // cd gloss

Afterwards:

Code: [Select]
       // Small albumart on the right
        if (albumart) {
            shadow_image && gr.DrawImage(shadow_image, aa_size[0]-geo["aa_shadow"],aa_size[1]-geo["aa_shadow"],aa_size[2]+2*geo["aa_shadow"],aa_size[3]+2*geo["aa_shadow"],0,0,shadow_image.Width,shadow_image.Height);
gr.DrawImage(jewel_bg, aa_size[0], aa_size[1], aa_size[2], aa_size[3], 0, 0, albumart.Width, albumart.Height);
gr.DrawImage(albumart, aa_size[0], aa_size[1], aa_size[2], aa_size[3], 0, 0, albumart.Width, albumart.Height);
gr.DrawImage(gloss_bg, aa_size[0], aa_size[1], aa_size[2], aa_size[3], 0, 0, albumart.Width, albumart.Height);

            gr.DrawRect(aa_size[0]-1,aa_size[1]-1,aa_size[2]+1,aa_size[3]+1,1,col["aa_border"]);
            if (fb.IsPaused) { gr.FillSolidRect(aa_size[0],aa_size[1],aa_size[2],aa_size[3],RGBA(0,0,0,150)); }
        }

This should be also done in the // BIG ALBUMART part, I suppose.

Just tell me if I am on the right path :-) How do I disable the //BIG ALBUMART version of the panel? Is the size of the jewel/gloss images important, or the script will resize them too like the album art image?

Thanks and all best.
In the province of the mind, there are no limits.

HTPC Fullscreen panels II

Reply #95
OK, I got this far, I can see the gloss on the album art, but not the jewel case. Please help :-)

Code: [Select]
//
// WSHtpc04
//
// Description  a fullscreen now-playing script for foo_uie_wsh_panel
// Author   ojdo
// Version   0.2.0
// Last change  2011-11-26
// --------------------------------------------------------------------------------------

// CONFIGURATION //////////////////////////////////////

// faux "associative arrays" for settings
var tf   = new Object(); // titleformating strings
var ft   = new Object(); // fonts
var col   = new Object(); // colours
var geo   = new Object(); // sizes
var pref = new Object(); // preferences

// TEXTS
tf["title"] = "%title%";
tf["artist"] = "[%artist%]";
tf["grid"]   = Array( // simply add, change or remove entries to change grid layout
Array("Album",   "[%album%]"),
Array("Track",   "$if(%tracknumber%,$num(%tracknumber%,1)$if(%totaltracks%,/$replace($num(%totaltracks%,1),0,₀,1,₁,2,₂,3,₃,4,₄,5,₅,6,₆,7,₇,8,₈,9,₉)))$ifgreater(%totaldiscs%,1,  CD %discnumber%/$replace($num(%totaldiscs%,1),0,₀,1,₁,2,₂,3,₃,4,₄,5,₅,6,₆,7,₇,8,₈,9,₉),)"),
Array("Genre",   "[%genre%]"),
Array("Style",   "[%style%]"),
Array("Publisher",  "[%publisher%]"),
Array("Release", "[%release%]"),
Array("Play count", "$puts(X,10)$repeat($repeat(I,$get(X))  ,$div(%play_count%,$get(X)))$repeat(I,$mod(%play_count%,$get(X)))"),
Array("URL", "$if(%source webpage url%,$left($put(url,$replace(%source webpage url%,'http://',,www.,)),$sub($strchr($get(url),/),1)))"),
Array("Rating", "$repeat(IIIII  ,%rating%)"),
Array("Mood",   "$repeat(IIIII  ,%mood%)")
);

// TIMING
pref["t_start"]  = 30; // seconds to display tag grid after track change
pref["t_tag"] =  5; // seconds to display tag grid on tag change

// GLOB PICTURES
pref["aa_glob"] = true;  // true: use glob, false: use albumart reader (front only)
pref["aa_glob_shuffle"] = false; // true: random order, false: ordered like found by glob_paths
pref["t_aa_glob"]   = 20; // seconds per image
tf["glob_paths"] = Array( // simply add, change or re-order entries
"$replace(%path%,%filename_ext%,)folder*",
"$replace(%path%,%filename_ext%,)*.jpg",
"$replace(%path%,%filename_ext%,)*.png",
"$replace(%path%,%directoryname%\\%filename_ext%,)folder.jpg"
);

// FONTS
ft["title"]   = gdi.Font("Calibri",40,0);
ft["artist"] = gdi.Font("Calibri",24,0);
ft["grd_key"] = gdi.Font("Calibri",14,0);
ft["grd_val"] = gdi.Font("Calibri",16,0);
ft["lower_bar"]  = gdi.Font("Calibri",18,0);

// COLOURS
col["title"] = RGB(255,255,255);
col["artist"]  = RGB(192,192,192);
col["grd_key"]  = RGB(090,090,090);
col["grd_val"]  = RGB(192,192,192);
col["btm_key"]  = RGB(090,090,090);
col["btm_val"]  = RGB(192,192,192);
col["bg"]   = RGB(000,000,000);
col["rating"]  = RGB(255,128,000);
col["mood"] = RGB(000,128,255);
col["prgrss_fill"] = RGBA(255,255,255,050);
col["prgrss_line"] = RGBA(255,255,255,050);

// ALBUM ART DISPLAY PROPERTIES
col["aa_border"] = RGBA(060,060,060,128);
col["aa_shadow"] = RGBA(000,000,000,255);
geo["aa_shadow"] = 22; // size of albumart shadow

// BACKGROUND IMAGE
pref["bg_image"] = fb.ProfilePath+"images/WSHtpc04/diagonal-stripes.png";
pref["bg_case"] = fb.ProfilePath+"images/WSHtpc04/case.png";
pref["bg_gloss"] = fb.ProfilePath+"images/WSHtpc04/gloss.png";

// END OF CONFIGURATION /////////////////////////////////

// INIT
// ALBUM ART
var albumart   = null; // albumart image
var albumart_size = new Array(0,0,0,0);   // position (big image)
var aa_size   = new Array(0,0,0,0);   // position (small image)
var image_bg   = gdi.Image(pref["bg_image"]); // background image
var case_bg   = gdi.Image(pref["bg_case"]); // cd case
var gloss_bg   = gdi.Image(pref["bg_gloss"]); // cd gloss

var textrender = gdi.CreateStyleTextRender(); // anti-aliased text
var str   = new Object();
var img   = new Object();
var pbtext  = new Array("Default", "Repeat (Playlist)", "Repeat (Track)", "Random", "Shuffle (tracks)", "Shuffle (albums)", "Shuffle (folders)");

var metadb_handle = null; // watch db for tag changes
var timer;   // 40ms repaint of progress bar

// TIMER & STATUS
var ww = 0, wh = 0; // size of panel
var start_timer = 0; // timer for panel layout after track change
var glob_timer = 0;  // timer for glob albumart cycle
var tag_timer = 0;  // timer for panel layout after tag change
var pb_timer = 0;  // timer for playback_order text
var last_pb; // saves last playback order
var g_drag = 0; // status variable for clickable progress bar

var aa_list = new Array();
var aa_k = 0;

// Function: Remove duplicates from array
Array.prototype.myUnique = function(){
var r = new Array();
o:for(var i = 0; i < this.length; i++) {
for(var x = 0; x < r.length; x++) {
if(r[x]==this[i]) {
continue o;
}
}
r[r.length] = this[i];
}
return r;
};
 

// Call initialization function
on_init();

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function on_paint(gr) {
gr.SetTextRenderingHint(5);
gr.SetSmoothingMode(4);
//gr.SetInterpolationMode(7);

// Background
gr.FillSolidRect(-1,-1,ww+2,wh+2,col["bg"]);
gr.DrawImage(image_bg, 0,0,ww,wh-geo["lower_bar_h"]-1, 0,0,image_bg.Width,image_bg.Height-geo["lower_bar_h"]-1);
 
if (ww > 600 && ((tag_timer < pref["t_tag"]*25) || (start_timer < pref["t_start"]*25))) {

// TAG GRID & ALBUMART
 
// Small albumart on the right
if (albumart) {
shadow_image && gr.DrawImage(shadow_image, aa_size[0]-geo["aa_shadow"],aa_size[1]-geo["aa_shadow"],aa_size[2]+2*geo["aa_shadow"],aa_size[3]+2*geo["aa_shadow"],0,0,shadow_image.Width,shadow_image.Height);
gr.DrawImage(case_bg, aa_size[0], aa_size[1], aa_size[2], aa_size[3], 0, 0, albumart.Width, albumart.Height);
gr.DrawImage(albumart, aa_size[0], aa_size[1], aa_size[2], aa_size[3], 0, 0, albumart.Width, albumart.Height);
gr.DrawImage(gloss_bg, aa_size[0], aa_size[1], aa_size[2], aa_size[3], 0, 0, albumart.Width, albumart.Height);
gr.DrawRect(aa_size[0]-1,aa_size[1]-1,aa_size[2]+1,aa_size[3]+1,1,col["aa_border"]);
if (fb.IsPaused) { gr.FillSolidRect(aa_size[0],aa_size[1],aa_size[2],aa_size[3],RGBA(0,0,0,150)); }
}

// Artist & title
textrender.EnableShadow(true);
textrender.ResetShadow();
textrender.GlowText(col["title"], col["bg"], 6);
if(str["title"]) { textrender.RenderStringRect(gr, str["title"],  ft["title"],  0.025*ww, 0.175*wh, 0.5*ww, 40, StringFormat(0,0,4)); }
textrender.GlowText(col["artist"], col["bg"], 6);
if(str["artist"])   { textrender.RenderStringRect(gr, str["artist"], ft["artist"], 0.025*ww, 0.175*wh+50, 0.5*ww, 20, StringFormat(0,0,4)); }

// Tag grid
for (k=0; k<str["grid"].length; k++) {
key  = str["grid"][k][0];
value = str["grid"][k][1];
if(value) {
if(k%2 == 0 || ww > 780) {
cell_width = (ww <= 780) ? 0.5*ww-80 : 0.25*ww-80;
textrender.GlowText(col["grd_key"], col["bg"], 3);
textrender.RenderStringRect(gr, key, ft["grd_key"], 0.025*ww + (k%2)*0.25*ww, 0.45*wh+Math.floor(k/2)*30+3, cell_width, 20, StringFormat(0,0,4));
switch (key) {
case "Rating": textrender.GlowText(col["rating"], col["bg"], 3); break;
case "Mood":  textrender.GlowText(col["mood"], col["bg"], 3); break;
default:   textrender.GlowText(col["grd_val"], col["bg"], 3);

}
textrender.RenderStringRect(gr, value, ft["grd_val"], 0.025*ww+80 + (k%2)*0.25*ww, 0.45*wh+Math.floor(k/2)*30, cell_width, 20, StringFormat(0,0,4));
}
}
}
} else {

// BIG ALBUMART
if (albumart) {
shadow_image && gr.DrawImage(shadow_image, albumart_size[0]-geo["aa_shadow"],albumart_size[1]-geo["aa_shadow"],albumart_size[2]+2*geo["aa_shadow"],albumart_size[3]+2*geo["aa_shadow"],0,0,shadow_image.Width,shadow_image.Height);
gr.DrawImage(case_bg, albumart_size[0], albumart_size[1], albumart_size[2], albumart_size[3], 0, 0, albumart.Width, albumart.Height);
gr.DrawImage(albumart, albumart_size[0], albumart_size[1], albumart_size[2], albumart_size[3], 0, 0, albumart.Width, albumart.Height);
gr.DrawImage(gloss_bg, albumart_size[0], albumart_size[1], albumart_size[2], albumart_size[3], 0, 0, albumart.Width, albumart.Height);
gr.DrawRect(albumart_size[0]-1,albumart_size[1]-1,albumart_size[2]+1,albumart_size[3]+1,1,col["aa_border"]);
if (fb.IsPaused) { gr.FillSolidRect(albumart_size[0],albumart_size[1],albumart_size[2],albumart_size[3],RGBA(0,0,0,150)
); }
}

}


// LOWER BAR

// Title & artist
gr.DrawString(str["lower_bar1"]+" "+str["lower_bar2"],ft["lower_bar"],col["btm_key"],0.025*ww,wh-geo["lower_bar_h"],0.95*ww,0.5*geo["lower_bar_h"]);
gr.DrawString(str["lower_bar1"], ft["lower_bar"],col["btm_val"],0.025*ww,wh-geo["lower_bar_h"],0.95*ww,0.5*geo["lower_bar_h"]);

// Playback order
if(pb_timer < 5*25 && ww > 600) {
gr.DrawString(pbtext[fb.PlaybackOrder]+"   "+str["time"]+"  "+str["length"],ft["lower_bar"],col["btm_key"],0.575*ww,wh-geo["lower_bar_h"],0.4*ww,0.5*geo["lower_bar_h"],StringFormat(2,0));
}
// Progress bar
gr.DrawRect( 0.025*ww,wh-0.5*geo["lower_bar_h"],0.95*ww,4,1,col["prgrss_line"]);
if(fb.PlaybackLength > 0) {
if (ww > 600) {
gr.DrawString(str["time"]+"  "+str["length"],ft["lower_bar"],col["btm_key"],0.725*ww,wh-geo["lower_bar_h"],0.25*ww,0.5*geo["lower_bar_h"],StringFormat(2,0));
gr.DrawString(   str["length"],ft["lower_bar"],col["btm_val"],0.725*ww,wh-geo["lower_bar_h"],0.25*ww,0.5*geo["lower_bar_h"],StringFormat(2,0));
}
gr.FillSolidRect(0.025*ww,wh-0.5*geo["lower_bar_h"],0.95*ww*(fb.PlaybackTime / fb.PlaybackLength),4,col["prgrss_fill"]);
}

}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////















// -----------------------------------------------------------------------
// CALLBACKS
// -----------------------------------------------------------------------

// custom initialisation function, called once after variable declarations
function on_init() {
on_size();

geo["lower_bar_h"] = 60;


str["title"] = "";
str["artist"] = "";
str["lower_bar1"] = "foobar2000";
str["lower_bar2"] = "plays music";
str["grid"]  = new Array();

last_pb = fb.PlaybackOrder;

var bg_scale = Math.max(1,(wh-geo["lower_bar_h"]-1) / image_bg.Height);
image_bg = image_bg.Resize(image_bg.Width*bg_scale,image_bg.Height*bg_scale);

on_playback_new_track(fb.GetNowPlaying());
}

// window size changed
function on_size() {
ww = window.Width;
wh = window.Height;

if(albumart) {
// Size for big albumart
var album_scale = Math.min(0.95*ww / albumart.Width, 0.9*(wh-geo["lower_bar_h"]) / albumart.Height);
albumart_size[2] = albumart.Width * album_scale;
albumart_size[3] = albumart.Height * album_scale;
albumart_size[0] = 0.5*ww-0.5*albumart_size[2];
albumart_size[1] = 0.5*(wh-geo["lower_bar_h"])-0.5*albumart_size[3];

// Size for small
var aa_scale = Math.min(0.45*ww / albumart.Width, 0.7*(wh-geo["lower_bar_h"]) / albumart.Height);
aa_size[2] = albumart.Width * aa_scale;
aa_size[3] = albumart.Height * aa_scale;
aa_size[0] = 0.75*ww-0.5*aa_size[2];
aa_size[1] = 0.5*wh-0.5*aa_size[3];
} else {
albumart_size = Array(0,0,0,0);
}
}

// new track
function on_playback_new_track(metadb) {
start_timer  = 0;
pb_timer = 0;
glob_timer = 0;
timer = window.CreateTimerInterval(40);

// Fetch new albumart
aa_list = [];
for(k = 0;k<tf["glob_paths"].length; k++) {
aa_list = aa_list.concat(utils.Glob(fb.TitleFormat(tf["glob_paths"][k]).Eval()).toArray());
}
if (!pref["aa_glob"]) {
if (metadb) {
utils.GetAlbumArtAsync(window.ID, metadb, 0); 
}
} else {
if(aa_list.length > 0) {
aa_list = eliminateDuplicates(aa_list); // remove duplicates
pref["aa_glob_shuffle"] && fisherYates(aa_list); // shuffle list
aa_k = 0;
glob_image(aa_k); // display first image
}
}

// enable "watch for tag changes" on new track
if (metadb_handle) {window.UnwatchMetadb();}
metadb_handle = fb.GetNowPlaying();
if (metadb_handle) {
on_metadb_changed(); // refresh panel
window.WatchMetadb(metadb_handle);
}
on_playback_time();
}


// tag content changed
function on_metadb_changed() { 
title  = fb.TitleFormat(tf["title"]).Eval();
artist = fb.TitleFormat(tf["artist"]).Eval();

str["title"] = title;
str["artist"] = artist;
str["lower_bar1"] = title;
str["lower_bar2"] = artist;

h = Math.floor(fb.PlaybackLength/3600);
m = Math.floor(fb.PlaybackLength%3600/60);
s = Math.floor(fb.PlaybackLength%60);
str["length"] = (h > 0 ? h+":"+(m < 10 ? "0":"")+m : m) + ":" + (s < 10 ? "0":"") + s;

for (k=0; k<tf["grid"].length; k++) {
str["grid"][k] = Array(
tf["grid"][k][0],
fb.TitleFormat(tf["grid"][k][1]).Eval()
);
}

tag_timer = 0;
window.Repaint();
}


// User activity
function on_mouse_lbtn_dblclk() {
// re-initialise the panel
on_playback_new_track(fb.GetNowPlaying());
}
function on_playback_order_changed(this_pb) {
// Repaint playback order
if (this_pb != last_pb) {
pb_timer = 0;
window.RepaintRect(0.5*ww,wh-geo["lower_bar_h"],0.5*ww,geo["lower_bar_h"]);
}
last_pb = this_pb;

}
function on_playback_seek() {
on_playback_time();
}

function on_mouse_lbtn_down(x, y) {
if(y > wh-geo["lower_bar_h"]) {
g_drag = 1;
}
}

function on_mouse_lbtn_up(x, y) {
on_mouse_move(x, y);
g_drag = 0;

// Play or pause on album cover
if (ww > 600 && ((tag_timer < pref["t_tag"]*25) || (start_timer < pref["t_start"]*25))) {
// small album art
if ( aa_size[0] <= x && aa_size[1] <= y && aa_size[0]+aa_size[2] >= x && aa_size[1]+aa_size[3] >= y) {
fb.PlayOrPause();
}
} else {
// big album art
if ( albumart_size[0] <= x && albumart_size[1] <= y && albumart_size[0]+aa_size[2] >= x && albumart_size[1]+aa_size[3] >= y) {
fb.PlayOrPause();
}
}

if (x < 0.01*ww) { fb.Prev(); }
if (x > 0.99*ww) { fb.Next(); }
}

function on_mouse_lbtn_dblclk() {
tag_timer = -1;
on_timer();
}

function on_mouse_move(x, y) {
if (g_drag) {
var v = (x-0.025*ww) / (0.95*ww);
v = (v < 0) ? 0 : (v < 1) ? v : 1;
if (fb.PlaybackTime != v*fb.PlaybackLength) fb.PlaybackTime = v*fb.PlaybackLength;
}
}


// Timed events

function on_playback_time(){
// Repaint seekbar and playback times
this_time = fb.PlaybackTime;
pb_length = fb.PlaybackLength;

h = Math.floor(this_time/3600);
m = Math.floor(this_time%3600/60);
s = Math.floor(this_time%60);
str["time"]  = (h > 0 ? h+":"+(m < 10 ? "0":"")+m : m) + ":" + (s < 10 ? "0":"")+ s;

}
function on_timer(id){ 
start_timer = start_timer + 1;
tag_timer = tag_timer + 1;
pb_timer = pb_timer + 1;
glob_timer = glob_timer + 1;
if (glob_timer == pref["t_aa_glob"]*25) {
aa_k = (aa_k + 1) % aa_list.length;
glob_image(aa_k);
glob_timer = 0;
}
if ((tag_timer == pref["t_tag"]*25) || (tag_timer <= 0) || (start_timer == pref["t_start"]*25) || (glob_timer == 0)) {
window.Repaint();
} else {
window.RepaintRect(0,wh-geo["lower_bar_h"],ww,geo["lower_bar_h"]);
}
}
function on_playback_pause() {
// Draws grey shadow on album art
window.RepaintRect(albumart_size[0],albumart_size[1],albumart_size[2],albumart_size[3]);
window.RepaintRect(aa_size[0],aa_size[1],aa_size[2],aa_size[3]);
}

function on_playback_stop(reason) {
if(reason != 2) { // starting_another
// clear all variables and repaint
albumart = null; artistart = null;

str["title"] = "";
str["artist"] = "";
str["lower_bar1"] = "foobar2000";
str["lower_bar2"] = "plays music";
str["grid"] = Array();
window.Repaint();
}
timer && window.KillTimer(timer);
}

// album art retrieved
function on_get_album_art_done(metadb, art_id, image) {
// only use album art reader if globbing is disabled
if (!pref["aa_glob"]) {
switch(art_id) {
case 0:  // front
if(image) { albumart = image; }
else { albumart = null; }
break;
}
on_size(); // recalculate image positions
createDropShadow(); // recreate shadow image
window.Repaint(); // calls on_paint()
}
}


// HELPER FUNCTIONS
function StringFormat() {
var h_align = 0, v_align = 0, trimming = 0, flags = 0;
switch (arguments.length)
{
// fall-through
case 4: flags = arguments[3];
case 3: trimming = arguments[2];
case 2: v_align = arguments[1];
case 1: h_align = arguments[0]; break;
default: return 0;
}
return ((h_align << 28) | (v_align << 24) | (trimming << 20) | flags);
}
function RGB(r, g, b) { return (0xff000000 | (r << 16) | (g << 8) | (b)); }
function RGBA(r, g, b, a) { return ((a << 24) | (r << 16) | (g << 8) | (b)); }

function drawStar(gr, x, y) {
// gr = Drawing Object handle
// x,y = position of center
// color = array of colors for filling and border
// size = radius
// n = number of peaks
// phi = rotation
var size=16, n=5, phi=Math.PI/2, color=Array(RGB(210,170,0),RGB(255,255,0)), innerSize=.5;
switch(arguments.length) {
// fall-through
case 8: innerSize = arguments[7];
case 7: phi  = arguments[6];
case 6: n = arguments[5];
case 5: size  = arguments[4];
case 4: color = arguments[3];
}
var points = new Array(4*n);
for(var k=0;k<n;k++) {
// outer edge
points[4*k]  = x+size*Math.cos(2*Math.PI*k/n-phi);
points[4*k+1] = y+size*Math.sin(2*Math.PI*k/n-phi);
// inner edge
points[4*k+2] = x+innerSize*size*Math.cos(2*Math.PI*(k+.5)/n-phi);
points[4*k+3] = y+innerSize*size*Math.sin(2*Math.PI*(k+.5)/n-phi);
}
gr.FillPolygon(color[0],1,points);
gr.DrawPolygon(color[1],1.2,points);
}

function createDropShadow() {
shadow_image = gdi.CreateImage(albumart_size[2]+2*geo["aa_shadow"], albumart_size[3]+2*geo["aa_shadow"]);
if (shadow_image) {
shimg = shadow_image.GetGraphics();
shimg.FillEllipse(1.5*geo["aa_shadow"],1.0*geo["aa_shadow"],albumart_size[2]-geo["aa_shadow"],2*geo["aa_shadow"],col["aa_shadow"]);
shimg.FillEllipse(1.0*geo["aa_shadow"],1.5*geo["aa_shadow"],2*geo["aa_shadow"],albumart_size[3]-geo["aa_shadow"],col["aa_shadow"]);
shimg.FillEllipse(1.5*geo["aa_shadow"],albumart_size[3]-geo["aa_shadow"],albumart_size[2]-geo["aa_shadow"],2*geo["aa_shadow"],col["aa_shadow"]);
shimg.FillEllipse(albumart_size[2]-geo["aa_shadow"],1.5*geo["aa_shadow"],2*geo["aa_shadow"],albumart_size[3]-geo["aa_shadow"],col["aa_shadow"]);
shadow_image.ReleaseGraphics(shimg);
shadow_image.BoxBlur(geo["aa_shadow"],1);
}
}

function glob_image(k) {
albumart = gdi.Image(aa_list[k]);
on_size(); // recalculate image positions
createDropShadow(); // recreate shadow image
}

function fisherYates ( myArray ) {
//
var i = myArray.length;
if ( i == 0 ) return false;
while ( --i ) {
var j = Math.floor( Math.random() * ( i + 1 ) );
var tempi = myArray[i];
var tempj = myArray[j];
myArray[i] = tempj;
myArray[j] = tempi;
}
}


function eliminateDuplicates(arr) {
  var i,
  len=arr.length,
  out=[],
  obj={};

  for (i=0;i<len;i++) {
obj[arr[i]]=0;
  }
  for (i in obj) {
out.push(i);
  }
  return out;
}



// EOF
In the province of the mind, there are no limits.

HTPC Fullscreen panels II

Reply #96
Hi!... thanks a lot ojdo!
However, I can't load it as I get:

Scripting Engine Initialization Failed ({C632EBF9-C418-48FA-A98F-9D10E429A375}, CODE: 0x80020101)
Check the console for more information (Always caused by unexcepted script error).

On console:

Error: WSH Panel Mod ({C632EBF9-C418-48FA-A98F-9D10E429A375}): Error en tiempo de ejecución de Microsoft JScript:
Se requiere un objeto
File: <main>
Ln: 252, Col: 5
<source text only available at compile time>


All the rest of your beautiful panels work ok!!
Thanks again!

HTPC Fullscreen panels II

Reply #97
Sorry ojdo!!!... sorry for being so stupid...
I had used all the 'WSHtpc04_0.2.0' as name for the folder with the image file...
Renamed to WSHtpc04 and everything works fine now! :-)

HTPC Fullscreen panels II

Reply #98
OK, I got this far, I can see the gloss on the album art, but not the jewel case. Please help :-)

Great: The gloss probably has the right size. The case is drawn behind the cover image and at the moment has the same size. Obviously, it cannot be seen that way. What's left to do is to
- increase the size for the jewel case
- adjust its position accordingly.
This is done by playing around with the four arguments involving the albumart_size (or aa_size). Let me give you an example:
The jewel case image might be 800x700 pixels (width x height) big, with an area of 600x600 pixels designated to show the cover image, vertically centered 50 pixels from the right image border. So in order to have the right size for an albumart image of a given height aa_size[3], the jewel case must be displayed with a height of aa_size[3]/600*700. The width consequently must be aa_size[2]/600*800. You have to measure the exact numbers with your own image. I hope you can figure out the x- and y-positions yourself. If not, tell me the exact measurements as in the example above.

HTPC Fullscreen panels II

Reply #99
....... can someone please tell me how I stop WSHtpc04 v0.2.0 from rotating ?

I would like that it only displays the 1st instance with the albumart on the right and text to the left.

If one isn't a coder like myself it's very difficult to manage without help.

Thanks in advance .......
Tommy