Skip to content

Commit

Permalink
Merge: lib/gtk: add services from GTK+ 3.10 and rename some core serv…
Browse files Browse the repository at this point in the history
…ices

Services from v3.10 includes the `HeaderBar` (the large window top bar with custom buttons) and the `Stack` which shows only 1 widget at a time with transition effects. The renamed services use the same name as in C.

Pull-Request: #1809
Reviewed-by: Jean Privat <jean@pryen.org>
  • Loading branch information
privat committed Nov 5, 2015
2 parents d329c5c + 139b263 commit aa7b441
Show file tree
Hide file tree
Showing 7 changed files with 241 additions and 14 deletions.
167 changes: 167 additions & 0 deletions 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
43 changes: 43 additions & 0 deletions 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);
`}
2 changes: 1 addition & 1 deletion lib/gtk/v3_4/gtk_assistant.nit
Expand Up @@ -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);
`}

Expand Down
29 changes: 23 additions & 6 deletions lib/gtk/v3_4/gtk_core.nit
Expand Up @@ -43,13 +43,19 @@ 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(); `}

# 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 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
Expand Down Expand Up @@ -142,8 +148,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);
`}

Expand All @@ -156,7 +163,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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -1054,4 +1072,3 @@ end

extern class GdkRGBA `{GdkRGBA*`}
end

1 change: 1 addition & 0 deletions lib/gtk/v3_4/v3_4.nit
Expand Up @@ -20,3 +20,4 @@ module v3_4 is pkgconfig "gtk+-3.0"
import gtk_widgets_ext
import gtk_dialogs
import gtk_assistant
import gdk
4 changes: 2 additions & 2 deletions lib/linux/ui.nit
Expand Up @@ -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.
Expand All @@ -34,7 +34,7 @@ redef class App

var window = window
window.native.show_all
run_gtk
gtk_main

app.on_pause
app.on_stop
Expand Down
9 changes: 4 additions & 5 deletions tests/test_gtk.nit
Expand Up @@ -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
Expand All @@ -70,5 +69,5 @@ end

if "NIT_TESTING".environ != "true" then
var app = new MyApp
run_gtk
gtk_main
end

0 comments on commit aa7b441

Please sign in to comment.