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: Columns UI appearance (Read 3294708 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

Columns UI appearance

Reply #550
There is definitely a lot of work that goes into creating these skins. I just got done setting mine up with panels (its a quite simple layout) and it was pain. But it is getting easier. I really like the dark simple themes like the one you have qwertz. Elegant sleek and not busy.


Columns UI appearance

Reply #552
I made some small changes to my layout.

Album layout:



Basic playlist layout:

"I never thought I'd see this much candy in one mission!"


Columns UI appearance

Reply #554
been trying to do my own. This evening it was a crash course in panel stack splitter panel placement. The track info script is from a dark one theme atm. Took me awhile to get my header straightened out. My next project will be to get my seek bar how I want it. Will be interesting as I dont know squat about Jscript.

Im really liking foobar though, as I can curtail it to what I want without all the extra crap that I dont use (as found in other unmentionable mps) Just takes a little time.


Columns UI appearance

Reply #555
pee_wee, that is amazing
I am feeling stupid when I am using default cui

Columns UI appearance

Reply #556
Here's mine, it's a mod of Averia by Rol. Loads of WSH Panels.


Columns UI appearance

Reply #557
Really nice use of WSH panels Tom  congratulations !

i hope you'll share the Jscript used for seekbar and control buttons, i'd like to create controls too in WSH for my new config (work in prgress) ?

keep the good work!

btw, here are 2 screenshots of my project (as it is today) :

[a href="http://xs539.xs.to/xs539/09186/xchange_project_01299.jpg" target="_blank"]

Columns UI appearance

Reply #558
Thanks, yours looks excellent, and I love the concept. Here are my scripts, the first is the left hand buttons:

Code: [Select]
var bg = gdi.Image(fb.FoobarPath+ "\\themes\\Averia\\images\\btn_m.png");
var bgL = gdi.Image(fb.FoobarPath+ "\\themes\\Averia\\images\\btnbg_l.png");
var bgR = gdi.Image(fb.FoobarPath+ "\\themes\\Averia\\images\\btnbg_r.png");
var button_bg_hov = gdi.Image(fb.FoobarPath + "\\themes\\Averia\\images\\btn_bg.png");
var button_bg_down = gdi.Image(fb.FoobarPath + "\\themes\\Averia\\images\\btn_bg_d.png");
var cur_btn = null;
var act_btn = null;

ButtonStates = {
normal: 0,
hover: 1,
down: 2
}

ShowButton = {
hide: 0,
show: 1
}

var ww = window.Width;
var wh = window.Height;

//button function
function button(icon,func_onClick,x,state,show)
{
this.icon=gdi.Image(fb.FoobarPath + "\\images\\black indented\\pngs\\"+icon+".png");
this.state=state ? state : ButtonStates.normal;
this.show=show ? show : ShowButton.show;
this.x=x;
this.func_onClick = func_onClick;

this.containXY = function (x, y)
{
return (this.x <= x) && (x <= this.x + 23) && (0 <= y) && (y <= 20);
}
   
this.draw = function (gr)
{
if (this.show == ShowButton.hide){return;}
else
{
if(this.state == ButtonStates.normal)
{
gr.DrawImage(this.icon, this.x+3, 2, 16, 16, 0, 0, 16, 16);
}
else if(this.state == ButtonStates.hover)
{
gr.DrawImage(button_bg_hov, this.x, 0, 23, 20, 0, 0, 23, 20);
gr.DrawImage(this.icon, this.x+3, 2, 16, 16, 0, 0, 16, 16);
}
else if(this.state == ButtonStates.down)
{
gr.DrawImage(button_bg_down, this.x, 0, 23, 20, 0, 0, 23, 20);
gr.DrawImage(this.icon, this.x+3, 2, 16, 16, 0, 0, 16, 16);
}
}
}
   
this.onClick = function ()
{
this.func_onClick && this.func_onClick();
}
}

function showhidebuttons()
{
if(fb.IsPlaying && !fb.IsPaused)
{
$buttons.play.show = ShowButton.hide;
$buttons.pause.show = ShowButton.show;
}
else
{
$buttons.pause.show = ShowButton.hide;
$buttons.play.show = ShowButton.show;
}
if(fb.StopAfterCurrent)
{
$buttons.sac.show = ShowButton.hide;
$buttons.sac_on.show = ShowButton.show;
}
else
{
$buttons.sac_on.show = ShowButton.hide;
$buttons.sac.show = ShowButton.show;
}
}

function drawAllButtons(gr)
{
showhidebuttons();
for (var i in $buttons)
{
$buttons[i].draw(gr);
}
}

function chooseButton(x, y)
{
for (var i in $buttons)
{
if ($buttons[i].containXY(x, y) && $buttons[i].show != ShowButton.hide)
return $buttons[i];
}
   
return null;
}

$buttons = {
back:  new button('back'  ,function(){fb.Prev();},0),
stop:  new button('stop'  ,function(){fb.Stop();},23),
play:  new button('play'  ,function(){fb.PlayOrPause();},46),
pause: new button('pause' ,function(){fb.PlayOrPause();},46),
sac:  new button('sac'  ,function(){fb.StopAfterCurrent=true;},69),
sac_on:new button('sac_on',function(){fb.StopAfterCurrent=false;},69),
next:  new button('fwd'  ,function(){fb.Next();},92)
}

function on_paint(gr)
{
gr.FillSolidRect(0,0,window.Width,window.Height,0xfffcfcfc);
gr.DrawImage( bg, bgL.Width, 0, window.Width-bgL.Width, bg.Height, 0, 0, bg.Width, bg.Height);
gr.DrawImage( bgL, 0, 0, bgL.Width, bgL.Height, 0, 0, bgL.Width, bgL.Height);

drawAllButtons(gr);
}

function on_size()
{
ww = window.Width;
wh = window.Height;
}

function on_mouse_lbtn_down(x,y)
{
cur_btn = chooseButton(x, y);
if(cur_btn)
{
cur_btn.state=ButtonStates.down;
}
act_btn = cur_btn;
window.Repaint();
}
function on_mouse_move(x, y)
{
cur_btn = chooseButton(x, y);
if(cur_btn)
{
if(cur_btn.state!=ButtonStates.down&&!act_btn)
{
cur_btn.state=ButtonStates.hover;
}
for(var i in $buttons)
{
if($buttons[i] != cur_btn)
{
$buttons[i].state=ButtonStates.normal;
}
}
if(cur_btn==act_btn)
{
cur_btn.state=ButtonStates.down;
}
}
else
{
for(var i in $buttons)
{
$buttons[i].state=ButtonStates.normal;
}

}

window.Repaint();
}
function on_mouse_lbtn_up(x, y)
{
if (cur_btn&&act_btn==cur_btn)
{
cur_btn.onClick();
cur_btn = chooseButton(x, y);
showhidebuttons();
cur_btn.state=ButtonStates.hover;
}
act_btn = null;
window.Repaint();
}
function on_mouse_leave()
{
for (var i in $buttons)
{
$buttons[i].state=ButtonStates.normal;
}
window.Repaint();
}
function on_playback_stop()
{
window.Repaint();
}
function on_playback_pause(state)
{
window.Repaint();
}
function on_playback_starting(cmd, is_paused)
{
window.Repaint();
}
function on_playlist_stop_after_current_changed(state)
{
window.Repaint();
}
The right hand buttons are basically the same, but with a different $buttons array:

Code: [Select]
$buttons = {
    cfp:    new button('cfp'       ,function() {fb.CursorFollowPlayback=true;},0),
    cfp_on: new button('cfp_on'    ,function() {fb.CursorFollowPlayback=false;},0),
    pfc:    new button('pfc'       ,function() {fb.PlaybackFollowCursor=true;},23),
    pfc_on: new button('pfc_on'    ,function() {fb.PlaybackFollowCursor=false;},23),
    shuf:   new button('shuff'     ,function() {fb.PlaybackOrder=4;},46),
    shuf_on:new button('shuff_on'  ,function() {fb.PlaybackOrder=0;},46),
    rtrk:   new button('rep_trk'   ,function() {fb.PlaybackOrder=2;},69),
    rtrk_on:new button('rep_trk_on',function() {fb.PlaybackOrder=0;},69),
    rall:   new button('rep_all'   ,function() {fb.PlaybackOrder=1;},92),
    rall_on:new button('rep_all_on',function() {fb.PlaybackOrder=0},92)
}
and different showhidebuttons function:
Code: [Select]
function showhidebuttons()
{
if(fb.CursorFollowPlayback)
{
$buttons.cfp.show = ShowButton.hide;
$buttons.cfp_on.show = ShowButton.show;
}
else
{
$buttons.cfp_on.show = ShowButton.hide;
$buttons.cfp.show = ShowButton.show;
}
if(fb.PlaybackFollowCursor)
{
$buttons.pfc.show = ShowButton.hide;
$buttons.pfc_on.show = ShowButton.show;
}
else
{
$buttons.pfc_on.show = ShowButton.hide;
$buttons.pfc.show = ShowButton.show;
}
if(fb.PlaybackOrder==0)
{
$buttons.shuf_on.show = ShowButton.hide;
$buttons.rtrk_on.show = ShowButton.hide;
$buttons.rall_on.show = ShowButton.hide;
$buttons.shuf.show = ShowButton.show;
$buttons.rtrk.show = ShowButton.show;
$buttons.rall.show = ShowButton.show;
}
else if(fb.PlaybackOrder==1)
{
$buttons.shuf_on.show = ShowButton.hide;
$buttons.rtrk_on.show = ShowButton.hide;
$buttons.rall_on.show = ShowButton.show;
$buttons.shuf.show = ShowButton.show;
$buttons.rtrk.show = ShowButton.show;
$buttons.rall.show = ShowButton.hide;
}
else if(fb.PlaybackOrder==2)
{
$buttons.shuf_on.show = ShowButton.hide;
$buttons.rtrk_on.show = ShowButton.show;
$buttons.rall_on.show = ShowButton.hide;
$buttons.shuf.show = ShowButton.show;
$buttons.rtrk.show = ShowButton.hide;
$buttons.rall.show = ShowButton.show;
}
else if(fb.PlaybackOrder==4)
{
$buttons.shuf_on.show = ShowButton.show;
$buttons.rtrk_on.show = ShowButton.hide;
$buttons.rall_on.show = ShowButton.hide;
$buttons.shuf.show = ShowButton.hide;
$buttons.rtrk.show = ShowButton.show;
$buttons.rall.show = ShowButton.show;
}
}
As well as different callbacks, the relevant ones from the callbacks.txt.

Then there's the seekbar, features include tooltip, seeking with mouse scroll, redraw more than once per sec, and it also only shows anything while it's playing, and has a different display for streams.

Code: [Select]
//Text formatting function
function StringFormat() {
var h_align = 0, v_align = 0, trimming = 0, flags = 0;
switch (arguments.length)
{
// fall-thru
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);
}
//Time formatting
function TimeFmt(t){
var zpad = function(n){
var str = n.toString();
return (str.length<2) ? "0"+str : str;
}
var h = Math.floor(t/3600); t-=h*3600;
var m = Math.floor(t/60); t-=m*60;
var s = Math.floor(t);
if(h>0) return h.toString()+":"+zpad(m)+":"+zpad(s);
return m.toString()+":"+zpad(s);
}
StringAlignment = {
Near: 0,
Centre: 1,
Far: 2
};
var font = gdi.Font("Calibri", 10, 1);
var l_stringformat = StringFormat(StringAlignment.Near, StringAlignment.Centre);
var c_stringformat = StringFormat(StringAlignment.Centre, StringAlignment.Centre);
var r_stringformat = StringFormat(StringAlignment.Far, StringAlignment.Centre);

var g_drag = 0;
var g_drag_seek = 0;
var g_drag_hov = 0;
//The seekbar
var L = gdi.Image(fb.FoobarPath + "\\images\\black indented\\seekbar\\L.png");
var R = gdi.Image(fb.FoobarPath + "\\images\\black indented\\seekbar\\R.png");
var seeker = gdi.Image(fb.FoobarPath + "\\images\\black indented\\seekbar\\seeker2.png");
//background
var bg = gdi.Image(fb.FoobarPath+ "\\themes\\Averia\\images\\btn_m.png");
var bgL = gdi.Image(fb.FoobarPath+ "\\themes\\Averia\\images\\btnbg_l.png");
var bgR = gdi.Image(fb.FoobarPath+ "\\themes\\Averia\\images\\btnbg_r.png");

var ww = window.Width;
var wh = window.Height;
//Titleformatting
var len = fb.Titleformat("%length%");
var elap = fb.TitleFormat("%playback_time%");
var remain = fb.TitleFormat("[%playback_time_remaining%]");

var tooltip = window.CreateTooltip();

var pos = 0;
var seekstart = 0;
var seekend = 0;
var seekpad = 6;
var seekerwidth = seeker.Width/2;

var g_timer;

function on_paint(gr)
{
gr.SetTextRenderingHint(5);
gr.FillSolidRect(0,0,window.Width,window.Height,0xfffcfcfc);
gr.DrawImage( bg, 0, 0, window.Width, bg.Height, 0, 0, bg.Width, bg.Height);
//For normal playback
if(fb.PlaybackLength>0)
{
seekstart = gr.CalcTextWidth(len.Eval(),font);
seekend = gr.CalcTextWidth(len.Eval(),font);
gr.DrawImage( L, seekstart+seekpad, 2, window.Width-(seekstart+seekend+2*seekpad)-R.Width, 16, 0, 0, window.Width-(seekstart+seekend+2*seekpad)-R.Width, 16);
gr.DrawImage( R, window.Width-(seekend+seekpad)-R.Width, 2, 2, 16, 0, 0, 2, 16);
gr.DrawString(elap.Eval(), font, 0xff000000, 3, 0, seekstart+seekpad, 18, l_stringformat);
gr.DrawString(remain.Eval(), font, 0xff000000, ww-seekend-3-seekpad, 0, seekend+seekpad, 18, r_stringformat);
if(g_drag)
{
pos = seekstart+seekpad+seekerwidth+(window.Width-(seekstart+seekend+2*(seekpad+seekerwidth))) * g_drag_seek;
}
else
{
pos = seekstart+seekpad+seekerwidth+(window.Width-(seekstart+seekend+2*(seekpad+seekerwidth))) * (fb.PlaybackTime / fb.PlaybackLength);
}
gr.DrawImage( seeker, pos-seekerwidth, 2, 12, 16, 0, 0, 12, 16);
if(g_drag_hov)
{
gr.DrawImage(bgL, 0, 0, bgL.Width, bgL.Height, 0, 0, bgL.Width, bgL.Height);
gr.DrawImage(bgR, window.Width-bgR.Width, 0, bgR.Width, bgR.Height, 0, 0, bgR.Width, bgR.Height);
}
}
//For streams
else if(fb.IsPlaying && fb.PlaybackLength)
{
seekstart = 0;
seekend = 0;
gr.DrawString(elap.Eval()+" / continuous", font, 0xff000000, 0, 0, window.Width, 18, c_stringformat);
if(g_drag_hov)
{
gr.DrawImage(bgL, 0, 0, bgL.Width, bgL.Height, 0, 0, bgL.Width, bgL.Height);
gr.DrawImage(bgR, window.Width-bgR.Width, 0, bgR.Width, bgR.Height, 0, 0, bgR.Width, bgR.Height);
}
}
}

function on_size()
{
ww = window.Width;
wh = window.Height;
}

function on_mouse_lbtn_down(x,y)
{
if(x>seekstart+seekpad&&x<window.Width-(seekend+seekpad))
{
if(fb.PlaybackLength){g_drag = 1;}
g_drag_seek = (x>seekstart+seekpad+seekerwidth)?(x-(seekstart+seekpad+seekerwidth))/(window.Width-(seekstart+seekend+2*(seekpad+seekerwidth))):(x<(window.Width-(seekend+seekpad+seekerwidth)))?(x-(seekstart+seekpad+seekerwidth))/(window.Width-(seekstart+seekend+2*(seekpad+seekerwidth))):1;
g_drag_seek = (g_drag_seek<0) ? 0 : (g_drag_seek<1) ? g_drag_seek : 1;
}
window.Repaint();
}

function on_mouse_move(x, y)
{
g_drag_hov = true;
if(fb.IsPlaying&&fb.PlaybackLength>0&&x>seekstart&&x<window.Width-seekend)
{
g_drag_seek = (x>seekstart+seekpad+seekerwidth)?(x-(seekstart+seekpad+seekerwidth))/(window.Width-(seekstart+seekend+2*(seekpad+seekerwidth))):(x<(window.Width-(seekend+seekpad+seekerwidth)))?(x-(seekstart+seekpad+seekerwidth))/(window.Width-(seekstart+seekend+2*(seekpad+seekerwidth))):1;
g_drag_seek = (g_drag_seek<0) ? 0 : (g_drag_seek<1) ? g_drag_seek : 1;
tooltip.Text = TimeFmt(fb.PlaybackLength * g_drag_seek);
tooltip.Activate();
}
else
{
tooltip.Deactivate();
}
window.Repaint();
}

function on_mouse_lbtn_up(x, y)
{
if(g_drag)
{
g_drag = 0;
g_drag_seek = (x>seekstart+seekpad+seekerwidth)?(x-(seekstart+seekpad+seekerwidth))/(window.Width-(seekstart+seekend+2*(seekpad+seekerwidth))):(x<(window.Width-(seekend+seekpad+seekerwidth)))?(x-(seekstart+seekpad+seekerwidth))/(window.Width-(seekstart+seekend+2*(seekpad+seekerwidth))):1;
g_drag_seek = (g_drag_seek<0) ? 0 : (g_drag_seek<1) ? g_drag_seek : 1;
fb.PlaybackTime = fb.PlaybackLength * g_drag_seek;
}
window.Repaint();
}

function on_mouse_leave()
{
g_drag_hov = false;
tooltip.Deactivate();
window.Repaint();
}

function on_playback_seek(time)
{
window.Repaint();
}
function on_playback_time(time)
{
if(g_timer){window.KillTimer(g_timer);}
if(fb.PlaybackLength<500&&fb.PlaybackLength>0){g_timer = window.CreateTimerInterval(100);}
window.Repaint();
}
function on_playback_stop()
{
if(g_timer){window.KillTimer(g_timer);}
window.Repaint();
}
function on_playback_pause(state)
{
window.Repaint();
}
function on_playback_starting(cmd, is_paused)
{
g_timer = window.CreateTimerInterval(100);
window.Repaint();
}
//Redraw more than once per sec
function on_timer(id)
{
window.Repaint();
}
//Seek using mouse wheel
function on_mouse_wheel(delta){
if(delta>0)
fb.RunMainMenuCommand("Seek Ahead by 10 Seconds");
else
fb.RunMainMenuCommand("Seek Back by 10 Seconds");
}
Feel free to use/abuse. I hope this all fits, it's quite a long post!

 

Columns UI appearance

Reply #559
@Falstaff, very nice concept

One question, that scroll bar in track info isn't standard windows isn't it, how did you make it?

Columns UI appearance

Reply #560
@Falstaff, very nice concept

One question, that scroll bar in track info isn't standard windows isn't it, how did you make it?


not standard, right, a coded one in a Panel Stack Splitter panel. Now, with the global variables support, it is possible to realize a such scrollbar.

concept is easy to understand:
- i set a global variable which i'll use to positionnate text/images in the panel (an offset value), i set it to 0 at the beginning -  i.e : $if(%offset%,,$set_ps_global(offset,0))
- i use 2 buttons (the 2 one in the scrollbar), one that will increase this offset (by a # of pixel which is the text line height i want to use,  i.e 18 for tahoma,8,normal), the other to decrease the offset value!

then, all text/image vertical position is using this offset, i.e :  $drawtextex('a simple text',$get(x),$add($get(y),%offset%,%_width%,18,255-255-255,left)

of course, after this, you have to add controls to force the offset to 0 if it become < 0 ... etc and you have to calculate the number of lines to scroll depending of the panel height, this in order to draw the position indicator in the scrollbar at the good place, ... etc

i hope that's help you

Columns UI appearance

Reply #561
thanx Tom, i'll try to figure out how they work to adapt them to my needs

thanx for the seekbar jscript too, i've already added Tooltip to mine and it refresh more than a sec too , i'll check it too btw, thanx again

Columns UI appearance

Reply #562
Yes thank you. The concept sounds easy enough, though in my whole life time, I would have never come up with an idea like that, so kudos to you 

It seems to get complicated with your last sentence, so I'll wait to see your implementation   

Columns UI appearance

Reply #563
thanx Tom, i'll try to figure out how they work to adapt them to my needs

thanx for the seekbar jscript too, i've already added Tooltip to mine and it refresh more than a sec too , i'll check it too btw, thanx again


WSH report me an error in your Jscript for the seekbar on this line (line 127, col. 43) :

g_drag_seek = (x>seekstart+seekpad+seekerwidth)?(x-(seekstart+seekpad+seekerwidth))/(window.Width-(seekstart+seekend+2*(seekpad+seekerwidth)))sad.gifx<(window.Width-(seekend+seekpad+seekerwidth)))?(x-(seekstart+seekpad+seekerwidth))/(window.Width-(seekstart+seekend+2*(seekpad+seekerwidth))):1;

here is the console message :
Error: foo_uie_wsh_panel_mod: Erreur de compilation Microsoft JScript:
':' attendu
Ln: 127, Col: 143


i've marked above where it seems to need a ':' (char #143 in the line) ... any idea ?


Columns UI appearance

Reply #564


Could use some work, but I like it!

Columns UI appearance

Reply #565
@Tom,  I really like the reflection on the cover. Was curious as to what plugin that is?

Columns UI appearance

Reply #566
@Falstaff: Ahhh! The forum turned a colon-open-bracket into a sad face, which copied over as 'sad.gif'!!! It's part of an if statement, instead of $if(cond,then,else) it's cond?then:else, except my else began with a ( 

I turned off emoticons in that post, you should be able to copy it back over.

@pee_wee: it's a WSH panel (not addicted) - Averia by default uses a trackinfo panel with a mask image, I needed to use a wsh panel because I have embedded art, trackinfo mod doesn't find that. The fade effect is just done with a mask over the rotated image.


Columns UI appearance

Reply #568
@ falstaff:

hi, think of me! and release a playlist switcher and quicksearch. i love this features!

merci

lg frank

Columns UI appearance

Reply #569
new project, work in progress (started today...) : HELIUM Project for foobar

[a href="http://xs137.xs.to/xs137/09100/p2336.jpg" target="_blank"]



when you will finish it ?

hope progress going well,curious about it,cant wait..


Columns UI appearance

Reply #571
Thats looking damn good Falstaff, very impressive.

i may even give up my Curacao config which i dearly love haha!

looking forward to the release

Columns UI appearance

Reply #572
cant waittt

Columns UI appearance

Reply #573
Falstaff, the helium layout looks pretty sweet. Will you be working on that more after your new project is released?

Also, Will you be adding support for album art embedded into the mp3?

Thanks for all the hard work, we all appreciate it!