Skip to content

Commit

Permalink
added gaction2.nim example, and some small fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
StefanSalewski committed Dec 5, 2019
1 parent f50ff67 commit 68f99d3
Show file tree
Hide file tree
Showing 7 changed files with 320 additions and 7 deletions.
139 changes: 137 additions & 2 deletions README.adoc
@@ -1,6 +1,6 @@
= High level GTK3 (and GTK4) bindings for the Nim programming language
(c) Stefan Salewski
//Version 0.6.0
//Version 0.6.1
:experimental:
:imagesdir: http://ssalewski.de/tmp
:source-highlighter: pygments
Expand Down Expand Up @@ -1100,7 +1100,142 @@ main()
While in the previous example we create only a single menu instance in proc appStartup()
for all of our application windows, here we create a new menu for all of our instances
in proc appActivate(). That seems to work fine, so I assume it is correct.
in proc appActivate(). That seems to work fine, so I assume it is correct.
== GMenu and GAction with GTK Builder
And here is an example from https://github.com/GNOME/gtk/blob/mainline/tests/
which uses a combination of gaction and gmenu with a GTK builder XML file for
the menu description.
[[gaction2.nim]]
[source, nim]
.gaction2.nim
----
# nim c gaction2.nim
# https://github.com/GNOME/gtk/blob/mainline/tests/testgaction.c
# gcc -Wall gaction.c -o gaction `pkg-config --cflags --libs gtk4`
import gintro/[gtk, glib, gobject, gio]

const menuData = """
<interface>
<menu id="menuModel">
<section>
<item>
<attribute name="label">Normal Menu Item</attribute>
<attribute name="action">win.normal-menu-item</attribute>
</item>
<submenu>
<attribute name="label">Submenu</attribute>
<item>
<attribute name="label">Submenu Item</attribute>
<attribute name="action">win.submenu-item</attribute>
</item>
</submenu>
<item>
<attribute name="label">Toggle Menu Item</attribute>
<attribute name="action">win.toggle-menu-item</attribute>
</item>
</section>
<section>
<item>
<attribute name="label">Radio 1</attribute>
<attribute name="action">win.radio</attribute>
<attribute name="target">1</attribute>
</item>
<item>
<attribute name="label">Radio 2</attribute>
<attribute name="action">win.radio</attribute>
<attribute name="target">2</attribute>
</item>
<item>
<attribute name="label">Radio 3</attribute>
<attribute name="action">win.radio</attribute>
<attribute name="target">3</attribute>
</item>
</section>
</menu>
</interface>
"""

proc changeLabelButton(action: SimpleAction; v: Variant; label: Label) =
label.setLabel("Text set from button")

proc normalMenuItem(action: SimpleAction; v: Variant; label: Label) =
label.setLabel("Text set from normal menu item")

proc toggleMenuItem(action: SimpleAction; v: Variant; label: Label) =
label.setLabel("Text set from toggle menu item")

proc submenuItem(action: SimpleAction; v: Variant; label: Label) =
label.setLabel("Text set from submenu item")

proc radio(action: SimpleAction; parameter: Variant; label: Label) =
var l: uint64
let newState: Variant = newVariantString(getString(parameter, l))
let str: string = "From Radio menu item " & getString(newState, l)
label.setLabel(str)

proc bye(w: Window) =
mainQuit()
echo "Bye..."

proc main =
gtk.init()
let
window = newWindow()
box = newBox(Orientation.vertical, 12)
menubutton = newMenuButton()
button1 = newButton("Change Label Text")
label = newLabel("Initial Text")
actionGroup = newSimpleActionGroup()

window.connect("destroy", gtk.mainQuit)
#window.connect("destroy", bye)

var action = newSimpleAction("change-label-button")
discard action.connect("activate", changeLabelButton, label)
actionGroup.addAction(action)

action = newSimpleAction("normal-menu-item")
discard action.connect("activate", normalMenuItem, label)
actionGroup.addAction(action)

var v = newVariantBoolean(true)
action = newSimpleActionStateful("toggle-menu-item", nil, v)
discard action.connect("activate", toggleMenuItem, label)
actionGroup.addAction(action)

action = newSimpleAction("submenu-item")
discard action.connect("activate", subMenuItem, label)
actionGroup.addAction(action)

v = newVariantString("1")
let vt = newVariantType("s")
action = newSimpleActionStateful("radio", vt, v)
discard action.connect("activate", radio, label)
actionGroup.addAction(action)

insertActionGroup(window, "win", actionGroup)

label.setMarginTop(12)
label.setMarginBottom(12)
box.add(label)
menubutton.setHAlign(Align.center)
let builder: Builder = newBuilderFromString(menuData)
let menuModel = builder.getMenuModel("menuModel")
let menu = newMenuFromModel(menuModel)
menuButton.setPopup(menu)
box.add(menubutton)
button1.setHalign(Align.center)
button1.setActionName("win.change-label-button")
box.add(button1)
window.add(box)
window.showAll
gtk.main()

