From ff7c0520f88cfea195b2ca24f7322cffc51bd127 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexis=20Laferri=C3=A8re?= Date: Tue, 27 Oct 2015 20:32:24 -0400 Subject: [PATCH 1/5] lib/gtk: rename gtk life-cycle methods, and other, to their C counter parts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Alexis Laferrière --- lib/gtk/v3_4/gtk_assistant.nit | 2 +- lib/gtk/v3_4/gtk_core.nit | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/gtk/v3_4/gtk_assistant.nit b/lib/gtk/v3_4/gtk_assistant.nit index 34319dce44..0d4378489b 100644 --- a/lib/gtk/v3_4/gtk_assistant.nit +++ b/lib/gtk/v3_4/gtk_assistant.nit @@ -60,7 +60,7 @@ extern class GtkAssistant `{GtkAssistant *`} return gtk_assistant_insert_page(self, page, position); `} - fun remove(page_num: Int) `{ + fun remove_page(page_num: Int) `{ gtk_assistant_remove_page(self, page_num); `} diff --git a/lib/gtk/v3_4/gtk_core.nit b/lib/gtk/v3_4/gtk_core.nit index b9929f5d0c..902c1ee031 100644 --- a/lib/gtk/v3_4/gtk_core.nit +++ b/lib/gtk/v3_4/gtk_core.nit @@ -43,13 +43,13 @@ in "C Header" `{ `} # Initialize the GTK system -fun init_gtk `{ gtk_init(0, NULL); `} +fun gtk_init `{ gtk_init(0, NULL); `} # Hand over control to the GTK event loop -fun run_gtk `{ gtk_main(); `} +fun gtk_main `{ gtk_main(); `} # Quit the GTK event loop and clean up the system -fun quit_gtk `{ gtk_main_quit(); `} +fun gtk_main_quit `{ gtk_main_quit(); `} interface GtkCallable # return true to stop event processing, false to let it propagate @@ -142,8 +142,9 @@ extern class GtkContainer `{GtkContainer *`} fun add(widget: GtkWidget) `{ gtk_container_add(self, widget); `} + # Remove the widget from the container - fun remove_widget(widget: GtkWidget) `{ + fun remove(widget: GtkWidget) `{ gtk_container_remove(self, widget); `} @@ -156,7 +157,6 @@ extern class GtkContainer `{GtkContainer *`} fun resize_mode=(resize_mode: GtkResizeMode) `{ gtk_container_set_resize_mode(self, resize_mode); `} - end # A container with just one child From 7920c54bfbd17aa579dc0e4da0ab652822ae1536 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexis=20Laferri=C3=A8re?= Date: Mon, 26 Oct 2015 15:05:21 -0400 Subject: [PATCH 2/5] lib/gtk: intro new services from GTK+ 3.10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Alexis Laferrière --- lib/gtk/v3_10.nit | 167 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 lib/gtk/v3_10.nit diff --git a/lib/gtk/v3_10.nit b/lib/gtk/v3_10.nit new file mode 100644 index 0000000000..f47b46e225 --- /dev/null +++ b/lib/gtk/v3_10.nit @@ -0,0 +1,167 @@ +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# GTK+ services added at version 3.10 +module v3_10 is pkgconfig("gtk+-3.0") + +import v3_8 + +redef class GtkWindow + fun titlebar=(widget: GtkWidget) `{ gtk_window_set_titlebar(self, widget); `} +end + +# A vertical container of `GtkListBoxRow` +extern class GtkListBox `{ GtkListBox * `} + super GtkContainer + + new `{ return (GtkListBox*)gtk_list_box_new(); `} + + fun prepend(child: GtkWidget) `{ gtk_list_box_prepend(self, child); `} + + fun insert(child: GtkWidget, position: Int) `{ gtk_list_box_insert(self, child, position); `} + + fun selected_row: GtkListBoxRow `{ return gtk_list_box_get_selected_row(self); `} + + fun row_at_index(index: Int): GtkListBoxRow`{ return gtk_list_box_get_row_at_index(self, index); `} + + fun row_at_y(y: Int): GtkListBoxRow `{ return gtk_list_box_get_row_at_y(self, y); `} + + fun select_row(row: GtkListBoxRow) `{ gtk_list_box_select_row(self, row); `} + + fun placeholder=(placeholder: GtkWidget) `{ gtk_list_box_set_placeholder(self, placeholder); `} + + fun adjustment=(adjustment: GtkAdjustment) `{ gtk_list_box_set_adjustment(self, adjustment); `} + + fun selection_mode=(mode: GtkSelectionMode) `{ gtk_list_box_set_selection_mode(self, mode); `} + + fun selection_mode: GtkSelectionMode `{ return gtk_list_box_get_selection_mode (self); `} + + fun invalidate_filter `{ gtk_list_box_invalidate_filter(self); `} + + fun invalidate_sort `{ gtk_list_box_invalidate_sort(self); `} + + fun invalidate_headers `{ gtk_list_box_invalidate_headers(self); `} + + fun activate_on_single_click=(single: Bool) `{ gtk_list_box_set_activate_on_single_click(self, single); `} + + fun activate_on_single_click: Bool `{ return gtk_list_box_get_activate_on_single_click(self); `} + + fun drag_unhighlight_row `{ gtk_list_box_drag_unhighlight_row(self); `} + + fun drag_highlight_row(row: GtkListBoxRow) `{ gtk_list_box_drag_highlight_row(self, row); `} + + # TODO + #fun (* GtkListBoxForeachFunc)(GtkListBoxRow *row, gpointer user_data) `{ (* GtkListBoxForeachFunc)(self, GtkListBoxRow *row, gpointer user_data); `} + #fun set_filter_func(GtkListBoxFilterFunc filter_func, gpointer user_data, GDestroyNotify destroy) `{ gtk_list_box_set_filter_func(self, GtkListBoxFilterFunc filter_func, gpointer user_data, GDestroyNotify destroy); `} + #fun set_header_func(GtkListBoxUpdateHeaderFunc update_header, gpointer user_data, GDestroyNotify destroy) `{ gtk_list_box_set_header_func(self, GtkListBoxUpdateHeaderFunc update_header, gpointer user_data, GDestroyNotify destroy); `} + #fun set_sort_func(GtkListBoxSortFunc sort_func, gpointer user_data, GDestroyNotify destroy) `{ gtk_list_box_set_sort_func(self, GtkListBoxSortFunc sort_func, gpointer user_data, GDestroyNotify destroy); `} +end + +# A single row of a `GtkListBox` +extern class GtkListBoxRow `{ GtkListBoxRow* `} + super GtkWidget + + new `{ return (GtkListBoxRow*)gtk_list_box_row_new(); `} + + fun header: GtkWidget `{ return gtk_list_box_row_get_header(self); `} + + fun header=(header: GtkWidget) `{ gtk_list_box_row_set_header(self, header); `} + + fun index: Int `{ return gtk_list_box_row_get_index(self); `} + + fun changed `{ gtk_list_box_row_changed(self); `} +end + +# Horizontal container with a title and subtitle +extern class GtkHeaderBar `{ GtkHeaderBar* `} + super GtkContainer + + new `{ return (GtkHeaderBar*)gtk_header_bar_new(); `} + + fun title=(title: Text) do native_title = title.to_cstring + private fun native_title=(title: NativeString) `{ gtk_header_bar_set_title(self, title); `} + + fun title: String do return native_title.to_s + private fun native_title: NativeString `{ return (gchar *)gtk_header_bar_get_title(self); `} + + fun subtitle=(subtitle: Text) do native_subtitle = subtitle.to_cstring + fun native_subtitle=(subtitle: NativeString) `{ gtk_header_bar_set_subtitle(self, subtitle); `} + + fun subtitle: String do return native_subtitle.to_s + fun native_subtitle: NativeString `{ return (gchar *)gtk_header_bar_get_subtitle(self); `} + + fun custom_title=(title_widget: GtkWidget) `{ gtk_header_bar_set_custom_title(self, title_widget); `} + + fun custom_title: GtkWidget `{ return gtk_header_bar_get_custom_title(self); `} + + fun pack_start(child: GtkWidget) `{ gtk_header_bar_pack_start(self, child); `} + + fun pack_end(child: GtkWidget) `{ gtk_header_bar_pack_end(self, child); `} + + fun show_close_button=(setting: Bool) `{ gtk_header_bar_set_show_close_button(self, setting); `} + + fun show_close_button: Bool `{ return gtk_header_bar_get_show_close_button(self); `} +end + +# Container with a single child visible at a time +extern class GtkStack `{ GtkStack * `} + super GtkContainer + + new `{ return (GtkStack*)gtk_stack_new(); `} + + fun stack_add(child: GtkWidget, name: String) do native_stack_add(child, name.to_cstring) + private fun native_stack_add(child: GtkWidget, name: NativeString) `{ gtk_stack_add_named(self, child, name); `} + + fun add_titled(child: GtkWidget, name, title: NativeString) `{ gtk_stack_add_titled(self, child, name, title); `} + fun native_add_titled(child: GtkWidget, name, title: NativeString) `{ gtk_stack_add_titled(self, child, name, title); `} + + fun visible_child=(child: GtkWidget) `{ gtk_stack_set_visible_child(self, child); `} + + fun visible_child: GtkWidget `{ return gtk_stack_get_visible_child(self); `} + + fun visible_child_name=(name: Text) do native_visible_child_name = name.to_cstring + fun native_visible_child_name=(name: NativeString) `{ gtk_stack_set_visible_child_name(self, name); `} + + fun visible_child_name: Text do return native_visible_child_name.to_s + fun native_visible_child_name: NativeString `{ return (gchar *)gtk_stack_get_visible_child_name(self); `} + + fun set_visible_child_full(name: Text, transition: GtkStackTransitionType) do native_set_visible_child_full(name.to_cstring, transition) + fun native_set_visible_child_full(name: NativeString, transition: GtkStackTransitionType) `{ + gtk_stack_set_visible_child_full(self, name, transition); + `} + + fun homogeneous=(homogeneous: Bool) `{ gtk_stack_set_homogeneous(self, homogeneous); `} + + fun homogeneous: Bool `{ return gtk_stack_get_homogeneous(self); `} + + fun transition_duration=(duration: Int) `{ gtk_stack_set_transition_duration(self, duration); `} + + fun transition_duration: Int `{ return gtk_stack_get_transition_duration(self); `} + + fun transition_type=(transition: GtkStackTransitionType) `{ gtk_stack_set_transition_type(self, transition); `} + + fun transition_type: GtkStackTransitionType `{ return gtk_stack_get_transition_type(self); `} +end + +# Type of animation used for transitions between pages in a `GtkStack` +extern class GtkStackTransitionType `{ GtkStackTransitionType `} + new none `{ return GTK_STACK_TRANSITION_TYPE_NONE; `} + new crossfade `{ return GTK_STACK_TRANSITION_TYPE_CROSSFADE; `} + new slide_right `{ return GTK_STACK_TRANSITION_TYPE_SLIDE_RIGHT; `} + new slide_left `{ return GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT; `} + new slide_up `{ return GTK_STACK_TRANSITION_TYPE_SLIDE_UP; `} + new slide_down `{ return GTK_STACK_TRANSITION_TYPE_SLIDE_DOWN; `} + new slide_left_right `{ return GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT_RIGHT; `} + new slide_up_down `{ return GTK_STACK_TRANSITION_TYPE_SLIDE_UP_DOWN; `} +end From d427dc06fd6d483e03751ac40e46c1cd35faf732 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexis=20Laferri=C3=A8re?= Date: Wed, 28 Oct 2015 08:45:21 -0400 Subject: [PATCH 3/5] lib/gtk: add more services to gtk_core MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Alexis Laferrière --- lib/gtk/v3_4/gtk_core.nit | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/lib/gtk/v3_4/gtk_core.nit b/lib/gtk/v3_4/gtk_core.nit index 902c1ee031..f7d2c78a67 100644 --- a/lib/gtk/v3_4/gtk_core.nit +++ b/lib/gtk/v3_4/gtk_core.nit @@ -48,6 +48,12 @@ fun gtk_init `{ gtk_init(0, NULL); `} # Hand over control to the GTK event loop fun gtk_main `{ gtk_main(); `} +# Run a single iteration of the main loop, block until an event is noticed +fun gtk_main_iteration: Bool `{ return gtk_main_iteration(); `} + +# Run a single iteration of the main loop, only block until an event is noticed if `blocking` +fun gtk_main_iteration_do(blocking: Bool): Bool `{ return gtk_main_iteration_do(blocking); `} + # Quit the GTK event loop and clean up the system fun gtk_main_quit `{ gtk_main_quit(); `} @@ -290,6 +296,9 @@ extern class GtkWindow `{GtkWindow *`} fun keep_below=(setting: Bool) `{ gtk_window_set_keep_below(self, setting); `} + + # Try to convince the window manage to decorate or not this window + fun decorated=(setting: Bool) `{ gtk_window_set_decorated(self, setting); `} end # A bin with a decorative frame and optional label @@ -772,6 +781,15 @@ extern class GtkButton `{GtkButton *`} signal_connect("clicked", to_call, user_data) end + # Set the image of button to the given widget + fun image=(image: GtkWidget) `{ + gtk_button_set_image(self, image); + `} + + # Get the widget that is currenty set as the image of button + fun image: GtkWidget `{ + return gtk_button_get_image(self); + `} end # A button which pops up a scale @@ -1054,4 +1072,3 @@ end extern class GdkRGBA `{GdkRGBA*`} end - From 4b177b08483e29fbbecc00a2e49dce3152f1135a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexis=20Laferri=C3=A8re?= Date: Wed, 28 Oct 2015 08:45:02 -0400 Subject: [PATCH 4/5] lib/gtk: intro threading system of GDK MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Alexis Laferrière --- lib/gtk/v3_4/gdk.nit | 43 +++++++++++++++++++++++++++++++++++++++++++ lib/gtk/v3_4/v3_4.nit | 1 + 2 files changed, 44 insertions(+) create mode 100644 lib/gtk/v3_4/gdk.nit diff --git a/lib/gtk/v3_4/gdk.nit b/lib/gtk/v3_4/gdk.nit new file mode 100644 index 0000000000..2195ee22d9 --- /dev/null +++ b/lib/gtk/v3_4/gdk.nit @@ -0,0 +1,43 @@ +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Services from GDK +module gdk is pkgconfig "gtk+-3.0" + +import gtk_core + +`{ +#ifdef GdkCallback_run + // Callback to GdkCallaback::run + gboolean nit_gdk_callback(gpointer user_data) { + GdkCallback_decr_ref(user_data); + return GdkCallback_run(user_data); + } +#endif +`} + +# Callback to pass to `gdk_threads_add_idle` +class GdkCallback + + # Small unit of code executed by the GDK loop when idle + # + # Returns true if this object should be invoked again. + fun run: Bool do return false +end + +# Add a callback to execute whenever there are no higher priority events pending +fun gdk_threads_add_idle(callback: GdkCallback): Int import GdkCallback.run `{ + GdkCallback_incr_ref(callback); + return gdk_threads_add_idle(&nit_gdk_callback, callback); +`} diff --git a/lib/gtk/v3_4/v3_4.nit b/lib/gtk/v3_4/v3_4.nit index db45724b78..bd1d63bbdb 100644 --- a/lib/gtk/v3_4/v3_4.nit +++ b/lib/gtk/v3_4/v3_4.nit @@ -20,3 +20,4 @@ module v3_4 is pkgconfig "gtk+-3.0" import gtk_widgets_ext import gtk_dialogs import gtk_assistant +import gdk From 139b263c789613752ab4bd8a0ebce7e7f7b90ae4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexis=20Laferri=C3=A8re?= Date: Tue, 3 Nov 2015 10:55:22 -0500 Subject: [PATCH 5/5] tests & lib/ui: update gtk users MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Alexis Laferrière --- lib/linux/ui.nit | 4 ++-- tests/test_gtk.nit | 9 ++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/lib/linux/ui.nit b/lib/linux/ui.nit index 4f67eedaa7..f3deb77ba3 100644 --- a/lib/linux/ui.nit +++ b/lib/linux/ui.nit @@ -21,7 +21,7 @@ import gtk import data_store redef class App - redef fun setup do init_gtk + redef fun setup do gtk_init # On GNU/Linux, we go through all the callbacks once, # there is no complex life-cycle. @@ -34,7 +34,7 @@ redef class App var window = window window.native.show_all - run_gtk + gtk_main app.on_pause app.on_stop diff --git a/tests/test_gtk.nit b/tests/test_gtk.nit index 4916f4b45e..28ee606f0c 100644 --- a/tests/test_gtk.nit +++ b/tests/test_gtk.nit @@ -33,19 +33,18 @@ class MyApp if sender == but_ok then print "ok!" - quit_gtk + gtk_main_quit else if sender == but_cancel then print "cancel!" - quit_gtk + gtk_main_quit else print sender end - end init do - init_gtk + gtk_init win = new GtkWindow(new GtkWindowType.toplevel) win.connect_destroy_signal_to_quit @@ -70,5 +69,5 @@ end if "NIT_TESTING".environ != "true" then var app = new MyApp - run_gtk + gtk_main end