So you want a Custom Switchbar?

Contributed by Soul_Eater
So you want a Custom Switchbar?? So, you want a Custom Switchbar??


A custom switchbar tutorial by Soul_Eater



Hey. I'm stil learning on writing this tutorial thing so I'm rolling with the punches here. Let's begin, I have a few minor requirements for this lesson:


Requirements

1. A basic knowledge of @windows
2. A basic knowledge of dialogs
3. Intermediate/Advanced knowledge on mdx.dll


Files

1. mdx.dll
2. dmu.dll
3. bars.mdx
4. ctl_gen.mdx
5. dialog.mdx


Ok then. I've been bugged about this several times, and I've decided to make this, even though I don't even use a custom switchbar. We'll begin with a picture window switchbar, which I will display several methods to do.

The first example will convert your switchbar from what you have, channels and all, to a picture window switchbar. I would like to note that in some of these I do not go out fully, I'm not here to do this for you, only give you an idea on how to do create a switchbar. Alrighty, here we go, buckle your seatbelt, Dorothy, because Kansas is going bye bye.

Picture Window Switchbar #1

To begin, thanks alot SirNo3DfX, for coding $button(), you are my savior and time saver. $button is a nice identifier/command that allows you to input certain options, and it draws a button on your window! The syntax is like this: $button(<window>,<x>,<y>,<w>,<h>,<button-colour>,<light-border-colour>,<dark-border-colour>,<command>,<1/2/3>,<0/1>,<1/2/3>,<button-text>,<text-colour>,<font>,<font-size>) I provide the code for $button here, but if you are interested in his snippet and example, see it here .

Ok. Now I will display some code, along with commenting, which is easier for me.


alias button {
if (!$window($1)) || (!$12) return
var %f = $iif($15,$+(",$15,"),Fixedsys),%s = $iif($16,$16,9),%x = $calc($2 + (($4 - $width($13,%f,%s,0,0))/2) $iif($12 == 2,+1)),%y = $calc(($3 +($5 - $height($13,%f,%s))/2) $iif($12 == 2,+1)),%d $iif($12 == 2,$8,$7),%a $iif($12 == 2,$7,$8),%t drawrect -nfr $1,%l drawline -nr $1,%p drawtext -nr $1,%i 1,%- $calc($5 -1),%. 6,%1 $calc($2 +$4 -1),%2 $calc(6+$3),%3 $calc($3 +$5 -6),%4 $calc($2 +$4 -6),%5 $calc($3 +$5 -1),%6 $calc(5+$2),%7 = $calc(1+$2),%8 = $calc(%1 -1),%9 = $calc(3+$3),%10 = $calc(%5 -2),%11 = $calc(2+$2)
if ($11 == 1) %a = %d
if ($10 isnum 2-3) { while (%- >= 0) { $iif(%. != 0 && %- > 4,dec %.,$iif(%- <= 4,inc %.)) | %l $6 1 $calc(%. +$2) $calc(%- +$3) $calc(($2 +$4)-%.) $calc(%- +$3) | dec %- } }
if ($10 == 2) { %l %d 1 %11 %10 %7 $calc(%5 -4) $2 %3 $2 $calc(5+$3) $calc(1+$2) $calc(4+$3) $calc(1+$2) %9 %6 $3 %4 $3 $calc(%1 -2) $calc(2+$3) %8 %9 | %l %a 1 %8 %9 %1 %2 %1 %3 $calc(3+%4) $calc(3+%3) %4 $calc(5+%3) %4 %5 $calc(5+$2) %5 %11 %10 }
if ($10 == 3) { %l %d 1 $2 %3 $2 $calc(5+$3) %6 $3 %6 $3 %4 $3 $calc($2 +$4) %2 | %l %a 1 %1 %2 %1 %3 %4 %5 %6 %5 $2 %3 }
if ($10 == 1) { %t %a 1 $2 $3 $4 $5 | %t %d 1 $2 $3 $calc($4 -1) $calc($5 -1) | %t $6 1 $calc(1+$2) $calc(1+$3) $calc($4 -2) $calc($5 -2) }
if ($12 == 3) { %c = $8 | %p $7 %f %s $calc(1+%x) $calc(1+%y) $13 }
else %c = $iif($14,$14,0)
if ($13) %p %c %f %s %x %y $13
drawdot $1
while ($hget(button. $+ $1,%i)) inc %i
if (!$prop) && ($12 == 1) hadd -m button. $+ $1 %i $+($2,;,$3,;,$4,;,$5,;,$6,;,$7,;,$8,;,$9,;,$10,;,$11,;,$13,;,$14,;,$15,;,$16)
}