main()
----
== GSettings
Expand Down
1 change: 1 addition & 0 deletions examples/gtk3/gaction.nim
Expand Up @@ -23,3 +23,4 @@ proc main =
discard run(app)

main()

123 changes: 123 additions & 0 deletions examples/gtk3/gaction2.nim
@@ -0,0 +1,123 @@
# nim c gaction.nim
# https://github.com/GNOME/gtk/blob/mainline/tests/testgaction.c
# gcc -Wall gaction.c -o gaction `pkg-config --cflags --libs gtk4`
import gintro/[gtk, glib, gobject, gio]

const menuData = """
<interface>
<menu id="menuModel">
<section>
<item>
<attribute name="label">Normal Menu Item</attribute>
<attribute name="action">win.normal-menu-item</attribute>
</item>
<submenu>
<attribute name="label">Submenu</attribute>
<item>
<attribute name="label">Submenu Item</attribute>
<attribute name="action">win.submenu-item</attribute>
</item>
</submenu>
<item>
<attribute name="label">Toggle Menu Item</attribute>
<attribute name="action">win.toggle-menu-item</attribute>
</item>
</section>
<section>
<item>
<attribute name="label">Radio 1</attribute>
<attribute name="action">win.radio</attribute>
<attribute name="target">1</attribute>
</item>
<item>
<attribute name="label">Radio 2</attribute>
<attribute name="action">win.radio</attribute>
<attribute name="target">2</attribute>
</item>
<item>
<attribute name="label">Radio 3</attribute>
<attribute name="action">win.radio</attribute>
<attribute name="target">3</attribute>
</item>
</section>
</menu>
</interface>
"""

proc changeLabelButton(action: SimpleAction; v: Variant; label: Label) =
label.setLabel("Text set from button")

proc normalMenuItem(action: SimpleAction; v: Variant; label: Label) =
label.setLabel("Text set from normal menu item")

proc toggleMenuItem(action: SimpleAction; v: Variant; label: Label) =
label.setLabel("Text set from toggle menu item")

proc submenuItem(action: SimpleAction; v: Variant; label: Label) =
label.setLabel("Text set from submenu item")

proc radio(action: SimpleAction; parameter: Variant; label: Label) =
var l: uint64
let newState: Variant = newVariantString(getString(parameter, l))
let str: string = "From Radio menu item " & getString(newState, l)
label.setLabel(str)

proc bye(w: Window) =
mainQuit()
echo "Bye..."

proc main =
gtk.init()
let
window = newWindow()
box = newBox(Orientation.vertical, 12)
menubutton = newMenuButton()
button1 = newButton("Change Label Text")
label = newLabel("Initial Text")
actionGroup = newSimpleActionGroup()

window.connect("destroy", gtk.mainQuit)
#window.connect("destroy", bye)

var action = newSimpleAction("change-label-button")
discard action.connect("activate", changeLabelButton, label)
actionGroup.addAction(action)

action = newSimpleAction("normal-menu-item")
discard action.connect("activate", normalMenuItem, label)
actionGroup.addAction(action)

var v = newVariantBoolean(true)
action = newSimpleActionStateful("toggle-menu-item", nil, v)
discard action.connect("activate", toggleMenuItem, label)
actionGroup.addAction(action)

action = newSimpleAction("submenu-item")
discard action.connect("activate", subMenuItem, label)
actionGroup.addAction(action)

v = newVariantString("1")
let vt = newVariantType("s")
action = newSimpleActionStateful("radio", vt, v)
discard action.connect("activate", radio, label)
actionGroup.addAction(action)

insertActionGroup(window, "win", actionGroup)

label.setMarginTop(12)
label.setMarginBottom(12)
box.add(label)
menubutton.setHAlign(Align.center)
let builder: Builder = newBuilderFromString(menuData)
let menuModel = builder.getMenuModel("menuModel")
let menu = newMenuFromModel(menuModel)
menuButton.setPopup(menu)
box.add(menubutton)
button1.setHalign(Align.center)
button1.setActionName("win.change-label-button")
box.add(button1)
window.add(box)
window.showAll
gtk.main()

main()
2 changes: 2 additions & 0 deletions examples/gtk3/makeAll
Expand Up @@ -7,6 +7,7 @@ nim c count_button.nim
nim c darea_test.nim
nim c drawingarea.nim
nim c gaction.nim
nim c gaction2.nim
nim c gsettings.nim
nim c label.nim
nim c listview.nim
Expand All @@ -19,3 +20,4 @@ nim c cairoImage.nim
nim c gstBasicTutorial1.nim
nim c sourceview_test.nim
nim c overlay_tree1.nim
nim c celldatafunction.nim
2 changes: 1 addition & 1 deletion gintro.nimble
@@ -1,6 +1,6 @@
# Package

