import data_store
+# Request width of the GTK window for an app.nit application
+#
+# This is the minimum width of the window, it may grow bigger to fit content.
+fun gtk_window_width_request: Int do return 480
+
redef class App
redef fun setup do gtk_init
+ # Single GTK window of this application
+ var native_window: GtkWindow is lazy do
+ var win = new GtkWindow(new GtkWindowType.toplevel)
+ win.connect_destroy_signal_to_quit
+ win.titlebar = native_header_bar
+ win.add native_stack
+ return win
+ end
+
+ # GTK 3 header bar
+ var native_header_bar: GtkHeaderBar is lazy do
+ var bar = new GtkHeaderBar
+ bar.title = "app.nit" # TODO offer a portable API to name windows
+ bar.show_close_button = true
+
+ # TODO add back button
+
+ return bar
+ end
+
+ # Root `GtkStack` used to simulate the many app.nit windows
+ var native_stack: GtkStack is lazy do
+ var stack = new GtkStack
+ stack.homogeneous = false
+ return stack
+ end
+
# On GNU/Linux, we go through all the callbacks once,
# there is no complex life-cycle.
redef fun run
app.on_start
app.on_resume
- var window = window
- window.native.show_all
+ native_window.show_all
gtk_main
app.on_pause
# Spacing between GTK controls, default at 2
var control_spacing = 2 is writable
+
+ redef fun window=(window)
+ do
+ var root_view = window.view
+ assert root_view != null
+ native_stack.add root_view.native
+ native_stack.visible_child = root_view.native
+
+ # FIXME These settings forces the GTK window to resize to its minimum
+ # size when changing app.nit windows. It is not pretty, but it could be
+ # improved with GTK 3.18 and interpolate_size.
+ native_window.resizable = false
+
+ super
+ end
end
redef class Control
end
redef class CompositeControl
- redef type NATIVE: GtkContainer
-
- redef fun add(item)
- do
- super
- native.add item.native
- end
end
+# On GNU/Linux, a window is implemented by placing the `view` in a `GtkStack` in the single GTK window
redef class Window
- redef type NATIVE: GtkWindow
- redef var native do
- var win = new GtkWindow(new GtkWindowType.toplevel)
- win.connect_destroy_signal_to_quit
- return win
+
+ # Root view of this window
+ var view: nullable View = null
+
+ redef fun add(view)
+ do
+ if view isa View then
+ self.view = view
+ view.native.valign = new GtkAlign.start
+ view.native.set_size_request(gtk_window_width_request, 0)
+ end
+
+ super
end
end
redef class Layout
redef type NATIVE: GtkBox
- redef fun remove(view)
+
+ redef fun add(item)
+ do
+ super
+ if item isa View then native.add item.native
+ end
+
+ redef fun remove(item)
do
super
- native.remove view.native
+ if item isa View then native.remove item.native
end
end
redef fun add(item)
do
super
+ # FIXME abstract the use either homogeneous or weight to balance views size in a layout
native.homogeneous = true
native.set_child_packing(item.native, true, true, 0, new GtkPackType.start)
end
do
super
- # FIXME abstract the use either homogeneous or weight to balance views size in a layout
- native.homogeneous = true
native.set_child_packing(item.native, true, true, 0, new GtkPackType.start)
end
end
+# On GNU/Linux, this is implemented by a `GtkListBox` inside a `GtkScrolledWindow`
redef class ListLayout
- redef type NATIVE: GtkListBox
- redef var native = new GtkListBox
- init do native.selection_mode = new GtkSelectionMode.none
+ redef type NATIVE: GtkScrolledWindow
+
+ redef var native = new GtkScrolledWindow
+
+ # Container inside `native`
+ var native_list_box = new GtkListBox
+
+ init do
+ native_list_box.selection_mode = new GtkSelectionMode.none
+ native.add native_list_box
+
+ # Set the size of the GtkScrolledWindow:
+ # use content width and set static height
+ native.set_policy(new GtkPolicyType.never, new GtkPolicyType.automatic)
+ native.set_size_request(gtk_window_width_request, 640)
+ end
+
+ redef fun add(item)
+ do
+ super
+ if item isa View then native_list_box.add item.native
+ end
+
+ redef fun remove(item)
+ do
+ super
+ if item isa View then native_list_box.remove item.native
+ end
end
redef class Button