lib/linux: move down add and remove logic to Layout only (where it was used)
[nit.git] / lib / linux / ui.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # Implementation of the app.nit UI module for GNU/Linux
16 module ui
17
18 import app::ui
19 import gtk::v3_10
20
21 import data_store
22
23 redef class App
24 redef fun setup do gtk_init
25
26 # Single GTK window of this application
27 var native_window: GtkWindow is lazy do
28 var win = new GtkWindow(new GtkWindowType.toplevel)
29 win.connect_destroy_signal_to_quit
30 win.titlebar = native_header_bar
31 win.add native_stack
32 return win
33 end
34
35 # GTK 3 header bar
36 var native_header_bar: GtkHeaderBar is lazy do
37 var bar = new GtkHeaderBar
38 bar.title = "app.nit" # TODO offer a portable API to name windows
39 bar.show_close_button = true
40
41 # TODO add back button
42
43 return bar
44 end
45
46 # Root `GtkStack` used to simulate the many app.nit windows
47 var native_stack: GtkStack is lazy do
48 var stack = new GtkStack
49 stack.homogeneous = false
50 return stack
51 end
52
53 # On GNU/Linux, we go through all the callbacks once,
54 # there is no complex life-cycle.
55 redef fun run
56 do
57 app.on_create
58 app.on_restore_state
59 app.on_start
60 app.on_resume
61
62 native_window.show_all
63 gtk_main
64
65 app.on_pause
66 app.on_stop
67 app.on_save_state
68 app.on_destroy
69 end
70
71 # Spacing between GTK controls, default at 2
72 var control_spacing = 2 is writable
73
74 redef fun window=(window)
75 do
76 var root_view = window.view
77 assert root_view != null
78 native_stack.add root_view.native
79 native_stack.visible_child = root_view.native
80 super
81 end
82 end
83
84 redef class Control
85 super GtkCallable
86 super Finalizable
87
88 # The GTK element used to implement `self`
89 fun native: NATIVE is abstract
90
91 # Type of `native`
92 type NATIVE: GtkWidget
93
94 redef fun finalize
95 do
96 var native = native
97 if not native.address_is_null then native.destroy
98 end
99 end
100
101 redef class CompositeControl
102 end
103
104 # On GNU/Linux, a window is implemented by placing the `view` in a `GtkStack` in the single GTK window
105 redef class Window
106
107 # Root view of this window
108 var view: nullable View = null
109
110 redef fun add(view)
111 do
112 if view isa View then
113 self.view = view
114 end
115
116 super
117 end
118 end
119
120 redef class View
121 init do native.show
122
123 redef fun enabled do return native.sensitive
124 redef fun enabled=(enabled) do native.sensitive = enabled or else true
125 end
126
127 redef class Layout
128 redef type NATIVE: GtkBox
129
130 redef fun add(item)
131 do
132 super
133 if item isa View then native.add item.native
134 end
135
136 redef fun remove(item)
137 do
138 super
139 if item isa View then native.remove item.native
140 end
141 end
142
143 redef class HorizontalLayout
144 redef var native = new GtkBox(new GtkOrientation.horizontal, app.control_spacing)
145
146 redef fun add(item)
147 do
148 super
149 native.homogeneous = true
150 native.set_child_packing(item.native, true, true, 0, new GtkPackType.start)
151 end
152 end
153
154 redef class VerticalLayout
155 redef var native = new GtkBox(new GtkOrientation.vertical, app.control_spacing)
156
157 redef fun add(item)
158 do
159 super
160
161 # FIXME abstract the use either homogeneous or weight to balance views size in a layout
162 native.homogeneous = true
163 native.set_child_packing(item.native, true, true, 0, new GtkPackType.start)
164 end
165 end
166
167 redef class ListLayout
168 redef type NATIVE: GtkListBox
169 redef var native = new GtkListBox
170
171 init do native.selection_mode = new GtkSelectionMode.none
172 end
173
174 redef class Button
175 redef type NATIVE: GtkButton
176 redef var native = new GtkButton
177
178 redef fun text do return native.text
179 redef fun text=(value) do native.text = (value or else "").to_s
180
181 redef fun signal(sender, data) do notify_observers new ButtonPressEvent(self)
182
183 init do native.signal_connect("clicked", self, null)
184 end
185
186 redef class Label
187 redef type NATIVE: GtkLabel
188 redef var native = new GtkLabel("")
189
190 redef fun text do return native.text
191 redef fun text=(value) do native.text = (value or else "").to_s
192 end
193
194 redef class TextInput
195 redef type NATIVE: GtkEntry
196 redef var native = new GtkEntry
197
198 redef fun text do return native.text
199 redef fun text=(value) do
200 if value == null then value = ""
201 native.text = value.to_s
202 end
203
204 redef fun is_password=(value)
205 do
206 native.visibility = value != true
207 super
208 end
209 end