version = "0.6.0"
version = "0.6.1"
author = "Stefan Salewski"
description = "High level GObject-Introspection based GTK3/GTK4 bindings"
license = "MIT"
Expand Down
34 changes: 33 additions & 1 deletion gintro/cairoimpl.nim
@@ -1,7 +1,7 @@
# This is the high level cairo module for Nim -- based on the low level ngtk3 module, manually tuned.
# (c) S. Salewski 2017, cairo 1.15.6
# v0.6.0
# 28-OCT-2019
# 03-DEC-2019

# starting with gintro v.0.6.0 we split cairo into the gobject-introspection generated cairo.nim and this file.

Expand Down Expand Up @@ -242,6 +242,7 @@ proc cairo_pop_group*(cr: ptr Context00): ptr Pattern00 {.importc, libcairo.}
proc popGroup*(cr: Context): Pattern =
new(result, patternDestroy)
result.impl = cairo_pop_group(cr.impl)
GC_Ref(result)
discard cairo_pattern_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref)

proc cairo_pop_group_to_source*(cr: ptr Context00) {.importc, libcairo.}
Expand Down Expand Up @@ -271,6 +272,11 @@ proc setSource*(cr: Context; red, green, blue: float) =
cairo_set_source_rgb(cr.impl, red.cdouble, green.cdouble, blue.cdouble)
#
#const `source=`* = setSourceRgb
proc setSource*(cr: Context; rgb: array[3, float]) =
cairo_set_source_rgb(cr.impl, rgb[0], rgb[1], rgb[2])
#
proc setSource*(cr: Context; rgb: tuple[r, g, b: float]) =
cairo_set_source_rgb(cr.impl, rgb[0], rgb[1], rgb[2])

proc cairo_set_source_rgba*(cr: ptr Context00; red, green, blue, alpha: cdouble) {.importc, libcairo.}
#
Expand All @@ -279,6 +285,12 @@ proc setSource*(cr: Context; red, green, blue, alpha: float) =
cairo_set_source_rgba(cr.impl, red.cdouble, green.cdouble, blue.cdouble, alpha.cdouble)
#
#const `sourceRgba=`* = setSourceRgba
#
proc setSource*(cr: Context; rgba: array[4, float]) =
cairo_set_source_rgba(cr.impl, rgba[0], rgba[1], rgba[2], rgba[3])
#
proc setSource*(cr: Context; rgba: tuple[r, g, b, a: float]) =
cairo_set_source_rgba(cr.impl, rgba[0], rgba[1], rgba[2], rgba[3])

proc cairo_surface_get_reference_count*(surface: ptr Surface00): cuint {.importc, libcairo.}
#
Expand Down Expand Up @@ -389,33 +401,53 @@ proc cairo_user_to_device*(cr: ptr Context00; x, y: var cdouble) {.importc, libc
#
proc userToDevice*(cr: Context; x, y: var float) =
var x1, y1: cdouble
(x1, y1) = (x, y)
cairo_user_to_device(cr.impl, x1, y1)
x = x1.float
y = y1.float
#
proc userToDevice*(cr: Context; x, y: float): array[2, float] =
result = [x, y]
cairo_user_to_device(cr.impl, result[0], result[1])

proc cairo_user_to_device_distance*(cr: ptr Context00; dx, dy: var cdouble) {.importc, libcairo.}
#
proc userToDeviceDistance*(cr: Context; dx, dy: var float) =
var dx1, dy1: cdouble
(dx1, dy1) = (dx, dy)
cairo_user_to_device_distance(cr.impl, dx1, dy1)
dx = dx1.float
dy = dy1.float
#
proc userToDeviceDistance*(cr: Context; dx, dy: float): array[2, float] =
result = [dx, dy]
cairo_user_to_device_distance(cr.impl, result[0], result[1])

proc cairo_device_to_user*(cr: ptr Context00; x, y: var cdouble) {.importc, libcairo.}
#
proc deviceToUser*(cr: Context; x, y: var float) =
var x1, y1: cdouble
(x1, y1) = (x, y)
cairo_device_to_user(cr.impl, x1, y1)
x = x1.float
y = y1.float
#
proc deviceToUser*(cr: Context; x, y: float): array[2, float] =
result = [x, y]
cairo_device_to_user(cr.impl, result[0], result[1])

proc cairo_device_to_user_distance*(cr: ptr Context00; dx, dy: var cdouble) {.importc, libcairo.}
#
proc deviceToUserDistance*(cr: Context; dx, dy: var float) =
var dx1, dy1: cdouble
(dx1, dy1) = (dx, dy)
cairo_device_to_user_distance(cr.impl, dx1, dy1)
dx = dx1.float
dy = dy1.float
#
proc deviceToUserDistance*(cr: Context; dx, dy: float): array[2, float] =
result = [dx, dy]
cairo_device_to_user_distance(cr.impl, result[0], result[1])

proc cairo_new_path*(cr: ptr Context00) {.importc, libcairo.}
#
Expand Down

0 comments on commit 68f99d3

Please sign in to comment.