2 import gtk = gtk2.gtk2;
4 int main(string argv[]) {
7 auto window = new AppWin("Hello World!");
19 window = gtk.Window(gtk.WindowType.TOPLEVEL);
22 set_default_size(200, 128);
24 this.signal_connect!"delete-event"(&delete_cb);
26 auto vbox = gtk.VBox(0, 0);
27 auto disp = gtk.Entry();
29 vbox.set_child_packing(disp, 0, 1, 0, gtk.PackType.START);
31 auto calc = new Calculator(disp);
33 auto keypad = new Keypad(calc);
39 static extern (C) int delete_cb(gtk.Widget* this_, gtk.Event* event, void* user_data) nothrow {
46 // A custom widget, composited out of many std buttons:
52 // D lets us "magically" inherit the GTK object, but the "parent"
53 // widget has no idea about our pseudo-derived class. We keep a
54 // mapping from gtk-widgets to instances of this object;
55 // This also allows us to "cheat" and eg. redirect child widget
56 // callbacks directly to this "class".
57 static Keypad*[gtk.Widget*] widget2this;
61 enum colnum=5, rownum=4;
62 static immutable string[colnum][rownum] labels = [
63 ["7", "8", "9", "/", "C"],
64 ["4", "5", "6", "*", ""],
65 ["1", "2", "3", "-", ""],
66 ["0", ".", "=", "+", ""]
69 this(Calculator* calc) {
72 table = gtk.Table(colnum, rownum, 0);
78 foreach (gtk.c_uint y, labelrow; labels)
79 foreach (gtk.c_uint x, label; labelrow) {
80 auto button = gtk.Button.new_with_label(label);
81 button.signal_connect!"button-press-event"(&bpress_cb, cast(void*)label);
82 widget2this[&button.widget] = &this;
83 attach_defaults(button, x, x+1, y, y+1);
87 static extern (C) int bpress_cb(gtk.Widget* this_, gtk.Gdk2.EventButton* event,
88 void* user_data) nothrow {
90 if (event.type==gtk.EventType.BUTTON_PRESS && event.button==1)
91 widget2this[this_].calc.key(cast(immutable char*)user_data);
96 // The code sitting between the keypad and the display:
98 // NOTE: The "display" could be another custom widget, just like the
99 // keypad, but to keep this example simple we'll use a gtk.Entry
103 double v = 0, pv = 0;
104 string display_string;
106 bool entering, haveprev;
116 str0 = cast(char*)toStringz(display_string);
120 this(typeof(disp) disp) {
122 disp.set_alignment(1);
128 private static DT ntto(DT, ST)(ST d) {
138 if (!entering && op==pop)
143 display_string = null;
150 case '+': v = pv + v; break;
151 case '-': v = pv - v; break;
152 case '*': v = pv * v; break;
153 case '/': v = pv / v; break;
157 display_string = ntto!string(v);
162 void clear() { v = 0; pv = 0; display_string = null; haveprev = 0; entering = 0; pop = 0; }
164 void key(immutable char* key) {
168 case '0': .. case '9': case '.':
172 v = to!double(display_string);
175 display_string = display_string[0..$-1];
176 v = ntto!double(display_string);
180 display_string = (k=='.') ? "0." : key[0..1];
181 v = ntto!double(display_string);
185 case '+', '-', '*', '/', '=': oper(k); break;