menu * {
mouse:if ($hget(history. $+ $active,0)) click 2 $ifmatch
sclick: { var %i = 1 | while ($hget(button. $+ $active,%i)) { tokenize 59 $ifmatch | if ($inrect($mouse.x,$mouse.y,$1,$2,$3,$4)) { hadd -m history. $+ $active 0 %i | click 1 %i | break } | inc %i } }
uclick:if ($hget(history. $+ $active,0)) click 3 $ifmatch
}

alias -l click {
var %t = $1
tokenize 59 $hget(button. $+ $active,$2)
if (%t == 2) && ($inrect($mouse.x,$mouse.y,$1,$2,$3,$4)) return
if (%t != 1) hfree history. $+ $active
$button($active,$1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$iif(%t == 1,2,1),$11,$12,$13,$14).c
if (%t == 3) $8
}

on *:CLOSE:*:if ($hget(button. $+ $target,1)) { hfree button. $+ $target }
;All the code above here is necessary for $button(), so you need it!


alias switch {
hfree -w butto*
;clearing button hash tables
hfree -w history*
;clearing button history hash tables
window -apBzk0 +d @switchbar 1 1 $dll(dmu.dll,SbSize,width) $dll(dmu.dll,SbSize,height)
clear @switchbar
;creating window with switchbar height and width
drawfill @switchbar 9 9 1 1
;specifies switchbar color, in this case i didn't use RGB
;the color is 9, or that bright green
dll dmu.dll BarAdd switchbar > @switchbar
;attaching window with dmu.dll to switchbar
$button(@switchbar,10,4,50,18,$rgb(face),$rgb(hilight),$rgb(shadow),window -a "Status Window",1,0,1,Status,1,Arial,12)
;drawing status button, window -a makes that window active, which is used throughout this tutorial.
chanlist
;listing channels
}

;channel listing alias
alias chanlist {
var %ctr = 1,%x = 80,%length = $calc($len($chan(%ctr)) + 55)
;%ctr is our control variable, beginning with 1
;%x is the x coordinate of the button we are going to draw
;%length is the button length, which is determined by the number of characters in the
;channel name, plus 55

while ($chan(%ctr)) {
%length = $calc($len($chan(%ctr)) + 55)
$button(@switchbar,%x,4,%length,18,$rgb(face),$rgb(hilight),$rgb(shadow),window -a $ifmatch,1,0,1,$ifmatch,1,Arial,12)
%x = $calc(%x + 80)
;increases space to put windows apart
inc %ctr
}
}

;switchbar menu, you can make your own menu for your own switchbar. In this case,
;you can close the custom switchbar, and put it back to normal, or change the color

menu @switchbar {
Close:window -c @switchbar | unset %x
Change color:{
var %color = $$?="Enter color number: "
hfree -w butto*
;clearing button hash tables
hfree -w history*
;clearing button history hash tables
clear @switchbar
drawfill @switchbar %color %color 1 1
$button(@switchbar,10,4,50,18,$rgb(face),$rgb(hilight),$rgb(shadow),window -a "Status Window",1,0,1,Status,1,Arial,12)
chanlist
}
}


Now that we have this code in our Remote section(Press Alt+R), type /switch
And our switchbar is drawn! "But it only shows the status and my channels!" you say.
Well, like I said before, I give you a good idea of how to do it, then the rest is up to you.

BIG HINT: Read help on $query and $window


===================================================================

Picture Window Example #2


Well that wasn't so bad was it? Time to move on to something a little more challenging,
but still in @windows. Now we're going to actually draw on the switchbar as events happen.

We're going to use the exact same code as above, except change a few minor things.
In order to add channels to the switchbar, we're going to obviously need to remember
the x coordinate as shown in the /chanlist alias. That means instead of using a
variable(var) we're going to /set it:


;replace 1st /chanlist with this
alias chanlist {
var %ctr = 1
set %x 80
var %length = $calc($len($chan(%ctr)) + 50)
while ($chan(%ctr)) {
%length = $calc($len($chan(%ctr)) + 50)
;adds length of the channel name with 50 to make a decent button width
$button(@switchbar,%x,4,%length,18,$rgb(face),$rgb(hilight),$rgb(shadow),window -a $ifmatch,1,0,1,$ifmatch,1,Arial,12)
set %x $calc(%x + 80)
;increases space to put windows
inc %ctr
}
}

Than, we add our events. To add a new button when we join a channel, we use the on join event:
on *:join:*:{
if ($nick == $me) {
var %length = $calc($len($chan) + 55)
;same method to determine a button length again
$button(@switchbar,%x,4,%length,18,$rgb(face),$rgb(hilight),$rgb(shadow),window -a $chan,1,0,1,$chan,1,Arial,12)
;drawing the button
set %x $calc(%x + 80)
;since we set %x when we first did /chanlist, it already has a value. Everytime a new channel is added, it goes off of this value
;so we need to increase it
}
}

Then, since we part channels, we need to add an on part event:

on *:part:*:{
if ($nick == $me) {
set %x $calc(%x - 80)
.timersbp 1 1 partsb
;we have to use a timer here to perform the multiple commands to redraw the switchbar
}
}

alias partsb {
hfree -w butto*
;clearing button hash tables
hfree -w history*
;clearing button history hash tables
clear @switchbar
drawfill @switchbar 9 9 1 1
;redrawing
$button(@switchbar,10,4,50,18,$rgb(face),$rgb(hilight),$rgb(shadow),window -a "Status Window",1,0,1,Status,1,Arial,12)
chanlist
;listing buttons again
}


Finally, since we are setting the %x variable, we need to /unset it when
the window closes:


;replace 1st on close with this
on *:CLOSE:*:if ($hget(button. $+ $target,1)) { hfree button. $+ $target } | unset %x


This wasn't as hard as you thought was it? Just simple /draw commands, available in your mIRC help.

=========================================================

Time to take a breather. Picture window's may be a challenge for most of you, so you script
in dialogs, well here is your moment of glory, because that's what we're doing next!

OK times up. From cooperation with -maverick-, he is willing to let me use sIRC as an
example for a dialog'ed switchbar. This will require MDX usage, so have the DOCS ON HAND
in case you don't understand something, I really do not want to go into a whole lot of detail
on how MDX works or what the command is actually doing, because that's what the MDX docs
are for, and being an MDX user already you should have no problem in the first place.

In sIRC, -maverick-'s modular system runs on *.smf files, this is taken directly from his
file, only explained( and edited with permission). If you have a question on how to create
an *.smf, please talk to mav. I have removed some aspects of the switchbar, for example the
combo.


First we create a dialog:

dialog sb2 {
title "�"
size 0 1 9999 9999
button "",1,1 1 1 1,hide cancel
list 6,155 1 3000 25,size
text "50 0 86", 2, 1 1 150 25
button "",5,1 1 1 1,hide
edit "",7,4 30 1017 20,read
}

on *:dialog:sb2:init:*: {
echo -a $dll(mdx.dll,SetMircVersion,$version)
echo -a $dll(mdx.dll,MarkDialog,$dname)
; Mav uses an alias combined with these 2 functions, I just separated them
echo -a $dll(mdx.dll,SetDialog, $dname style windowedge)
echo -a $dll(mdx.dll,SetControlMDX,5 positioner noclose > [ dialog.mdx ] )
echo -a $dll(mdx.dll,SetControlMDX,6 toolbar list nodivider flat arrows noresize push > [ bars.mdx ] )
;creating a toolbar with mdx, which is what the buttons really are
echo -s $dll(mdx.dll,SetControlMDX,2 progressbar smooth > [ ctl_gen.mdx ] )
;Maverick uses a combo box here, but you can put anything you want to, or not even use this
;space! For demonstration, I put in a progressbar.
did -a $dname 2 barcolor $rgb(255,0,0)
did -a $dname 2 bgcolor $rgb(0,0,0)
;mdx color setting
did -i $dname 6 1 bmpsize 16 16
did -i $dname 6 1 bwidth 1 100
var %j 0 | while (%j <= 13) { did -i $dname 6 1 setimage icon small %j $+ ,c:\windows\system\shell32.dll | inc %j }
;I used windows shell32.dll for icons, maverick uses his own icon dll,
;and you can use whatever you want.
did -f $dname 6
var %blah $dll(dmu.dll,BarAdd,switchbar > $dname)
; attaching the switchbar with dmu.dll
echo -a $dll(mdx.dll,SetBorderStyle,6)
echo -a $dll(mdx.dll,SetBorderStyle,7 staticedge)
echo -a $dll(mdx.dll,SetColor,sb2 7 background $rgb(222,219,214)),%blah $dll(mdx.dll,SetColor,sb2 7 textbg $rgb(222,219,214))
;setting colors and other settings
sb.rehash -sw
.timersb -o 0 1 sb.watch
}

;everything below this point are required aliases for the switchbar to work
;on maverick's part. I think he explains them pretty well.
alias switchbarini { return " $+ switchbar.ini $+ " }
alias sb.pos { return top }

alias sb.lastpos { return $readini($switchbarini,switchbar,lastpos) }
alias mircsettings { return mirc.ini }
alias sb.watch {
if ($dialog(sb2)) {
; Check the position
var %pos = $gettok($readini($mircsettings,options,n4),21,44)
writeini $switchbarini switchbar lastpos $sb.pos
writeini $switchbarini switchbar pos $iif(%pos == 3,Right,$iif(%pos == 0,Bottom,$iif(%pos == 1,Top,Left)))
if ($sb.lastpos != $sb.pos) { sb.rehash -w }

; Move the switchbar dialog
dialog -s sb2 0 1 9999 9999
var %blah = $mdx(MoveControl, sb2 7 $iif(($sb.pos == Top) || ($sb.pos == Bottom),4,900) 30 $calc($window(-2).w - 16) 20),%a = $mdx(MoveControl, sb2 6 $iif(($sb.pos == Top) || ($sb.pos == Bottom),155 3 $calc($window(-2).w - 16) 25,5 30 100 9999)),%a = $mdx(MoveControl, sb2 3 4 3 $iif(($sb.pos == Top) || ($sb.pos == Bottom),151,91) 20 )

; Refresh the servers
sb.rehash -s
}
}

; Use $sb.window(<connection number>,<window>) alias sb.window { var %b = $scon($1).cid | if (%b) { scid %b | if ($window($2)) { return $true } | else { return $false } | scid -r } | else { return $false } }

; Use $sb.add(combo|list,<flags>,<icon>,<text>) alias sb.add { if ($1 == list) { did -a sb2 6 $2 $3- } | elseif ($1 == combo) { did -a sb2 3 1 1 0 0 $activecid $+ . $1- } }

; Use $sb.remove(combo|list,<icon number>,<text>) alias sb.remove { if ($1 == list) { did -d sb2 6 $sb.find(6,$2,$3) } | elseif ($1 == combo) { did -d sb2 3 $sb.find(3,$2,$3) } }

; Use $sb.find(<id>,<icon number>,<text>) alias sb.find { return $didwm(sb2,$1,* $+ $2- $+ *,2) }

; Use $sb.active(<window>) alias sb.active { return $iif($1- == $active,$iif(($sb.pos == Top) || ($sb.pos == Bottom),+cgWx,+cgwWx),$iif(($sb.pos == Top) || ($sb.pos == Bottom),+cgW,+cgwW)) }

; Use $sb.rehash(<connection number) alias sb.rehash {
if (s isin $1) {
var %x donothing
}
if (w isin $1) {
var %l = $calc($chan(0) + $query(0) + $chat(0) + $send(0) + $get(0) + $window(0)),%n = $iif(($sb.pos == Top) || ($sb.pos == Bottom),$calc($round($calc($window(-2).w / 80),0) - 3),$calc($round($calc($window(-2).h / 25),0) - 1)),%w = $iif(($sb.pos == Top) || ($sb.pos == Bottom),80,90)
did -r sb2 6,7 | $iif(($sb.pos == Top) || ($sb.pos == Bottom),did -a sb2 6 + -) | did -a sb2 6 $sb.active(Status Window) %w 1 Status $tab $nick on $server
if (%l >= %n) {
if ($chan(0)) { sb.add list +vW 90 2 Channels }
if ($query(0)) { sb.add list +vW 90 3 Queries }
if ($get(0)) { sb.add list +vW 90 4 Gets }
if ($send(0)) { sb.add list +vW 90 5 Sends }
if ($chat(0)) { sb.add list +vW 90 6 Chats }
if (($window(0)) && ($window(0) != 1)) { sb.add list +vW 90 11 Windows }
}
else {
if ($window(Notify List)) { sb.add list $sb.active(Notify List) %w 10 Notify $tab Notify List on $server }
if ($window(Url List)) { sb.add list $sb.active(Url List) %w 12 Url $tab Url List }
if ($window(Channels List)) { sb.add list $sb.active(Channels List) %w 2 Channels $tab Channels List }
var %a = 1
while (%a <= $chan(0)) { sb.add list $sb.active($chan(%a)) %w 9 $chan(%a) $tab Channel $chan(%a) on $server | inc %a }
var %a = 1
while (%a <= $query(0)) { sb.add list $sb.active($query(%a)) %w 3 $query(%a) $tab Query with $query(%a) | inc %a }
var %a = 1
while (%a <= $get(0)) { if ($cid == $get(%a).cid) { sb.add list $sb.active(Get $get(%a) $get(%a).file) %w 4 $get(%a) $tab Get $get(%a) $get(%a).file } | inc %a }
var %a = 1
while (%a <= $send(0)) { if ($cid == $send(%a).cid) { sb.add list $sb.active(Send $send(%a) $send(%a).file) %w 5 $send(%a) $tab Send $send(%a) $send(%a).file } | inc %a }
var %a = 1
while (%a <= $chat(0)) { if ($cid == $chat(%a).cid) { sb.add list $sb.active(= $+ $chat(%a)) %w 6 $chat(%a) $tab Chat with $chat(%a) } | inc %a }
var %a = 1
while (%a <= $window(0)) { if (($cid == $window(%a).cid) && ($window(%a).state != hidden)) { sb.add list $sb.active($window(%a)) %w 11 $window(%a) $tab $window(%a) } | inc %a }
}
}
}

