The wxWidnows library is one of the best open source libraries for developing cross-platform user interface. Its API for event handling simplifies embedding a scripting language for widget creation.
Upon startup, the widget program "zsw.exe" creates a main frame window and then executes the ZeScript file "zsw.zs". The script should first obtain the main frame and then add menubar, toolbar, or controls in it. For instance,
frame = wxframe(); a = frame.menubar("&File", "&Item-1\tCtrl-I", "_", "I&tem-2\tCtrl-t", ">", "Submenu", "&Sub-1\tCtrl-S", "S&ub-2\tCtrl-u", "<", "It&em-3\tCtrl-e"); b = frame.menubar("&Help", "&About\tCtrl-A"); na = size(a); nb = size(b); for (i = 0; i < nb; i++) a[na+i] = b[i]; frame = wxcast(frame); frame.push("event_handler", "menu", a); function event_handler(id) { s = " " + id; wxmsg(s); }
You may have noticed that in the reference the function push() is registered to the base window; therefore if we want to push a event-handling callback function to handle menu event in the main frame, we have to cast the frame from the top window type to the base window type. Here are more examples.
frame=wxframe(); win=wxcast(frame); if (wxactive()) { wxmsg("I am active!"); } [w,h]=wxsize(); wxmsg("Window size: Width="+w+" Height="+h); [pname,fname,ename]=wxsplit("c:\\zs\\test.zs"); wxmsg("Path="+pname+" File="+fname+" Extension="+ename); wxexec("zsw.exe");
frame=wxframe(); frame.title("My App"); frame.icon("icons/chart.ico"); frame.evth("frame_event"); frame.timer(10000); win=wxcast(frame); // create manu bar and add the first menu menu_file=frame.menubar( "&File", "Load &Parameters\tCtrl-P", "_", "Set &Output\tCtrl-O", "_", "&Pick Color\tCtrl-C", "_", "&Quit\tCtrl-Q" ); win.push("file_handler","menu",menu_file); // add the second menu menu_option=frame.menubar( "&Option", "^", "&Check/Uncheck", "^", ">", "&Submenu", "S&ub-1", "Su&b-2", "<", "_", "@", "&Op-1", "O&p-2" ); win.push("option_handler","menu",menu_option); menubar=frame.menubar(); menubar.check(menu_option[0],true); // add tool bar tool_bar=frame.toolbar( "|", " ", "icons/param.ico", "load parameters", "icons/save.ico", "set output path", "|", " ", "icons/color.ico", "set color", "|", " ", "icons/font.ico", "set font" ); win.push("toolbar_handler","tool",tool_bar); // create status bar status_bar=frame.statusbar(3); frame.statusbar(0,"Status-1"); frame.statusbar(1,"Status-2"); frame.statusbar(2,"Status-3"); ///////////////////////////////////////////////////////////////////// // handlers function frame_event(evt) { if (evt=="exit") { wxmsg("The app is about to exit."); wxmsg("Let's test full screen mode"); frame.size(-1); wxmsg("and then close the app."); wxexit(); } else if (evt=="timer") { wxmsg("Timer."); } } function file_handler(id) { if (id==menu_file[0]) { file=frame.file(); wxmsg("Parameter file: "+file); } else if (id==menu_file[1]) { path=frame.directory(); wxmsg("Output path: "+path); } else if (id==menu_file[2]) { [r,g,b]=frame.color(); wxmsg("Color: red="+r+" green="+g+" blue="+b); } else if (id==menu_file[3]) { wxexit(); } } function option_handler(id) { // wxmsg("Option: "+menubar.label(id)); if (id==menu_option[0]) { if (menubar.check(id)) { menubar.check(id,false); } else { menubar.check(id,true); } } else { wxmsg("Enabled: "+menubar.enable(id)); } } function toolbar_handler(id) { // execute the same command as menu }
// get the top frame frame=wxframe(); // cast top frame to generic window control type win=wxcast(frame); // set size win.size(800,800); // create a panel in the top frame panel=win.panel(); win.font(12); // set colors panel.fgcolor(0,0,255); panel.bgcolor(255,255,255); // create vertically aligned sizer topsizer=panel.sizer("verbox"); // add some space topsizer.add(10,30); /* 1) create a horizontally aligned sizer in the top sizer; 2) add label and text box to the sizer. */ sizer=topsizer.sizer("horbox","aligncenter"); obj=panel.statictext("Static Label:",1); sizer.add(obj,"alignright"); text=panel.textbox("text content",200,30); sizer.add(text); obj=panel.button("Font",90,30); sizer.add(obj); obj.push("font_handler","mouse"); obj.focus(); topsizer.add(10,20); /* 1) create a horizontally aligned group sizer in the top sizer; 2) add check boxes to the sizer. 3) add combo box to the sizer. 4) add radio buttons to the sizer. */ panel2=panel.panel(); panel2.bgcolor(225,225,225); topsizer.add(panel2,"aligncenter"); sizer=panel2.sizer("horstatic","Group",500,100); obj=panel2.checkbox("check1",true); sizer.add(10,10); sizer.add(obj,"aligncenter"); obj=panel2.checkbox("check2",false); sizer.add(10,10); sizer.add(obj,"aligncenter"); obj=panel2.statictext("Items: ",1); sizer.add(10,10); sizer.add(obj,"aligncenter"); obj=panel2.combobox(["item1", "item2", "item3"], 1); sizer.add(obj,"aligncenter"); topsizer.add(10,20); // add a group of options sizer=topsizer.sizer("horbox","aligncenter"); obj=panel.radiobox("Options","col","opt1 ","opt2 ","opt3 ","opt4 ","opt5 "); sizer.add(obj,"aligncenter"); /* create a grid sizer in the top sizer and add controls in it. */ topsizer.add(10, 20); sizer=topsizer.sizer("flexgrid",2,5,3,5,"all|aligncenter"); obj=panel.button("button1"); obj.push("button1_handler","mouse"); sizer.add(obj,"all|aligncenter"); obj=panel.button("button2"); obj.push("button2_handler","mouse"); sizer.add(obj,"all|aligncenter"); obj=panel.button("button3"); obj.push("button3_handler","mouse"); sizer.add(obj,"all|aligncenter"); obj=panel.button("button4"); obj.push("button4_handler","mouse"); sizer.add(obj,"all|aligncenter"); obj=panel.button("button5"); obj.push("button5_handler","mouse"); sizer.add(obj,"all|aligncenter"); obj=panel.button("button6"); obj.push("button6_handler","mouse"); sizer.add(obj,"all|aligncenter"); //////////////////////////////////////////////// function font_handler(p1, p2, p3, p4, p5, p6) { if (p1==1) { // left up // set textbox font text.font(); } } function button1_handler(p1, p2, p3, p4, p5, p6) { if (p1==1) { // left up wxmsg("Testing the cursor function."); win.cursor("wait"); sleep(3000); win.cursor("arrow"); } } function button2_handler(p1, p2, p3, p4, p5, p6) { if (p1==1) { wxmsg("Testing the get/set functions."); wxmsg("Textbox content: "+text.get()); wxmsg("Now change the content."); text.set("Testing the set function."); } } function button3_handler(p1, p2, p3, p4, p5, p6) { if (p1==1) { wxmsg("Testing disable function."); text.disable(); } } function button4_handler(p1, p2, p3, p4, p5, p6) { if (p1==1) { wxmsg("Testing the enable function."); text.enable(); } } function button5_handler(p1, p2, p3, p4, p5, p6) { if (p1==1) { wxmsg("Testing the size function."); [w,h]=win.size(); wxmsg("Window size: "+w+"x"+h); wxmsg("It will be enlarged by 10%."); win.size(integer(w*1.1),integer(h*1.1)); } } function button6_handler(p1, p2, p3, p4, p5, p6) { if (p1==1) { wxmsg("Do nothing."); } }
g_width=900; g_height=800; frame=wxframe(); win=wxcast(frame); // add a plitter splitter=win.splitter(); splitter.min(100); spw=wxcast(splitter); // add a image panel plot=spw.panel(); plot.bgcolor(255,255,255); sizer=plot.sizer("verbox"); sizer.add(50,50); sizer=sizer.sizer("horbox"); sizer.add(10,10); // a transparent label obj=plot.statictext("Items: ",1,true); obj.fgcolor(255,255,255); sizer.add(obj,"alignleft"); // a combo control obj=plot.combobox(["item1", "item2", "item3"], 1); obj.push("combo_handler","combo"); sizer.add(obj,"alignleft"); // add a notebook control notebook=spw.notebook("top"); //arrange the two controls in the splitter splitter.horizontal(wxcast(plot),wxcast(notebook),g_height/3); // add a panel to the notebook for grid control w=notebook.add("Grid",true); grid=w.grid(20,10); grid.label(0,"Parameter"); grid.label(1,"Value"); grid.label(2,"Remark"); grid[0,0]="Address"; grid[0,1]="00-000 Street"; grid[0,2]="Updated on Jan.01"; // add a panel for treeview control w=notebook.add("Treeview",false); tree=w.treeview("treeview_handler"); tree.root("root"); tree.append("/", "group1"); tree.append("/", "group2"); tree.append("/group1", "item1"); tree.append("/group1", "item2"); tree.append("/group1", "item3"); tree.append("/group2", "item1"); tree.append("/group2", "item2"); tree.append("/group2", "item3"); // push event handlers just before resizing // so that when the functions are called // all objects are accessible. w=wxcast(plot); w.push("plot_handler1","paint"); w.push("plot_handler2","size"); w=wxcast(notebook); w.push("notebook_handler","size"); // set window size win.size(g_width,g_height); ///////////////////////////////////////////////////////////////////// function notebook_handler(cw, ch) { cw-=10; ch-=40; w=wxcast(grid); w.size(cw,ch); w=wxcast(tree); w.size(cw,ch); } function plot_handler1(w) { plot.bitmap("data/earth.png"); } function plot_handler2(w, h) { plot_handler1(null); } function treeview_handler(evt, item) { wxmsg(evt+": "+item); } function combo_handler(obj) { wxmsg("Item: "+obj.get()); }
frame=wxframe(); win=wxcast(frame); // add two panels as two interfaces panel2=win.panel(); frame.push(panel2); panel2.bgcolor(0,0,255); panel1=win.panel(); panel1.bgcolor(0,255,0); // add a button to panel1 sizer=panel1.sizer("verbox"); sizer.add(50,50); obj=panel1.button("Button-1"); obj.push("handler1","mouse"); sizer.add(obj,"aligncenter"); // add a button to panel2 sizer=panel2.sizer("verbox"); sizer.add(50,50); obj=panel2.button("Button-2"); obj.push("handler2","mouse"); sizer.add(obj,"aligncenter"); // set window size win.size(500,500); ///////////////////////////////////////////////////////////////////// function handler1(p1, p2, p3, p4, p5, p6) { if (p1==1) { frame.push(panel1); frame.pop(panel2); //trigger widget update by resizeing [w,h]=win.size(); win.size(w+1,h+1); } } function handler2(p1, p2, p3, p4, p5, p6) { if (p1==1) { frame.push(panel2); frame.pop(panel1); //trigger widget update by resizeing [w,h]=win.size(); win.size(w-1,h-1); } }