Draw on-top of Button control
gregorK
Is it possible to draw on-top of a button (button control)? I was even thinking of using a CustomControl but it seems that one cannot draw on-top of a generic button ("frame=1" option), or am I mistaken? I know that I can use a custom picture for the buttons but I would prefer to use the generic button because I have already put a lot of effort in a programmatic drawing of specific items in IGOR ... I would be happy for any ideas, solutions for this rather specific issue. Thanks!
Best regards,
Gregor
You say that "I know that I can use a custom picture for the buttons but I would prefer to use the generic button because I have already put a lot of effort in a programmatic drawing of specific items in IGOR". Is this a dynamic, run-time generated picture? If it is something that can be drawn once and saved, then you could make a ProcPicture from it that can be saved with your code and then used as the picture for a button. Draw the picture into a graph or panel window, copy it, go to Misc->Pictures to load it from the clipboard, and click Copy Proc Picture. That puts code into the clipboard that can be pasted into a procedure file.
If you must draw it at runtime, then a custom control is your only option.
John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
February 13, 2013 at 09:01 am - Permalink
static constant kCCE_mousedown= 1
static constant kCCE_mousemoved= 4
static constant kCCE_draw= 10
static constant kCCE_drawOSBM= 17
// PNG: width= 177, height= 120
Picture drawButton
ASCII85Begin
M,6r;%14!\!!!!.8Ou6I!!!#(!!!"E#Qau+!;Z+c9)nql&TgHDFAm*iFE_/6AH5;7DfQssEc39jTBQ
=U"3X8(5u`*!mG6$QUEC+5i?G0Agc'Em3!N$NM#7s-^X[.(1Wf"cPFU4Ko.7duc6`MW3)A%2lN`MGb
j.Df;q^3GU)V_]Iq*o+T"Npj\GqV`lY!Wc-@?7<;V:S\FSad9ejML5D:T8=_'A=1GrFKsIL3L@_(T^
#aNZp?7[pWp0'$JbI50?l#W78DQ=6Tr;jS$fRCZd?eqDa-N1%PSg3,;uFkS\2S0NV&DOTk*5bH3^'8
!`(Su*n(a/>n"-O:n^jaCgU-:YV?aKF5X;POP5aJI1t.+lJrQ^?fu^2P[P"G<D.6=V6i'C6nnbJ)<D
Hn@r%ojtmEc.N4c[$!A+CeYI/>8acgYb,;nBh+IpkG'B&_5<!!Uc6,!@9iBr8E,)M+RDbX@AG_G&A:
WXicYt<d?fM;mPR9A4h@-%N@"q*?am=sD1WmV(S=,q'*Rh8O]bpJ5nIrIPJos("S"[B=Z#p12N0_5J
g'YbkG*Vh!UXM5%#K0i)&:APEW+&>\-[o.a:=X]LiFDp$J#]#\d=,0B_J3Q3<>\iV?qt[KK0&d*#7?
X(_Z>*'@<$l(_Tr;&*=!ORXjP_H"Q$Nb"WOj!ZFcuUBtb\e&3>iJB"+07MF-^!ZFcuUBtTj!KAG!d0
):pJ4:4!BEB)H5beX!T6["KT8Oo/SA5?d]u'l>JG'Qe[M0!%-h-59%7ClVQ6o]tY[U@8Z//E>-D5dV
@/1XBGiMBX"LLl:N/B?h]@/M_T]md?'r0I>_YRY8OMs0hmqL)$!U[B'7`>WCLP22A$*kB`CWE)s%1,
%5Jl+6Lk/<'NL4iei_5J1^F(.,l6UG7N?rXe\AIoJ7-ck9f@Y0^:[=^#V(E%n]g/!f!^Z'm-]6d5Wk
g?LT,iQ=e/GaBG#k@ZX83)mo%s;+>IruE2ho$k-+/TI1P&"0Kr(.RF+Xk6eLG^UfH/?J[+Dr=P>/Jk
L:q$,,fmC/m.gX8oGm@KZOtd6arYZPUe<`*"agdtq*0a`A'j5^E#DXnY`,]P6.&KfMbJD@ZZ(/Tirt
"+6DI&Te^1tWVpn!>#eRu2V)h+BW=qebfnj'T*UiI-l.2`tH'\teiT<WhY65Is`Ned'pRku;)hG[NN
[_atJgAJt!C1?cWL@:m_#9aaTKLX^Of&&)b1=q1<65]uCn;K9aKklS<T8<=haQt^$\d>4RD25*M6DU
3A#T8-8][!"nL%O*;b1b.Yln0GfpJ#mIkAf^22_eYKH,9+J&(6;>I/-\be,TIK!(fUS7'8jaJc
ASCII85End
End
Function drawscale(vmin,vmax,n)
Variable vmin,vmax,n
variable i
Variable theta0= 2.39 // Note: constants are specific to panel button image
Variable dtheta= -1.67/n
Variable x00= 90, y00= 120,len= 85,ticklen=10,labellen=15
String s
SetDrawEnv textxjust= 1,textyjust= 1,save
for(i=0;i<=n;i+=1)
Variable theta= theta0 + i*dtheta
Variable x0= x00 + len*cos(theta)
Variable y0= y00 - len*sin(theta)
sprintf s,"%.2g",vmin+i*(vmax-vmin)/n
DrawLine x0,y0,x00 + (len+ticklen)*cos(theta),y00- (len+ticklen)*sin(theta)
DrawText x00 + (len+labellen)*cos(theta),y00 - (len+labellen)*sin(theta),s
if( i!=n )
DrawLine x0,y0,x00 + len*cos(theta+dtheta),y00 - len*sin(theta+dtheta)
endif
endfor
End
Function MyCC_ButtonFunc(s)
STRUCT WMCustomControlAction &s
if( s.eventCode==kCCE_drawOSBM )
drawscale(0,10,10)
elseif( s.eventCode==kCCE_mousedown )
beep
endif
return 0
End
Window Panel0() : Panel
PauseUpdate; Silent 1 // building window...
NewPanel /W=(150,50,350,200)
CustomControl cc3,pos={10,10},proc=MyCC_ButtonFunc
// This should be after the setting of the proc
CustomControl cc3,picture= {ProcGlobal#drawButton,1}
EndMacro
The Procedure picture (created previously with the drawing tools) is the "button" outline, and the Igor drawing stuff is found in the drawscale( ) function. That is where you could put your own drawing routines. The extra necessary item is the MouseDown event which would call your "button" procedure function in place of my "beep" command. Test this by executing Panel0() from the command line.
February 13, 2013 at 09:55 am - Permalink
John: yes indeed it is a dynamic drawing which can get redrawn (basically part of its color changes) at different times. Clearly if the buttons are drawn on top I will need to use a custom control for this. Could I ask you for a minimal working example? I could not understand from the help file how I can draw at runtime a custom drawing "inside" a custom control.
Thanks for your kind help.
Regards,
Gregor
February 13, 2013 at 12:00 pm - Permalink
--Jim Prouty
Software Engineer, WaveMetrics, Inc.
February 13, 2013 at 12:44 pm - Permalink
John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
February 13, 2013 at 12:54 pm - Permalink
The following is an example of my code to illustrate this:
Function DemoTransparentCustomControl()
NewPanel /W=(150,50,350,200)
CustomControl cctb,pos={50,50},size={100,50}
CustomControl cctb,frame=0,proc=cctButtonProc
SetDrawLayer ProgBack
SetDrawEnv gstart,gname=cctbDraw
SetDrawEnv linethick=2,linefgc=(65535,0,0),rounding=10
DrawRRect 49,49,151,101
DrawOval 70,60,130,90
SetDrawEnv gstop
End
Function cctButtonProc(s)
STRUCT WMCustomControlAction &s
s.blockReentry=1
switch(s.eventCode)
case 2: // mouse up
// code for button press here
print "Button Pressed"
break
endSwitch
return 0
End
In playing with this I have found some weird behaviour - if you change the coordinates of the rounded rectangle to the following: "DrawRRect 50,50,150,100" the custom control interferes with the picture in that its rectangle is not drawn on any more. I am using Igor 6.30Beta03 on a PC running Windows 7. Has anyone got any ideas about this?
Best regards,
Kurt
February 13, 2013 at 02:06 pm - Permalink
Gregor
February 14, 2013 at 12:40 am - Permalink
I offer this simple example:
NewPanel /W=(150,50,350,200)
CustomControl cctb,pos={50,50},size={100,50}
CustomControl cctb,frame=0,proc=cctButtonProc
End
Function cctButtonProc(s)
STRUCT WMCustomControlAction &s
s.blockReentry=1
switch(s.eventCode)
case 10: // draw: (0,0) is top-left corner of drawn content
Variable isHot = NumVarOrDefault("root:buttonHot",0)
Variable right= s.ctrlRect.right-s.ctrlRect.left
Variable bottom= s.ctrlRect.bottom-s.ctrlRect.top
SetDrawEnv linethick=2,linefgc=(isHot ? 65535 : 0,0,0),rounding=10
Variable mouseIsDown= s.eventmod & 0x1
if( isHot && mouseIsDown )
SetDrawEnv fillfgc=(0,0,0)
endif
DrawRRect 0,0,right,bottom
DrawOval 20,10,right-20,bottom-10
SetDrawEnv textxjust=1, textyjust=1 // centered at x0, y0
DrawText right/2, bottom/2, "Custom"
break
case 2: // mouse up in control
// code for button press here
print "Button Pressed"
break
case 5: // Mouse entered control
variable/G root:buttonHot= 1
s.needAction = 1
break;
case 6: // Mouse left control
variable/G root:buttonHot= 0
s.needAction = 1
break;
endSwitch
return 0
End
--Jim Prouty
Software Engineer, WaveMetrics, Inc.
February 18, 2013 at 11:30 am - Permalink