; Use $sb.load.windows(<connection number) alias sb.load.windows { var %a = 1,%b = $1 | while (%a <= $scon(0)) { scid $scon(%a).cid | window -h "Status Window" | inc %a } | scid %b | window -a "Status Window" | scid -r }

on *:ACTIVE:*: {
if ($dialog(sb2)) {
sb.rehash -w
if ($active == Status Window) {
if ($lactivecid == $activecid) { return }
else {
var %t = 1
while (%t <= $scon(0)) {
scid $scon(%t).cid
var %c = 1
while (%c <= $chan(0)) { window $iif($scon(%t).cid == $activecid,-aw,-h) $chan(%c) | inc %c }
var %c 1
while (%c <= $query(0)) { window $iif($scon(%t).cid == $activecid,-aw,-h) $query(%c) | inc %c }
var %c 1
while (%c <= $get(0)) { window $iif($get(%t).cid == $activecid,-aw,-h) "Get $get(%c) $get(%c).file $+ " | inc %c }
var %c 1
while (%c <= $send(0)) { window $iif($send(%t).cid == $activecid,-aw,-h) "Send $send(%c) $send(%c).file $+ " | inc %c }
var %c 1
while (%c <= $chat(0)) { window $iif($chat(%t).cid == $activecid,-aw,-h) = $+ $chat(%c) | inc %c }
inc %t
}
}
}
}
}
on *:text:*:?: { if ($cid != $sb.server(-c)) { did -ra sb2 7 $asctime(hh:nn tt) / $scid($cid).server / $nick / $strip($1-) } }
on *:text:*:*: { if (($cid != $sb.server(-c)) && ($me isin $1-)) { did -ra sb2 7 $asctime(hh:nn tt) / $scid($cid).server / $nick / $strip($1-) } }
on *:OPEN:*: { sb.rehash -w }
on *:CLOSE:*: { sb.rehash -w }

; Dialog Clicks
on *:dialog:sb2:sclick:3: { $sb.load.windows($sb.server(-c)) | sb.rehash -w }
on *:dialog:sb2:sclick:6: {
var %t = $gettok($did(6).seltext,3,32),%f = $gettok($did(6).seltext,1,32),%i = $gettok($did(6).seltext,2,32),%b = $iif($mouse.key == 4,-c,-a)
if (v isin %f) { halt }
scid $sb.server(-c)
if (%t == Status) { var %w = "Status Window" }
elseif (%i == 9) { if (%b == -a) { var %w = $chan(%t) } | else { part $chan(%t) | halt } }
elseif (%i == 3) { var %w = $query(%t) }
elseif (%i == 10) { var %w = "Notify List" }
elseif (%i == 12) { var %w = "URL List" }
elseif (%i == 2) { var %w = "Channels List" }
elseif (%i == 4) { var %w = " $+ $gettok($did(6).seltext,5-,32) $+ " }
elseif (%i == 5) { var %w = " $+ $gettok($did(6).seltext,5-,32) $+ " }
elseif ((%i == 6) && ($window(= $+ %t))) { var %w = = $+ %t }
elseif ((%i == 11) && ($window(%t))) { var %w = %t }
if ((%b == -c) && (%i != 1)) { did -d sb2 6 $did(6).sel }
window %b %w
scid -r
}


***BIG note here-as this is sIRC's switchbar, I wouldn't reccommend
trying this code out for yourself in sIRC.

Next- to run this, just type /dialog -md sb2 sb2
To close it, /dialog -c sb2


Thanks alot for being a great crowd. Questions? Comments? Quandaries?
Anxieties?


Soul_Eater on irc.dal.net,irc.webchat.org, irc.scriptaz.com
Soul_Eate on eu.undernet.org
[email protected]
SoulEata on AIM
All content is copyright by mircscripts.org and cannot be used without permission. For more details, click here.