various fixes
This commit is contained in:
parent
fd90029090
commit
8a59ea33d0
5 changed files with 668 additions and 50 deletions
87
README.adoc
87
README.adoc
|
|
@ -841,14 +841,13 @@ main()
|
||||||
== A more advanced example for cairo drawing with zooming, panning, scrolling
|
== A more advanced example for cairo drawing with zooming, panning, scrolling
|
||||||
|
|
||||||
The following code is a plain Nim version of a drawing demo which I wrote some years ago in Ruby (http://ssalewski.de/PetEd-Demo.html.en).
|
The following code is a plain Nim version of a drawing demo which I wrote some years ago in Ruby (http://ssalewski.de/PetEd-Demo.html.en).
|
||||||
With the latest fix to Nim GTK3 bingings it seems to work fine, but some rewriting for optimized performance
|
With the latest fix to Nim GTK3 bindings it seems to work fine, but some rewriting for optimized performance
|
||||||
may be needed, I have to investigate that.
|
may be needed, I have to investigate that. Cairo surface is currently manually freed, because GC may have a too large delay.
|
||||||
|
Later we may use Destructors for that.
|
||||||
|
|
||||||
NOTE: The latest needed gintro patch is not yet available, I will provide it soon...
|
[[drawingarea.nim]]
|
||||||
|
|
||||||
[[cairo2.nim]]
|
|
||||||
[source,nim]
|
[source,nim]
|
||||||
.cairo2.nim
|
.drawingarea.nim
|
||||||
----
|
----
|
||||||
# Plain demo for zooming, panning, scrolling with GTK DrawingArea
|
# Plain demo for zooming, panning, scrolling with GTK DrawingArea
|
||||||
# (c) S. Salewski, 21-DEC-2010 (initial Ruby version)
|
# (c) S. Salewski, 21-DEC-2010 (initial Ruby version)
|
||||||
|
|
@ -879,7 +878,7 @@ proc drawWorld(cr: cairo.Context) =
|
||||||
cr.rectangle(DataX, DataY, DataWidth, DataHeight)
|
cr.rectangle(DataX, DataY, DataWidth, DataHeight)
|
||||||
var i = 10.0
|
var i = 10.0
|
||||||
while true:
|
while true:
|
||||||
if [DataWidth - 2.0 * i, DataHeight - 2.0 * i].min <= 0:
|
if min(DataWidth - 2.0 * i, DataHeight - 2.0 * i) <= 0:
|
||||||
break
|
break
|
||||||
cr.rectangle(DataX + i, DataY + i, DataWidth - 2.0 * i,
|
cr.rectangle(DataX + i, DataY + i, DataWidth - 2.0 * i,
|
||||||
DataHeight - 2.0 * i)
|
DataHeight - 2.0 * i)
|
||||||
|
|
@ -933,7 +932,7 @@ proc newPosAdj: PosAdj =
|
||||||
initAdjustment(result, 0, 0, 1, 1, 10, 1)
|
initAdjustment(result, 0, 0, 1, 1, 10, 1)
|
||||||
|
|
||||||
type
|
type
|
||||||
PDA = ref object of Table
|
PDA = ref object of Grid
|
||||||
zoomNearMousepointer: bool
|
zoomNearMousepointer: bool
|
||||||
selecting: bool
|
selecting: bool
|
||||||
userZoom: float
|
userZoom: float
|
||||||
|
|
@ -973,7 +972,7 @@ proc drawingAreaDrawCb(darea: DrawingArea; cr: Context; this: PDA): bool =
|
||||||
# clamp to correct values, 0 <= value <= (adj.upper - adj.pageSize), block calling onAdjustmentEvent()
|
# clamp to correct values, 0 <= value <= (adj.upper - adj.pageSize), block calling onAdjustmentEvent()
|
||||||
proc updateVal(adj: PosAdj; d: float) =
|
proc updateVal(adj: PosAdj; d: float) =
|
||||||
adj.signalHandlerBlock(adj.handlerID)
|
adj.signalHandlerBlock(adj.handlerID)
|
||||||
adj.setValue([0.0, [adj.value + d, adj.upper - adj.pageSize].min].max)
|
adj.setValue(max(0.0, min(adj.value + d, adj.upper - adj.pageSize)))
|
||||||
adj.signalHandlerUnblock(adj.handlerID)
|
adj.signalHandlerUnblock(adj.handlerID)
|
||||||
|
|
||||||
proc updateAdjustments(this: PDA; dx, dy: float) =
|
proc updateAdjustments(this: PDA; dx, dy: float) =
|
||||||
|
|
@ -991,7 +990,7 @@ proc updateAdjustments(this: PDA; dx, dy: float) =
|
||||||
# or maybe even better do all drwing from within "draw" callback?
|
# or maybe even better do all drwing from within "draw" callback?
|
||||||
proc paint(this: PDA) =
|
proc paint(this: PDA) =
|
||||||
if this.surf != nil:
|
if this.surf != nil:
|
||||||
cairosurfaceDestroy(this.surf.impl) # we may have to fix that later for automatically destroy
|
cairosurfaceDestroy(this.surf.impl) # we may have to fix that later for automatically destroy
|
||||||
this.surf = this.darea.window.createSimilarSurface(Content.color,
|
this.surf = this.darea.window.createSimilarSurface(Content.color,
|
||||||
this.darea.allocatedWidth, this.darea.allocatedHeight)
|
this.darea.allocatedWidth, this.darea.allocatedHeight)
|
||||||
let cr = newContext(this.surf)
|
let cr = newContext(this.surf)
|
||||||
|
|
@ -1007,8 +1006,8 @@ proc dareaConfigureCallback(darea: DrawingArea; event: EventConfigure;
|
||||||
this.updateAdjustments(0, 0)
|
this.updateAdjustments(0, 0)
|
||||||
(this.dataX, this.dataY, this.dataWidth,
|
(this.dataX, this.dataY, this.dataWidth,
|
||||||
this.dataHeight) = getWorldExtends() # query user defined size
|
this.dataHeight) = getWorldExtends() # query user defined size
|
||||||
this.fullScale = [this.darea.allocatedWidth.float / this.dataWidth,
|
this.fullScale = min(this.darea.allocatedWidth.float / this.dataWidth,
|
||||||
this.darea.allocatedHeight.float / this.dataHeight].min
|
this.darea.allocatedHeight.float / this.dataHeight)
|
||||||
this.paint
|
this.paint
|
||||||
|
|
||||||
proc updateAdjustmentsAndPaint(this: PDA; dx, dy: float) =
|
proc updateAdjustmentsAndPaint(this: PDA; dx, dy: float) =
|
||||||
|
|
@ -1017,11 +1016,17 @@ proc updateAdjustmentsAndPaint(this: PDA; dx, dy: float) =
|
||||||
this.darea.queueDrawArea(0, 0, this.darea.allocatedWidth,
|
this.darea.queueDrawArea(0, 0, this.darea.allocatedWidth,
|
||||||
this.darea.allocatedHeight)
|
this.darea.allocatedHeight)
|
||||||
|
|
||||||
|
# event coordinates to user space
|
||||||
|
proc getUserCoordinates(this: PDA; eventX, eventY: float): (float, float) =
|
||||||
|
((eventX - this.hadjustment.upper * 0.5 + this.hadjustment.value) / (
|
||||||
|
this.fullScale * this.userZoom) + this.dataX + this.dataWidth * 0.5,
|
||||||
|
(eventY - this.vadjustment.upper * 0.5 + this.vadjustment.value) / (
|
||||||
|
this.fullScale * this.userZoom) + this.dataY + this.dataHeight * 0.5)
|
||||||
|
|
||||||
proc onMotion(darea: DrawingArea; event: EventMotion; this: PDA): bool =
|
proc onMotion(darea: DrawingArea; event: EventMotion; this: PDA): bool =
|
||||||
var state: ModifierType
|
let state = getState(event)
|
||||||
discard event.state(state)
|
let (x, y) = event.getCoords
|
||||||
var x, y: float
|
#(x, y) = this.getUserCoordinates(x, y)
|
||||||
discard event.getCoords(x, y)
|
|
||||||
if (state.contains(button1)): # selecting
|
if (state.contains(button1)): # selecting
|
||||||
this.selecting = true
|
this.selecting = true
|
||||||
this.zoomRectX1 = x
|
this.zoomRectX1 = x
|
||||||
|
|
@ -1040,10 +1045,8 @@ proc onMotion(darea: DrawingArea; event: EventMotion; this: PDA): bool =
|
||||||
# is the relative movement caused by zooming
|
# is the relative movement caused by zooming
|
||||||
proc scrollEvent(darea: DrawingArea; event: EventScroll; this: PDA): bool =
|
proc scrollEvent(darea: DrawingArea; event: EventScroll; this: PDA): bool =
|
||||||
let z0 = this.userZoom
|
let z0 = this.userZoom
|
||||||
var d: ScrollDirection
|
var d = getScrollDirection(event)
|
||||||
discard scrollDirection(event, d)
|
var (x, y) = event.getCoords
|
||||||
var x, y: float
|
|
||||||
discard event.getCoords(x, y)
|
|
||||||
if d == ScrollDirection.up:
|
if d == ScrollDirection.up:
|
||||||
this.userZoom *= ZOOM_FACTOR_MOUSE_WHEEL
|
this.userZoom *= ZOOM_FACTOR_MOUSE_WHEEL
|
||||||
elif d == ScrollDirection.down:
|
elif d == ScrollDirection.down:
|
||||||
|
|
@ -1059,38 +1062,30 @@ proc scrollEvent(darea: DrawingArea; event: EventScroll; this: PDA): bool =
|
||||||
this.updateAdjustmentsAndPaint((this.hadjustment.value +
|
this.updateAdjustmentsAndPaint((this.hadjustment.value +
|
||||||
this.darea.allocatedWidth.float * 0.5) * (this.userZoom / z0 - 1),
|
this.darea.allocatedWidth.float * 0.5) * (this.userZoom / z0 - 1),
|
||||||
(this.vadjustment.value +
|
(this.vadjustment.value +
|
||||||
this.darea.allocatedHeight.float * 0.5) * (this.userZoom / z0 - 1))
|
this.darea.allocatedHeight.float * 0.5) * (
|
||||||
|
this.userZoom / z0 - 1))
|
||||||
# event coordinates to user space
|
|
||||||
proc getUserCoordinates(this: PDA; eventX, eventY: float): (float, float) =
|
|
||||||
((eventX - this.hadjustment.upper * 0.5 + this.hadjustment.value) / (
|
|
||||||
this.fullScale * this.userZoom) + this.dataX + this.dataWidth * 0.5,
|
|
||||||
(eventY - this.vadjustment.upper * 0.5 + this.vadjustment.value) / (
|
|
||||||
this.fullScale * this.userZoom) + this.dataY + this.dataHeight * 0.5)
|
|
||||||
|
|
||||||
proc buttonPressEvent(darea: DrawingArea; event: EventButton;
|
proc buttonPressEvent(darea: DrawingArea; event: EventButton;
|
||||||
this: PDA): bool =
|
this: PDA): bool =
|
||||||
var x, y: float
|
var (x, y) = event.getCoords
|
||||||
discard event.getCoords(x, y)
|
|
||||||
(x, y) = this.getUserCoordinates(x, y)
|
|
||||||
echo "User coordinates: ", x, ' ', y, "\n" # to verify getUserCoordinates()
|
|
||||||
this.lastMousePosX = x
|
this.lastMousePosX = x
|
||||||
this.lastMousePosY = y
|
this.lastMousePosY = y
|
||||||
this.lastButtonDownPosX = x
|
this.lastButtonDownPosX = x
|
||||||
this.lastButtonDownPosY = y
|
this.lastButtonDownPosY = y
|
||||||
|
echo "buttonPressEvent", x, " ", y
|
||||||
|
(x, y) = this.getUserCoordinates(x, y)
|
||||||
|
echo "User coordinates: ", x, ' ', y, "\n" # to verify getUserCoordinates()
|
||||||
|
|
||||||
# zoom into selected rectangle and center it
|
# zoom into selected rectangle and center it
|
||||||
proc buttonReleaseEvent(darea: DrawingArea; event: EventButton;
|
proc buttonReleaseEvent(darea: DrawingArea; event: EventButton;
|
||||||
this: PDA): bool =
|
this: PDA): bool =
|
||||||
var x, y: float
|
var (x, y) = event.getCoords
|
||||||
discard event.getCoords(x, y)
|
var b = getButton(event)
|
||||||
var b: int
|
|
||||||
discard button(event, b)
|
|
||||||
if b == 1:
|
if b == 1:
|
||||||
this.selecting = false
|
this.selecting = false
|
||||||
let z1 = [this.darea.allocatedWidth.float / (
|
let z1 = min(this.darea.allocatedWidth.float / (
|
||||||
this.lastButtonDownPosX - x).abs, this.darea.allocatedHeight.float / (
|
this.lastButtonDownPosX - x).abs, this.darea.allocatedHeight.float / (
|
||||||
this.lastButtonDownPosY - y).abs].min
|
this.lastButtonDownPosY - y).abs)
|
||||||
if z1 < ZOOM_FACTOR_SELECT_MAX: # else selection rectangle will persist, we may output a message...
|
if z1 < ZOOM_FACTOR_SELECT_MAX: # else selection rectangle will persist, we may output a message...
|
||||||
this.userZoom *= z1
|
this.userZoom *= z1
|
||||||
this.updateAdjustmentsAndPaint(
|
this.updateAdjustmentsAndPaint(
|
||||||
|
|
@ -1105,13 +1100,14 @@ proc onAdjustmentEvent(this: PosAdj; pda: PDA) =
|
||||||
pda.darea.allocatedHeight)
|
pda.darea.allocatedHeight)
|
||||||
|
|
||||||
proc newPDA: PDA =
|
proc newPDA: PDA =
|
||||||
initTable(result, 2, 2, false)
|
initGrid(result)
|
||||||
result.zoomNearMousepointer = ZOOM_NEAR_MOUSEPOINTER # mouse wheel zooming
|
result.zoomNearMousepointer = ZOOM_NEAR_MOUSEPOINTER # mouse wheel zooming
|
||||||
result.selecting = false
|
result.selecting = false
|
||||||
result.userZoom = 1.0
|
result.userZoom = 1.0
|
||||||
result.surf = nil
|
result.surf = nil
|
||||||
result.darea = newDrawingArea()
|
result.darea = newDrawingArea()
|
||||||
|
result.darea.setHExpand#(true)
|
||||||
|
result.darea.setVExpand#(true)
|
||||||
result.darea.connect("draw", drawingAreaDrawCb, result)
|
result.darea.connect("draw", drawingAreaDrawCb, result)
|
||||||
result.darea.connect("configure-event", dareaConfigureCallback, result)
|
result.darea.connect("configure-event", dareaConfigureCallback, result)
|
||||||
result.darea.addEvents({EventFlag.buttonPress, EventFlag.buttonRelease,
|
result.darea.addEvents({EventFlag.buttonPress, EventFlag.buttonRelease,
|
||||||
|
|
@ -1130,12 +1126,11 @@ proc newPDA: PDA =
|
||||||
onAdjustmentEvent, result)
|
onAdjustmentEvent, result)
|
||||||
result.hscrollbar = newScrollbar(Orientation.horizontal, result.hadjustment)
|
result.hscrollbar = newScrollbar(Orientation.horizontal, result.hadjustment)
|
||||||
result.vscrollbar = newScrollbar(Orientation.vertical, result.vadjustment)
|
result.vscrollbar = newScrollbar(Orientation.vertical, result.vadjustment)
|
||||||
result.attach(result.darea, 0, 1, 0, 1, {AttachFlag.expand, AttachFlag.fill}, {
|
result.hscrollbar.setHExpand#(true)
|
||||||
AttachFlag.expand, AttachFlag.fill}, 0, 0)
|
result.vscrollbar.setVExpand#(true)
|
||||||
result.attach(result.hscrollbar, 0, 1, 1, 2, {AttachFlag.expand,
|
result.attach(result.darea, 0, 0, 1, 1)
|
||||||
AttachFlag.fill}, {}, 0, 0)
|
result.attach(result.vscrollbar, 1, 0, 1, 1)
|
||||||
result.attach(result.vscrollbar, 1, 2, 0, 1, {}, {AttachFlag.expand,
|
result.attach(result.hscrollbar, 0, 1, 1, 1)
|
||||||
AttachFlag.fill}, 0, 0)
|
|
||||||
|
|
||||||
proc appActivate(app: Application) =
|
proc appActivate(app: Application) =
|
||||||
let window = newApplicationWindow(app)
|
let window = newApplicationWindow(app)
|
||||||
|
|
|
||||||
297
examples/drawingarea.nim
Normal file
297
examples/drawingarea.nim
Normal file
|
|
@ -0,0 +1,297 @@
|
||||||
|
# Plain demo for zooming, panning, scrolling with GTK DrawingArea
|
||||||
|
# (c) S. Salewski, 21-DEC-2010 (initial Ruby version)
|
||||||
|
# Nim version April 2019 -- well first draft :-)
|
||||||
|
# License MIT
|
||||||
|
|
||||||
|
import gintro/[gtk, gdk, glib, gobject, gio, cairo]
|
||||||
|
|
||||||
|
const
|
||||||
|
DataX = 150.0
|
||||||
|
DataY = 250.0
|
||||||
|
DataWidth = 200.0
|
||||||
|
DataHeight = 120.0
|
||||||
|
|
||||||
|
# The following two functions are intended to be user defined -- we have still
|
||||||
|
# to investigate how to do that best.
|
||||||
|
|
||||||
|
# bounding box of user data -- x, y, w, h -- top left corner, width, height
|
||||||
|
proc getWorldExtends(): (float, float, float, float) =
|
||||||
|
(DataX, DataY, DataWidth, DataHeight) # current extents of our user world
|
||||||
|
|
||||||
|
# draw to cairo context
|
||||||
|
proc drawWorld(cr: cairo.Context) =
|
||||||
|
cr.setSource(1, 1, 1)
|
||||||
|
cr.paint
|
||||||
|
cr.setSource(0, 0, 0)
|
||||||
|
cr.setLineWidth(2)
|
||||||
|
cr.rectangle(DataX, DataY, DataWidth, DataHeight)
|
||||||
|
var i = 10.0
|
||||||
|
while true:
|
||||||
|
if min(DataWidth - 2.0 * i, DataHeight - 2.0 * i) <= 0:
|
||||||
|
break
|
||||||
|
cr.rectangle(DataX + i, DataY + i, DataWidth - 2.0 * i,
|
||||||
|
DataHeight - 2.0 * i)
|
||||||
|
i += 10.0
|
||||||
|
cr.stroke
|
||||||
|
|
||||||
|
const
|
||||||
|
|
||||||
|
ZOOM_FACTOR_MOUSE_WHEEL = 1.1
|
||||||
|
ZOOM_FACTOR_SELECT_MAX = 10 # ignore zooming in tiny selection
|
||||||
|
ZOOM_NEAR_MOUSEPOINTER = true # mouse wheel zooming -- to mousepointer or center
|
||||||
|
SELECT_RECT_COL = [0.0, 0, 1, 0.5] # blue with transparency
|
||||||
|
|
||||||
|
discard """
|
||||||
|
Zooming, scrolling, panning...
|
||||||
|
|
||||||
|
|-------------------------|
|
||||||
|
|<-------- A ------------>|
|
||||||
|
| |
|
||||||
|
| |---------------| |
|
||||||
|
| | <---- a ----->| |
|
||||||
|
| | visible | |
|
||||||
|
| |---------------| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
|-------------------------|
|
||||||
|
|
||||||
|
a is the visible, zoomed in area == darea.allocatedWidth
|
||||||
|
A is the total data range
|
||||||
|
A/a == userZoom >= 1
|
||||||
|
For horizontal adjustment we use
|
||||||
|
hadjustment.setUpper(darea.allocatedWidth * userZoom) == A
|
||||||
|
hadjustment.setPageSize(darea.allocatedWidth) == a
|
||||||
|
So hadjustment.value == left side of visible area
|
||||||
|
|
||||||
|
Initially, we set userZoom = 1, scale our data to fit into darea.allocatedWidth
|
||||||
|
and translate the origin of our data to (0, 0)
|
||||||
|
|
||||||
|
Zooming: Mouse wheel or selecting a rectangle with left mouse button pressed
|
||||||
|
Scrolling: Scrollbars
|
||||||
|
Panning: Moving mouse while middle mouse button pressed
|
||||||
|
"""
|
||||||
|
|
||||||
|
# drawing area and scroll bars in 2x2 table (PDA == Plain Drawing Area)
|
||||||
|
|
||||||
|
type
|
||||||
|
PosAdj = ref object of Adjustment
|
||||||
|
handlerID: uint64
|
||||||
|
|
||||||
|
proc newPosAdj: PosAdj =
|
||||||
|
initAdjustment(result, 0, 0, 1, 1, 10, 1)
|
||||||
|
|
||||||
|
type
|
||||||
|
PDA = ref object of Grid
|
||||||
|
zoomNearMousepointer: bool
|
||||||
|
selecting: bool
|
||||||
|
userZoom: float
|
||||||
|
surf: Surface
|
||||||
|
darea: DrawingArea
|
||||||
|
hadjustment: PosAdj
|
||||||
|
vadjustment: PosAdj
|
||||||
|
hscrollbar: Scrollbar
|
||||||
|
vscrollbar: Scrollbar
|
||||||
|
fullScale: float
|
||||||
|
dataX: float
|
||||||
|
dataY: float
|
||||||
|
dataWidth: float
|
||||||
|
dataHeight: float
|
||||||
|
lastButtonDownPosX: float
|
||||||
|
lastButtonDownPosY: float
|
||||||
|
lastMousePosX: float
|
||||||
|
lastMousePosY: float
|
||||||
|
zoomRectX1: float
|
||||||
|
zoomRectY1: float
|
||||||
|
|
||||||
|
proc drawingAreaDrawCb(darea: DrawingArea; cr: Context; this: PDA): bool =
|
||||||
|
if this.surf.isNil: return
|
||||||
|
cr.setSource(patternCreateForSurface(this.surf))
|
||||||
|
cr.paint
|
||||||
|
if this.selecting:
|
||||||
|
cr.rectangle(this.lastButtonDownPosX, 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.fillPreserve
|
||||||
|
cr.setSource(0, 0, 0)
|
||||||
|
cr.setLineWidth(2)
|
||||||
|
cr.stroke
|
||||||
|
return true # TRUE to stop other handlers from being invoked for the event. FALSE to propagate the event further.
|
||||||
|
|
||||||
|
# clamp to correct values, 0 <= value <= (adj.upper - adj.pageSize), block calling onAdjustmentEvent()
|
||||||
|
proc updateVal(adj: PosAdj; d: float) =
|
||||||
|
adj.signalHandlerBlock(adj.handlerID)
|
||||||
|
adj.setValue(max(0.0, min(adj.value + d, adj.upper - adj.pageSize)))
|
||||||
|
adj.signalHandlerUnblock(adj.handlerID)
|
||||||
|
|
||||||
|
proc updateAdjustments(this: PDA; dx, dy: float) =
|
||||||
|
this.hadjustment.setUpper(this.darea.allocatedWidth.float * this.userZoom)
|
||||||
|
this.vadjustment.setUpper(this.darea.allocatedHeight.float *
|
||||||
|
this.userZoom)
|
||||||
|
this.hadjustment.setPageSize(this.darea.allocatedWidth.float)
|
||||||
|
this.vadjustment.setPageSize(this.darea.allocatedHeight.float)
|
||||||
|
updateVal(this.hadjustment, dx)
|
||||||
|
updateVal(this.vadjustment, dy)
|
||||||
|
|
||||||
|
# Maybe we should fix this for latest GTK3, see
|
||||||
|
# https://developer.gnome.org/gdk3/stable/gdk3-Cairo-Interaction.html
|
||||||
|
# so use gdk_drawing_context_get_cairo_context ()
|
||||||
|
# or maybe even better do all drwing from within "draw" callback?
|
||||||
|
proc paint(this: PDA) =
|
||||||
|
if this.surf != nil:
|
||||||
|
cairosurfaceDestroy(this.surf.impl) # we may have to fix that later for automatically destroy
|
||||||
|
this.surf = this.darea.window.createSimilarSurface(Content.color,
|
||||||
|
this.darea.allocatedWidth, this.darea.allocatedHeight)
|
||||||
|
let cr = newContext(this.surf)
|
||||||
|
cr.translate(this.hadjustment.upper * 0.5 - this.hadjustment.value, # our origin is the center
|
||||||
|
this.vadjustment.upper * 0.5 - this.vadjustment.value)
|
||||||
|
cr.scale(this.fullScale * this.userZoom, this.fullScale * this.userZoom)
|
||||||
|
cr.translate(-this.dataX - this.dataWidth * 0.5,
|
||||||
|
-this.dataY - this.dataHeight * 0.5)
|
||||||
|
drawWorld(cr) # call the user provided drawing fonction
|
||||||
|
|
||||||
|
proc dareaConfigureCallback(darea: DrawingArea; event: EventConfigure;
|
||||||
|
this: PDA): bool =
|
||||||
|
this.updateAdjustments(0, 0)
|
||||||
|
(this.dataX, this.dataY, this.dataWidth,
|
||||||
|
this.dataHeight) = getWorldExtends() # query user defined size
|
||||||
|
this.fullScale = min(this.darea.allocatedWidth.float / this.dataWidth,
|
||||||
|
this.darea.allocatedHeight.float / this.dataHeight)
|
||||||
|
this.paint
|
||||||
|
|
||||||
|
proc updateAdjustmentsAndPaint(this: PDA; dx, dy: float) =
|
||||||
|
this.updateAdjustments(dx, dy)
|
||||||
|
this.paint
|
||||||
|
this.darea.queueDrawArea(0, 0, this.darea.allocatedWidth,
|
||||||
|
this.darea.allocatedHeight)
|
||||||
|
|
||||||
|
# event coordinates to user space
|
||||||
|
proc getUserCoordinates(this: PDA; eventX, eventY: float): (float, float) =
|
||||||
|
((eventX - this.hadjustment.upper * 0.5 + this.hadjustment.value) / (
|
||||||
|
this.fullScale * this.userZoom) + this.dataX + this.dataWidth * 0.5,
|
||||||
|
(eventY - this.vadjustment.upper * 0.5 + this.vadjustment.value) / (
|
||||||
|
this.fullScale * this.userZoom) + this.dataY + this.dataHeight * 0.5)
|
||||||
|
|
||||||
|
proc onMotion(darea: DrawingArea; event: EventMotion; this: PDA): bool =
|
||||||
|
let state = getState(event)
|
||||||
|
let (x, y) = event.getCoords
|
||||||
|
#(x, y) = this.getUserCoordinates(x, y)
|
||||||
|
if (state.contains(button1)): # selecting
|
||||||
|
this.selecting = true
|
||||||
|
this.zoomRectX1 = x
|
||||||
|
this.zoomRectY1 = y
|
||||||
|
this.darea.queueDrawArea(0, 0, this.darea.allocatedWidth,
|
||||||
|
this.darea.allocatedHeight)
|
||||||
|
elif button2 in state: # panning
|
||||||
|
this.updateAdjustmentsAndPaint(this.lastMousePosX - x,
|
||||||
|
this.lastMousePosY - y)
|
||||||
|
this.lastMousePosX = x
|
||||||
|
this.lastMousePosY = y
|
||||||
|
#event.request # request more motion events ?
|
||||||
|
|
||||||
|
# zooming with mouse wheel -- data near mouse pointer should not move if possible!
|
||||||
|
# hadjustment.value + event.x is the position in our zoomed_in world, (userZoom / z0 - 1)
|
||||||
|
# is the relative movement caused by zooming
|
||||||
|
proc scrollEvent(darea: DrawingArea; event: EventScroll; this: PDA): bool =
|
||||||
|
let z0 = this.userZoom
|
||||||
|
var d = getScrollDirection(event)
|
||||||
|
var (x, y) = event.getCoords
|
||||||
|
if d == ScrollDirection.up:
|
||||||
|
this.userZoom *= ZOOM_FACTOR_MOUSE_WHEEL
|
||||||
|
elif d == ScrollDirection.down:
|
||||||
|
this.userZoom /= ZOOM_FACTOR_MOUSE_WHEEL
|
||||||
|
if (this.userZoom < 1):
|
||||||
|
this.userZoom = 1
|
||||||
|
if this.zoomNearMousepointer:
|
||||||
|
this.updateAdjustmentsAndPaint((this.hadjustment.value + x) * (
|
||||||
|
this.userZoom / z0 - 1),
|
||||||
|
(this.vadjustment.value + y) * (
|
||||||
|
this.userZoom / z0 - 1))
|
||||||
|
else: # zoom to center
|
||||||
|
this.updateAdjustmentsAndPaint((this.hadjustment.value +
|
||||||
|
this.darea.allocatedWidth.float * 0.5) * (this.userZoom / z0 - 1),
|
||||||
|
(this.vadjustment.value +
|
||||||
|
this.darea.allocatedHeight.float * 0.5) * (
|
||||||
|
this.userZoom / z0 - 1))
|
||||||
|
|
||||||
|
proc buttonPressEvent(darea: DrawingArea; event: EventButton;
|
||||||
|
this: PDA): bool =
|
||||||
|
var (x, y) = event.getCoords
|
||||||
|
this.lastMousePosX = x
|
||||||
|
this.lastMousePosY = y
|
||||||
|
this.lastButtonDownPosX = x
|
||||||
|
this.lastButtonDownPosY = y
|
||||||
|
echo "buttonPressEvent", x, " ", y
|
||||||
|
(x, y) = this.getUserCoordinates(x, y)
|
||||||
|
echo "User coordinates: ", x, ' ', y, "\n" # to verify getUserCoordinates()
|
||||||
|
|
||||||
|
# zoom into selected rectangle and center it
|
||||||
|
proc buttonReleaseEvent(darea: DrawingArea; event: EventButton;
|
||||||
|
this: PDA): bool =
|
||||||
|
var (x, y) = event.getCoords
|
||||||
|
var b = getButton(event)
|
||||||
|
if b == 1:
|
||||||
|
this.selecting = false
|
||||||
|
let z1 = min(this.darea.allocatedWidth.float / (
|
||||||
|
this.lastButtonDownPosX - x).abs, this.darea.allocatedHeight.float / (
|
||||||
|
this.lastButtonDownPosY - y).abs)
|
||||||
|
if z1 < ZOOM_FACTOR_SELECT_MAX: # else selection rectangle will persist, we may output a message...
|
||||||
|
this.userZoom *= z1
|
||||||
|
this.updateAdjustmentsAndPaint(
|
||||||
|
((2 * this.hadjustment.value + x + this.lastButtonDownPosX) * z1 -
|
||||||
|
this.darea.allocatedWidth.float) * 0.5 - this.hadjustment.value,
|
||||||
|
((2 * this.vadjustment.value + y + this.lastButtonDownPosY) * z1 -
|
||||||
|
this.darea.allocatedHeight.float) * 0.5 - this.vadjustment.value)
|
||||||
|
|
||||||
|
proc onAdjustmentEvent(this: PosAdj; pda: PDA) =
|
||||||
|
pda.paint
|
||||||
|
pda.darea.queueDrawArea(0, 0, pda.darea.allocatedWidth,
|
||||||
|
pda.darea.allocatedHeight)
|
||||||
|
|
||||||
|
proc newPDA: PDA =
|
||||||
|
initGrid(result)
|
||||||
|
result.zoomNearMousepointer = ZOOM_NEAR_MOUSEPOINTER # mouse wheel zooming
|
||||||
|
result.selecting = false
|
||||||
|
result.userZoom = 1.0
|
||||||
|
result.surf = nil
|
||||||
|
result.darea = newDrawingArea()
|
||||||
|
result.darea.setHExpand#(true)
|
||||||
|
result.darea.setVExpand#(true)
|
||||||
|
result.darea.connect("draw", drawingAreaDrawCb, result)
|
||||||
|
result.darea.connect("configure-event", dareaConfigureCallback, result)
|
||||||
|
result.darea.addEvents({EventFlag.buttonPress, EventFlag.buttonRelease,
|
||||||
|
EventFlag.scroll,
|
||||||
|
EventFlag.button1Motion, EventFlag.button2Motion,
|
||||||
|
EventFlag.pointerMotionHint})
|
||||||
|
result.darea.connect("motion-notify-event", onMotion, result)
|
||||||
|
result.darea.connect("scroll_event", scrollEvent, result)
|
||||||
|
result.darea.connect("button_press_event", buttonPressEvent, result)
|
||||||
|
result.darea.connect("button_release_event", buttonReleaseEvent, result)
|
||||||
|
result.hadjustment = newPosAdj()
|
||||||
|
result.hadjustment.handlerID = result.hadjustment.connect("value-changed",
|
||||||
|
onAdjustmentEvent, result)
|
||||||
|
result.vadjustment = newPosAdj()
|
||||||
|
result.vadjustment.handlerID = result.vadjustment.connect("value-changed",
|
||||||
|
onAdjustmentEvent, result)
|
||||||
|
result.hscrollbar = newScrollbar(Orientation.horizontal, result.hadjustment)
|
||||||
|
result.vscrollbar = newScrollbar(Orientation.vertical, result.vadjustment)
|
||||||
|
result.hscrollbar.setHExpand#(true)
|
||||||
|
result.vscrollbar.setVExpand#(true)
|
||||||
|
result.attach(result.darea, 0, 0, 1, 1)
|
||||||
|
result.attach(result.vscrollbar, 1, 0, 1, 1)
|
||||||
|
result.attach(result.hscrollbar, 0, 1, 1, 1)
|
||||||
|
|
||||||
|
proc appActivate(app: Application) =
|
||||||
|
let window = newApplicationWindow(app)
|
||||||
|
window.title = "Drawing example"
|
||||||
|
window.defaultSize = (400, 400)
|
||||||
|
let pda = newPDA()
|
||||||
|
window.add(pda)
|
||||||
|
showAll(window)
|
||||||
|
|
||||||
|
proc main =
|
||||||
|
let app = newApplication("org.gtk.example")
|
||||||
|
connect(app, "activate", appActivate)
|
||||||
|
discard run(app)
|
||||||
|
|
||||||
|
main()
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# Package
|
# Package
|
||||||
|
|
||||||
version = "0.4.11"
|
version = "0.4.12"
|
||||||
author = "Stefan Salewski"
|
author = "Stefan Salewski"
|
||||||
description = "High level GObject-Introspection based GTK3 bindings"
|
description = "High level GObject-Introspection based GTK3 bindings"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
|
||||||
|
|
@ -145,7 +145,7 @@ proc $1$2 {.cdecl.} =
|
||||||
r1s.add(resu & "\n")
|
r1s.add(resu & "\n")
|
||||||
all = all.replace(")", "; data: pointer)")
|
all = all.replace(")", "; data: pointer)")
|
||||||
r1s = r1s % [$procNameCdecl, all, $p, wts, ats]
|
r1s = r1s % [$procNameCdecl, all, $p, wts, ats]
|
||||||
echo r1s
|
#echo r1s
|
||||||
result = parseStmt(r1s)
|
result = parseStmt(r1s)
|
||||||
if not ignoreArg.boolVal:
|
if not ignoreArg.boolVal:
|
||||||
ahl = ahl.replace(")", "; arg: " & ats & ")")
|
ahl = ahl.replace(")", "; arg: " & ats & ")")
|
||||||
|
|
@ -175,7 +175,7 @@ proc $1(self: $2; p: proc $3; a: $4): culong {.discardable.} =
|
||||||
sc$5(self, $6, cast[pointer](ar[]))
|
sc$5(self, $6, cast[pointer](ar[]))
|
||||||
$1($7, $8, $9)
|
$1($7, $8, $9)
|
||||||
""" % [$procName, wts, ahl, ats, signalName, $procNameCdecl, $(widget.toStrLit), $p, $(arg.toStrLit)]
|
""" % [$procName, wts, ahl, ats, signalName, $procNameCdecl, $(widget.toStrLit), $p, $(arg.toStrLit)]
|
||||||
echo r2s
|
#echo r2s
|
||||||
result.add(parseStmt(r2s))
|
result.add(parseStmt(r2s))
|
||||||
|
|
||||||
template connect*(widget: gobject.Object; signal: string; p: typed; arg: typed): untyped =
|
template connect*(widget: gobject.Object; signal: string; p: typed; arg: typed): untyped =
|
||||||
|
|
|
||||||
328
tests/gen.nim
328
tests/gen.nim
|
|
@ -1,5 +1,5 @@
|
||||||
# High level gobject-introspection based GTK3 bindings for the Nim programming language
|
# High level gobject-introspection based GTK3 bindings for the Nim programming language
|
||||||
# v 0.4.12 2019-APR-11
|
# v 0.4.12 2019-APR-14
|
||||||
# (c) S. Salewski 2018
|
# (c) S. Salewski 2018
|
||||||
|
|
||||||
# https://wiki.gnome.org/Projects/GObjectIntrospection
|
# https://wiki.gnome.org/Projects/GObjectIntrospection
|
||||||
|
|
@ -460,6 +460,12 @@ proc genP(info: GICallableInfo; genProxy = false; binfo: GIBaseInfo = nil): (str
|
||||||
if genProxy and (str == "string" or str == "cstring") and mayBeNil: # v0.4.11
|
if genProxy and (str == "string" or str == "cstring") and mayBeNil: # v0.4.11
|
||||||
#str.add(" = nil")
|
#str.add(" = nil")
|
||||||
str.add(" = \"\"")
|
str.add(" = \"\"")
|
||||||
|
if genProxy and m == 0:
|
||||||
|
if sym.contains("_set_") and str == "bool":
|
||||||
|
#echo "TTTTTTTTTT", sym
|
||||||
|
str.add(" = true")
|
||||||
|
|
||||||
|
|
||||||
if genProxy and isProxyCandidate(t) and mayBeNil:
|
if genProxy and isProxyCandidate(t) and mayBeNil:
|
||||||
#if not str.contains("|") and (gArgInfoGetDirection(arg) == GIDirection.OUT or gArgInfoGetDirection(arg) == GIDirection.INOUT):
|
#if not str.contains("|") and (gArgInfoGetDirection(arg) == GIDirection.OUT or gArgInfoGetDirection(arg) == GIDirection.INOUT):
|
||||||
# str.add(" = cast[" & str & "](nil)")
|
# str.add(" = cast[" & str & "](nil)")
|
||||||
|
|
@ -573,6 +579,15 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo; genProxy = false) =
|
||||||
var ret2 = gCallableInfoGetReturnType(minfo)
|
var ret2 = gCallableInfoGetReturnType(minfo)
|
||||||
#var ret22 = gCallableInfoGetReturnType(minfo)
|
#var ret22 = gCallableInfoGetReturnType(minfo)
|
||||||
for run in 0 .. 1:
|
for run in 0 .. 1:
|
||||||
|
|
||||||
|
#if run == 0:
|
||||||
|
# if asym.startsWith("set"):
|
||||||
|
# if gCallableInfoGetNArgs(minfo) == 1 or (gCallableInfoIsMethod(minfo) and gCallableInfoGetNArgs(minfo) == 2):
|
||||||
|
# echo "XXXXXXXXXX", asym, " ", gCallableInfoGetNArgs(minfo)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if run == 1:
|
if run == 1:
|
||||||
|
|
||||||
#if not (asym != "errorQuark" and asym != "getPlugin" and asym != "quark"): continue
|
#if not (asym != "errorQuark" and asym != "getPlugin" and asym != "quark"): continue
|
||||||
|
|
@ -589,6 +604,10 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo; genProxy = false) =
|
||||||
asym = asym[3 .. ^1]
|
asym = asym[3 .. ^1]
|
||||||
asym[0] = asym[0].toLowerAscii
|
asym[0] = asym[0].toLowerAscii
|
||||||
if asym.startsWith("set"):
|
if asym.startsWith("set"):
|
||||||
|
#if plist.contains(" = true"):
|
||||||
|
#echo "ZZZZZZ ", plist, " ", arglist
|
||||||
|
plist = plist.replace(": bool = true", ": bool")
|
||||||
|
|
||||||
asym = asym[3 .. ^1]
|
asym = asym[3 .. ^1]
|
||||||
asym[0] = asym[0].toLowerAscii
|
asym[0] = asym[0].toLowerAscii
|
||||||
asym = '`' & asym & '=' & '`'
|
asym = '`' & asym & '=' & '`'
|
||||||
|
|
@ -601,12 +620,18 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo; genProxy = false) =
|
||||||
if gBaseInfoGetType(iface) == GIInfoType.Object and gBaseInfoGetName(iface) != "ParamSpec":
|
if gBaseInfoGetType(iface) == GIInfoType.Object and gBaseInfoGetName(iface) != "ParamSpec":
|
||||||
isGObject = true
|
isGObject = true
|
||||||
(plist, arglist, replist) = genP(mInfo, true, info)
|
(plist, arglist, replist) = genP(mInfo, true, info)
|
||||||
|
if asym[^2] == '=':
|
||||||
|
plist = plist.replace(": bool = true", ": bool")
|
||||||
if (gFunctionInfoGetFlags(mInfo).int and GIFunctionInfoFlags.IS_CONSTRUCTOR.int) != 0:
|
if (gFunctionInfoGetFlags(mInfo).int and GIFunctionInfoFlags.IS_CONSTRUCTOR.int) != 0:
|
||||||
if info != nil:
|
if info != nil:
|
||||||
asym = asym.replace("new", "new" & manglename(gBaseInfoGetName(info)))
|
asym = asym.replace("new", "new" & manglename(gBaseInfoGetName(info)))
|
||||||
if fixedProcNames.contains(sym):
|
if fixedProcNames.contains(sym):
|
||||||
asym = fixedProcNames[sym]
|
asym = fixedProcNames[sym]
|
||||||
for i in 0 .. 1:
|
for i in 0 .. 1:
|
||||||
|
|
||||||
|
#if i > 0 and isGObject:
|
||||||
|
# echo "XYZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ", asym
|
||||||
|
|
||||||
var hhh = "\nproc " & asym & EM & plist
|
var hhh = "\nproc " & asym & EM & plist
|
||||||
if i > 0:
|
if i > 0:
|
||||||
let semi = if hhh.contains("()"): "" else: "; "
|
let semi = if hhh.contains("()"): "" else: "; "
|
||||||
|
|
@ -1401,6 +1426,237 @@ proc processInfo(i: GIBaseInfo) =
|
||||||
writeConst(i)
|
writeConst(i)
|
||||||
else: assert(false)
|
else: assert(false)
|
||||||
|
|
||||||
|
|
||||||
|
# Gtk objects builder may provide. Only for Gtk module, so Gtk prefix is assume.
|
||||||
|
# Other objects loke gtkSourceView are separated!
|
||||||
|
# This a guessed list, so it may be inaccurate.
|
||||||
|
const GtkBuilderObjects = """
|
||||||
|
|
||||||
|
AboutDialog
|
||||||
|
AccelLabel
|
||||||
|
ActionBar
|
||||||
|
ActionGroup
|
||||||
|
Alignment
|
||||||
|
AppChooserButton
|
||||||
|
AppChooserDialog
|
||||||
|
AppChooserWidget
|
||||||
|
Application
|
||||||
|
ApplicationWindow
|
||||||
|
Arrow
|
||||||
|
AspectFrame
|
||||||
|
Assistant
|
||||||
|
Box
|
||||||
|
Builder
|
||||||
|
Button
|
||||||
|
ButtonBox
|
||||||
|
Calendar
|
||||||
|
CellAreaBox
|
||||||
|
CellView
|
||||||
|
CheckButton
|
||||||
|
CheckMenuItem
|
||||||
|
ColorButton
|
||||||
|
ColorChooserDialog
|
||||||
|
ColorChooserWidget
|
||||||
|
ColorSelectionDialog
|
||||||
|
ComboBox
|
||||||
|
ComboBoxText
|
||||||
|
Dialog
|
||||||
|
DrawingArea
|
||||||
|
Entry
|
||||||
|
EntryCompletion
|
||||||
|
EventBox
|
||||||
|
Expander
|
||||||
|
FileChooserButton
|
||||||
|
FileChooserNative
|
||||||
|
FileChooserWidget
|
||||||
|
FileFilter
|
||||||
|
Fixed
|
||||||
|
FlowBox
|
||||||
|
FontButton
|
||||||
|
FontChooserDialog
|
||||||
|
FontChooserWidget
|
||||||
|
FontSelection
|
||||||
|
FontSelectionDialog
|
||||||
|
Frame
|
||||||
|
GLArea
|
||||||
|
Grid
|
||||||
|
HandleBox
|
||||||
|
HBox
|
||||||
|
HButtonBox
|
||||||
|
HeaderBar
|
||||||
|
HPaned
|
||||||
|
HScale
|
||||||
|
HScrollbar
|
||||||
|
HSeparator
|
||||||
|
IconView
|
||||||
|
ImageMenuItem
|
||||||
|
InfoBar
|
||||||
|
Invisible
|
||||||
|
Label
|
||||||
|
Layout
|
||||||
|
LevelBar
|
||||||
|
LinkButton
|
||||||
|
ListBox
|
||||||
|
ListBoxRow
|
||||||
|
ListStore
|
||||||
|
LockButton
|
||||||
|
Menu
|
||||||
|
MenuBar
|
||||||
|
MenuButton
|
||||||
|
MenuItem
|
||||||
|
MenuToolButton
|
||||||
|
ModelButton
|
||||||
|
Notebook
|
||||||
|
OffscreenWindow
|
||||||
|
Overlay
|
||||||
|
Paned
|
||||||
|
PlacesSidebar
|
||||||
|
Popover
|
||||||
|
PopoverMenu
|
||||||
|
ProgressBar
|
||||||
|
RadioButton
|
||||||
|
RadioMenuItem
|
||||||
|
RadioToolButton
|
||||||
|
RecentChooserMenu
|
||||||
|
RecentChooserWidget
|
||||||
|
RecentManager
|
||||||
|
Revealer
|
||||||
|
Scale
|
||||||
|
ScaleButton
|
||||||
|
Scrollbar
|
||||||
|
ScrolledWindow
|
||||||
|
SearchBar
|
||||||
|
SearchEntry
|
||||||
|
Separator
|
||||||
|
SeparatorMenuItem
|
||||||
|
SeparatorToolItem
|
||||||
|
ShortcutLabel
|
||||||
|
SizeGroup
|
||||||
|
SpinButton
|
||||||
|
Spinner
|
||||||
|
Stack
|
||||||
|
StackSidebar
|
||||||
|
StackSwitcher
|
||||||
|
Statusbar
|
||||||
|
Style
|
||||||
|
Switch
|
||||||
|
Table
|
||||||
|
TearoffMenuItem
|
||||||
|
TextView
|
||||||
|
ToggleButton
|
||||||
|
ToggleToolButton
|
||||||
|
Toolbar
|
||||||
|
ToolButton
|
||||||
|
ToolItem
|
||||||
|
ToolItemGroup
|
||||||
|
ToolPalette
|
||||||
|
TreeStore
|
||||||
|
TreeView
|
||||||
|
TreeViewColumn
|
||||||
|
VBox
|
||||||
|
VButtonBox
|
||||||
|
Viewport
|
||||||
|
VolumeButton
|
||||||
|
VPaned
|
||||||
|
VScrollbar
|
||||||
|
VSeparator
|
||||||
|
Window
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
const GTK_SOURCE_EPI = """
|
||||||
|
|
||||||
|
proc getView(builder: Builder; name: string): View =
|
||||||
|
new result
|
||||||
|
let gt = g_type_from_name("GSource")
|
||||||
|
assert(gt != 0)
|
||||||
|
result.impl = gtk_builder_get_object(cast[ptr Builder00](builder.impl), name)
|
||||||
|
assert(toBool(g_type_check_instance_is_a(cast[ptr TypeInstance00](result.impl), gt)))
|
||||||
|
|
||||||
|
proc completionContextGetType*(): GType {.importc: "gtk_source_completion_context_get_type", libprag.}
|
||||||
|
|
||||||
|
proc completionProviderGetType*(): GType {.importc: "gtk_source_completion_provider_get_type", libprag.}
|
||||||
|
|
||||||
|
proc completionWordsGetType*(): GType {.importc: "gtk_source_completion_words_get_type", libprag.}
|
||||||
|
|
||||||
|
proc bufferGetType*(): GType {.importc: "gtk_source_buffer_get_type", libprag.}
|
||||||
|
|
||||||
|
proc completionGetType*(): GType {.importc: "gtk_source_completion_get_type", libprag.}
|
||||||
|
|
||||||
|
proc completionInfoGetType*(): GType {.importc: "gtk_source_completion_info_get_type", libprag.}
|
||||||
|
|
||||||
|
proc completionItemGetType*(): GType {.importc: "gtk_source_completion_item_get_type", libprag.}
|
||||||
|
|
||||||
|
proc completionProposalGetType*(): GType {.importc: "gtk_source_completion_proposal_get_type", libprag.}
|
||||||
|
|
||||||
|
proc encodingGetType*(): GType {.importc: "gtk_source_encoding_get_type", libprag.}
|
||||||
|
|
||||||
|
proc fileGetType*(): GType {.importc: "gtk_source_file_get_type", libprag.}
|
||||||
|
|
||||||
|
proc fileLoaderGetType*(): GType {.importc: "gtk_source_file_loader_get_type", libprag.}
|
||||||
|
|
||||||
|
proc fileSaverGetType*(): GType {.importc: "gtk_source_file_saver_get_type", libprag.}
|
||||||
|
|
||||||
|
proc gutterGetType*(): GType {.importc: "gtk_source_gutter_get_type", libprag.}
|
||||||
|
|
||||||
|
proc gutterRendererGetType*(): GType {.importc: "gtk_source_gutter_renderer_get_type", libprag.}
|
||||||
|
|
||||||
|
proc gutterRendererTextGetType*(): GType {.importc: "gtk_source_gutter_renderer_text_get_type", libprag.}
|
||||||
|
|
||||||
|
proc gutterRendererPixbufGetType*(): GType {.importc: "gtk_source_gutter_renderer_pixbuf_get_type", libprag.}
|
||||||
|
|
||||||
|
proc languageGetType*(): GType {.importc: "gtk_source_language_get_type", libprag.}
|
||||||
|
|
||||||
|
proc languageManagerGetType*(): GType {.importc: "gtk_source_language_manager_get_type", libprag.}
|
||||||
|
|
||||||
|
proc viewGetType*(): GType {.importc: "gtk_source_view_get_type", libprag.}
|
||||||
|
|
||||||
|
proc mapGetType*(): GType {.importc: "gtk_source_map_get_type", libprag.}
|
||||||
|
|
||||||
|
proc markGetType*(): GType {.importc: "gtk_source_mark_get_type", libprag.}
|
||||||
|
|
||||||
|
proc markAttributesGetType*(): GType {.importc: "gtk_source_mark_attributes_get_type", libprag.}
|
||||||
|
|
||||||
|
proc printCompositorGetType*(): GType {.importc: "gtk_source_print_compositor_get_type", libprag.}
|
||||||
|
|
||||||
|
proc regionGetType*(): GType {.importc: "gtk_source_region_get_type", libprag.}
|
||||||
|
|
||||||
|
proc searchContextGetType*(): GType {.importc: "gtk_source_search_context_get_type", libprag.}
|
||||||
|
|
||||||
|
proc searchSettingsGetType*(): GType {.importc: "gtk_source_search_settings_get_type", libprag.}
|
||||||
|
|
||||||
|
proc spaceDrawerGetType*(): GType {.importc: "gtk_source_space_drawer_get_type", libprag.}
|
||||||
|
|
||||||
|
proc styleGetType*(): GType {.importc: "gtk_source_style_get_type", libprag.}
|
||||||
|
|
||||||
|
proc styleSchemeGetType*(): GType {.importc: "gtk_source_style_scheme_get_type", libprag.}
|
||||||
|
|
||||||
|
proc styleSchemeChooserGetType*(): GType {.importc: "gtk_source_style_scheme_chooser_get_type", libprag.}
|
||||||
|
|
||||||
|
proc styleSchemeChooserButtonGetType*(): GType {.importc: "gtk_source_style_scheme_chooser_button_get_type", libprag.}
|
||||||
|
|
||||||
|
proc styleSchemeChooserWidgetGetType*(): GType {.importc: "gtk_source_style_scheme_chooser_widget_get_type", libprag.}
|
||||||
|
|
||||||
|
proc styleSchemeManagerGetType*(): GType {.importc: "gtk_source_style_scheme_manager_get_type", libprag.}
|
||||||
|
|
||||||
|
proc tagGetType*(): GType {.importc: "gtk_source_tag_get_type", libprag.}
|
||||||
|
|
||||||
|
proc undoManagerGetType*(): GType {.importc: "gtk_source_undo_manager_get_type", libprag.}
|
||||||
|
|
||||||
|
proc completionWordsProposalGetType*(): GType {.importc: "gtk_source_completion_words_proposal_get_type", libprag.}
|
||||||
|
|
||||||
|
proc completionWordsLibraryGetType*(): GType {.importc: "gtk_source_completion_words_library_get_type", libprag.}
|
||||||
|
|
||||||
|
proc completionWordsBufferGetType*(): GType {.importc: "gtk_source_completion_words_buffer_get_type", libprag.}
|
||||||
|
|
||||||
|
# register the GObject types so builder can use them, see
|
||||||
|
# https://mail.gnome.org/archives/gtk-list/2015-March/msg00016.html
|
||||||
|
discard viewGetType()
|
||||||
|
discard completionInfoGetType()
|
||||||
|
discard styleSchemeChooserButtonGetType()
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
const GDK_EPI = """
|
const GDK_EPI = """
|
||||||
|
|
||||||
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) {.
|
||||||
|
|
@ -1419,6 +1675,60 @@ proc fixednewCursorFromName*(display: Display; name: string): Cursor =
|
||||||
#assert(g_object_get_qdata(result.impl, Quark) == nil)
|
#assert(g_object_get_qdata(result.impl, Quark) == nil)
|
||||||
g_object_set_qdata(result.impl, Quark, addr(result[]))
|
g_object_set_qdata(result.impl, Quark, addr(result[]))
|
||||||
|
|
||||||
|
proc getAngle*(self: SomeEvent; event2: SomeEvent): cdouble =
|
||||||
|
if not toBool(gdk_events_get_angle(cast[ptr Event00](self.impl), cast[ptr Event00](event2.impl), result)):
|
||||||
|
raise newException(Defect, "Events do not support getAngle().")
|
||||||
|
|
||||||
|
proc getCenter*(self: SomeEvent; event2: SomeEvent): (cdouble, cdouble) =
|
||||||
|
if not toBool(gdk_events_get_center(cast[ptr Event00](self.impl), cast[ptr Event00](event2.impl), result[0], result[1])):
|
||||||
|
raise newException(Defect, "Events do not support getCenter().")
|
||||||
|
|
||||||
|
proc getDistance*(self: SomeEvent; event2: SomeEvent): cdouble =
|
||||||
|
if not toBool(gdk_events_get_distance(cast[ptr Event00](self.impl), cast[ptr Event00](event2.impl), result)):
|
||||||
|
raise newException(Defect, "Events do not support getDistance().")
|
||||||
|
|
||||||
|
proc getAxis*(self: SomeEvent; axisUse: AxisUse): cdouble =
|
||||||
|
if not toBool(gdk_event_get_axis(cast[ptr Event00](self.impl), axisUse, result)):
|
||||||
|
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)
|
||||||
|
|
||||||
|
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 = """
|
||||||
|
|
@ -1801,12 +2111,28 @@ proc main(namespace: string) =
|
||||||
if namespace == "Gtk":
|
if namespace == "Gtk":
|
||||||
output.write(GTK_EPI)
|
output.write(GTK_EPI)
|
||||||
|
|
||||||
|
for i in GtkBuilderObjects.split:
|
||||||
|
if i == "": continue
|
||||||
|
output.write("""
|
||||||
|
proc get$1*(builder: Builder; name: string): $1 =
|
||||||
|
new result
|
||||||
|
let gt = g_type_from_name("Gtk$1")
|
||||||
|
assert(gt != 0)
|
||||||
|
result.impl = gtk_builder_get_object(cast[ptr Builder00](builder.impl), name)
|
||||||
|
assert(toBool(g_type_check_instance_is_a(cast[ptr TypeInstance00](result.impl), gt)))
|
||||||
|
|
||||||
|
""" % [i])
|
||||||
|
output.write("")
|
||||||
|
|
||||||
if namespace == "Gio":
|
if namespace == "Gio":
|
||||||
output.write(GIO_EPI)
|
output.write(GIO_EPI)
|
||||||
|
|
||||||
if namespace == "Gdk":
|
if namespace == "Gdk":
|
||||||
output.write(GDK_EPI)
|
output.write(GDK_EPI)
|
||||||
|
|
||||||
|
if namespace == "GtkSource":
|
||||||
|
output.write(GTK_SOURCE_EPI)
|
||||||
|
|
||||||
output.flush
|
output.flush
|
||||||
var o = open("nim_gi" / (namespace.toLowerAscii) & ".nim", fmWrite)
|
var o = open("nim_gi" / (namespace.toLowerAscii) & ".nim", fmWrite)
|
||||||
o.write(output.data)
|
o.write(output.data)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue