-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.d
More file actions
135 lines (112 loc) · 3.58 KB
/
app.d
File metadata and controls
135 lines (112 loc) · 3.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// basic use of gtkui
import std.conv : to;
import std.stdio : stderr;
// import all needed gtk classes
import gtk.Box; // layout container
import gtk.Button;
import gtk.Label;
import gtk.Widget; // base class for all widgets
import gtk.Window;
import gtkui;
void main()
{
auto ui = new UI;
// on close main window exit from gtk.Main loop
ui.addOnQuit({ ui.exitLoop(); });
// run gtk.Main loop
ui.runLoop();
}
// main window (main ui class)
class UI : MainBuilderUI
{
/+ override method that find `@gtkwidget` fields
and get instances of those fields from builder
override method that find `@gtksignal` methods
and connect those methods in builder
+/
mixin GtkBuilderHelper;
// widgets definition
@gtkwidget Window mwindow;
@gtkwidget Box vbox;
@gtkwidget Button addbtn;
@gtksignal void clickAdd(GtkButton* btnptr)
{
new Button(btnptr).setLabel("add " ~ (panels_count+1).to!string);
}
@gtksignal void setFocus(GtkContainer* c, GtkWidget* e)
{
stderr.writeln(" set focus callback: ",
cast(void*)vbox.getBoxStruct(), " = ",
cast(void*)c, " widget: ", cast(void*)e);
}
@gtksignal(true) void setFocusSwapped(GtkWidget* e, GtkContainer* c)
{
stderr.writeln("set focus swapped callback: ",
cast(void*)vbox.getBoxStruct(), " = ",
cast(void*)c, " widget: ", cast(void*)e);
}
uint panels_count;
this()
{
enum CUSTOMCSS = ""; // you can customize ui
// get "main.glade" from string import paths at compile-time
// you can use run-time loading glade files
super(import("main.glade"), CUSTOMCSS);
// widgets automaticaly gets from builder and you
// can use those without any boilereplate code
addbtn.addOnClicked((b)
{
// create new dynamic part of ui and add this to `vbox`
auto tmp = new Panel(panels_count++);
vbox.packEnd(tmp.mainWidget, true, true, 12);
vbox.setFocusChild(tmp.mainWidget);
});
// add calling `quit()` on hide mwindow
// and call `showAll()` for mwindow
setupMainWindow(mwindow);
}
}
// part of ui -- `ChildBuilder` have no method for working with
// gtk.Main and used as part of main ui, but have own builder
// and requires a glade file in ctor
class Panel : ChildBuilderUI
{
mixin GtkBuilderHelper;
uint idx;
// child parts
Foo!"g1" g1;
Foo!"g2" g2;
@gtkwidget Box panelmainbox;
// as for widgets signals can have namespace
// at glade file signal should have name "panel.clickG2"
@gtksignal("panel") void clickG2()
{
stderr.writefln("clickG2 signal (from %d)", idx);
}
this(uint idx)
{
this.idx = idx;
super(import("panel.glade"));
g1 = new typeof(g1)(this);
g2 = new typeof(g2)(this);
}
override Widget mainWidget() @property { return panelmainbox; }
}
// `ChildGtkUI` most simplest implementation of GtkUI and can't be used
// independently of some `GtkUI` that provides `getObject` method as parent
class Foo(string NAME) : ChildGtkUI
{
mixin GtkUIHelper;
// you can use prefix in glade file for widget names ("g1", and "g2")
@gtkwidget(NAME)
{
Button btn; // "g1.btn" or "g2.btn"
Label label; // "g1.label" or "g2.label"
}
this(GtkUI parent)
{
super(parent);
btn.addOnClicked((b) // some behavior
{ label.setText((label.getText.to!uint + 1).to!string); });
}
}