diff --git a/README.adoc b/README.adoc index ef20de8..cbacc7a 100644 --- a/README.adoc +++ b/README.adoc @@ -761,6 +761,56 @@ instead of an external XML files, we have to investigate how we can do that in N And it may be possible to connect the signal handlers to handler procs from within the XML file -- this is also work in progress... +== GAction + +GAction represents a single named action and is for GTK3 the prefered way to do +user interactions. GAction works with button, menus and keyboard shortcuts. + +The following example is based on + +https://wiki.gnome.org/HowDoI/GAction + +[[gaction.nim]] +[source, nim] +.gaction.nim +---- +# https://wiki.gnome.org/HowDoI/GAction +# nim c gaction.nim +import gintro/[gtk, glib, gobject, gio] + +proc saveCb(action: SimpleAction; v: Variant) = + echo "saveCb" + +proc appActivate(app: Application) = + let window = newApplicationWindow(app) + let action = newSimpleAction("save") + discard action.connect("activate", saveCB) + window.actionMap.addAction(action) + let button = newButton() + button.label = "Save" + window.add(button) + button.setActionName("win.save") + var h: cstringArray = allocCstringArray(["S"]) + setAccelsForAction(app, "win.save", h) + deallocCStringArray(h) + showAll(window) + +proc main = + let app = newApplication("org.gtk.example") + connect(app, "activate", appActivate) + discard run(app) + +main() +---- + +GtkApplicationWindow provides an interface to GActionMap. As +the interface itself and the interface provider are defined in different modules, +automatic conversion is not possible, so we have to convert the ApplicationWindow +to ActionMap. (We could use a converter to do the conversion for us, but as +these conversions are rare, and because gintro use no converters at all still, we use +an explicit proc.) The use of cstringArray as third parameter for proc setAccelsForAction() +is a bit ugly, we have to fix that later. + == Drawing with Cairo graphics library The next example shows how we can use the cairo graphics library for drawing on a DrawingArea widget, diff --git a/examples/drawingarea.nim b/examples/drawingarea.nim index 6830845..9f0f910 100644 --- a/examples/drawingarea.nim +++ b/examples/drawingarea.nim @@ -136,13 +136,22 @@ proc paint(this: PDA) = destroy(cr) # we can also manually destroy the context here, but GC would do it for us proc dareaConfigureCallback(darea: DrawingArea; event: EventConfigure; this: PDA): bool = - this.updateAdjustments(0, 0) + #this.updateAdjustments(0, 0) (this.dataX, this.dataY, this.dataWidth, this.dataHeight) = this.extents() # query user defined size this.fullScale = min(this.darea.allocatedWidth.float / this.dataWidth, this.darea.allocatedHeight.float / this.dataHeight) this.paint +proc hscrollbarSizeAllocateCallback(s: Scrollbar; r: gdk.Rectangle; pda: PDA) = + pda.hadjustment.setUpper(r.width.float * pda.userZoom) + pda.hadjustment.setPageSize(r.width.float) + +proc vscrollbarSizeAllocateCallback(s: Scrollbar; r: gdk.Rectangle; pda: PDA) = + pda.vadjustment.setUpper(r.height.float * pda.userZoom) + pda.vadjustment.setPageSize(r.height.float) + + proc updateAdjustmentsAndPaint(this: PDA; dx, dy: float) = this.updateAdjustments(dx, dy) this.paint @@ -246,6 +255,8 @@ proc newPDA: PDA = result.vscrollbar = newScrollbar(Orientation.vertical, result.vadjustment) result.hscrollbar.setHExpand result.vscrollbar.setVExpand + result.hscrollbar.connect("size-allocate", hscrollbarSizeAllocateCallback, result) + result.vscrollbar.connect("size-allocate", vscrollbarSizeAllocateCallback, result) result.attach(result.darea, 0, 0, 1, 1) result.attach(result.vscrollbar, 1, 0, 1, 1) result.attach(result.hscrollbar, 0, 1, 1, 1) diff --git a/examples/gaction.nim b/examples/gaction.nim new file mode 100644 index 0000000..bb32b7c --- /dev/null +++ b/examples/gaction.nim @@ -0,0 +1,27 @@ +# https://wiki.gnome.org/HowDoI/GAction +# nim c gaction.nim +import gintro/[gtk, glib, gobject, gio] + +proc saveCb(action: SimpleAction; v: Variant) = + echo "saveCb" + +proc appActivate(app: Application) = + let window = newApplicationWindow(app) + let action = newSimpleAction("save") + discard action.connect("activate", saveCB) + window.actionMap.addAction(action) + let button = newButton() + button.label = "Save" + window.add(button) + button.setActionName("win.save") + var h: cstringArray = allocCstringArray(["S"]) + setAccelsForAction(app, "win.save", h) + deallocCStringArray(h) + showAll(window) + +proc main = + let app = newApplication("org.gtk.example") + connect(app, "activate", appActivate) + discard run(app) + +main() diff --git a/gintro.nimble b/gintro.nimble index 235f414..186afe7 100644 --- a/gintro.nimble +++ b/gintro.nimble @@ -1,6 +1,6 @@ # Package -version = "0.4.22" +version = "0.4.23" author = "Stefan Salewski" description = "High level GObject-Introspection based GTK3 bindings" license = "MIT" diff --git a/tests/gen.nim b/tests/gen.nim index ac210fb..7856c1c 100644 --- a/tests/gen.nim +++ b/tests/gen.nim @@ -1,5 +1,5 @@ # High level gobject-introspection based GTK3 bindings for the Nim programming language -# v 0.4.22 2019-JUN-05 +# v 0.4.23 2019-JUN-17 # (c) S. Salewski 2018 # https://wiki.gnome.org/Projects/GObjectIntrospection @@ -1829,6 +1829,7 @@ proc main(namespace: string) = classList = newSeq[GIBaseInfo]() output = newStringStream() methodBuffer = newStringStream() + var externInterfaces: seq[string] var error: GError ct = initCountTable[string]() var delayedSyms = newSeq[GIBaseInfo]() @@ -2012,8 +2013,16 @@ proc main(namespace: string) = if ninterfaces > 0: var interf = newSeq[string]() let name = $gBaseInfoGetName(info) - for i in 0.cint ..< ninterfaces: + + var ns = ($gBaseInfoGetNamespace(info.gObjectInfoGetInterface(i))).toLowerAscii + if ns != moduleNamespace: + var iname = $gBaseInfoGetName(info.gObjectInfoGetInterface(i)) + var fname = iname + fname[0] = toLowerAscii(fname[0]) + iname = ns & "." & iname + let tname = moduleNamespace & "." & $gBaseInfoGetName(info) + externInterfaces.add("proc " & fname & "*(x: " & tname & "): " & iname & " = cast[" & iname & "](x)") interf.add($gBaseInfoGetName(info.gObjectInfoGetInterface(i))) if provInt.contains(name): @@ -2028,6 +2037,7 @@ proc main(namespace: string) = else: interfaceProvider[i].add(obj) + #echo "<<<<<<<<<", interfaceProvider["ActionMap"] #@["ApplicationWindow", "Application"] if namespace == "Gdk": # special care for gdk keys due to nim's style insensitivity! for i in s: var h = $gBaseInfoGetName(i) @@ -2143,6 +2153,13 @@ proc main(namespace: string) = for i in delayedSyms: processInfo(i) + if externInterfaces.len > 0: + output.writeLine("\n# Extern interfaces: (we don't use converters, but explicit procs for now.)") + for i in externInterfaces: + output.writeLine("") + output.writeLine(i) + + if namespace == "Gtk": output.write(GTK_EPI) @@ -2222,4 +2239,4 @@ o.close() supmod.close #for i in callerAllocCollector: echo i -# 2233 lines +# 2233 lines interfa