support for GTK 3.98.3
This commit is contained in:
parent
e20c95abf5
commit
a725770ff0
15 changed files with 386 additions and 193 deletions
94
README.adoc
94
README.adoc
|
|
@ -1,6 +1,6 @@
|
||||||
= High level GTK3 (and GTK4) bindings for the Nim programming language
|
= High level GTK3 (and GTK4) bindings for the Nim programming language
|
||||||
(c) Stefan Salewski
|
(c) Stefan Salewski
|
||||||
//Version 0.7.3
|
//Version 0.7.4
|
||||||
:experimental:
|
:experimental:
|
||||||
:imagesdir: http://ssalewski.de/tmp
|
:imagesdir: http://ssalewski.de/tmp
|
||||||
:source-highlighter: pygments
|
:source-highlighter: pygments
|
||||||
|
|
@ -25,7 +25,9 @@ with code inserted from files directly.
|
||||||
NOTE: This work is partly based on earlier works of J. Mansour and has been supported by A. Rumpf, E. Bassi and other _Nim_ and _GTK/Gnome_ developers.
|
NOTE: This work is partly based on earlier works of J. Mansour and has been supported by A. Rumpf, E. Bassi and other _Nim_ and _GTK/Gnome_ developers.
|
||||||
The `combinatorics` module was kindly provided by R. Behrends.
|
The `combinatorics` module was kindly provided by R. Behrends.
|
||||||
|
|
||||||
NOTE: Starting with current version v0.7.3 we allow passing a type descriptor as first parameter to the
|
NOTE: With current version 0.7.4 we support latest GTK 3.98.3 which may become GTK 4 at the end of 2020.
|
||||||
|
|
||||||
|
NOTE: Starting with version v0.7.3 we allow passing a type descriptor as first parameter to the
|
||||||
new() procs like `newButton(MyButtonSubclass)` to support subclassing and extending Widgets in OOP style.
|
new() procs like `newButton(MyButtonSubclass)` to support subclassing and extending Widgets in OOP style.
|
||||||
See <<Extending or sub-classing Widgets>> for an complete example. The init() procs which were used
|
See <<Extending or sub-classing Widgets>> for an complete example. The init() procs which were used
|
||||||
before for this task are now deprecated and will be removed later. This new approach generally saves
|
before for this task are now deprecated and will be removed later. This new approach generally saves
|
||||||
|
|
@ -2723,6 +2725,7 @@ proc main =
|
||||||
## Wait until error or EOS
|
## Wait until error or EOS
|
||||||
bus = gst.getBus(pipeline)
|
bus = gst.getBus(pipeline)
|
||||||
msg = gst.timedPopFiltered(bus, gst.Clock_Time_None, {gst.MessageFlag.error, gst.MessageFlag.eos})
|
msg = gst.timedPopFiltered(bus, gst.Clock_Time_None, {gst.MessageFlag.error, gst.MessageFlag.eos})
|
||||||
|
echo msg.getType
|
||||||
discard gst.setState(pipeline, gst.State.null) # is this necessary?
|
discard gst.setState(pipeline, gst.State.null) # is this necessary?
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|
@ -2752,8 +2755,10 @@ button, but called after gtk4.main(). A bit strange indeed, see forum note of Mr
|
||||||
.headerbar.nim
|
.headerbar.nim
|
||||||
----
|
----
|
||||||
# https://github.com/GNOME/gtk/blob/mainline/tests/testheaderbar.c
|
# https://github.com/GNOME/gtk/blob/mainline/tests/testheaderbar.c
|
||||||
|
# this is still based on the original testheaderbar.c, which was recently replaced by testheaderbar2.c
|
||||||
|
# and testheaderbar.c is not a very good Nim GTK4 example unfortunately -- too comlicated and strange code.
|
||||||
# nim c headerbar.nim
|
# nim c headerbar.nim
|
||||||
import gintro/[gtk4, glib, gobject, gio]
|
import gintro/[gtk4, glib, gobject]
|
||||||
|
|
||||||
const
|
const
|
||||||
Css = """
|
Css = """
|
||||||
|
|
@ -2775,7 +2780,7 @@ const
|
||||||
# we try to avoid use of global header variable as done in C code
|
# we try to avoid use of global header variable as done in C code
|
||||||
type
|
type
|
||||||
MyWindow = ref object of gtk4.Window
|
MyWindow = ref object of gtk4.Window
|
||||||
header: gtk4.Headerbar
|
header: gtk4.Widget
|
||||||
|
|
||||||
proc response(d: gtk4.FileChooserDialog; responseID: int) = gtk4.destroy(d)
|
proc response(d: gtk4.FileChooserDialog; responseID: int) = gtk4.destroy(d)
|
||||||
|
|
||||||
|
|
@ -2787,11 +2792,11 @@ proc onBookmarkClicked(button: Button; data: MyWindow) =
|
||||||
chooser.connect("response", response)
|
chooser.connect("response", response)
|
||||||
chooser.show
|
chooser.show
|
||||||
|
|
||||||
proc changeSubtitle(button: Button; w: MyWindow) =
|
#proc changeSubtitle(button: Button; w: MyWindow) =
|
||||||
if w.header.subtitle == "":
|
# if w.header.subtitle == "":
|
||||||
w.header.setSubtitle("(subtle subtitle)")
|
# w.header.setSubtitle("(subtle subtitle)")
|
||||||
else:
|
# else:
|
||||||
w.header.setSubtitle("") # can we pass nil?
|
# w.header.setSubtitle("") # can we pass nil?
|
||||||
|
|
||||||
proc toggleFullscreen(button: Button; window: MyWindow) =
|
proc toggleFullscreen(button: Button; window: MyWindow) =
|
||||||
var fullscreen {.global.}: bool
|
var fullscreen {.global.}: bool
|
||||||
|
|
@ -2807,68 +2812,85 @@ proc toIntVal(i: int): Value =
|
||||||
discard init(result, gtype)
|
discard init(result, gtype)
|
||||||
setInt(result, i)
|
setInt(result, i)
|
||||||
|
|
||||||
proc quit(b: Button) = gtk4.mainQuit()
|
var done = false
|
||||||
|
|
||||||
|
proc quit_cb(b: Button) = # we can not pass a var parameter
|
||||||
|
#gtk4.mainQuit()
|
||||||
|
done = true
|
||||||
|
wakeup(defaultMainContext()) # g_main_context_wakeup (NULL);
|
||||||
|
|
||||||
proc changeHeader(button: ToggleButton; window: MyWindow) =
|
proc changeHeader(button: ToggleButton; window: MyWindow) =
|
||||||
if button != nil and button.getActive:
|
if button != nil and button.getActive:
|
||||||
window.header = cast[HeaderBar](newBox(gtk4.Orientation.horizontal,
|
window.header = (newBox(gtk4.Orientation.horizontal,
|
||||||
10)) # intended cast, see C code!
|
10))
|
||||||
addClass(getStyleContext(window.header), "titlebar")
|
addCssClass(window.header, "titlebar")
|
||||||
addClass(getStyleContext(window.header), "header-bar")
|
addCssClass(window.header, "header-bar")
|
||||||
window.header.setProperty("margin", toIntVal(10))
|
#window.header.setProperty("margin_start", toIntVal(10))
|
||||||
|
#window.header.setProperty("margin_end", toIntVal(10))
|
||||||
|
#window.header.setProperty("margin_top", toIntVal(10))
|
||||||
|
#window.header.setProperty("margin_bottom", toIntVal(10))
|
||||||
|
window.header.setMarginStart(10)
|
||||||
|
window.header.setMarginEnd(10)
|
||||||
|
window.header.setMarginTop(10)
|
||||||
|
window.header.setMarginBottom(10)
|
||||||
let label = newLabel("Label")
|
let label = newLabel("Label")
|
||||||
window.header.add(label)
|
gtk4.Box(window.header).append(label)
|
||||||
let levelBar = newLevelBar()
|
let levelBar = newLevelBar()
|
||||||
levelBar.setValue(0.4)
|
levelBar.setValue(0.4)
|
||||||
levelBar.setHexpand
|
levelBar.setHexpand
|
||||||
window.header.add(levelBar)
|
gtk4.Box(window.header).append(levelBar)
|
||||||
else:
|
else:
|
||||||
window.header = newHeaderBar()
|
window.header = newHeaderBar()
|
||||||
addClass(getStyleContext(window.header), "titlebar")
|
#addClass(getStyleContext(window.header), "titlebar")
|
||||||
window.header.setTitle("Example header")
|
addCssClass(window.header, "titlebar")
|
||||||
|
#window.header.setTitle("Example header")
|
||||||
var button = newButton("_Close")
|
var button = newButton("_Close")
|
||||||
button.setUseUnderline
|
button.setUseUnderline
|
||||||
addClass(getStyleContext(button), "suggested-action")
|
addCssClass(button, "suggested-action")
|
||||||
button.connect("clicked", quit)
|
button.connect("clicked", quit_cb)
|
||||||
window.header.packEnd(button)
|
gtk4.HeaderBar(window.header).packEnd(button)
|
||||||
button = newButton()
|
button = newButton()
|
||||||
let image = newImageFromIconName("bookmark-new-symbolic")
|
let image = newImageFromIconName("bookmark-new-symbolic")
|
||||||
button.connect("clicked", onBookmarkClicked, window)
|
button.connect("clicked", onBookmarkClicked, window)
|
||||||
button.add(image)
|
button.setChild(image)
|
||||||
window.header.packStart(button)
|
gtk4.HeaderBar(window.header).packStart(button)
|
||||||
window.setTitlebar(window.header)
|
window.setTitlebar(window.header)
|
||||||
|
|
||||||
proc main =
|
proc main =
|
||||||
gtk4.init()
|
gtk4.init()
|
||||||
var window: MyWindow
|
#var window: MyWindow
|
||||||
initWindow(window)
|
let window = newWindow(MyWindow)
|
||||||
addClass(getStyleContext(window), "main")
|
addCssClass(window, "main") # gtk_widget_add_css_class (window, "main");
|
||||||
let provider = newCssProvider()
|
let provider = newCssProvider()
|
||||||
provider.loadFromData(Css)
|
provider.loadFromData(Css)
|
||||||
addProviderForDisplay(getDisplay(window), provider, STYLE_PROVIDER_PRIORITY_USER)
|
addProviderForDisplay(getDisplay(window), provider, STYLE_PROVIDER_PRIORITY_USER)
|
||||||
changeHeader(nil, window)
|
changeHeader(nil, window)
|
||||||
let box = newBox(Orientation.vertical, 0)
|
let box = newBox(Orientation.vertical, 0)
|
||||||
window.add(box)
|
window.setChild(box) # gtk_window_set_child (GTK_WINDOW (window), box);
|
||||||
|
#window.add(box)
|
||||||
let content = newImageFromIconName("start-here-symbolic")
|
let content = newImageFromIconName("start-here-symbolic")
|
||||||
content.setPixelSize(512)
|
content.setPixelSize(512)
|
||||||
box.add(content)
|
content.setVexpand
|
||||||
|
box.append(content)
|
||||||
let footer = newActionBar()
|
let footer = newActionBar()
|
||||||
footer.setCenterWidget(newCheckButtonWithLabel("Middle"))
|
footer.setCenterWidget(newCheckButtonWithLabel("Middle"))
|
||||||
let button = newToggleButtonWithLabel("Custom")
|
let button = newToggleButtonWithLabel("Custom")
|
||||||
button.connect("clicked", changeHeader, window)
|
button.connect("clicked", changeHeader, window)
|
||||||
footer.packStart(button)
|
footer.packStart(button)
|
||||||
var button1 = newButton("Subtitle")
|
#var button1 = newButton("Subtitle")
|
||||||
button1.connect("clicked", changeSubtitle, window)
|
#button1.connect("clicked", changeSubtitle, window)
|
||||||
footer.packEnd(button1)
|
#footer.packEnd(button1)
|
||||||
button1 = newButton("Fullscreen")
|
var button1 = newButton("Fullscreen")
|
||||||
footer.packEnd(button1)
|
footer.packEnd(button1)
|
||||||
button1.connect("clicked", toggleFullscreen, window)
|
button1.connect("clicked", toggleFullscreen, window)
|
||||||
box.add(footer)
|
box.append(footer)
|
||||||
window.show
|
window.show
|
||||||
gtk4.main()
|
#gtk4.main()
|
||||||
|
while not done:
|
||||||
|
discard iteration(defaultMainContext(), true) # g_main_context_iteration (NULL, TRUE);
|
||||||
destroy(window) # this is special for this example, see https://discourse.gnome.org/t/tests-testgaction-c/2232/6
|
destroy(window) # this is special for this example, see https://discourse.gnome.org/t/tests-testgaction-c/2232/6
|
||||||
|
|
||||||
main() # 118 lines
|
main() # 137 lines
|
||||||
----
|
----
|
||||||
|
|
||||||
NOTE: Related work: https://github.com/jdmansour/nim-smartgi
|
NOTE: Related work: https://github.com/jdmansour/nim-smartgi
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# app0.nim -- minimal application style example
|
# app0.nim -- minimal application style example
|
||||||
# nim c app0.nim
|
# nim c app0.nim
|
||||||
import gintro/[gtk, glib, gobject, gio]
|
import gintro/[gtk, gobject, gio]
|
||||||
|
|
||||||
proc appActivate(app: Application) =
|
proc appActivate(app: Application) =
|
||||||
let window = newApplicationWindow(app)
|
let window = newApplicationWindow(app)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
# https://developer.gnome.org/gtk3/stable/ch01s03.html
|
# https://developer.gnome.org/gtk3/stable/ch01s03.html
|
||||||
# builder.nim -- application style example using builder/glade xml file for user interface
|
# builder.nim -- application style example using builder/glade xml file for user interface
|
||||||
# nim c builder.nim
|
# nim c builder.nim
|
||||||
import gintro/[gtk, glib, gobject, gio]
|
import gintro/[gtk, gobject, gio]
|
||||||
|
|
||||||
proc hello(b: Button; msg: string) =
|
proc hello(b: Button; msg: string) =
|
||||||
echo "Hello", msg
|
echo "Hello", msg
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# This example shows how to apply a CellDataFunc to a GtkTreeView
|
# This example shows how to apply a CellDataFunc to a GtkTreeView
|
||||||
# C example code was provided by A.Krause in chapter 8 of his book
|
# C example code was provided by A.Krause in chapter 8 of his book
|
||||||
import gintro/[gtk, gobject, glib]
|
import gintro/[gtk, gobject]
|
||||||
|
|
||||||
const
|
const
|
||||||
Color = 0
|
Color = 0
|
||||||
|
|
|
||||||
55
examples/gtk3/colorpickers.nim
Normal file
55
examples/gtk3/colorpickers.nim
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
# nim c button.nim
|
||||||
|
import gintro/[gtk, glib, gobject, gio, cairo]
|
||||||
|
from math import Tau
|
||||||
|
|
||||||
|
type
|
||||||
|
ColorPicker = ref object of Button
|
||||||
|
c: array[4, float]
|
||||||
|
|
||||||
|
proc newColorPicker(c: array[4, float]): ColorPicker =
|
||||||
|
result = newButton(ColorPicker)
|
||||||
|
result.c = c
|
||||||
|
|
||||||
|
proc buttonClicked (button: ColorPicker) =
|
||||||
|
#button.label = utf8Strreverse(button.label, -1)
|
||||||
|
echo "clicked"
|
||||||
|
|
||||||
|
proc draw(b: ColorPicker; cr: cairo.Context): bool =
|
||||||
|
echo "draw"
|
||||||
|
let x = getAllocatedWidth(b).float / 2
|
||||||
|
let y = getAllocatedHeight(b).float / 2
|
||||||
|
cr.moveTo(x, y)
|
||||||
|
cr.newPath
|
||||||
|
cr.arc(x, y, 10, 0, math.Tau)
|
||||||
|
cr.setSource(b.c)
|
||||||
|
cr.setLineWidth(5)
|
||||||
|
cr.stroke
|
||||||
|
|
||||||
|
proc appActivate (app: Application) =
|
||||||
|
let window = newApplicationWindow(app)
|
||||||
|
window.title = "GNOME Button"
|
||||||
|
window.defaultSize = (250, 50)
|
||||||
|
let box = newBox(Orientation.horizontal, 0)
|
||||||
|
var button = newColorPicker([1.0, 0, 0, 1])#newButton(ColorPicker)#"Click Me")
|
||||||
|
box.add(button)
|
||||||
|
button.connect("clicked", buttonClicked)
|
||||||
|
button.connectAfter("draw", draw)
|
||||||
|
button = newColorPicker([0.0, 0, 1, 1])#newButton(ColorPicker)#"Click Me")
|
||||||
|
box.add(button)
|
||||||
|
button.connect("clicked", buttonClicked)
|
||||||
|
button.connectAfter("draw", draw)
|
||||||
|
button = newColorPicker([0.0, 1, 0, 1])#newButton(ColorPicker)#"Click Me")
|
||||||
|
box.add(button)
|
||||||
|
button.connect("clicked", buttonClicked)
|
||||||
|
button.connectAfter("draw", draw)
|
||||||
|
window.add(box)
|
||||||
|
|
||||||
|
window.showAll
|
||||||
|
|
||||||
|
proc main =
|
||||||
|
let app = newApplication("org.gtk.example")
|
||||||
|
connect(app, "activate", appActivate)
|
||||||
|
discard app.run
|
||||||
|
|
||||||
|
main()
|
||||||
|
|
||||||
|
|
@ -60,7 +60,7 @@ type
|
||||||
handlerID: uint64
|
handlerID: uint64
|
||||||
|
|
||||||
proc newPosAdj: PosAdj =
|
proc newPosAdj: PosAdj =
|
||||||
initAdjustment(result, 0, 0, 1, 1, 10, 1)
|
newAdjustment(PosAdj, 0, 0, 1, 1, 10, 1)
|
||||||
|
|
||||||
type
|
type
|
||||||
PDA_Data* = object
|
PDA_Data* = object
|
||||||
|
|
@ -104,7 +104,7 @@ proc drawingAreaDrawCb(darea: DrawingArea; cr: Context; this: PDA): bool =
|
||||||
if this.selecting:
|
if this.selecting:
|
||||||
cr.rectangle(this.lastButtonDownPosX, this.lastButtonDownPosY,
|
cr.rectangle(this.lastButtonDownPosX, this.lastButtonDownPosY,
|
||||||
this.zoomRectX1 - this.lastButtonDownPosX, this.zoomRectY1 - this.lastButtonDownPosY)
|
this.zoomRectX1 - this.lastButtonDownPosX, this.zoomRectY1 - this.lastButtonDownPosY)
|
||||||
cr.setSource(0, 0, 1, 0.5) # SELECT_RECT_COL) # 0, 0, 1, 0.5
|
cr.setSource(SelectRectCol) # SELECT_RECT_COL) # 0, 0, 1, 0.5
|
||||||
cr.fillPreserve
|
cr.fillPreserve
|
||||||
cr.setSource(0, 0, 0)
|
cr.setSource(0, 0, 0)
|
||||||
cr.setLineWidth(2)
|
cr.setLineWidth(2)
|
||||||
|
|
@ -256,7 +256,7 @@ proc onAdjustmentEvent(this: PosAdj; pda: PDA) =
|
||||||
pda.darea.queueDrawArea(0, 0, pda.darea.allocatedWidth, pda.darea.allocatedHeight)
|
pda.darea.queueDrawArea(0, 0, pda.darea.allocatedWidth, pda.darea.allocatedHeight)
|
||||||
|
|
||||||
proc newPDA: PDA =
|
proc newPDA: PDA =
|
||||||
initGrid(result)
|
result = newGrid(PDA)
|
||||||
let da = newDrawingArea()
|
let da = newDrawingArea()
|
||||||
result.darea = da
|
result.darea = da
|
||||||
da.setHExpand
|
da.setHExpand
|
||||||
|
|
|
||||||
|
|
@ -62,9 +62,9 @@ proc radio(action: SimpleAction; parameter: Variant; label: Label) =
|
||||||
let str: string = "From Radio menu item " & getString(newState, l)
|
let str: string = "From Radio menu item " & getString(newState, l)
|
||||||
label.setLabel(str)
|
label.setLabel(str)
|
||||||
|
|
||||||
proc bye(w: Window) =
|
#proc bye(w: Window) =
|
||||||
mainQuit()
|
# mainQuit()
|
||||||
echo "Bye..."
|
# echo "Bye..."
|
||||||
|
|
||||||
proc main =
|
proc main =
|
||||||
gtk.init()
|
gtk.init()
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
# gsettings.nim -- basic use of gsettings
|
# gsettings.nim -- basic use of gsettings
|
||||||
# nim c gsettings.nim
|
# nim c gsettings.nim
|
||||||
# https://blog.gtk.org/2017/05/01/first-steps-with-gsettings/
|
# https://blog.gtk.org/2017/05/01/first-steps-with-gsettings/
|
||||||
import gintro/[gtk, glib, gobject, gio]
|
import gintro/[gtk, gobject, gio]
|
||||||
|
|
||||||
# unused
|
# unused
|
||||||
proc toggle(b: CheckButton) =
|
#proc toggle(b: CheckButton) =
|
||||||
echo b.active
|
# echo b.active
|
||||||
let s = newSettings("org.gnome.Recipes")
|
# let s = newSettings("org.gnome.Recipes")
|
||||||
discard s.setBoolean("like-nim", b.active)
|
# discard s.setBoolean("like-nim", b.active)
|
||||||
|
|
||||||
proc appActivate(app: Application) =
|
proc appActivate(app: Application) =
|
||||||
let window = newApplicationWindow(app)
|
let window = newApplicationWindow(app)
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ proc main =
|
||||||
## Wait until error or EOS
|
## Wait until error or EOS
|
||||||
bus = gst.getBus(pipeline)
|
bus = gst.getBus(pipeline)
|
||||||
msg = gst.timedPopFiltered(bus, gst.Clock_Time_None, {gst.MessageFlag.error, gst.MessageFlag.eos})
|
msg = gst.timedPopFiltered(bus, gst.Clock_Time_None, {gst.MessageFlag.error, gst.MessageFlag.eos})
|
||||||
|
echo msg.getType
|
||||||
discard gst.setState(pipeline, gst.State.null) # is this necessary?
|
discard gst.setState(pipeline, gst.State.null) # is this necessary?
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ type
|
||||||
handlerID: uint64
|
handlerID: uint64
|
||||||
|
|
||||||
proc newPosAdj: PosAdj =
|
proc newPosAdj: PosAdj =
|
||||||
initAdjustment(result, 0, 0, 1, 1, 10, 1)
|
newAdjustment(PosAdj, 0, 0, 1, 1, 10, 1)
|
||||||
|
|
||||||
type
|
type
|
||||||
PDA_Data* = object
|
PDA_Data* = object
|
||||||
|
|
@ -98,7 +98,7 @@ proc drawingAreaDrawCb(darea: DrawingArea; cr: Context; this: PDA): bool =
|
||||||
if this.selecting:
|
if this.selecting:
|
||||||
cr.rectangle(this.lastButtonDownPosX, this.lastButtonDownPosY,
|
cr.rectangle(this.lastButtonDownPosX, this.lastButtonDownPosY,
|
||||||
this.zoomRectX1 - this.lastButtonDownPosX, this.zoomRectY1 - this.lastButtonDownPosY)
|
this.zoomRectX1 - this.lastButtonDownPosX, this.zoomRectY1 - this.lastButtonDownPosY)
|
||||||
cr.setSource(0, 0, 1, 0.5) # SELECT_RECT_COL) # 0, 0, 1, 0.5
|
cr.setSource(SelectRectCol) # SELECT_RECT_COL) # 0, 0, 1, 0.5
|
||||||
cr.fillPreserve
|
cr.fillPreserve
|
||||||
cr.setSource(0, 0, 0)
|
cr.setSource(0, 0, 0)
|
||||||
cr.setLineWidth(2)
|
cr.setLineWidth(2)
|
||||||
|
|
@ -227,7 +227,7 @@ proc onAdjustmentEvent(this: PosAdj; pda: PDA) =
|
||||||
pda.darea.queueDrawArea(0, 0, pda.darea.allocatedWidth, pda.darea.allocatedHeight)
|
pda.darea.queueDrawArea(0, 0, pda.darea.allocatedWidth, pda.darea.allocatedHeight)
|
||||||
|
|
||||||
proc newPDA: PDA =
|
proc newPDA: PDA =
|
||||||
initGrid(result)
|
result = newGrid(PDA)
|
||||||
let da = newDrawingArea()
|
let da = newDrawingArea()
|
||||||
result.darea = da
|
result.darea = da
|
||||||
da.setHExpand
|
da.setHExpand
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import gintro/[gtk, glib, gobject, gio, gtksource]
|
import gintro/[gtk, gobject, gio, gtksource]
|
||||||
|
|
||||||
proc appActivate (app: Application) =
|
proc appActivate (app: Application) =
|
||||||
let window = newApplicationWindow(app)
|
let window = newApplicationWindow(app)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# app0.nim -- minimal application style example
|
# app0.nim -- minimal application style example
|
||||||
# nim c app0.nim
|
# nim c app0.nim
|
||||||
import gintro/[gtk4, glib, gobject, gio]
|
import gintro/[gtk4, gobject, gio]
|
||||||
|
|
||||||
proc appActivate(app: Application) =
|
proc appActivate(app: Application) =
|
||||||
let window = newApplicationWindow(app)
|
let window = newApplicationWindow(app)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
# https://github.com/GNOME/gtk/blob/mainline/tests/testheaderbar.c
|
# https://github.com/GNOME/gtk/blob/mainline/tests/testheaderbar.c
|
||||||
|
# this is still based on the original testheaderbar.c, which was recently replaced by testheaderbar2.c
|
||||||
|
# and testheaderbar.c is not a very good Nim GTK4 example unfortunately -- too comlicated and strange code.
|
||||||
# nim c headerbar.nim
|
# nim c headerbar.nim
|
||||||
import gintro/[gtk4, glib, gobject, gio]
|
import gintro/[gtk4, glib, gobject]
|
||||||
|
|
||||||
const
|
const
|
||||||
Css = """
|
Css = """
|
||||||
|
|
@ -22,7 +24,7 @@ const
|
||||||
# we try to avoid use of global header variable as done in C code
|
# we try to avoid use of global header variable as done in C code
|
||||||
type
|
type
|
||||||
MyWindow = ref object of gtk4.Window
|
MyWindow = ref object of gtk4.Window
|
||||||
header: gtk4.Headerbar
|
header: gtk4.Widget
|
||||||
|
|
||||||
proc response(d: gtk4.FileChooserDialog; responseID: int) = gtk4.destroy(d)
|
proc response(d: gtk4.FileChooserDialog; responseID: int) = gtk4.destroy(d)
|
||||||
|
|
||||||
|
|
@ -34,11 +36,11 @@ proc onBookmarkClicked(button: Button; data: MyWindow) =
|
||||||
chooser.connect("response", response)
|
chooser.connect("response", response)
|
||||||
chooser.show
|
chooser.show
|
||||||
|
|
||||||
proc changeSubtitle(button: Button; w: MyWindow) =
|
#proc changeSubtitle(button: Button; w: MyWindow) =
|
||||||
if w.header.subtitle == "":
|
# if w.header.subtitle == "":
|
||||||
w.header.setSubtitle("(subtle subtitle)")
|
# w.header.setSubtitle("(subtle subtitle)")
|
||||||
else:
|
# else:
|
||||||
w.header.setSubtitle("") # can we pass nil?
|
# w.header.setSubtitle("") # can we pass nil?
|
||||||
|
|
||||||
proc toggleFullscreen(button: Button; window: MyWindow) =
|
proc toggleFullscreen(button: Button; window: MyWindow) =
|
||||||
var fullscreen {.global.}: bool
|
var fullscreen {.global.}: bool
|
||||||
|
|
@ -54,65 +56,82 @@ proc toIntVal(i: int): Value =
|
||||||
discard init(result, gtype)
|
discard init(result, gtype)
|
||||||
setInt(result, i)
|
setInt(result, i)
|
||||||
|
|
||||||
proc quit(b: Button) = gtk4.mainQuit()
|
var done = false
|
||||||
|
|
||||||
|
proc quit_cb(b: Button) = # we can not pass a var parameter
|
||||||
|
#gtk4.mainQuit()
|
||||||
|
done = true
|
||||||
|
wakeup(defaultMainContext()) # g_main_context_wakeup (NULL);
|
||||||
|
|
||||||
proc changeHeader(button: ToggleButton; window: MyWindow) =
|
proc changeHeader(button: ToggleButton; window: MyWindow) =
|
||||||
if button != nil and button.getActive:
|
if button != nil and button.getActive:
|
||||||
window.header = cast[HeaderBar](newBox(gtk4.Orientation.horizontal,
|
window.header = (newBox(gtk4.Orientation.horizontal,
|
||||||
10)) # intended cast, see C code!
|
10))
|
||||||
addClass(getStyleContext(window.header), "titlebar")
|
addCssClass(window.header, "titlebar")
|
||||||
addClass(getStyleContext(window.header), "header-bar")
|
addCssClass(window.header, "header-bar")
|
||||||
window.header.setProperty("margin", toIntVal(10))
|
#window.header.setProperty("margin_start", toIntVal(10))
|
||||||
|
#window.header.setProperty("margin_end", toIntVal(10))
|
||||||
|
#window.header.setProperty("margin_top", toIntVal(10))
|
||||||
|
#window.header.setProperty("margin_bottom", toIntVal(10))
|
||||||
|
window.header.setMarginStart(10)
|
||||||
|
window.header.setMarginEnd(10)
|
||||||
|
window.header.setMarginTop(10)
|
||||||
|
window.header.setMarginBottom(10)
|
||||||
let label = newLabel("Label")
|
let label = newLabel("Label")
|
||||||
window.header.add(label)
|
gtk4.Box(window.header).append(label)
|
||||||
let levelBar = newLevelBar()
|
let levelBar = newLevelBar()
|
||||||
levelBar.setValue(0.4)
|
levelBar.setValue(0.4)
|
||||||
levelBar.setHexpand
|
levelBar.setHexpand
|
||||||
window.header.add(levelBar)
|
gtk4.Box(window.header).append(levelBar)
|
||||||
else:
|
else:
|
||||||
window.header = newHeaderBar()
|
window.header = newHeaderBar()
|
||||||
addClass(getStyleContext(window.header), "titlebar")
|
#addClass(getStyleContext(window.header), "titlebar")
|
||||||
window.header.setTitle("Example header")
|
addCssClass(window.header, "titlebar")
|
||||||
|
#window.header.setTitle("Example header")
|
||||||
var button = newButton("_Close")
|
var button = newButton("_Close")
|
||||||
button.setUseUnderline
|
button.setUseUnderline
|
||||||
addClass(getStyleContext(button), "suggested-action")
|
addCssClass(button, "suggested-action")
|
||||||
button.connect("clicked", quit)
|
button.connect("clicked", quit_cb)
|
||||||
window.header.packEnd(button)
|
gtk4.HeaderBar(window.header).packEnd(button)
|
||||||
button = newButton()
|
button = newButton()
|
||||||
let image = newImageFromIconName("bookmark-new-symbolic")
|
let image = newImageFromIconName("bookmark-new-symbolic")
|
||||||
button.connect("clicked", onBookmarkClicked, window)
|
button.connect("clicked", onBookmarkClicked, window)
|
||||||
button.add(image)
|
button.setChild(image)
|
||||||
window.header.packStart(button)
|
gtk4.HeaderBar(window.header).packStart(button)
|
||||||
window.setTitlebar(window.header)
|
window.setTitlebar(window.header)
|
||||||
|
|
||||||
proc main =
|
proc main =
|
||||||
gtk4.init()
|
gtk4.init()
|
||||||
var window: MyWindow
|
#var window: MyWindow
|
||||||
initWindow(window)
|
let window = newWindow(MyWindow)
|
||||||
addClass(getStyleContext(window), "main")
|
addCssClass(window, "main") # gtk_widget_add_css_class (window, "main");
|
||||||
let provider = newCssProvider()
|
let provider = newCssProvider()
|
||||||
provider.loadFromData(Css)
|
provider.loadFromData(Css)
|
||||||
addProviderForDisplay(getDisplay(window), provider, STYLE_PROVIDER_PRIORITY_USER)
|
addProviderForDisplay(getDisplay(window), provider, STYLE_PROVIDER_PRIORITY_USER)
|
||||||
changeHeader(nil, window)
|
changeHeader(nil, window)
|
||||||
let box = newBox(Orientation.vertical, 0)
|
let box = newBox(Orientation.vertical, 0)
|
||||||
window.add(box)
|
window.setChild(box) # gtk_window_set_child (GTK_WINDOW (window), box);
|
||||||
|
#window.add(box)
|
||||||
let content = newImageFromIconName("start-here-symbolic")
|
let content = newImageFromIconName("start-here-symbolic")
|
||||||
content.setPixelSize(512)
|
content.setPixelSize(512)
|
||||||
box.add(content)
|
content.setVexpand
|
||||||
|
box.append(content)
|
||||||
let footer = newActionBar()
|
let footer = newActionBar()
|
||||||
footer.setCenterWidget(newCheckButtonWithLabel("Middle"))
|
footer.setCenterWidget(newCheckButtonWithLabel("Middle"))
|
||||||
let button = newToggleButtonWithLabel("Custom")
|
let button = newToggleButtonWithLabel("Custom")
|
||||||
button.connect("clicked", changeHeader, window)
|
button.connect("clicked", changeHeader, window)
|
||||||
footer.packStart(button)
|
footer.packStart(button)
|
||||||
var button1 = newButton("Subtitle")
|
#var button1 = newButton("Subtitle")
|
||||||
button1.connect("clicked", changeSubtitle, window)
|
#button1.connect("clicked", changeSubtitle, window)
|
||||||
footer.packEnd(button1)
|
#footer.packEnd(button1)
|
||||||
button1 = newButton("Fullscreen")
|
var button1 = newButton("Fullscreen")
|
||||||
footer.packEnd(button1)
|
footer.packEnd(button1)
|
||||||
button1.connect("clicked", toggleFullscreen, window)
|
button1.connect("clicked", toggleFullscreen, window)
|
||||||
box.add(footer)
|
box.append(footer)
|
||||||
window.show
|
window.show
|
||||||
gtk4.main()
|
#gtk4.main()
|
||||||
|
while not done:
|
||||||
|
discard iteration(defaultMainContext(), true) # g_main_context_iteration (NULL, TRUE);
|
||||||
destroy(window) # this is special for this example, see https://discourse.gnome.org/t/tests-testgaction-c/2232/6
|
destroy(window) # this is special for this example, see https://discourse.gnome.org/t/tests-testgaction-c/2232/6
|
||||||
|
|
||||||
main() # 118 lines
|
main() # 137 lines
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# Package
|
# Package
|
||||||
|
|
||||||
version = "0.7.3"
|
version = "0.7.4"
|
||||||
author = "Stefan Salewski"
|
author = "Stefan Salewski"
|
||||||
description = "High level GObject-Introspection based GTK3/GTK4 bindings"
|
description = "High level GObject-Introspection based GTK3/GTK4 bindings"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
|
||||||
302
tests/gen.nim
302
tests/gen.nim
|
|
@ -1,6 +1,6 @@
|
||||||
# High level gobject-introspection based GTK3/GTK4 bindings for the Nim programming language
|
# High level gobject-introspection based GTK3/GTK4 bindings for the Nim programming language
|
||||||
# nimpretty --maxLineLen:130 gen.nim
|
# nimpretty --maxLineLen:130 gen.nim
|
||||||
# v 0.7.3 2020-MAR-09
|
# v 0.7.4 2020-MAY-19
|
||||||
# (c) S. Salewski 2018
|
# (c) S. Salewski 2018
|
||||||
|
|
||||||
# https://wiki.gnome.org/Projects/GObjectIntrospection
|
# https://wiki.gnome.org/Projects/GObjectIntrospection
|
||||||
|
|
@ -33,9 +33,7 @@
|
||||||
|
|
||||||
# This module is really ugly currently -- the first goal was to get a working gi solution
|
# This module is really ugly currently -- the first goal was to get a working gi solution
|
||||||
|
|
||||||
# NOTE: Currently we support subclassing only for constructor functions like gtk_button_new() -- for
|
# NOTE: Currently we support subclassing only for constructor functions like gtk_button_new()
|
||||||
# these we provide an initButton() additional to the well know newButton(). Maybe other functions
|
|
||||||
# with a result variable that we may intent to subclass should get a init() variant also...
|
|
||||||
|
|
||||||
from os import `/`, paramCount
|
from os import `/`, paramCount
|
||||||
import gir, gobject, glib
|
import gir, gobject, glib
|
||||||
|
|
@ -167,6 +165,8 @@ var allSyms: HashSet[string]
|
||||||
var droppedSyms: HashSet[string]
|
var droppedSyms: HashSet[string]
|
||||||
var privStr: HashSet[string]
|
var privStr: HashSet[string]
|
||||||
var processedFunctions: HashSet[string]
|
var processedFunctions: HashSet[string]
|
||||||
|
var useTempProcessedFunctions: bool
|
||||||
|
var tempProcessedFunctions: seq[string]
|
||||||
var knownSyms: HashSet[string]
|
var knownSyms: HashSet[string]
|
||||||
|
|
||||||
var gdkKeys: Table[string, seq[string]]
|
var gdkKeys: Table[string, seq[string]]
|
||||||
|
|
@ -210,9 +210,14 @@ fixedProcNames.add("gtk_settings_get_for_display", "getSettingsForDisplay")
|
||||||
fixedProcNames.add("gtk_icon_theme_get_for_display", "getIconThemeForDisplay")
|
fixedProcNames.add("gtk_icon_theme_get_for_display", "getIconThemeForDisplay")
|
||||||
fixedProcNames.add("gst_element_factory_find", "findElementFactory")
|
fixedProcNames.add("gst_element_factory_find", "findElementFactory")
|
||||||
|
|
||||||
|
fixedProcNames.add("gtk_shortcut_action_parse_string", "shortcutActionParseString")
|
||||||
|
fixedProcNames.add("gtk_shortcut_trigger_parse_string", "shortcutTriggerParseString")
|
||||||
|
fixedProcNames.add("g_main_context_default", "defaultMainContext")
|
||||||
|
|
||||||
defaultParameters.add("gtk_window_new", "`type` WindowType WindowType.toplevel")
|
defaultParameters.add("gtk_window_new", "`type` WindowType WindowType.toplevel")
|
||||||
defaultParameters.add("gtk_application_new", "flags gio.ApplicationFlags {}")
|
defaultParameters.add("gtk_application_new", "flags gio.ApplicationFlags {}")
|
||||||
defaultParameters.add("gtk_builder_new_from_string", "length int64 -1")
|
defaultParameters.add("gtk_builder_new_from_string", "length int64 -1")
|
||||||
|
defaultParameters.add("gtk_box_new", "spacing int32 0")
|
||||||
|
|
||||||
for i in keywords: mangledNames.add(i, '`' & i & '`')
|
for i in keywords: mangledNames.add(i, '`' & i & '`')
|
||||||
|
|
||||||
|
|
@ -340,10 +345,11 @@ graphene.Euler
|
||||||
#cairo.Matrix
|
#cairo.Matrix
|
||||||
cairo.Rectangle
|
cairo.Rectangle
|
||||||
cairo.RectangleInt
|
cairo.RectangleInt
|
||||||
|
gsk.RoundedRect
|
||||||
""".split.toHashSet
|
""".split.toHashSet
|
||||||
|
|
||||||
type
|
type
|
||||||
UndefEx = object of Exception
|
UndefEx = object of CatchableError
|
||||||
|
|
||||||
proc mangleType(s: cstring): string =
|
proc mangleType(s: cstring): string =
|
||||||
result = mangleName(s)
|
result = mangleName(s)
|
||||||
|
|
@ -534,7 +540,10 @@ proc genPars(info: GICallableInfo; genProxy = false; binfo: GIBaseInfo = nil): (
|
||||||
self = "(self: " & manglename(gBaseInfoGetName(binfo)) & "; "
|
self = "(self: " & manglename(gBaseInfoGetName(binfo)) & "; "
|
||||||
arglist = "(self"
|
arglist = "(self"
|
||||||
else:
|
else:
|
||||||
arglist = "(cast[ptr " & manglename(gBaseInfoGetName(binfo)) & "00](" & "self.impl)"
|
## only for very few procs the instance variable itself can be NULL in GTK. We assume non NULL and may provide an overload.
|
||||||
|
arglist = "(cast[ptr " & manglename(gBaseInfoGetName(binfo)) & "00](" &
|
||||||
|
"self.impl)" # https://discourse.gnome.org/t/g-arg-info-may-be-null-for-the-instace-itself/3284/7
|
||||||
|
# arglist = "(if self.isNil: nil else: cast[ptr " & manglename(gBaseInfoGetName(binfo)) & "00](" & "self.impl)"
|
||||||
if genProxy:
|
if genProxy:
|
||||||
var h = manglename(gBaseInfoGetName(binfo))
|
var h = manglename(gBaseInfoGetName(binfo))
|
||||||
let provider = interfaceProvider.getOrDefault(h, @[])
|
let provider = interfaceProvider.getOrDefault(h, @[])
|
||||||
|
|
@ -759,6 +768,18 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
|
||||||
if boxedFreeMeName == "gBoxedFreeGVariantType": # this does not work
|
if boxedFreeMeName == "gBoxedFreeGVariantType": # this does not work
|
||||||
assert false
|
assert false
|
||||||
|
|
||||||
|
if gBaseInfoGetType(info) == GIInfoType.Object:
|
||||||
|
assert(gObjectInfoGetFundamental(info) == GTrue)
|
||||||
|
var parent = info
|
||||||
|
while true:
|
||||||
|
let h = g_object_info_get_parent(parent)
|
||||||
|
if h == nil:
|
||||||
|
break
|
||||||
|
parent = h
|
||||||
|
boxedFreeMeName = ""
|
||||||
|
freeMeName = "generic_" & $g_object_info_get_unref_function(parent)
|
||||||
|
assert(freeMeName != "")
|
||||||
|
|
||||||
# assert(info != nil) # why can it be nil?
|
# assert(info != nil) # why can it be nil?
|
||||||
assert(isCallableInfo(mInfo))
|
assert(isCallableInfo(mInfo))
|
||||||
assert(isFunctionInfo(mInfo))
|
assert(isFunctionInfo(mInfo))
|
||||||
|
|
@ -819,7 +840,8 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
|
||||||
try:
|
try:
|
||||||
(plist, arglist, replist, arrLex) = genPars(mInfo, false, info)
|
(plist, arglist, replist, arrLex) = genPars(mInfo, false, info)
|
||||||
processedFunctions.incl(sym)
|
processedFunctions.incl(sym)
|
||||||
if sym.startsWith("g_param_spec_", "g_type_interface_", "g_object_interface_"): return
|
if not sym.startsWith("g_param_spec_uref"):
|
||||||
|
if sym.startsWith("g_param_spec_", "g_type_interface_", "g_object_interface_"): return
|
||||||
if sym in ["gtk_widget_class_find_style_property", "gtk_container_class_find_child_property",
|
if sym in ["gtk_widget_class_find_style_property", "gtk_container_class_find_child_property",
|
||||||
"gtk_cell_area_class_find_cell_property"]: return
|
"gtk_cell_area_class_find_cell_property"]: return
|
||||||
var asym = manglename(gBaseInfoGetName(mInfo))
|
var asym = manglename(gBaseInfoGetName(mInfo))
|
||||||
|
|
@ -878,7 +900,8 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
|
||||||
let tag = gTypeInfoGetTag(ret2)
|
let tag = gTypeInfoGetTag(ret2)
|
||||||
if tag == GITypeTag.INTERFACE:
|
if tag == GITypeTag.INTERFACE:
|
||||||
let iface = gTypeInfoGetInterface(ret2)
|
let iface = gTypeInfoGetInterface(ret2)
|
||||||
if gBaseInfoGetType(iface) == GIInfoType.Object and gBaseInfoGetName(iface) != "ParamSpec":
|
#if gBaseInfoGetType(iface) == GIInfoType.Object and gBaseInfoGetName(iface) != "ParamSpec":
|
||||||
|
if gBaseInfoGetType(iface) == GIInfoType.Object and gObjectInfoGetFundamental(iface) == GFalse:
|
||||||
isGObject = true
|
isGObject = true
|
||||||
(plist, arglist, replist, arrLex, blex) = genPars(mInfo, true, info)
|
(plist, arglist, replist, arrLex, blex) = genPars(mInfo, true, info)
|
||||||
var sss = ""
|
var sss = ""
|
||||||
|
|
@ -954,6 +977,7 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
|
||||||
methodBuffer.writeLine(" fnew(result, $1)" % boxedFreeMeName)
|
methodBuffer.writeLine(" fnew(result, $1)" % boxedFreeMeName)
|
||||||
elif freeMeName == "":
|
elif freeMeName == "":
|
||||||
assert false
|
assert false
|
||||||
|
echo "????????", sym
|
||||||
methodBuffer.writeLine(" new(result)")
|
methodBuffer.writeLine(" new(result)")
|
||||||
else:
|
else:
|
||||||
methodBuffer.writeLine(" fnew(result, $1)" % freeMeName)
|
methodBuffer.writeLine(" fnew(result, $1)" % freeMeName)
|
||||||
|
|
@ -999,16 +1023,17 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
|
||||||
assert tag == GITypeTag.INTERFACE
|
assert tag == GITypeTag.INTERFACE
|
||||||
var iface = gTypeInfoGetInterface(ret2)
|
var iface = gTypeInfoGetInterface(ret2)
|
||||||
if gBaseInfoGetType(iface) == GIInfoType.INTERFACE:
|
if gBaseInfoGetType(iface) == GIInfoType.INTERFACE:
|
||||||
|
#methodBuffer.writeLine("#GIInfoType.INTERFACE")
|
||||||
gobjectTemp()
|
gobjectTemp()
|
||||||
#iface = gInterfaceInfoGetIfaceStruct(iface)
|
#iface = gInterfaceInfoGetIfaceStruct(iface)
|
||||||
#methodBuffer.writeLine(" fnew(result, $1genericGObjectUnref) # Interface" % [mprefix])
|
#methodBuffer.writeLine(" fnew(result, $1genericGObjectUnref) # Interface" % [mprefix])
|
||||||
#methodBuffer.writeLine(" result.impl = " & sym & arglist)
|
#methodBuffer.writeLine(" result.impl = " & sym & arglist)
|
||||||
elif gBaseInfoGetType(iface) == GIInfoType.OBJECT: # rare, ParamSpec in gobject.nim
|
elif false: #gBaseInfoGetType(iface) == GIInfoType.OBJECT: # rare, ParamSpec in gobject.nim
|
||||||
#echo "XXXXXXXXXXXXXXXXX what shall we do? for ", sym
|
#echo "XXXXXXXXXXXXXXXXX what shall we do? for ", sym
|
||||||
methodBuffer.writeLine(" fnew(result, $1genericGObjectUnref) # Object" % [mprefix])
|
methodBuffer.writeLine(" fnew(result, $1genericGObjectUnref) # Object" % [mprefix])
|
||||||
methodBuffer.writeLine(" result.impl = " & sym & arglist)
|
methodBuffer.writeLine(" result.impl = " & sym & arglist)
|
||||||
else:
|
else:
|
||||||
assert(gBaseInfoGetType(iface) in {GIInfoType.STRUCT, GIInfoType.UNION})
|
assert(gBaseInfoGetType(iface) in {GIInfoType.STRUCT, GIInfoType.UNION, GIInfoType.OBJECT})
|
||||||
var freeMeName: string
|
var freeMeName: string
|
||||||
var freeMe: GIFunctionInfo
|
var freeMe: GIFunctionInfo
|
||||||
var boxedFreeMeName: string
|
var boxedFreeMeName: string
|
||||||
|
|
@ -1017,7 +1042,7 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
|
||||||
methodBuffer.writeLine(" fnew(result, $1)" % boxedFreeMeName)
|
methodBuffer.writeLine(" fnew(result, $1)" % boxedFreeMeName)
|
||||||
elif freeMeName == "":
|
elif freeMeName == "":
|
||||||
# assert false # TODO we have to fix this case manually
|
# assert false # TODO we have to fix this case manually
|
||||||
#echo "xCaution: No free/unref found for ", ' ', gBaseInfoGetName(iface), " (", sym, ')'
|
# echo "xCaution: No free/unref found for ", ' ', gBaseInfoGetName(iface), " (", sym, ')' # check this from time to time!
|
||||||
methodBuffer.writeLine(" new(result)")
|
methodBuffer.writeLine(" new(result)")
|
||||||
else:
|
else:
|
||||||
methodBuffer.writeLine(" fnew(result, $1)" % freeMeName)
|
methodBuffer.writeLine(" fnew(result, $1)" % freeMeName)
|
||||||
|
|
@ -1149,18 +1174,39 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
|
||||||
methodBuffer.writeLine("\nproc `defaultSize=`*(self: Window; dim: tuple[width: int; height: int]) =")
|
methodBuffer.writeLine("\nproc `defaultSize=`*(self: Window; dim: tuple[width: int; height: int]) =")
|
||||||
methodBuffer.writeLine(" gtk_window_set_default_size(cast[ptr Window00](self.impl), int32(dim[0]), int32(dim[1]))")
|
methodBuffer.writeLine(" gtk_window_set_default_size(cast[ptr Window00](self.impl), int32(dim[0]), int32(dim[1]))")
|
||||||
if sym == "g_object_unref":
|
if sym == "g_object_unref":
|
||||||
methodBuffer.writeLine("\nproc genericGObjectUnref*[T](self: ref T) =")
|
# methodBuffer.writeLine("\nproc genericGObjectUnref*[T](self: ref T) =") # we do not really need generics here
|
||||||
|
methodBuffer.writeLine("\nproc genericGObjectUnref*(self: Object) =")
|
||||||
methodBuffer.writeLine(" if not self.ignoreFinalizer:")
|
methodBuffer.writeLine(" if not self.ignoreFinalizer:")
|
||||||
methodBuffer.writeLine(" g_object_unref(cast[ptr Object00](self.impl))")
|
methodBuffer.writeLine(" g_object_unref(cast[ptr Object00](self.impl))")
|
||||||
|
|
||||||
|
#if gBaseInfoGetType(info) == GIInfoType.Object and isgobject
|
||||||
|
if info != nil and gBaseInfoGetType(info) == GIInfoType.Object and gObjectInfoGetFundamental(info) == GTrue and sym.endsWith("unref"):
|
||||||
|
when false: # we can not use baseName, we have to use generics.
|
||||||
|
var parent = info
|
||||||
|
while true:
|
||||||
|
let h = g_object_info_get_parent(parent)
|
||||||
|
if h == nil:
|
||||||
|
break
|
||||||
|
parent = h
|
||||||
|
let baseName = $gBaseInfoGetName(parent)
|
||||||
|
methodBuffer.writeLine("\nproc generic_$1*[T](self: ref T) =" % [sym])
|
||||||
|
# methodBuffer.writeLine("\nproc generic_$1*(self: $2) =" % [sym, baseName]) # we can not avoid generics here
|
||||||
|
methodBuffer.writeLine(" if not self.ignoreFinalizer:")
|
||||||
|
# methodBuffer.writeLine(" $1(cast[ptr Object00](self.impl))" % [sym]) # we do not need that cast!
|
||||||
|
methodBuffer.writeLine(" $1(self.impl)" % [sym])
|
||||||
|
|
||||||
|
if useTempProcessedFunctions:
|
||||||
|
tempProcessedFunctions.add(sym)
|
||||||
except UndefEx:
|
except UndefEx:
|
||||||
|
|
||||||
processedFunctions.excl(sym)
|
processedFunctions.excl(sym)
|
||||||
delayedMethods.add((info, minfo))
|
delayedMethods.add((info, minfo))
|
||||||
methodBuffer.cut(p)
|
methodBuffer.cut(p)
|
||||||
|
|
||||||
template genBoxedFree =
|
template genBoxedFree =
|
||||||
if not callerAlloc.contains(($gBaseInfoGetNamespace(info)).toLowerAscii & '.' & mangleName(gBaseInfoGetName(info))):
|
if not callerAlloc.contains(($gBaseInfoGetNamespace(info)).toLowerAscii & '.' & mangleName(gBaseInfoGetName(info))):
|
||||||
if gRegisteredTypeInfoGetGType(info) != G_TYPE_NONE and gTypeFundamental(gRegisteredTypeInfoGetGType(info)) == G_TYPE_BOXED and
|
if gRegisteredTypeInfoGetGType(info) != G_TYPE_NONE and gTypeFundamental(gRegisteredTypeInfoGetGType(info)) ==
|
||||||
|
G_TYPE_BOXED and
|
||||||
gBaseInfoGetName(info) != "VariantType": # we have no g_variant_type_get_gtype
|
gBaseInfoGetName(info) != "VariantType": # we have no g_variant_type_get_gtype
|
||||||
# For example, GVariant has a GType but is not a boxed type
|
# For example, GVariant has a GType but is not a boxed type
|
||||||
#assert(g_type_fundamental(g_registered_type_info_get_g_type(info)) == G_TYPE_BOXED)
|
#assert(g_type_fundamental(g_registered_type_info_get_g_type(info)) == G_TYPE_BOXED)
|
||||||
|
|
@ -1195,12 +1241,7 @@ template genBoxedFree =
|
||||||
else:
|
else:
|
||||||
#if gStructInfoIsGtypeStruct(info) and gBaseInfoGetName(info) != "ObjectClass":
|
#if gStructInfoIsGtypeStruct(info) and gBaseInfoGetName(info) != "ObjectClass":
|
||||||
assert gBaseInfoGetType(info) == GIInfoType.STRUCT
|
assert gBaseInfoGetType(info) == GIInfoType.STRUCT
|
||||||
#echo "aaa", info.isNil
|
|
||||||
#echo "bbb", gStructInfoIsGtypeStruct(info)
|
|
||||||
#echo "ccc", gStructInfoGetNMethods(info)
|
|
||||||
#echo gBaseInfoGetName(info)
|
|
||||||
freeMe = gStructInfoFindMethod(info, "free")
|
freeMe = gStructInfoFindMethod(info, "free")
|
||||||
#echo "xxxxxxxx"
|
|
||||||
if freeMe.isNil:
|
if freeMe.isNil:
|
||||||
freeMe = gStructInfoFindMethod(info, "unref")
|
freeMe = gStructInfoFindMethod(info, "unref")
|
||||||
|
|
||||||
|
|
@ -1208,7 +1249,6 @@ template genDestroyFreeUnref =
|
||||||
if not callerAlloc.contains(($gBaseInfoGetNamespace(info)).toLowerAscii & '.' & mangleName(gBaseInfoGetName(info))):
|
if not callerAlloc.contains(($gBaseInfoGetNamespace(info)).toLowerAscii & '.' & mangleName(gBaseInfoGetName(info))):
|
||||||
if gRegisteredTypeInfoGetGType(info) == G_TYPE_NONE or gTypeFundamental(gRegisteredTypeInfoGetGType(info)) != G_TYPE_BOXED or
|
if gRegisteredTypeInfoGetGType(info) == G_TYPE_NONE or gTypeFundamental(gRegisteredTypeInfoGetGType(info)) != G_TYPE_BOXED or
|
||||||
gBaseInfoGetName(info) == "VariantType": # we have no g_variant_type_get_gtype
|
gBaseInfoGetName(info) == "VariantType": # we have no g_variant_type_get_gtype
|
||||||
#if true:
|
|
||||||
if gBaseInfoGetType(info) == GIInfoType.UNION or gBaseInfoGetType(info) == GIInfoType.STRUCT and
|
if gBaseInfoGetType(info) == GIInfoType.UNION or gBaseInfoGetType(info) == GIInfoType.STRUCT and
|
||||||
gBaseInfoGetName(info) != "ObjectClass" and gBaseInfoGetName(info) != "TypeFind":
|
gBaseInfoGetName(info) != "ObjectClass" and gBaseInfoGetName(info) != "TypeFind":
|
||||||
var freeMe: GIFunctionInfo
|
var freeMe: GIFunctionInfo
|
||||||
|
|
@ -1217,7 +1257,6 @@ template genDestroyFreeUnref =
|
||||||
if freeMe.isNil:
|
if freeMe.isNil:
|
||||||
freeMe = gUnionInfoFindMethod(info, "unref")
|
freeMe = gUnionInfoFindMethod(info, "unref")
|
||||||
else:
|
else:
|
||||||
#if gStructInfoIsGtypeStruct(info) and gBaseInfoGetName(info) != "ObjectClass":
|
|
||||||
assert gBaseInfoGetType(info) == GIInfoType.STRUCT
|
assert gBaseInfoGetType(info) == GIInfoType.STRUCT
|
||||||
freeMe = gStructInfoFindMethod(info, "free")
|
freeMe = gStructInfoFindMethod(info, "free")
|
||||||
if freeMe.isNil:
|
if freeMe.isNil:
|
||||||
|
|
@ -1350,7 +1389,8 @@ proc writeStruct(info: GIStructInfo) =
|
||||||
output.writeLine(" ", mangleName(gBaseInfoGetName(info)) & "00" & EM & " {.pure.} = object")
|
output.writeLine(" ", mangleName(gBaseInfoGetName(info)) & "00" & EM & " {.pure.} = object")
|
||||||
if WriteFields or callerAlloc.contains(($gBaseInfoGetNamespace(info)).toLowerAscii & '.' & mangleName(gBaseInfoGetName(
|
if WriteFields or callerAlloc.contains(($gBaseInfoGetNamespace(info)).toLowerAscii & '.' & mangleName(gBaseInfoGetName(
|
||||||
info))) or
|
info))) or
|
||||||
mangleName(gBaseInfoGetName(info)) == "TargetEntry":
|
mangleName(gBaseInfoGetName(info)) == "TargetEntry" or
|
||||||
|
["gst.Message", "gst.MiniObject"].contains(($gBaseInfoGetNamespace(info)).toLowerAscii & '.' & mangleName(gBaseInfoGetName(info))):
|
||||||
for j in 0.cint ..< info.gStructInfoGetNFields():
|
for j in 0.cint ..< info.gStructInfoGetNFields():
|
||||||
let field = info.gStructInfoGetField(j)
|
let field = info.gStructInfoGetField(j)
|
||||||
let name = manglename(gBaseInfoGetName(field)) & EM
|
let name = manglename(gBaseInfoGetName(field)) & EM
|
||||||
|
|
@ -1506,7 +1546,7 @@ proc writeModifierType(info: GIEnumInfo) =
|
||||||
output.writeLine(i)
|
output.writeLine(i)
|
||||||
output.writeLine("\n ", we & EM, " {.size: sizeof(cint).} = set[$1Flag]" % [tname])
|
output.writeLine("\n ", we & EM, " {.size: sizeof(cint).} = set[$1Flag]" % [tname])
|
||||||
if we == "ModifierType":
|
if we == "ModifierType":
|
||||||
output.writeLine("\nconst ModifierMask* = {ModifierFlag.shift .. ModifierFlag.button5, ModifierFlag.super .. ModifierFlag.meta, ModifierFlag.release}")
|
output.writeLine("\nconst ModifierMask* = {ModifierFlag.shift .. ModifierFlag.button5, ModifierFlag.super .. ModifierFlag.meta}") #, ModifierFlag.release}")
|
||||||
elif we == "EventMask":
|
elif we == "EventMask":
|
||||||
output.writeLine("\nconst AllEventsMask* = {EventFlag.exposure .. EventFlag.smoothScroll}")
|
output.writeLine("\nconst AllEventsMask* = {EventFlag.exposure .. EventFlag.smoothScroll}")
|
||||||
for j in 0.cint ..< gEnumInfoGetNMethods(info):
|
for j in 0.cint ..< gEnumInfoGetNMethods(info):
|
||||||
|
|
@ -1638,7 +1678,7 @@ proc writeObj(info: GIObjectInfo) =
|
||||||
assert not callerAlloc.contains(($gBaseInfoGetNamespace(info)).toLowerAscii & '.' & mangleName(gBaseInfoGetName(info)))
|
assert not callerAlloc.contains(($gBaseInfoGetNamespace(info)).toLowerAscii & '.' & mangleName(gBaseInfoGetName(info)))
|
||||||
when WriteFields:
|
when WriteFields:
|
||||||
if mangleName(gBaseInfoGetName(info)) != "InitiallyUnowned":
|
if mangleName(gBaseInfoGetName(info)) != "InitiallyUnowned":
|
||||||
for j in 0.cint ..< n:
|
for j in 0.cint ..< info.gObjectInfoGetNFields():
|
||||||
let field = info.gObjectInfoGetField(j)
|
let field = info.gObjectInfoGetField(j)
|
||||||
var name = mangleName(gBaseInfoGetName(field))
|
var name = mangleName(gBaseInfoGetName(field))
|
||||||
if privStr.contains(name) and cnt > 0:
|
if privStr.contains(name) and cnt > 0:
|
||||||
|
|
@ -1674,6 +1714,7 @@ proc writeObj(info: GIObjectInfo) =
|
||||||
if getTypeProc notin ["intern", "g_gstring_get_type"]:
|
if getTypeProc notin ["intern", "g_gstring_get_type"]:
|
||||||
output.write("\nproc " & getTypeProc & "*(): GType ")
|
output.write("\nproc " & getTypeProc & "*(): GType ")
|
||||||
output.writeLine("{.importc, " & libprag & ".}")
|
output.writeLine("{.importc, " & libprag & ".}")
|
||||||
|
|
||||||
let numsig = info.gObjectInfoGetNSignals
|
let numsig = info.gObjectInfoGetNSignals
|
||||||
#if numsig > 0: signalbuffer.writeLine("")
|
#if numsig > 0: signalbuffer.writeLine("")
|
||||||
for j in 0.cint ..< numsig:
|
for j in 0.cint ..< numsig:
|
||||||
|
|
@ -1685,9 +1726,23 @@ proc writeObj(info: GIObjectInfo) =
|
||||||
var h = genPars(signalInfo, false)[0][1..^1]
|
var h = genPars(signalInfo, false)[0][1..^1]
|
||||||
let zzzu = gCallableInfoGetReturnType(signalinfo)
|
let zzzu = gCallableInfoGetReturnType(signalinfo)
|
||||||
writeSignal()
|
writeSignal()
|
||||||
|
#for j in 0.cint ..< gObjectInfoGetNMethods(info):
|
||||||
|
# let mInfo = gObjectInfoGetMethod(info, j)
|
||||||
|
# writeMethod(info, minfo)
|
||||||
|
|
||||||
|
var mseq: seq[GIFunctionInfo]
|
||||||
|
var freePos = -1
|
||||||
for j in 0.cint ..< gObjectInfoGetNMethods(info):
|
for j in 0.cint ..< gObjectInfoGetNMethods(info):
|
||||||
let mInfo = gObjectInfoGetMethod(info, j)
|
mseq.add(gObjectInfoGetMethod(info, j))
|
||||||
|
if freePos < 0 and gBaseInfoGetName(gObjectInfoGetMethod(info, j)) in ["free", "unref"]:
|
||||||
|
#assert false executed for gtk3
|
||||||
|
freePos = j
|
||||||
|
if freePos > 0: swap(mseq[0], mseq[freePos])
|
||||||
|
for i, mInfo in mseq:
|
||||||
writeMethod(info, minfo)
|
writeMethod(info, minfo)
|
||||||
|
#if i == 0:
|
||||||
|
# genDestroyFreeUnref()
|
||||||
|
|
||||||
if class != nil and not allSyms.contains(mangleName(gBaseInfoGetName(class))):
|
if class != nil and not allSyms.contains(mangleName(gBaseInfoGetName(class))):
|
||||||
assert false
|
assert false
|
||||||
classList.add(class)
|
classList.add(class)
|
||||||
|
|
@ -1704,6 +1759,45 @@ proc writeObj(info: GIObjectInfo) =
|
||||||
output.writeLine(" g_object_remove_toggle_ref(self.impl, toggleNotify, addr(self))")
|
output.writeLine(" g_object_remove_toggle_ref(self.impl, toggleNotify, addr(self))")
|
||||||
output.writeLine(" self.impl = nil")
|
output.writeLine(" self.impl = nil")
|
||||||
|
|
||||||
|
if gBaseInfoGetName(info) == "ParamSpec" and moduleNamespace == "gobject":
|
||||||
|
## for ParamSpec no unref proc is provided by gobject-introspection, and it asks for uref!
|
||||||
|
output.writeLine("\nproc g_param_spec_unref(self: ptr ParamSpec00) {.")
|
||||||
|
output.writeLine(" importc, libprag.}")
|
||||||
|
|
||||||
|
output.writeLine("\nproc g_param_spec_uref(self: ptr ParamSpec00) {.")
|
||||||
|
output.writeLine(" importc: \"g_param_spec_unref\", libprag.}")
|
||||||
|
|
||||||
|
output.writeLine("\nproc unref*(self: ParamSpec) =")
|
||||||
|
output.writeLine(" g_param_spec_unref(cast[ptr ParamSpec00](self.impl))")
|
||||||
|
|
||||||
|
output.writeLine("\nproc uref*(self: ParamSpec) =")
|
||||||
|
output.writeLine(" g_param_spec_unref(cast[ptr ParamSpec00](self.impl))")
|
||||||
|
|
||||||
|
output.writeLine("\nproc generic_g_param_spec_uref*(self: ParamSpec) =")
|
||||||
|
output.writeLine(" g_param_spec_unref(cast[ptr ParamSpec00](self.impl))")
|
||||||
|
|
||||||
|
if gBaseInfoGetType(info) == GIInfoType.Object and gObjectInfoGetFundamental(info) == GTrue:
|
||||||
|
## generate the destroy() for the non gobject objects
|
||||||
|
assert(gObjectInfoGetFundamental(info) == GTrue)
|
||||||
|
var parent = info
|
||||||
|
while true:
|
||||||
|
let h = g_object_info_get_parent(parent)
|
||||||
|
if h == nil:
|
||||||
|
break
|
||||||
|
parent = h
|
||||||
|
let freeMeName = $g_object_info_get_unref_function(parent)
|
||||||
|
if freeMeName != "":
|
||||||
|
output.writeLine("\nwhen defined(gcDestructors):")
|
||||||
|
let n = mangleName(gBaseInfoGetName(info))
|
||||||
|
output.writeLine(" proc destroy_" & freeMeName & "(self: ptr " & n & "00) {.importc: \"" & freeMeName & "\", libprag.}\n")
|
||||||
|
output.writeLine(" proc `=destroy`*(self: var typeof(" & mangleName(gBaseInfoGetName(info)) & "()[])) =")
|
||||||
|
output.writeLine(" if not self.ignoreFinalizer and self.impl != nil:")
|
||||||
|
if n in ["ParamArray", "ParamFraction"]:
|
||||||
|
output.writeLine(" destroy_$#(cast[ptr $#00](self.impl))" % [freeMeName, n])
|
||||||
|
else:
|
||||||
|
output.writeLine(" destroy_$1(self.impl)" % [freeMeName])
|
||||||
|
output.writeLine(" self.impl = nil")
|
||||||
|
|
||||||
proc extractFromUnion(tag: GITypeTag; arg: GIArgumentObj): string =
|
proc extractFromUnion(tag: GITypeTag; arg: GIArgumentObj): string =
|
||||||
result =
|
result =
|
||||||
case tag:
|
case tag:
|
||||||
|
|
@ -1738,6 +1832,8 @@ proc writeConst(info: GIConstantInfo) =
|
||||||
var str = extractFromUnion(tag, arg)
|
var str = extractFromUnion(tag, arg)
|
||||||
if str == """"\"""": str = """"\\""""
|
if str == """"\"""": str = """"\\""""
|
||||||
var h = $gBaseInfoGetName(info)
|
var h = $gBaseInfoGetName(info)
|
||||||
|
if h == "MODIFIER_MASK":
|
||||||
|
return
|
||||||
if h.replace("_", "").toLowerAscii == "keych":
|
if h.replace("_", "").toLowerAscii == "keych":
|
||||||
h.add(str[^5])
|
h.add(str[^5])
|
||||||
if gdkKeys.contains(h.toLowerAscii):
|
if gdkKeys.contains(h.toLowerAscii):
|
||||||
|
|
@ -1833,6 +1929,45 @@ proc getView*(builder: Builder; name: string): View =
|
||||||
|
|
||||||
const GDK3_EPI = """
|
const GDK3_EPI = """
|
||||||
|
|
||||||
|
proc getButton*(self: SomeEvent): int =
|
||||||
|
var button: uint32
|
||||||
|
if not toBool(gdk_event_get_button(cast[ptr Event00](self.impl), button)):
|
||||||
|
raise newException(Defect, "Event don't has a button field.")
|
||||||
|
return int(button)
|
||||||
|
|
||||||
|
proc getClickCount*(self: SomeEvent): int =
|
||||||
|
var clickCount_00: uint32
|
||||||
|
if not toBool(gdk_event_get_click_count(cast[ptr Event00](self.impl), clickCount_00)):
|
||||||
|
raise newException(Defect, "Event does not support getClickCount().")
|
||||||
|
return int(clickCount_00)
|
||||||
|
|
||||||
|
proc getCoords*(self: SomeEvent): (cdouble, cdouble) =
|
||||||
|
if not toBool(gdk_event_get_coords(cast[ptr Event00](self.impl), result[0], result[1])):
|
||||||
|
raise newException(Defect, "This event don't has a coordinate field.")
|
||||||
|
|
||||||
|
proc getKeyval*(self: SomeEvent): int =
|
||||||
|
var keyval_00: uint32
|
||||||
|
if not toBool(gdk_event_get_keyval(cast[ptr Event00](self.impl), keyval_00)):
|
||||||
|
raise newException(Defect, "This event don't has a keyval field.")
|
||||||
|
return int(keyval_00)
|
||||||
|
|
||||||
|
# not available in GTK4
|
||||||
|
proc getRootCoords*(self: SomeEvent): (cdouble, cdouble) =
|
||||||
|
if not toBool(gdk_event_get_root_coords(cast[ptr Event00](self.impl), result[0], result[1])):
|
||||||
|
raise newException(Defect, "This event don't has a rootCoordinate field.")
|
||||||
|
|
||||||
|
proc getScrollDeltas*(self: SomeEvent): (cdouble, cdouble) =
|
||||||
|
if not toBool(gdk_event_get_scroll_deltas(cast[ptr Event00](self.impl), result[0], result[1])):
|
||||||
|
raise newException(Defect, "This event don't has a scrollDeltas field.")
|
||||||
|
|
||||||
|
proc getScrollDirection*(self: SomeEvent): ScrollDirection =
|
||||||
|
if not toBool(gdk_event_get_scroll_direction(cast[ptr Event00](self.impl), result)):
|
||||||
|
raise newException(Defect, "Event don't has a scrollDirection field.")
|
||||||
|
|
||||||
|
proc getState*(self: SomeEvent): ModifierType =
|
||||||
|
if not toBool(gdk_event_get_state(cast[ptr Event00](self.impl), result)):
|
||||||
|
raise newException(Defect, "Event don't has a state field.")
|
||||||
|
|
||||||
proc gdk_window_invalidate_nilrect(self: ptr Window00; rect: ptr Rectangle; invalidateChildren: gboolean) {.
|
proc gdk_window_invalidate_nilrect(self: ptr Window00; rect: ptr Rectangle; invalidateChildren: gboolean) {.
|
||||||
importc: "gdk_window_invalidate_rect", libprag.}
|
importc: "gdk_window_invalidate_rect", libprag.}
|
||||||
|
|
||||||
|
|
@ -1868,45 +2003,6 @@ proc getAxis*(self: SomeEvent; axisUse: AxisUse): cdouble =
|
||||||
if not toBool(gdk_event_get_axis(cast[ptr Event00](self.impl), axisUse, result)):
|
if not toBool(gdk_event_get_axis(cast[ptr Event00](self.impl), axisUse, result)):
|
||||||
raise newException(Defect, "Event does not support getAxis().")
|
raise newException(Defect, "Event does not support getAxis().")
|
||||||
|
|
||||||
proc getButton*(self: SomeEvent): int =
|
|
||||||
var button: uint32
|
|
||||||
if not toBool(gdk_event_get_button(cast[ptr Event00](self.impl), button)):
|
|
||||||
raise newException(Defect, "Event don't has a button field.")
|
|
||||||
return int(button)
|
|
||||||
|
|
||||||
proc getClickCount*(self: SomeEvent): int =
|
|
||||||
var clickCount_00: uint32
|
|
||||||
if not toBool(gdk_event_get_click_count(cast[ptr Event00](self.impl), clickCount_00)):
|
|
||||||
raise newException(Defect, "Event does not support getClickCount().")
|
|
||||||
return int(clickCount_00)
|
|
||||||
|
|
||||||
proc getCoords*(self: SomeEvent): (cdouble, cdouble) =
|
|
||||||
if not toBool(gdk_event_get_coords(cast[ptr Event00](self.impl), result[0], result[1])):
|
|
||||||
raise newException(Defect, "This event don't has a coordinate field.")
|
|
||||||
|
|
||||||
proc getKeyval*(self: SomeEvent): int =
|
|
||||||
var keyval_00: uint32
|
|
||||||
if not toBool(gdk_event_get_keyval(cast[ptr Event00](self.impl), keyval_00)):
|
|
||||||
raise newException(Defect, "This event don't has a keyval field.")
|
|
||||||
return int(keyval_00)
|
|
||||||
|
|
||||||
# not available in GTK4
|
|
||||||
#proc getRootCoords*(self: SomeEvent): (cdouble, cdouble) =
|
|
||||||
# if not toBool(gdk_event_get_root_coords(cast[ptr Event00](self.impl), result[0], result[1])):
|
|
||||||
# raise newException(Defect, "This event don't has a rootCoordinate field.")
|
|
||||||
|
|
||||||
proc getScrollDeltas*(self: SomeEvent): (cdouble, cdouble) =
|
|
||||||
if not toBool(gdk_event_get_scroll_deltas(cast[ptr Event00](self.impl), result[0], result[1])):
|
|
||||||
raise newException(Defect, "This event don't has a scrollDeltas field.")
|
|
||||||
|
|
||||||
proc getScrollDirection*(self: SomeEvent): ScrollDirection =
|
|
||||||
if not toBool(gdk_event_get_scroll_direction(cast[ptr Event00](self.impl), result)):
|
|
||||||
raise newException(Defect, "Event don't has a scrollDirection field.")
|
|
||||||
|
|
||||||
proc getState*(self: SomeEvent): ModifierType =
|
|
||||||
if not toBool(gdk_event_get_state(cast[ptr Event00](self.impl), result)):
|
|
||||||
raise newException(Defect, "Event don't has a state field.")
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
const GIO_EPI = """
|
const GIO_EPI = """
|
||||||
|
|
@ -1916,13 +2012,17 @@ proc run*(self: GApplication): int =
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
const GTK3_EPI = """
|
||||||
|
|
||||||
|
proc mainQuit*(w: Window) = mainQuit()
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
const GTK_EPI = """
|
const GTK_EPI = """
|
||||||
|
|
||||||
#proc loadFromData*(self: CssProvider; data: cstring): bool =
|
#proc loadFromData*(self: CssProvider; data: cstring): bool =
|
||||||
# loadFromData(self, uint8Array(data), -1)
|
# loadFromData(self, uint8Array(data), -1)
|
||||||
|
|
||||||
proc mainQuit*(w: Window) = mainQuit()
|
|
||||||
|
|
||||||
proc gtk_file_chooser_dialog_new*(title: cstring; parent: ptr Window00; action: FileChooserAction;
|
proc gtk_file_chooser_dialog_new*(title: cstring; parent: ptr Window00; action: FileChooserAction;
|
||||||
firstButtonText: cstring = nil): ptr FileChooserDialog00 {.varargs,
|
firstButtonText: cstring = nil): ptr FileChooserDialog00 {.varargs,
|
||||||
importc: "gtk_file_chooser_dialog_new", libprag.}
|
importc: "gtk_file_chooser_dialog_new", libprag.}
|
||||||
|
|
@ -1993,8 +2093,7 @@ proc main(namespace: string; version: cstring = nil) =
|
||||||
#g_irepository_prepend_search_path("/opt/gtk/lib64/girepository-1.0")
|
#g_irepository_prepend_search_path("/opt/gtk/lib64/girepository-1.0")
|
||||||
# ISGTK3 = not (((namespace == "Gtk") or (namespace == "Gdk") or (namespace == "GdkX11")) and version == "4.0")
|
# ISGTK3 = not (((namespace == "Gtk") or (namespace == "Gdk") or (namespace == "GdkX11")) and version == "4.0")
|
||||||
# ISGTK3 = parmCount() == 0 # we have to launch the generator two times, as typelibs can not be unloaded!
|
# ISGTK3 = parmCount() == 0 # we have to launch the generator two times, as typelibs can not be unloaded!
|
||||||
let typelib = gi.gIrepositoryRequire(namespace, version, cast[
|
let typelib = gi.gIrepositoryRequire(namespace, version, cast[GIRepositoryLoadFlags](0), error)
|
||||||
GIRepositoryLoadFlags](0), error)
|
|
||||||
#let typelib = gIrepositoryRequirePrivate(nil, namespace, "/usr/lib/girepository-1.0", version, cast[GIRepositoryLoadFlags](0), error)
|
#let typelib = gIrepositoryRequirePrivate(nil, namespace, "/usr/lib/girepository-1.0", version, cast[GIRepositoryLoadFlags](0), error)
|
||||||
if typelib.isNil:
|
if typelib.isNil:
|
||||||
echo "Failed to load ", namespace
|
echo "Failed to load ", namespace
|
||||||
|
|
@ -2011,8 +2110,7 @@ proc main(namespace: string; version: cstring = nil) =
|
||||||
if j == 0:
|
if j == 0:
|
||||||
importedModules = "import "
|
importedModules = "import "
|
||||||
output.writeLine("# ", dep[j])
|
output.writeLine("# ", dep[j])
|
||||||
importedModules.add(fixedModName(($dep[j]).split('-',
|
importedModules.add(fixedModName(($dep[j]).split('-', 2)[0].toLowerAscii) & ", ")
|
||||||
2)[0].toLowerAscii) & ", ")
|
|
||||||
importedModules.removeSuffix(", ")
|
importedModules.removeSuffix(", ")
|
||||||
strfreev(dep)
|
strfreev(dep)
|
||||||
let idep: cstringArray = gi.gIrepositoryGetImmediateDependencies(namespace)
|
let idep: cstringArray = gi.gIrepositoryGetImmediateDependencies(namespace)
|
||||||
|
|
@ -2028,8 +2126,8 @@ proc main(namespace: string; version: cstring = nil) =
|
||||||
output.writeLine("{.warning[UnusedImport]: off.}") # gmodule, xlib, cairo
|
output.writeLine("{.warning[UnusedImport]: off.}") # gmodule, xlib, cairo
|
||||||
output.writeLine(importedModules)
|
output.writeLine(importedModules)
|
||||||
var Lib = if libs.isNil: "" else: ($libs).split(',', 2)[0]
|
var Lib = if libs.isNil: "" else: ($libs).split(',', 2)[0]
|
||||||
if namespace == "PangoCairo" and Lib.startsWith(
|
if namespace == "PangoCairo" and Lib.startsWith("libpango-"):
|
||||||
"libpango-"): Lib = Lib.replace("libpango-", "libpangocairo-") # GI bug?
|
Lib = Lib.replace("libpango-", "libpangocairo-") # GI bug?
|
||||||
output.writeLine("const Lib = \"$1\"" % Lib)
|
output.writeLine("const Lib = \"$1\"" % Lib)
|
||||||
output.writeLine("{.pragma: libprag, cdecl, dynlib: Lib.}")
|
output.writeLine("{.pragma: libprag, cdecl, dynlib: Lib.}")
|
||||||
if namespace == "GObject": # declare array types to make it compile -- procs using these will need special care!
|
if namespace == "GObject": # declare array types to make it compile -- procs using these will need special care!
|
||||||
|
|
@ -2084,8 +2182,7 @@ proc main(namespace: string; version: cstring = nil) =
|
||||||
#gtype.h-#else /* for historic reasons, C++ links against gulong GTypes */
|
#gtype.h-#else /* for historic reasons, C++ links against gulong GTypes */
|
||||||
#gtype.h-typedef gulong GType;
|
#gtype.h-typedef gulong GType;
|
||||||
#gtype.h-#endif
|
#gtype.h-#endif
|
||||||
output.writeLine(
|
output.writeLine("when GLIB_SIZEOF_SIZE_T != GLIB_SIZEOF_LONG or not defined(cpp):")
|
||||||
"when GLIB_SIZEOF_SIZE_T != GLIB_SIZEOF_LONG or not defined(cpp):")
|
|
||||||
output.writeLine(" type\n GType* = Gsize")
|
output.writeLine(" type\n GType* = Gsize")
|
||||||
output.writeLine("else:")
|
output.writeLine("else:")
|
||||||
output.writeLine(" type\n GType* = culong")
|
output.writeLine(" type\n GType* = culong")
|
||||||
|
|
@ -2139,15 +2236,13 @@ proc uint8ArrayZT2seq*(p: pointer): seq[uint8] =
|
||||||
inc(i)
|
inc(i)
|
||||||
""")
|
""")
|
||||||
|
|
||||||
output.writeLine(
|
output.writeLine("proc cogfree*(mem: pointer) {.importc: \"g_free\", libprag.}")
|
||||||
"proc cogfree*(mem: pointer) {.importc: \"g_free\", libprag.}")
|
output.writeLine("proc g_strfreev*(strArray: cstringArray) {.importc: \"g_strfreev\", libprag.}")
|
||||||
output.writeLine(
|
|
||||||
"proc g_strfreev*(strArray: cstringArray) {.importc: \"g_strfreev\", libprag.}")
|
|
||||||
output.writeLine("proc toBool*(g: gboolean): bool = g.int != 0")
|
output.writeLine("proc toBool*(g: gboolean): bool = g.int != 0")
|
||||||
output.writeLine(
|
output.writeLine("proc safeStringToCString*(s: cstring): cstring = (if s.len == 0: nil else: s)")
|
||||||
"proc safeStringToCString*(s: cstring): cstring = (if s.len == 0: nil else: s)")
|
|
||||||
output.writeLine(PRO)
|
output.writeLine(PRO)
|
||||||
elif namespace == "Gdk":
|
elif namespace == "Gdk":
|
||||||
|
output.writeLine("type\n ContentProvider00Array* = pointer")
|
||||||
output.writeLine("type\n Atom00Array* = pointer")
|
output.writeLine("type\n Atom00Array* = pointer")
|
||||||
output.writeLine("type\n KeymapKeyArray* = pointer")
|
output.writeLine("type\n KeymapKeyArray* = pointer")
|
||||||
output.writeLine("type\n VisualTypeArray* = pointer") # enums!
|
output.writeLine("type\n VisualTypeArray* = pointer") # enums!
|
||||||
|
|
@ -2169,6 +2264,7 @@ proc uint8ArrayZT2seq*(p: pointer): seq[uint8] =
|
||||||
output.writeLine("type\n StockItemArray* = pointer")
|
output.writeLine("type\n StockItemArray* = pointer")
|
||||||
output.writeLine("type\n PageRangeArray* = pointer")
|
output.writeLine("type\n PageRangeArray* = pointer")
|
||||||
output.writeLine("type\n PadActionEntry00Array* = pointer")
|
output.writeLine("type\n PadActionEntry00Array* = pointer")
|
||||||
|
output.writeLine("type\n Widget00Array* = pointer")
|
||||||
output.writeLine("type\n Array* = pointer")
|
output.writeLine("type\n Array* = pointer")
|
||||||
elif namespace == "Atk":
|
elif namespace == "Atk":
|
||||||
output.writeLine("type\n StateTypeArray* = pointer") # enums!
|
output.writeLine("type\n StateTypeArray* = pointer") # enums!
|
||||||
|
|
@ -2234,16 +2330,14 @@ proc uint8ArrayZT2seq*(p: pointer): seq[uint8] =
|
||||||
var n = gi.gIrepositoryGetNInfos(namespace)
|
var n = gi.gIrepositoryGetNInfos(namespace)
|
||||||
var s: seq[GIBaseInfo]
|
var s: seq[GIBaseInfo]
|
||||||
for i in 0.cint ..< n:
|
for i in 0.cint ..< n:
|
||||||
if not droppedSyms.contains(mangleName(gBaseInfoGetName(
|
if not droppedSyms.contains(mangleName(gBaseInfoGetName(gi.gIrepositoryGetInfo(namespace, i)))):
|
||||||
gi.gIrepositoryGetInfo(namespace, i)))):
|
|
||||||
s.add(gi.gIrepositoryGetInfo(namespace, i))
|
s.add(gi.gIrepositoryGetInfo(namespace, i))
|
||||||
for i in s:
|
for i in s:
|
||||||
if gBaseInfoGetType(i) in {GIInfoType.OBJECT, GIInfoType.INTERFACE, GIInfoType.STRUCT, GIInfoType.UNION} or isEnumInfo(i) or
|
if gBaseInfoGetType(i) in {GIInfoType.OBJECT, GIInfoType.INTERFACE, GIInfoType.STRUCT, GIInfoType.UNION} or isEnumInfo(i) or
|
||||||
isCallbackInfo(i):
|
isCallbackInfo(i):
|
||||||
allSyms.incl(mangleName(gBaseInfoGetName(i)))
|
allSyms.incl(mangleName(gBaseInfoGetName(i)))
|
||||||
for i in 0 .. s.high:
|
for i in 0 .. s.high:
|
||||||
if namespace == "GLib" and gBaseInfoGetType(s[
|
if namespace == "GLib" and gBaseInfoGetType(s[i]) == GIInfoType.STRUCT and gBaseInfoGetName(s[i]) == "Error":
|
||||||
i]) == GIInfoType.STRUCT and gBaseInfoGetName(s[i]) == "Error":
|
|
||||||
let h = s[i]
|
let h = s[i]
|
||||||
s.delete(i, i)
|
s.delete(i, i)
|
||||||
s.insert([h])
|
s.insert([h])
|
||||||
|
|
@ -2255,16 +2349,13 @@ proc uint8ArrayZT2seq*(p: pointer): seq[uint8] =
|
||||||
var interf: seq[string]
|
var interf: seq[string]
|
||||||
let name = $gBaseInfoGetName(info)
|
let name = $gBaseInfoGetName(info)
|
||||||
for i in 0.cint ..< ninterfaces:
|
for i in 0.cint ..< ninterfaces:
|
||||||
var ns = ($gBaseInfoGetNamespace(info.gObjectInfoGetInterface(
|
var ns = ($gBaseInfoGetNamespace(info.gObjectInfoGetInterface(i))).toLowerAscii
|
||||||
i))).toLowerAscii
|
|
||||||
if ns != moduleNamespace:
|
if ns != moduleNamespace:
|
||||||
var iname = $gBaseInfoGetName(info.gObjectInfoGetInterface(i))
|
var iname = $gBaseInfoGetName(info.gObjectInfoGetInterface(i))
|
||||||
var fname = iname; fname.unCap
|
var fname = iname; fname.unCap
|
||||||
iname = fixedModName(ns) & "." & iname
|
iname = fixedModName(ns) & "." & iname
|
||||||
let tname = fixedModName(moduleNamespace) & "." &
|
let tname = fixedModName(moduleNamespace) & "." & $gBaseInfoGetName(info)
|
||||||
$gBaseInfoGetName(info)
|
externInterfaces.add("proc " & fname & "*(x: " & tname & "): " & iname & " = cast[" & iname & "](x)")
|
||||||
externInterfaces.add("proc " & fname & "*(x: " & tname & "): " &
|
|
||||||
iname & " = cast[" & iname & "](x)")
|
|
||||||
interf.add($gBaseInfoGetName(info.gObjectInfoGetInterface(i)))
|
interf.add($gBaseInfoGetName(info.gObjectInfoGetInterface(i)))
|
||||||
let builderinter = info.gObjectInfoGetInterface(i)
|
let builderinter = info.gObjectInfoGetInterface(i)
|
||||||
if gBaseInfoGetName(builderinter) == "Buildable":
|
if gBaseInfoGetName(builderinter) == "Buildable":
|
||||||
|
|
@ -2307,15 +2398,11 @@ proc uint8ArrayZT2seq*(p: pointer): seq[uint8] =
|
||||||
var more_runs = 50
|
var more_runs = 50
|
||||||
while s.len > 0 or more_runs > 0:
|
while s.len > 0 or more_runs > 0:
|
||||||
if s.len == 0: dec(more_runs)
|
if s.len == 0: dec(more_runs)
|
||||||
if namespace == "GObject" and not knownSyms.contains(
|
if namespace == "GObject" and not knownSyms.contains("g_signal_connect_data"):
|
||||||
"g_signal_connect_data"):
|
if knownSyms.contains("ClosureNotify") and knownSyms.contains("ConnectFlags"):
|
||||||
if knownSyms.contains("ClosureNotify") and knownSyms.contains(
|
|
||||||
"ConnectFlags"):
|
|
||||||
knownSyms.incl("g_signal_connect_data")
|
knownSyms.incl("g_signal_connect_data")
|
||||||
output.writeLine(
|
output.writeLine("proc g_signal_connect_data*(instance: pointer; detailedSignal: cstring; cHandler: GCallback;")
|
||||||
"proc g_signal_connect_data*(instance: pointer; detailedSignal: cstring; cHandler: GCallback;")
|
output.writeLine(" data: pointer; destroyData: ClosureNotify; connectFlags: ConnectFlags): culong {.")
|
||||||
output.writeLine(
|
|
||||||
" data: pointer; destroyData: ClosureNotify; connectFlags: ConnectFlags): culong {.")
|
|
||||||
output.writeLine(" importc: \"g_signal_connect_data\", libprag.}")
|
output.writeLine(" importc: \"g_signal_connect_data\", libprag.}")
|
||||||
while priList.len > 0: # move missing symbols to top, but only once!
|
while priList.len > 0: # move missing symbols to top, but only once!
|
||||||
let h = priList.pop
|
let h = priList.pop
|
||||||
|
|
@ -2370,6 +2457,9 @@ proc uint8ArrayZT2seq*(p: pointer): seq[uint8] =
|
||||||
methodBuffer = newStringStream()
|
methodBuffer = newStringStream()
|
||||||
signalBuffer = newStringStream()
|
signalBuffer = newStringStream()
|
||||||
let x = delayedMethods.len
|
let x = delayedMethods.len
|
||||||
|
#var processedFunctionsBack = processedFunctions # var due to https://forum.nim-lang.org/t/6312
|
||||||
|
tempProcessedFunctions.setLen(0)
|
||||||
|
useTempProcessedFunctions = true
|
||||||
try:
|
try:
|
||||||
var h = false
|
var h = false
|
||||||
for k in t:
|
for k in t:
|
||||||
|
|
@ -2384,8 +2474,7 @@ proc uint8ArrayZT2seq*(p: pointer): seq[uint8] =
|
||||||
for k in t:
|
for k in t:
|
||||||
processInfo(k)
|
processInfo(k)
|
||||||
for k in t:
|
for k in t:
|
||||||
delayedSyms.keepItIf(mangleName(gBaseInfoGetName(
|
delayedSyms.keepItIf(mangleName(gBaseInfoGetName(k)) != mangleName(gBaseInfoGetName(it)))
|
||||||
k)) != mangleName(gBaseInfoGetName(it)))
|
|
||||||
suppressType = false
|
suppressType = false
|
||||||
output.write(signalBuffer.data)
|
output.write(signalBuffer.data)
|
||||||
output.write(methodBuffer.data)
|
output.write(methodBuffer.data)
|
||||||
|
|
@ -2396,6 +2485,10 @@ proc uint8ArrayZT2seq*(p: pointer): seq[uint8] =
|
||||||
output.setPosition(pos)
|
output.setPosition(pos)
|
||||||
supmod3.cut(supmodpos3)
|
supmod3.cut(supmodpos3)
|
||||||
supmod4.cut(supmodpos4)
|
supmod4.cut(supmodpos4)
|
||||||
|
#processedFunctions = processedFunctionsBack #
|
||||||
|
for el in tempProcessedFunctions:
|
||||||
|
processedFunctions.excl(el)
|
||||||
|
useTempProcessedFunctions = false
|
||||||
assert delayedMethods.len >= x
|
assert delayedMethods.len >= x
|
||||||
delayedMethods.setLen(x)
|
delayedMethods.setLen(x)
|
||||||
suppressType = false
|
suppressType = false
|
||||||
|
|
@ -2411,8 +2504,7 @@ proc uint8ArrayZT2seq*(p: pointer): seq[uint8] =
|
||||||
assert false
|
assert false
|
||||||
processInfo(i)
|
processInfo(i)
|
||||||
if externInterfaces.len > 0:
|
if externInterfaces.len > 0:
|
||||||
output.writeLine(
|
output.writeLine("\n# Extern interfaces: (we don't use converters, but explicit procs for now.)")
|
||||||
"\n# Extern interfaces: (we don't use converters, but explicit procs for now.)")
|
|
||||||
for i in externInterfaces:
|
for i in externInterfaces:
|
||||||
output.writeLine("")
|
output.writeLine("")
|
||||||
output.writeLine(i)
|
output.writeLine(i)
|
||||||
|
|
@ -2424,10 +2516,14 @@ proc init* =
|
||||||
var argc: int32 = 0
|
var argc: int32 = 0
|
||||||
var argv: cstringArray = nil
|
var argv: cstringArray = nil
|
||||||
gst_init(argc, argv)
|
gst_init(argc, argv)
|
||||||
|
|
||||||
|
proc getType*(m: gst.Message): gst.MessageType =
|
||||||
|
m.impl.type
|
||||||
""")
|
""")
|
||||||
|
|
||||||
if namespace == "Gtk":
|
if namespace == "Gtk":
|
||||||
if ISGTK3:
|
if ISGTK3:
|
||||||
|
output.write(GTK3_EPI)
|
||||||
output.write(
|
output.write(
|
||||||
"""
|
"""
|
||||||
proc init* =
|
proc init* =
|
||||||
|
|
@ -2506,7 +2602,7 @@ proc get$1*(builder: Builder; name: string): $1 =
|
||||||
|
|
||||||
if namespace == "Gdk":
|
if namespace == "Gdk":
|
||||||
if ISGTK3:
|
if ISGTK3:
|
||||||
output.write(GDK3_EPI)
|
output.write(GDK3_EPI.replace("SomeEvent", "Event"))
|
||||||
output.write(GDK_EPI.replace("SomeEvent", "Event"))
|
output.write(GDK_EPI.replace("SomeEvent", "Event"))
|
||||||
if namespace == "GtkSource":
|
if namespace == "GtkSource":
|
||||||
output.write(GTK_SOURCE_EPI)
|
output.write(GTK_SOURCE_EPI)
|
||||||
|
|
@ -2612,4 +2708,4 @@ proc launch() =
|
||||||
supmod4.close
|
supmod4.close
|
||||||
|
|
||||||
launch()
|
launch()
|
||||||
# 2615 lines
|
# 2711 lines
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue