├── .gitignore ├── .gitmodules ├── README.md ├── examples ├── controllgallery.nim ├── controllgallery2.nim ├── histogram.nim ├── nim.cfg ├── table.nim └── toy.nim ├── headers ├── ui.c2nim └── ui.h ├── license.txt ├── res ├── resources.o └── resources.res ├── ui.nim ├── ui.nimble └── ui └── rawui.nim /.gitignore: -------------------------------------------------------------------------------- 1 | nimcache/ 2 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "ui/libui"] 2 | path = ui/libui 3 | url = https://github.com/ba0f3/libui.git 4 | branch = master 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UI 2 | 3 | This package wraps the [libui](https://github.com/andlabs/libui) C library. It 4 | also provides a high-level Nim binding for it. 5 | 6 | To get started, install using Nimble: 7 | 8 | ```bash 9 | nimble install ui 10 | ``` 11 | 12 | or add it to your project's Nimble file: 13 | 14 | ```nim 15 | requires "ui" 16 | ``` 17 | 18 | ### Dependencies 19 | - `gtk+-3.0` 20 | 21 | Linux: `$ sudo apt-get install libgtk-3-dev` 22 | 23 | OSX: `$ brew install gtk+3` 24 | 25 | 26 | You should then be able to compile the sample code in the 27 | [``examples/``](https://github.com/nim-lang/ui/tree/master/examples) 28 | directory successfully. 29 | 30 | ## Static vs. dynamic linking 31 | 32 | This library installs the C sources for libui and statically compiles them 33 | into your application. 34 | 35 | Static compilation is the default behaviour, but if you would prefer to depend 36 | on a DLL instead, pass the ``-d:useLibUiDll`` to the Nim compiler. You will 37 | then need to bundle your application with a libui.dll, libui.dylib, or libui.so 38 | for Windows, macOS, and Linux respectively. 39 | -------------------------------------------------------------------------------- /examples/controllgallery.nim: -------------------------------------------------------------------------------- 1 | # 2 september 2015 2 | 3 | import ui/rawui 4 | 5 | # TODOs 6 | # - rename variables in main() 7 | # - make both columns the same size? 8 | 9 | var mainwin*: ptr Window 10 | 11 | proc onClosing*(w: ptr Window; data: pointer): cint {.cdecl.} = 12 | controlDestroy(mainwin) 13 | rawui.quit() 14 | return 0 15 | 16 | proc shouldQuit*(data: pointer): cint {.cdecl.} = 17 | controlDestroy(mainwin) 18 | return 1 19 | 20 | proc openClicked*(item: ptr MenuItem; w: ptr Window; data: pointer) {.cdecl.} = 21 | var filename = rawui.openFile(mainwin) 22 | if filename == nil: 23 | msgBoxError(mainwin, "No file selected", "Don\'t be alarmed!") 24 | return 25 | msgBox(mainwin, "File selected", filename) 26 | freeText(filename) 27 | 28 | proc saveClicked*(item: ptr MenuItem; w: ptr Window; data: pointer) {.cdecl.} = 29 | var filename = rawui.saveFile(mainwin) 30 | if filename == nil: 31 | msgBoxError(mainwin, "No file selected", "Don't be alarmed!") 32 | return 33 | msgBox(mainwin, "File selected (don't worry, it's still there)", filename) 34 | freeText(filename) 35 | 36 | var spinbox*: ptr Spinbox 37 | 38 | var slider*: ptr Slider 39 | 40 | var progressbar*: ptr ProgressBar 41 | 42 | proc update*(value: int64) = 43 | spinboxSetValue(spinbox, value.cint) 44 | sliderSetValue(slider, value.cint) 45 | progressBarSetValue(progressbar, value.cint) 46 | 47 | proc onSpinboxChanged*(s: ptr Spinbox; data: pointer) {.cdecl.} = 48 | update(spinboxValue(spinbox)) 49 | 50 | proc onSliderChanged*(s: ptr Slider; data: pointer) {.cdecl.} = 51 | update(sliderValue(slider)) 52 | 53 | proc main*() = 54 | var o: rawui.InitOptions 55 | var err: cstring 56 | var menu: ptr Menu 57 | var item: ptr MenuItem 58 | var box: ptr Box 59 | var hbox: ptr Box 60 | var group: ptr Group 61 | var inner: ptr Box 62 | var inner2: ptr Box 63 | var entry: ptr Entry 64 | var cbox: ptr Combobox 65 | var ecbox: ptr EditableCombobox 66 | var rb: ptr RadioButtons 67 | var tab: ptr Tab 68 | err = rawui.init(addr(o)) 69 | if err != nil: 70 | echo "error initializing ui: ", err 71 | freeInitError(err) 72 | return 73 | menu = newMenu("File") 74 | item = menuAppendItem(menu, "Open") 75 | menuItemOnClicked(item, openClicked, nil) 76 | item = menuAppendItem(menu, "Save") 77 | menuItemOnClicked(item, saveClicked, nil) 78 | item = menuAppendQuitItem(menu) 79 | onShouldQuit(shouldQuit, nil) 80 | menu = newMenu("Edit") 81 | item = menuAppendCheckItem(menu, "Checkable Item") 82 | menuAppendSeparator(menu) 83 | item = menuAppendItem(menu, "Disabled Item") 84 | menuItemDisable(item) 85 | item = menuAppendPreferencesItem(menu) 86 | menu = newMenu("Help") 87 | item = menuAppendItem(menu, "Help") 88 | item = menuAppendAboutItem(menu) 89 | mainwin = newWindow("libui Control Gallery", 640, 480, 1) 90 | windowSetMargined(mainwin, 1) 91 | windowOnClosing(mainwin, onClosing, nil) 92 | box = newVerticalBox() 93 | boxSetPadded(box, 1) 94 | windowSetChild(mainwin, box) 95 | hbox = newHorizontalBox() 96 | boxSetPadded(hbox, 1) 97 | boxAppend(box, hbox, 1) 98 | group = newGroup("Basic Controls") 99 | groupSetMargined(group, 1) 100 | boxAppend(hbox, group, 0) 101 | inner = newVerticalBox() 102 | boxSetPadded(inner, 1) 103 | groupSetChild(group, inner) 104 | boxAppend(inner, newButton("Button"), 0) 105 | boxAppend(inner, newCheckbox("Checkbox"), 0) 106 | entry = newEntry() 107 | entrySetText(entry, "Entry") 108 | boxAppend(inner, entry, 0) 109 | boxAppend(inner, newLabel("Label"), 0) 110 | boxAppend(inner, newHorizontalSeparator(), 0) 111 | boxAppend(inner, newDatePicker(), 0) 112 | boxAppend(inner, newTimePicker(), 0) 113 | boxAppend(inner, newDateTimePicker(), 0) 114 | boxAppend(inner, newFontButton(), 0) 115 | boxAppend(inner, newColorButton(), 0) 116 | inner2 = newVerticalBox() 117 | boxSetPadded(inner2, 1) 118 | boxAppend(hbox, inner2, 1) 119 | group = newGroup("Numbers") 120 | groupSetMargined(group, 1) 121 | boxAppend(inner2, group, 0) 122 | inner = newVerticalBox() 123 | boxSetPadded(inner, 1) 124 | groupSetChild(group, inner) 125 | spinbox = newSpinbox(0, 100) 126 | spinboxOnChanged(spinbox, onSpinboxChanged, nil) 127 | boxAppend(inner, spinbox, 0) 128 | slider = newSlider(0, 100) 129 | sliderOnChanged(slider, onSliderChanged, nil) 130 | boxAppend(inner, slider, 0) 131 | progressbar = newProgressBar() 132 | boxAppend(inner, progressbar, 0) 133 | group = newGroup("Lists") 134 | groupSetMargined(group, 1) 135 | boxAppend(inner2, group, 0) 136 | inner = newVerticalBox() 137 | boxSetPadded(inner, 1) 138 | groupSetChild(group, inner) 139 | cbox = newCombobox() 140 | comboboxAppend(cbox, "Combobox Item 1") 141 | comboboxAppend(cbox, "Combobox Item 2") 142 | comboboxAppend(cbox, "Combobox Item 3") 143 | boxAppend(inner, cbox, 0) 144 | ecbox = newEditableCombobox() 145 | editableComboboxAppend(ecbox, "Editable Item 1") 146 | editableComboboxAppend(ecbox, "Editable Item 2") 147 | editableComboboxAppend(ecbox, "Editable Item 3") 148 | boxAppend(inner, ecbox, 0) 149 | rb = newRadioButtons() 150 | radioButtonsAppend(rb, "Radio Button 1") 151 | radioButtonsAppend(rb, "Radio Button 2") 152 | radioButtonsAppend(rb, "Radio Button 3") 153 | boxAppend(inner, rb, 1) 154 | tab = newTab() 155 | tabAppend(tab, "Page 1", newHorizontalBox()) 156 | tabAppend(tab, "Page 2", newHorizontalBox()) 157 | tabAppend(tab, "Page 3", newHorizontalBox()) 158 | boxAppend(inner2, tab, 1) 159 | controlShow(mainwin) 160 | rawui.main() 161 | rawui.uninit() 162 | 163 | main() 164 | -------------------------------------------------------------------------------- /examples/controllgallery2.nim: -------------------------------------------------------------------------------- 1 | # Test & show the new high level wrapper 2 | 3 | import ui 4 | 5 | proc main*() = 6 | var mainwin: Window 7 | 8 | var menu = newMenu("File") 9 | menu.addItem("Open", proc() = 10 | let filename = ui.openFile(mainwin) 11 | if filename.len == 0: 12 | msgBoxError(mainwin, "No file selected", "Don't be alarmed!") 13 | else: 14 | msgBox(mainwin, "File selected", filename) 15 | ) 16 | menu.addItem("Save", proc() = 17 | let filename = ui.saveFile(mainwin) 18 | if filename.len == 0: 19 | msgBoxError(mainwin, "No file selected", "Don't be alarmed!") 20 | else: 21 | msgBox(mainwin, "File selected (don't worry, it's still there)", filename) 22 | ) 23 | menu.addQuitItem(proc(): bool {.closure.} = 24 | mainwin.destroy() 25 | return true) 26 | 27 | menu = newMenu("Edit") 28 | menu.addCheckItem("Checkable Item", proc() = discard) 29 | menu.addSeparator() 30 | let item = menu.addItem("Disabled Item", proc() = discard) 31 | item.disable() 32 | menu.addPreferencesItem(proc() = discard) 33 | menu = newMenu("Help") 34 | menu.addItem("Help", proc () = discard) 35 | menu.addAboutItem(proc () = discard) 36 | 37 | mainwin = newWindow("libui Control Gallery", 640, 480, true) 38 | mainwin.margined = true 39 | mainwin.onClosing = (proc (): bool = return true) 40 | 41 | let box = newVerticalBox(true) 42 | mainwin.setChild(box) 43 | let hbox = newHorizontalBox(true) 44 | box.add(hbox, true) 45 | var group = newGroup("Basic Controls") 46 | group.margined = true 47 | hbox.add(group, false) 48 | var inner = newVerticalBox(true) 49 | group.child = inner 50 | inner.add newButton("Button") 51 | inner.add newCheckbox("Checkbox") 52 | add(inner, newEntry("Entry")) 53 | add(inner, newLabel("Label")) 54 | inner.add newHorizontalSeparator() 55 | #inner.add newDatePicker() 56 | #inner.add newTimePicker() 57 | #inner.add newDateTimePicker() 58 | #inner.add newFontButton() 59 | #inner.add newColorButton() 60 | var inner2 = newVerticalBox() 61 | inner2.padded = true 62 | hbox.add inner2 63 | group = newGroup("Numbers", true) 64 | inner2.add group 65 | inner = newVerticalBox(true) 66 | group.child = inner 67 | 68 | 69 | var spinbox: Spinbox 70 | var slider: Slider 71 | var progressbar: ProgressBar 72 | 73 | proc update(value: int) = 74 | spinbox.value = value 75 | slider.value = value 76 | progressBar.value = value 77 | 78 | spinbox = newSpinbox(0, 100, update) 79 | inner.add spinbox 80 | slider = newSlider(0, 100, update) 81 | inner.add slider 82 | progressbar = newProgressBar() 83 | inner.add progressbar 84 | 85 | group = newGroup("Lists") 86 | group.margined = true 87 | inner2.add group 88 | 89 | inner = newVerticalBox() 90 | inner.padded = true 91 | group.child = inner 92 | var cbox = newCombobox() 93 | cbox.add "Combobox Item 1" 94 | cbox.add "Combobox Item 2" 95 | cbox.add "Combobox Item 3" 96 | inner.add cbox 97 | var ecbox = newEditableCombobox() 98 | ecbox.add "Editable Item 1" 99 | ecbox.add "Editable Item 2" 100 | ecbox.add "Editable Item 3" 101 | inner.add ecbox 102 | var rb = newRadioButtons() 103 | rb.add "Radio Button 1" 104 | rb.add "Radio Button 2" 105 | rb.add "Radio Button 3" 106 | inner.add rb, true 107 | var tab = newTab() 108 | tab.add "Page 1", newHorizontalBox() 109 | tab.add "Page 2", newHorizontalBox() 110 | tab.add "Page 3", newHorizontalBox() 111 | inner2.add tab, true 112 | show(mainwin) 113 | mainLoop() 114 | 115 | init() 116 | main() 117 | -------------------------------------------------------------------------------- /examples/histogram.nim: -------------------------------------------------------------------------------- 1 | # 13 october 2015 2 | 3 | import ui/rawui, random 4 | 5 | var mainwin*: ptr Window 6 | 7 | var histogram*: ptr Area 8 | 9 | var handler*: AreaHandler 10 | 11 | var datapoints*: array[10, ptr Spinbox] 12 | 13 | var colorButton*: ptr ColorButton 14 | 15 | var currentPoint*: cint = - 1 16 | 17 | # some metrics 18 | 19 | const 20 | xoffLeft* = 20 21 | yoffTop* = 20 22 | xoffRight* = 20 23 | yoffBottom* = 20 24 | pointRadius* = 5 25 | 26 | # helper to quickly set a brush color 27 | 28 | 29 | proc renderText(ctx: ptr DrawContext; txt: cstring) = 30 | let fontDesc = FontDescriptor( 31 | family: "Courier New", 32 | size: 12.0, 33 | weight: TextWeightNormal, 34 | italic: TextItalicNormal, 35 | stretch: TextStretchNormal 36 | ) 37 | let textLayoutParams = DrawTextLayoutParams( 38 | str: newAttributedString(txt), 39 | defaultFont: unsafeAddr fontDesc, 40 | width: -1.0, 41 | align: DrawTextAlignCenter 42 | ) 43 | let textLayout = drawNewTextLayout(unsafeAddr textLayoutParams) 44 | ctx.drawText(textLayout, 10.0.cdouble, 400.0.cdouble) 45 | drawFreeTextLayout(textLayout) 46 | 47 | proc setSolidBrush*(brush: ptr DrawBrush; color: uint32; alpha: cdouble) {.cdecl.} = 48 | var component: uint8 49 | brush.`type` = DrawBrushTypeSolid 50 | component = (uint8)((color shr 16) and 0x000000FF) 51 | brush.r = (cdouble(component)) / 255.0 52 | component = (uint8)((color shr 8) and 0x000000FF) 53 | brush.g = (cdouble(component)) / 255.0 54 | component = (uint8)(color and 0x000000FF) 55 | brush.b = (cdouble(component)) / 255.0 56 | brush.a = alpha 57 | 58 | # and some colors 59 | # names and values from 60 | # https://msdn.microsoft.com/en-us/library/windows/desktop/dd370907%28v=vs.85%29.aspx 61 | 62 | const 63 | colorWhite* = 0x00FFFFFF 64 | colorBlack* = 0x00000000 65 | colorDodgerBlue* = 0x001E90FF 66 | 67 | proc pointLocations*(width: cdouble; height: cdouble; xs, ys: var array[10, cdouble]) {. 68 | cdecl.} = 69 | var 70 | xincr: cdouble 71 | yincr: cdouble 72 | var 73 | i: cint 74 | n: cint 75 | xincr = width / 9 76 | # 10 - 1 to make the last point be at the end 77 | yincr = height / 100 78 | i = 0 79 | while i < 10: 80 | # get the value of the point 81 | n = cint spinboxValue(datapoints[i]) 82 | # because y=0 is the top but n=0 is the bottom, we need to flip 83 | n = 100 - n 84 | xs[i] = xincr * cdouble i 85 | ys[i] = yincr * cdouble n 86 | inc(i) 87 | 88 | proc constructGraph*(width: cdouble; height: cdouble; extend: bool): ptr DrawPath {. 89 | cdecl.} = 90 | var path: ptr DrawPath 91 | var 92 | xs: array[10, cdouble] 93 | ys: array[10, cdouble] 94 | pointLocations(width, height, xs, ys) 95 | path = drawNewPath(DrawFillModeWinding) 96 | drawPathNewFigure(path, xs[0], ys[0]) 97 | for i in 1..<10: 98 | drawPathLineTo(path, xs[i], ys[i]) 99 | if extend: 100 | drawPathLineTo(path, width, height) 101 | drawPathLineTo(path, 0, height) 102 | drawPathCloseFigure(path) 103 | drawPathEnd(path) 104 | return path 105 | 106 | proc graphSize*(clientWidth: cdouble; clientHeight: cdouble; graphWidth: ptr cdouble; 107 | graphHeight: ptr cdouble) {.cdecl.} = 108 | graphWidth[] = clientWidth - xoffLeft - xoffRight 109 | graphHeight[] = clientHeight - yoffTop - yoffBottom 110 | 111 | proc handlerDraw*(a: ptr AreaHandler; area: ptr Area; p: ptr AreaDrawParams) {.cdecl.} = 112 | var path: ptr DrawPath 113 | var brush: DrawBrush 114 | var sp: DrawStrokeParams 115 | var m: DrawMatrix 116 | var 117 | graphWidth: cdouble 118 | graphHeight: cdouble 119 | var 120 | graphR: cdouble 121 | graphG: cdouble 122 | graphB: cdouble 123 | graphA: cdouble 124 | # fill the area with white 125 | setSolidBrush(addr(brush), colorWhite, 1.0) 126 | path = drawNewPath(DrawFillModeWinding) 127 | drawPathAddRectangle(path, 0, 0, p.areaWidth, p.areaHeight) 128 | drawPathEnd(path) 129 | drawFill(p.context, path, addr(brush)) 130 | drawFreePath(path) 131 | # figure out dimensions 132 | graphSize(p.areaWidth, p.areaHeight, addr(graphWidth), addr(graphHeight)) 133 | # make a stroke for both the axes and the histogram line 134 | sp.cap = DrawLineCapFlat 135 | sp.join = DrawLineJoinMiter 136 | sp.thickness = 2 137 | sp.miterLimit = DrawDefaultMiterLimit 138 | # draw the axes 139 | setSolidBrush(addr(brush), colorBlack, 1.0) 140 | path = drawNewPath(DrawFillModeWinding) 141 | drawPathNewFigure(path, xoffLeft, yoffTop) 142 | drawPathLineTo(path, xoffLeft, yoffTop + graphHeight) 143 | drawPathLineTo(path, xoffLeft + graphWidth, yoffTop + graphHeight) 144 | drawPathEnd(path) 145 | drawStroke(p.context, path, addr(brush), addr(sp)) 146 | drawFreePath(path) 147 | # now transform the coordinate space so (0, 0) is the top-left corner of the graph 148 | drawMatrixSetIdentity(addr(m)) 149 | drawMatrixTranslate(addr(m), xoffLeft, yoffTop) 150 | drawTransform(p.context, addr(m)) 151 | # now get the color for the graph itself and set up the brush 152 | colorButtonColor(colorButton, addr(graphR), addr(graphG), addr(graphB), 153 | addr(graphA)) 154 | brush.`type` = DrawBrushTypeSolid 155 | brush.r = graphR 156 | brush.g = graphG 157 | brush.b = graphB 158 | # we set brush->A below to different values for the fill and stroke 159 | # now create the fill for the graph below the graph line 160 | path = constructGraph(graphWidth, graphHeight, true) 161 | brush.a = graphA / 2 162 | drawFill(p.context, path, addr(brush)) 163 | drawFreePath(path) 164 | # now draw the histogram line 165 | path = constructGraph(graphWidth, graphHeight, false) 166 | brush.a = graphA 167 | drawStroke(p.context, path, addr(brush), addr(sp)) 168 | drawFreePath(path) 169 | renderText(p.context, "my example string") 170 | # now draw the point being hovered over 171 | if currentPoint != - 1: 172 | var 173 | xs: array[10, cdouble] 174 | ys: array[10, cdouble] 175 | pointLocations(graphWidth, graphHeight, xs, ys) 176 | path = drawNewPath(DrawFillModeWinding) 177 | drawPathNewFigureWithArc(path, xs[currentPoint], ys[currentPoint], 178 | pointRadius, 0, 6.23, # TODO pi 179 | 0) 180 | drawPathEnd(path) 181 | # use the same brush as for the histogram lines 182 | drawFill(p.context, path, addr(brush)) 183 | drawFreePath(path) 184 | 185 | proc inPoint*(x: cdouble; y: cdouble; xtest: cdouble; ytest: cdouble): bool {.cdecl.} = 186 | # TODO switch to using a matrix 187 | let x = x - xoffLeft 188 | let y = y - yoffTop 189 | return (x >= xtest - pointRadius) and (x <= xtest + pointRadius) and 190 | (y >= ytest - pointRadius) and (y <= ytest + pointRadius) 191 | 192 | proc handlerMouseEvent*(a: ptr AreaHandler; area: ptr Area; e: ptr AreaMouseEvent) {. 193 | cdecl.} = 194 | var 195 | graphWidth: cdouble 196 | graphHeight: cdouble 197 | var 198 | xs: array[10, cdouble] 199 | ys: array[10, cdouble] 200 | graphSize(e.areaWidth, e.areaHeight, addr(graphWidth), addr(graphHeight)) 201 | pointLocations(graphWidth, graphHeight, xs, ys) 202 | var i = 0.cint 203 | while i < 10: 204 | if inPoint(e.x, e.y, xs[i], ys[i]): break 205 | inc(i) 206 | if i == 10: 207 | i = - 1 208 | currentPoint = i 209 | # TODO only redraw the relevant area 210 | areaQueueRedrawAll(histogram) 211 | 212 | proc handlerMouseCrossed*(ah: ptr AreaHandler; a: ptr Area; left: cint) {.cdecl.} = 213 | # do nothing 214 | discard 215 | 216 | proc handlerDragBroken*(ah: ptr AreaHandler; a: ptr Area) {.cdecl.} = 217 | # do nothing 218 | discard 219 | 220 | proc handlerKeyEvent*(ah: ptr AreaHandler; a: ptr Area; e: ptr AreaKeyEvent): cint {. 221 | cdecl.} = 222 | # reject all keys 223 | return 0 224 | 225 | proc onDatapointChanged*(s: ptr Spinbox; data: pointer) {.cdecl.} = 226 | areaQueueRedrawAll(histogram) 227 | 228 | proc onColorChanged*(b: ptr ColorButton; data: pointer) {.cdecl.} = 229 | areaQueueRedrawAll(histogram) 230 | 231 | proc onClosing*(w: ptr Window; data: pointer): cint {.cdecl.} = 232 | controlDestroy(mainwin) 233 | rawui.quit() 234 | return 0 235 | 236 | proc shouldQuit*(data: pointer): cint {.cdecl.} = 237 | controlDestroy(mainwin) 238 | return 1 239 | 240 | proc main*() {.cdecl.} = 241 | var o: InitOptions 242 | var err: cstring 243 | var 244 | hbox: ptr Box 245 | vbox: ptr Box 246 | var i: cint 247 | var brush: DrawBrush 248 | handler.draw = handlerDraw 249 | handler.mouseEvent = handlerMouseEvent 250 | handler.mouseCrossed = handlerMouseCrossed 251 | handler.dragBroken = handlerDragBroken 252 | handler.keyEvent = handlerKeyEvent 253 | err = rawui.init(addr(o)) 254 | if err != nil: 255 | echo "error initializing ui: ", err 256 | freeInitError(err) 257 | return 258 | onShouldQuit(shouldQuit, nil) 259 | mainwin = newWindow("libui Histogram Example", 640, 480, 1) 260 | windowSetMargined(mainwin, 1) 261 | windowOnClosing(mainwin, onClosing, nil) 262 | hbox = newHorizontalBox() 263 | boxSetPadded(hbox, 1) 264 | windowSetChild(mainwin, hbox) 265 | vbox = newVerticalBox() 266 | boxSetPadded(vbox, 1) 267 | boxAppend(hbox, vbox, 0) 268 | randomize() 269 | i = 0 270 | while i < 10: 271 | datapoints[i] = newSpinbox(0, 100) 272 | spinboxSetValue(datapoints[i], rand(101).cint) 273 | spinboxOnChanged(datapoints[i], onDatapointChanged, nil) 274 | boxAppend(vbox, datapoints[i], 0) 275 | inc(i) 276 | colorButton = newColorButton() 277 | # TODO inline these 278 | setSolidBrush(addr(brush), colorDodgerBlue, 1.0) 279 | colorButtonSetColor(colorButton, brush.r, brush.g, brush.b, brush.a) 280 | colorButtonOnChanged(colorButton, onColorChanged, nil) 281 | boxAppend(vbox, colorButton, 0) 282 | histogram = newArea(addr(handler)) 283 | boxAppend(hbox, histogram, 1) 284 | controlShow(mainwin) 285 | rawui.main() 286 | rawui.uninit() 287 | 288 | main() 289 | -------------------------------------------------------------------------------- /examples/nim.cfg: -------------------------------------------------------------------------------- 1 | --path:".." -------------------------------------------------------------------------------- /examples/table.nim: -------------------------------------------------------------------------------- 1 | import ui, random 2 | 3 | 4 | const 5 | NUM_COLUMNS = 7 6 | NUM_ROWS = 10 7 | 8 | COLUMN_ID = 0 9 | COLUMN_FIRST_NAME = 1 10 | COLUMN_LAST_NAME = 2 11 | COLUMN_ADRESS = 3 12 | COLUMN_PROCESS = 4 13 | COLUMN_PASSED = 5 14 | COLUMN_ACTION = 6 15 | 16 | var 17 | progress: array[NUM_ROWS, array[NUM_COLUMNS, int]] 18 | 19 | proc modelNumColumns(mh: ptr TableModelHandler, m: TableModel): int {.cdecl.} = NUM_COLUMNS 20 | proc modelNumRows(mh: ptr TableModelHandler, m: TableModel): int {.cdecl.} = NUM_ROWS 21 | 22 | proc modelColumnType(mh: ptr TableModelHandler, m: TableModel, col: int): TableValueType {.noconv.} = 23 | echo "type" 24 | if col in [COLUMN_ID, COLUMN_PROCESS, COLUMN_PASSED]: 25 | result = TableValueTypeInt 26 | else: 27 | result = TableValueTypeString 28 | 29 | proc modelCellValue(mh: ptr TableModelHandler, m: TableModel, row, col: int): ptr TableValue {.noconv.} = 30 | if col == COLUMN_ID: 31 | result = newTableValueString($(row+1)) 32 | elif col == COLUMN_PROCESS: 33 | if progress[row][col] == 0: 34 | progress[row][col] = rand(100) 35 | result = newTableValueInt(progress[row][col]) 36 | #elif col == COLUMN_PASSED: 37 | # if progress[row][col] > 60: 38 | # result = newTableValueInt(1) 39 | # else: 40 | # result = newTableValueInt(0) 41 | elif col == COLUMN_ACTION: 42 | result = newTableValueString("Apply") 43 | else: 44 | result = newTableValueString("row " & $row & " x col " & $col) 45 | 46 | 47 | proc modelSetCellValue(mh: ptr TableModelHandler, m: TableModel, row, col: int, val: ptr TableValue) {.cdecl.} = 48 | echo "setCellValue" 49 | if col == COLUMN_PASSED: 50 | echo tableValueInt(val) 51 | elif col == COLUMN_ACTION: 52 | m.rowChanged(row) 53 | 54 | 55 | var 56 | mh: TableModelHandler 57 | p: TableParams 58 | tp: TableTextColumnOptionalParams 59 | 60 | proc main*() = 61 | var mainwin: Window 62 | 63 | var menu = newMenu("File") 64 | menu.addQuitItem(proc(): bool {.closure.} = 65 | mainwin.destroy() 66 | return true) 67 | 68 | mainwin = newWindow("uiTable", 640, 480, true) 69 | mainwin.margined = true 70 | mainwin.onClosing = (proc (): bool = return true) 71 | 72 | let box = newVerticalBox(true) 73 | mainwin.setChild(box) 74 | 75 | mh.numColumns = modelNumColumns 76 | mh.columnType = modelColumnType 77 | mh.numRows = modelNumRows 78 | mh.cellValue = modelCellValue 79 | mh.setCellValue = modelSetCellValue 80 | 81 | p.model = newTableModel(addr mh) 82 | p.rowBackgroundColorModelColumn = 4 83 | 84 | let table = newTable(addr p) 85 | table.appendTextColumn("ID", COLUMN_ID, TableModelColumnNeverEditable, nil) 86 | table.appendTextColumn("First Name", COLUMN_FIRST_NAME, TableModelColumnAlwaysEditable, nil) 87 | table.appendTextColumn("Last Name", COLUMN_LAST_NAME, TableModelColumnAlwaysEditable, nil) 88 | table.appendTextColumn("Address", COLUMN_ADRESS, TableModelColumnAlwaysEditable, nil) 89 | table.appendProgressBarColumn("Progress", COLUMN_PROCESS) 90 | table.appendCheckboxColumn("Passed", COLUMN_PASSED, TableModelColumnAlwaysEditable) 91 | table.appendButtonColumn("Action", COLUMN_ACTION, TableModelColumnAlwaysEditable) 92 | 93 | box.add(table, true) 94 | show(mainwin) 95 | 96 | init() 97 | main() 98 | mainLoop() 99 | -------------------------------------------------------------------------------- /examples/toy.nim: -------------------------------------------------------------------------------- 1 | 2 | # Test & show the new high level wrapper 3 | 4 | import ui 5 | 6 | proc main*() = 7 | var mainwin: Window 8 | 9 | var menu = newMenu("File") 10 | menu.addItem("Open", proc() = 11 | let filename = ui.openFile(mainwin) 12 | if filename.len == 0: 13 | msgBoxError(mainwin, "No file selected", "Don't be alarmed!") 14 | else: 15 | msgBox(mainwin, "File selected", filename) 16 | ) 17 | menu.addItem("Save", proc() = 18 | let filename = ui.saveFile(mainwin) 19 | if filename.len == 0: 20 | msgBoxError(mainwin, "No file selected", "Don't be alarmed!") 21 | else: 22 | msgBox(mainwin, "File selected (don't worry, it's still there)", filename) 23 | ) 24 | menu.addQuitItem(proc(): bool {.closure.} = 25 | mainwin.destroy() 26 | return true) 27 | 28 | menu = newMenu("Edit") 29 | menu.addCheckItem("Checkable Item", proc() = discard) 30 | menu.addSeparator() 31 | let item = menu.addItem("Disabled Item", proc() = discard) 32 | item.disable() 33 | menu.addPreferencesItem(proc() = discard) 34 | menu = newMenu("Help") 35 | menu.addItem("Help", proc () = discard) 36 | menu.addAboutItem(proc () = discard) 37 | 38 | mainwin = newWindow("libui Control Gallery", 640, 480, true) 39 | mainwin.margined = true 40 | mainwin.onClosing = (proc (): bool = return true) 41 | 42 | let box = newVerticalBox(true) 43 | mainwin.setChild(box) 44 | 45 | var group = newGroup("Basic Controls", true) 46 | box.add(group, false) 47 | 48 | var inner = newVerticalBox(true) 49 | group.child = inner 50 | 51 | inner.add newButton("Button", proc() = msgBoxError(mainwin, "Error", "Rotec")) 52 | 53 | show(mainwin) 54 | mainLoop() 55 | 56 | init() 57 | main() 58 | -------------------------------------------------------------------------------- /headers/ui.c2nim: -------------------------------------------------------------------------------- 1 | 2 | #def _UI_EXTERN 3 | 4 | #nep1 5 | #skipcomments 6 | 7 | #cdecl 8 | 9 | #dynlib dllName 10 | #mangle uint32_t uint32 11 | #mangle uint16_t uint16 12 | #mangle uint8_t uint8 13 | #mangle uint64_t uint64 14 | 15 | #mangle int32_t int32 16 | #mangle int16_t int16 17 | #mangle int8_t int8 18 | #mangle int64_t int64 19 | 20 | #mangle uintptr_t int 21 | #mangle uintmax_t uint64 22 | 23 | #mangle intmax_t int64 24 | #prefix ui 25 | #def defControl(x) struct x : public uiControl {} 26 | -------------------------------------------------------------------------------- /headers/ui.h: -------------------------------------------------------------------------------- 1 | 2 | // 6 april 2015 3 | 4 | // TODO add a uiVerifyControlType() function that can be used by control implementations to verify controls 5 | 6 | #ifndef __LIBUI_UI_H__ 7 | #define __LIBUI_UI_H__ 8 | 9 | #if defined(windows) 10 | # define dllName "libui.dll" 11 | #elif defined(macosx) 12 | # define dllName "libui.dylib" 13 | #else 14 | # define dllName "libui.so" 15 | #endif 16 | 17 | #def _UI_ENUM(s) enum s 18 | 19 | struct uiInitOptions { 20 | size_t Size; 21 | }; 22 | 23 | _UI_EXTERN const char *uiInit(uiInitOptions *options); 24 | _UI_EXTERN void uiUninit(void); 25 | _UI_EXTERN void uiFreeInitError(const char *err); 26 | 27 | _UI_EXTERN void uiMain(void); 28 | _UI_EXTERN void uiMainSteps(void); 29 | _UI_EXTERN int uiMainStep(int wait); 30 | _UI_EXTERN void uiQuit(void); 31 | 32 | _UI_EXTERN void uiQueueMain(void (*f)(void *data), void *data); 33 | 34 | _UI_EXTERN void uiOnShouldQuit(int (*f)(void *data), void *data); 35 | 36 | _UI_EXTERN void uiFreeText(char *text); 37 | 38 | #inheritable uiControl 39 | #pure uiControl 40 | typedef struct { 41 | uint32_t Signature; 42 | uint32_t OSSignature; 43 | uint32_t TypeSignature; 44 | void (*Destroy)(uiControl *); 45 | uintptr_t (*Handle)(uiControl *); 46 | uiControl *(*Parent)(uiControl *); 47 | void (*SetParent)(uiControl *, uiControl *); 48 | int (*Toplevel)(uiControl *); 49 | int (*Visible)(uiControl *); 50 | void (*Show)(uiControl *); 51 | void (*Hide)(uiControl *); 52 | int (*Enabled)(uiControl *); 53 | void (*Enable)(uiControl *); 54 | void (*Disable)(uiControl *); 55 | } uiControl; 56 | // TOOD add argument names to all arguments 57 | #define toUiControl(this) ((uiControl *) (this)) 58 | _UI_EXTERN void uiControlDestroy(uiControl *); 59 | _UI_EXTERN uintptr_t uiControlHandle(uiControl *); 60 | _UI_EXTERN uiControl *uiControlParent(uiControl *); 61 | _UI_EXTERN void uiControlSetParent(uiControl *, uiControl *); 62 | _UI_EXTERN int uiControlToplevel(uiControl *); 63 | _UI_EXTERN int uiControlVisible(uiControl *); 64 | _UI_EXTERN void uiControlShow(uiControl *); 65 | _UI_EXTERN void uiControlHide(uiControl *); 66 | _UI_EXTERN int uiControlEnabled(uiControl *); 67 | _UI_EXTERN void uiControlEnable(uiControl *); 68 | _UI_EXTERN void uiControlDisable(uiControl *); 69 | 70 | _UI_EXTERN uiControl *uiAllocControl(size_t n, uint32_t OSsig, uint32_t typesig, const char *typenamestr); 71 | _UI_EXTERN void uiFreeControl(uiControl *); 72 | 73 | // TODO make sure all controls have these 74 | _UI_EXTERN void uiControlVerifySetParent(uiControl *, uiControl *); 75 | _UI_EXTERN int uiControlEnabledToUser(uiControl *); 76 | 77 | _UI_EXTERN void uiUserBugCannotSetParentOnToplevel(const char *type); 78 | 79 | defControl(uiWindow); 80 | #define toUiWindow(this) ((uiWindow *) (this)) 81 | _UI_EXTERN char *uiWindowTitle(uiWindow *w); 82 | _UI_EXTERN void uiWindowSetTitle(uiWindow *w, const char *title); 83 | _UI_EXTERN void uiWindowContentSize(uiWindow *w, int *width, int *height); 84 | _UI_EXTERN void uiWindowSetContentSize(uiWindow *w, int width, int height); 85 | _UI_EXTERN int uiWindowFullscreen(uiWindow *w); 86 | _UI_EXTERN void uiWindowSetFullscreen(uiWindow *w, int fullscreen); 87 | _UI_EXTERN void uiWindowOnContentSizeChanged(uiWindow *w, void (*f)(uiWindow *, void *), void *data); 88 | _UI_EXTERN void uiWindowOnClosing(uiWindow *w, int (*f)(uiWindow *w, void *data), void *data); 89 | _UI_EXTERN int uiWindowBorderless(uiWindow *w); 90 | _UI_EXTERN void uiWindowSetBorderless(uiWindow *w, int borderless); 91 | _UI_EXTERN void uiWindowSetChild(uiWindow *w, uiControl *child); 92 | _UI_EXTERN int uiWindowMargined(uiWindow *w); 93 | _UI_EXTERN void uiWindowSetMargined(uiWindow *w, int margined); 94 | _UI_EXTERN uiWindow *uiNewWindow(const char *title, int width, int height, int hasMenubar); 95 | 96 | defControl(uiButton); 97 | #define toUiButton(this) ((uiButton *) (this)) 98 | _UI_EXTERN char *uiButtonText(uiButton *b); 99 | _UI_EXTERN void uiButtonSetText(uiButton *b, const char *text); 100 | _UI_EXTERN void uiButtonOnClicked(uiButton *b, void (*f)(uiButton *b, void *data), void *data); 101 | _UI_EXTERN uiButton *uiNewButton(const char *text); 102 | 103 | defControl(uiBox); 104 | #define toUiBox(this) ((uiBox *) (this)) 105 | _UI_EXTERN void uiBoxAppend(uiBox *b, uiControl *child, int stretchy); 106 | _UI_EXTERN void uiBoxDelete(uiBox *b, int index); 107 | _UI_EXTERN int uiBoxPadded(uiBox *b); 108 | _UI_EXTERN void uiBoxSetPadded(uiBox *b, int padded); 109 | _UI_EXTERN uiBox *uiNewHorizontalBox(void); 110 | _UI_EXTERN uiBox *uiNewVerticalBox(void); 111 | 112 | defControl(uiCheckbox); 113 | #define toUiCheckbox(this) ((uiCheckbox *) (this)) 114 | _UI_EXTERN char *uiCheckboxText(uiCheckbox *c); 115 | _UI_EXTERN void uiCheckboxSetText(uiCheckbox *c, const char *text); 116 | _UI_EXTERN void uiCheckboxOnToggled(uiCheckbox *c, void (*f)(uiCheckbox *c, void *data), void *data); 117 | _UI_EXTERN int uiCheckboxChecked(uiCheckbox *c); 118 | _UI_EXTERN void uiCheckboxSetChecked(uiCheckbox *c, int checked); 119 | _UI_EXTERN uiCheckbox *uiNewCheckbox(const char *text); 120 | 121 | defControl(uiEntry); 122 | #define toUiEntry(this) ((uiEntry *) (this)) 123 | _UI_EXTERN char *uiEntryText(uiEntry *e); 124 | _UI_EXTERN void uiEntrySetText(uiEntry *e, const char *text); 125 | _UI_EXTERN void uiEntryOnChanged(uiEntry *e, void (*f)(uiEntry *e, void *data), void *data); 126 | _UI_EXTERN int uiEntryReadOnly(uiEntry *e); 127 | _UI_EXTERN void uiEntrySetReadOnly(uiEntry *e, int readonly); 128 | _UI_EXTERN uiEntry *uiNewEntry(void); 129 | _UI_EXTERN uiEntry *uiNewPasswordEntry(void); 130 | _UI_EXTERN uiEntry *uiNewSearchEntry(void); 131 | 132 | defControl(uiLabel); 133 | #define toUiLabel(this) ((uiLabel *) (this)) 134 | _UI_EXTERN char *uiLabelText(uiLabel *label); 135 | _UI_EXTERN void uiLabelSetText(uiLabel *label, const char *text); 136 | _UI_EXTERN uiLabel *uiNewLabel(const char *text); 137 | 138 | defControl(uiTab); 139 | #define toUiTab(this) ((uiTab *) (this)) 140 | _UI_EXTERN void uiTabAppend(uiTab *t, const char *name, uiControl *c); 141 | _UI_EXTERN void uiTabInsertAt(uiTab *t, const char *name, int before, uiControl *c); 142 | _UI_EXTERN void uiTabDelete(uiTab *t, int index); 143 | _UI_EXTERN int uiTabNumPages(uiTab *t); 144 | _UI_EXTERN int uiTabMargined(uiTab *t, int page); 145 | _UI_EXTERN void uiTabSetMargined(uiTab *t, int page, int margined); 146 | _UI_EXTERN uiTab *uiNewTab(void); 147 | 148 | defControl(uiGroup); 149 | #define toUiGroup(this) ((uiGroup *) (this)) 150 | _UI_EXTERN char *uiGroupTitle(uiGroup *g); 151 | _UI_EXTERN void uiGroupSetTitle(uiGroup *g, const char *title); 152 | _UI_EXTERN void uiGroupSetChild(uiGroup *g, uiControl *c); 153 | _UI_EXTERN int uiGroupMargined(uiGroup *g); 154 | _UI_EXTERN void uiGroupSetMargined(uiGroup *g, int margined); 155 | _UI_EXTERN uiGroup *uiNewGroup(const char *title); 156 | 157 | // spinbox/slider rules: 158 | // setting value outside of range will automatically clamp 159 | // initial value is minimum 160 | // complaint if min >= max? 161 | 162 | defControl(uiSpinbox); 163 | #define toUiSpinbox(this) ((uiSpinbox *) (this)) 164 | _UI_EXTERN int uiSpinboxValue(uiSpinbox *s); 165 | _UI_EXTERN void uiSpinboxSetValue(uiSpinbox *s, int value); 166 | _UI_EXTERN void uiSpinboxOnChanged(uiSpinbox *s, void (*f)(uiSpinbox *s, void *data), void *data); 167 | _UI_EXTERN uiSpinbox *uiNewSpinbox(int min, int max); 168 | 169 | defControl(uiSlider); 170 | #define toUiSlider(this) ((uiSlider *) (this)) 171 | _UI_EXTERN int uiSliderValue(uiSlider *s); 172 | _UI_EXTERN void uiSliderSetValue(uiSlider *s, int value); 173 | _UI_EXTERN void uiSliderOnChanged(uiSlider *s, void (*f)(uiSlider *s, void *data), void *data); 174 | _UI_EXTERN uiSlider *uiNewSlider(int min, int max); 175 | 176 | defControl(uiProgressBar); 177 | #define toUiProgressBar(this) ((uiProgressBar *) (this)) 178 | _UI_EXTERN int uiProgressBarValue(uiProgressBar *p); 179 | _UI_EXTERN void uiProgressBarSetValue(uiProgressBar *p, int n); 180 | _UI_EXTERN uiProgressBar *uiNewProgressBar(void); 181 | 182 | defControl(uiSeparator); 183 | #define toUiSeparator(this) ((uiSeparator *) (this)) 184 | _UI_EXTERN uiSeparator *uiNewHorizontalSeparator(void); 185 | _UI_EXTERN uiSeparator *uiNewVerticalSeparator(void); 186 | 187 | defControl(uiCombobox); 188 | #define toUiCombobox(this) ((uiCombobox *) (this)) 189 | _UI_EXTERN void uiComboboxAppend(uiCombobox *c, const char *text); 190 | _UI_EXTERN int uiComboboxSelected(uiCombobox *c); 191 | _UI_EXTERN void uiComboboxSetSelected(uiCombobox *c, int n); 192 | _UI_EXTERN void uiComboboxOnSelected(uiCombobox *c, void (*f)(uiCombobox *c, void *data), void *data); 193 | _UI_EXTERN uiCombobox *uiNewCombobox(void); 194 | 195 | defControl(uiEditableCombobox); 196 | #define toUiEditableCombobox(this) ((uiEditableCombobox *) (this)) 197 | _UI_EXTERN void uiEditableComboboxAppend(uiEditableCombobox *c, const char *text); 198 | _UI_EXTERN char *uiEditableComboboxText(uiEditableCombobox *c); 199 | _UI_EXTERN void uiEditableComboboxSetText(uiEditableCombobox *c, const char *text); 200 | // TODO what do we call a function that sets the currently selected item and fills the text field with it? editable comboboxes have no consistent concept of selected item 201 | _UI_EXTERN void uiEditableComboboxOnChanged(uiEditableCombobox *c, void (*f)(uiEditableCombobox *c, void *data), void *data); 202 | _UI_EXTERN uiEditableCombobox *uiNewEditableCombobox(void); 203 | 204 | defControl(uiRadioButtons); 205 | #define toUiRadioButtons(this) ((uiRadioButtons *) (this)) 206 | _UI_EXTERN void uiRadioButtonsAppend(uiRadioButtons *r, const char *text); 207 | _UI_EXTERN int uiRadioButtonsSelected(uiRadioButtons *r); 208 | _UI_EXTERN void uiRadioButtonsSetSelected(uiRadioButtons *r, int n); 209 | _UI_EXTERN void uiRadioButtonsOnSelected(uiRadioButtons *r, void (*f)(uiRadioButtons *, void *), void *data); 210 | _UI_EXTERN uiRadioButtons *uiNewRadioButtons(void); 211 | 212 | defControl(uiDateTimePicker); 213 | #define toUiDateTimePicker(this) ((uiDateTimePicker *) (this)) 214 | _UI_EXTERN uiDateTimePicker *uiNewDateTimePicker(void); 215 | _UI_EXTERN uiDateTimePicker *uiNewDatePicker(void); 216 | _UI_EXTERN uiDateTimePicker *uiNewTimePicker(void); 217 | 218 | // TODO provide a facility for entering tab stops? 219 | defControl(uiMultilineEntry); 220 | #define toUiMultilineEntry(this) ((uiMultilineEntry *) (this)) 221 | _UI_EXTERN char *uiMultilineEntryText(uiMultilineEntry *e); 222 | _UI_EXTERN void uiMultilineEntrySetText(uiMultilineEntry *e, const char *text); 223 | _UI_EXTERN void uiMultilineEntryAppend(uiMultilineEntry *e, const char *text); 224 | _UI_EXTERN void uiMultilineEntryOnChanged(uiMultilineEntry *e, void (*f)(uiMultilineEntry *e, void *data), void *data); 225 | _UI_EXTERN int uiMultilineEntryReadOnly(uiMultilineEntry *e); 226 | _UI_EXTERN void uiMultilineEntrySetReadOnly(uiMultilineEntry *e, int readonly); 227 | _UI_EXTERN uiMultilineEntry *uiNewMultilineEntry(void); 228 | _UI_EXTERN uiMultilineEntry *uiNewNonWrappingMultilineEntry(void); 229 | 230 | defControl(uiMenuItem); 231 | #define toUiMenuItem(this) ((uiMenuItem *) (this)) 232 | _UI_EXTERN void uiMenuItemEnable(uiMenuItem *m); 233 | _UI_EXTERN void uiMenuItemDisable(uiMenuItem *m); 234 | _UI_EXTERN void uiMenuItemOnClicked(uiMenuItem *m, void (*f)(uiMenuItem *sender, uiWindow *window, void *data), void *data); 235 | _UI_EXTERN int uiMenuItemChecked(uiMenuItem *m); 236 | _UI_EXTERN void uiMenuItemSetChecked(uiMenuItem *m, int checked); 237 | 238 | defControl(uiMenu); 239 | #define toUiMenu(this) ((uiMenu *) (this)) 240 | _UI_EXTERN uiMenuItem *uiMenuAppendItem(uiMenu *m, const char *name); 241 | _UI_EXTERN uiMenuItem *uiMenuAppendCheckItem(uiMenu *m, const char *name); 242 | _UI_EXTERN uiMenuItem *uiMenuAppendQuitItem(uiMenu *m); 243 | _UI_EXTERN uiMenuItem *uiMenuAppendPreferencesItem(uiMenu *m); 244 | _UI_EXTERN uiMenuItem *uiMenuAppendAboutItem(uiMenu *m); 245 | _UI_EXTERN void uiMenuAppendSeparator(uiMenu *m); 246 | _UI_EXTERN uiMenu *uiNewMenu(const char *name); 247 | 248 | _UI_EXTERN char *uiOpenFile(uiWindow *parent); 249 | _UI_EXTERN char *uiSaveFile(uiWindow *parent); 250 | _UI_EXTERN void uiMsgBox(uiWindow *parent, const char *title, const char *description); 251 | _UI_EXTERN void uiMsgBoxError(uiWindow *parent, const char *title, const char *description); 252 | 253 | defControl(uiArea); 254 | 255 | _UI_ENUM(uiModifiers) { 256 | uiModifierCtrl = 1 << 0, 257 | uiModifierAlt = 1 << 1, 258 | uiModifierShift = 1 << 2, 259 | uiModifierSuper = 1 << 3, 260 | }; 261 | 262 | // TODO document drag captures 263 | typedef struct { 264 | // TODO document what these mean for scrolling areas 265 | double X; 266 | double Y; 267 | 268 | // TODO see draw above 269 | double AreaWidth; 270 | double AreaHeight; 271 | 272 | int Down; 273 | int Up; 274 | 275 | int Count; 276 | 277 | uiModifiers Modifiers; 278 | 279 | uint64_t Held1To64; 280 | } uiAreaMouseEvent; 281 | _UI_ENUM(uiExtKey) { 282 | uiExtKeyEscape = 1, 283 | uiExtKeyInsert, // equivalent to "Help" on Apple keyboards 284 | uiExtKeyDelete, 285 | uiExtKeyHome, 286 | uiExtKeyEnd, 287 | uiExtKeyPageUp, 288 | uiExtKeyPageDown, 289 | uiExtKeyUp, 290 | uiExtKeyDown, 291 | uiExtKeyLeft, 292 | uiExtKeyRight, 293 | uiExtKeyF1, // F1..F12 are guaranteed to be consecutive 294 | uiExtKeyF2, 295 | uiExtKeyF3, 296 | uiExtKeyF4, 297 | uiExtKeyF5, 298 | uiExtKeyF6, 299 | uiExtKeyF7, 300 | uiExtKeyF8, 301 | uiExtKeyF9, 302 | uiExtKeyF10, 303 | uiExtKeyF11, 304 | uiExtKeyF12, 305 | uiExtKeyN0, // numpad keys; independent of Num Lock state 306 | uiExtKeyN1, // N0..N9 are guaranteed to be consecutive 307 | uiExtKeyN2, 308 | uiExtKeyN3, 309 | uiExtKeyN4, 310 | uiExtKeyN5, 311 | uiExtKeyN6, 312 | uiExtKeyN7, 313 | uiExtKeyN8, 314 | uiExtKeyN9, 315 | uiExtKeyNDot, 316 | uiExtKeyNEnter, 317 | uiExtKeyNAdd, 318 | uiExtKeyNSubtract, 319 | uiExtKeyNMultiply, 320 | uiExtKeyNDivide, 321 | }; 322 | 323 | typedef struct { 324 | char Key; 325 | uiExtKey ExtKey; 326 | uiModifiers Modifier; 327 | 328 | uiModifiers Modifiers; 329 | 330 | int Up; 331 | } uiAreaKeyEvent; 332 | 333 | typedef struct {} uiDrawContext; 334 | 335 | typedef struct { 336 | uiDrawContext *Context; 337 | 338 | // TODO document that this is only defined for nonscrolling areas 339 | double AreaWidth; 340 | double AreaHeight; 341 | 342 | double ClipX; 343 | double ClipY; 344 | double ClipWidth; 345 | double ClipHeight; 346 | } uiAreaDrawParams; 347 | 348 | typedef struct { 349 | void (*Draw)(uiAreaHandler *, uiArea *, uiAreaDrawParams *); 350 | // TODO document that resizes cause a full redraw for non-scrolling areas; implementation-defined for scrolling areas 351 | void (*MouseEvent)(uiAreaHandler *, uiArea *, uiAreaMouseEvent *); 352 | // TODO document that on first show if the mouse is already in the uiArea then one gets sent with left=0 353 | // TODO what about when the area is hidden and then shown again? 354 | void (*MouseCrossed)(uiAreaHandler *, uiArea *, int left); 355 | void (*DragBroken)(uiAreaHandler *, uiArea *); 356 | int (*KeyEvent)(uiAreaHandler *, uiArea *, uiAreaKeyEvent *); 357 | } uiAreaHandler; 358 | 359 | #define toUiArea(this) ((uiArea *) (this)) 360 | // TODO give a better name 361 | // TODO document the types of width and height 362 | _UI_EXTERN void uiAreaSetSize(uiArea *a, int width, int height); 363 | // TODO uiAreaQueueRedraw() 364 | _UI_EXTERN void uiAreaQueueRedrawAll(uiArea *a); 365 | _UI_EXTERN void uiAreaScrollTo(uiArea *a, double x, double y, double width, double height); 366 | _UI_EXTERN uiArea *uiNewArea(uiAreaHandler *ah); 367 | _UI_EXTERN uiArea *uiNewScrollingArea(uiAreaHandler *ah, int width, int height); 368 | 369 | typedef struct {} uiDrawPath; 370 | 371 | _UI_ENUM(uiDrawBrushType) { 372 | uiDrawBrushTypeSolid, 373 | uiDrawBrushTypeLinearGradient, 374 | uiDrawBrushTypeRadialGradient, 375 | uiDrawBrushTypeImage, 376 | }; 377 | 378 | _UI_ENUM(uiDrawLineCap) { 379 | uiDrawLineCapFlat, 380 | uiDrawLineCapRound, 381 | uiDrawLineCapSquare, 382 | }; 383 | 384 | _UI_ENUM(uiDrawLineJoin) { 385 | uiDrawLineJoinMiter, 386 | uiDrawLineJoinRound, 387 | uiDrawLineJoinBevel, 388 | }; 389 | 390 | // this is the default for botoh cairo and Direct2D (in the latter case, from the C++ helper functions) 391 | // Core Graphics doesn't explicitly specify a default, but NSBezierPath allows you to choose one, and this is the initial value 392 | // so we're good to use it too! 393 | #define uiDrawDefaultMiterLimit 10.0 394 | 395 | _UI_ENUM(uiDrawFillMode) { 396 | uiDrawFillModeWinding, 397 | uiDrawFillModeAlternate, 398 | }; 399 | 400 | struct uiDrawMatrix { 401 | double M11; 402 | double M12; 403 | double M21; 404 | double M22; 405 | double M31; 406 | double M32; 407 | }; 408 | 409 | struct uiDrawBrush { 410 | uiDrawBrushType Type; 411 | 412 | // solid brushes 413 | double R; 414 | double G; 415 | double B; 416 | double A; 417 | 418 | // gradient brushes 419 | double X0; // linear: start X, radial: start X 420 | double Y0; // linear: start Y, radial: start Y 421 | double X1; // linear: end X, radial: outer circle center X 422 | double Y1; // linear: end Y, radial: outer circle center Y 423 | double OuterRadius; // radial gradients only 424 | uiDrawBrushGradientStop *Stops; 425 | size_t NumStops; 426 | // TODO extend mode 427 | // cairo: none, repeat, reflect, pad; no individual control 428 | // Direct2D: repeat, reflect, pad; no individual control 429 | // Core Graphics: none, pad; before and after individually 430 | // TODO cairo documentation is inconsistent about pad 431 | 432 | // TODO images 433 | 434 | // TODO transforms 435 | }; 436 | 437 | struct uiDrawBrushGradientStop { 438 | double Pos; 439 | double R; 440 | double G; 441 | double B; 442 | double A; 443 | }; 444 | 445 | struct uiDrawStrokeParams { 446 | uiDrawLineCap Cap; 447 | uiDrawLineJoin Join; 448 | // TODO what if this is 0? on windows there will be a crash with dashing 449 | double Thickness; 450 | double MiterLimit; 451 | double *Dashes; 452 | // TOOD what if this is 1 on Direct2D? 453 | // TODO what if a dash is 0 on Cairo or Quartz? 454 | size_t NumDashes; 455 | double DashPhase; 456 | }; 457 | 458 | _UI_EXTERN uiDrawPath *uiDrawNewPath(uiDrawFillMode fillMode); 459 | _UI_EXTERN void uiDrawFreePath(uiDrawPath *p); 460 | 461 | _UI_EXTERN void uiDrawPathNewFigure(uiDrawPath *p, double x, double y); 462 | _UI_EXTERN void uiDrawPathNewFigureWithArc(uiDrawPath *p, double xCenter, double yCenter, double radius, double startAngle, double sweep, int negative); 463 | _UI_EXTERN void uiDrawPathLineTo(uiDrawPath *p, double x, double y); 464 | // notes: angles are both relative to 0 and go counterclockwise 465 | // TODO is the initial line segment on cairo and OS X a proper join? 466 | // TODO what if sweep < 0? 467 | _UI_EXTERN void uiDrawPathArcTo(uiDrawPath *p, double xCenter, double yCenter, double radius, double startAngle, double sweep, int negative); 468 | _UI_EXTERN void uiDrawPathBezierTo(uiDrawPath *p, double c1x, double c1y, double c2x, double c2y, double endX, double endY); 469 | // TODO quadratic bezier 470 | _UI_EXTERN void uiDrawPathCloseFigure(uiDrawPath *p); 471 | 472 | // TODO effect of these when a figure is already started 473 | _UI_EXTERN void uiDrawPathAddRectangle(uiDrawPath *p, double x, double y, double width, double height); 474 | 475 | _UI_EXTERN void uiDrawPathEnd(uiDrawPath *p); 476 | 477 | _UI_EXTERN void uiDrawStroke(uiDrawContext *c, uiDrawPath *path, uiDrawBrush *b, uiDrawStrokeParams *p); 478 | _UI_EXTERN void uiDrawFill(uiDrawContext *c, uiDrawPath *path, uiDrawBrush *b); 479 | 480 | // TODO primitives: 481 | // - rounded rectangles 482 | // - elliptical arcs 483 | // - quadratic bezier curves 484 | 485 | _UI_EXTERN void uiDrawMatrixSetIdentity(uiDrawMatrix *m); 486 | _UI_EXTERN void uiDrawMatrixTranslate(uiDrawMatrix *m, double x, double y); 487 | _UI_EXTERN void uiDrawMatrixScale(uiDrawMatrix *m, double xCenter, double yCenter, double x, double y); 488 | _UI_EXTERN void uiDrawMatrixRotate(uiDrawMatrix *m, double x, double y, double amount); 489 | _UI_EXTERN void uiDrawMatrixSkew(uiDrawMatrix *m, double x, double y, double xamount, double yamount); 490 | _UI_EXTERN void uiDrawMatrixMultiply(uiDrawMatrix *dest, uiDrawMatrix *src); 491 | _UI_EXTERN int uiDrawMatrixInvertible(uiDrawMatrix *m); 492 | _UI_EXTERN int uiDrawMatrixInvert(uiDrawMatrix *m); 493 | _UI_EXTERN void uiDrawMatrixTransformPoint(uiDrawMatrix *m, double *x, double *y); 494 | _UI_EXTERN void uiDrawMatrixTransformSize(uiDrawMatrix *m, double *x, double *y); 495 | 496 | _UI_EXTERN void uiDrawTransform(uiDrawContext *c, uiDrawMatrix *m); 497 | 498 | // TODO add a uiDrawPathStrokeToFill() or something like that 499 | _UI_EXTERN void uiDrawClip(uiDrawContext *c, uiDrawPath *path); 500 | 501 | _UI_EXTERN void uiDrawSave(uiDrawContext *c); 502 | _UI_EXTERN void uiDrawRestore(uiDrawContext *c); 503 | 504 | // TODO manage the use of Text, Font, and TextFont, and of the uiDrawText prefix in general 505 | 506 | ///// TODO reconsider this 507 | typedef struct {} uiDrawFontFamilies; 508 | 509 | _UI_EXTERN uiDrawFontFamilies *uiDrawListFontFamilies(void); 510 | _UI_EXTERN int uiDrawFontFamiliesNumFamilies(uiDrawFontFamilies *ff); 511 | _UI_EXTERN char *uiDrawFontFamiliesFamily(uiDrawFontFamilies *ff, int n); 512 | _UI_EXTERN void uiDrawFreeFontFamilies(uiDrawFontFamilies *ff); 513 | ///// END TODO 514 | 515 | typedef struct {} uiDrawTextLayout; 516 | typedef struct {} uiDrawTextFont; 517 | 518 | _UI_ENUM(uiDrawTextWeight) { 519 | uiDrawTextWeightThin, 520 | uiDrawTextWeightUltraLight, 521 | uiDrawTextWeightLight, 522 | uiDrawTextWeightBook, 523 | uiDrawTextWeightNormal, 524 | uiDrawTextWeightMedium, 525 | uiDrawTextWeightSemiBold, 526 | uiDrawTextWeightBold, 527 | uiDrawTextWeightUltraBold, 528 | uiDrawTextWeightHeavy, 529 | uiDrawTextWeightUltraHeavy, 530 | }; 531 | 532 | _UI_ENUM(uiDrawTextItalic) { 533 | uiDrawTextItalicNormal, 534 | uiDrawTextItalicOblique, 535 | uiDrawTextItalicItalic, 536 | }; 537 | 538 | _UI_ENUM(uiDrawTextStretch) { 539 | uiDrawTextStretchUltraCondensed, 540 | uiDrawTextStretchExtraCondensed, 541 | uiDrawTextStretchCondensed, 542 | uiDrawTextStretchSemiCondensed, 543 | uiDrawTextStretchNormal, 544 | uiDrawTextStretchSemiExpanded, 545 | uiDrawTextStretchExpanded, 546 | uiDrawTextStretchExtraExpanded, 547 | uiDrawTextStretchUltraExpanded, 548 | }; 549 | 550 | struct uiDrawTextFontDescriptor { 551 | const char *Family; 552 | double Size; 553 | uiDrawTextWeight Weight; 554 | uiDrawTextItalic Italic; 555 | uiDrawTextStretch Stretch; 556 | }; 557 | 558 | struct uiDrawTextFontMetrics { 559 | double Ascent; 560 | double Descent; 561 | double Leading; 562 | // TODO do these two mean the same across all platforms? 563 | double UnderlinePos; 564 | double UnderlineThickness; 565 | }; 566 | 567 | _UI_EXTERN uiDrawTextFont *uiDrawLoadClosestFont(const uiDrawTextFontDescriptor *desc); 568 | _UI_EXTERN void uiDrawFreeTextFont(uiDrawTextFont *font); 569 | _UI_EXTERN uintptr_t uiDrawTextFontHandle(uiDrawTextFont *font); 570 | _UI_EXTERN void uiDrawTextFontDescribe(uiDrawTextFont *font, uiDrawTextFontDescriptor *desc); 571 | // TODO make copy with given attributes methods? 572 | // TODO yuck this name 573 | _UI_EXTERN void uiDrawTextFontGetMetrics(uiDrawTextFont *font, uiDrawTextFontMetrics *metrics); 574 | 575 | // TODO initial line spacing? and what about leading? 576 | _UI_EXTERN uiDrawTextLayout *uiDrawNewTextLayout(const char *text, uiDrawTextFont *defaultFont, double width); 577 | _UI_EXTERN void uiDrawFreeTextLayout(uiDrawTextLayout *layout); 578 | // TODO get width 579 | _UI_EXTERN void uiDrawTextLayoutSetWidth(uiDrawTextLayout *layout, double width); 580 | _UI_EXTERN void uiDrawTextLayoutExtents(uiDrawTextLayout *layout, double *width, double *height); 581 | 582 | // and the attributes that you can set on a text layout 583 | _UI_EXTERN void uiDrawTextLayoutSetColor(uiDrawTextLayout *layout, int startChar, int endChar, double r, double g, double b, double a); 584 | 585 | _UI_EXTERN void uiDrawText(uiDrawContext *c, double x, double y, uiDrawTextLayout *layout); 586 | 587 | defControl(uiFontButton); 588 | #define toUiFontButton(this) ((uiFontButton *) (this)) 589 | // TODO document this returns a new font 590 | _UI_EXTERN uiDrawTextFont *uiFontButtonFont(uiFontButton *b); 591 | // TOOD SetFont, mechanics 592 | _UI_EXTERN void uiFontButtonOnChanged(uiFontButton *b, void (*f)(uiFontButton *, void *), void *data); 593 | _UI_EXTERN uiFontButton *uiNewFontButton(void); 594 | 595 | defControl(uiColorButton); 596 | #define toUiColorButton(this) ((uiColorButton *) (this)) 597 | _UI_EXTERN void uiColorButtonColor(uiColorButton *b, double *r, double *g, double *bl, double *a); 598 | _UI_EXTERN void uiColorButtonSetColor(uiColorButton *b, double r, double g, double bl, double a); 599 | _UI_EXTERN void uiColorButtonOnChanged(uiColorButton *b, void (*f)(uiColorButton *, void *), void *data); 600 | _UI_EXTERN uiColorButton *uiNewColorButton(void); 601 | 602 | defControl(uiForm); 603 | #define toUiForm(this) ((uiForm *) (this)) 604 | _UI_EXTERN void uiFormAppend(uiForm *f, const char *label, uiControl *c, int stretchy); 605 | _UI_EXTERN void uiFormDelete(uiForm *f, int index); 606 | _UI_EXTERN int uiFormPadded(uiForm *f); 607 | _UI_EXTERN void uiFormSetPadded(uiForm *f, int padded); 608 | _UI_EXTERN uiForm *uiNewForm(void); 609 | 610 | _UI_ENUM(uiAlign) { 611 | uiAlignFill, 612 | uiAlignStart, 613 | uiAlignCenter, 614 | uiAlignEnd, 615 | }; 616 | 617 | _UI_ENUM(uiAt) { 618 | uiAtLeading, 619 | uiAtTop, 620 | uiAtTrailing, 621 | uiAtBottom, 622 | }; 623 | 624 | defControl(uiGrid); 625 | #define toUiGrid(this) ((uiGrid *) (this)) 626 | _UI_EXTERN void uiGridAppend(uiGrid *g, uiControl *c, int left, int top, int xspan, int yspan, int hexpand, uiAlign halign, int vexpand, uiAlign valign); 627 | _UI_EXTERN void uiGridInsertAt(uiGrid *g, uiControl *c, uiControl *existing, uiAt at, int xspan, int yspan, int hexpand, uiAlign halign, int vexpand, uiAlign valign); 628 | _UI_EXTERN int uiGridPadded(uiGrid *g); 629 | _UI_EXTERN void uiGridSetPadded(uiGrid *g, int padded); 630 | _UI_EXTERN uiGrid *uiNewGrid(void); 631 | 632 | #ifdef __cplusplus 633 | } 634 | #endif 635 | 636 | #endif 637 | -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /res/resources.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nim-lang/ui/547e1cea8e9fb68c138c422b77af0a3152e50210/res/resources.o -------------------------------------------------------------------------------- /res/resources.res: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nim-lang/ui/547e1cea8e9fb68c138c422b77af0a3152e50210/res/resources.res -------------------------------------------------------------------------------- /ui.nim: -------------------------------------------------------------------------------- 1 | 2 | import ui/rawui 3 | 4 | type 5 | Widget* = ref object of RootRef ## abstract Widget base class. 6 | internalImpl*: pointer 7 | 8 | func impl*(w: Widget): ptr[Control] = cast[ptr Control](w.internalImpl) 9 | 10 | proc init*() = 11 | var o: rawui.InitOptions 12 | var err: cstring 13 | err = rawui.init(addr(o)) 14 | if err != nil: 15 | let msg = $err 16 | freeInitError(err) 17 | raise newException(ValueError, msg) 18 | 19 | proc quit*() = rawui.quit() 20 | 21 | proc mainLoop*() = 22 | rawui.main() 23 | rawui.uninit() 24 | 25 | proc pollingMainLoop*(poll: proc(timeout: int); timeout: int) = 26 | ## Can be used to merge an async event loop with UI's event loop. 27 | ## Implemented using timeouts and polling because that's the only 28 | ## thing that truely composes. 29 | rawui.mainSteps() 30 | while true: 31 | poll(timeout) 32 | discard rawui.mainStep(0)# != 0: break 33 | rawui.uninit() 34 | 35 | template newFinal(result) = 36 | #proc finalize(x: type(result)) {.nimcall.} = 37 | # controlDestroy(x.impl) 38 | new(result) #, finalize) 39 | 40 | template voidCallback(name, supertyp, basetyp, on) {.dirty.} = 41 | proc name(w: ptr rawui.supertyp; data: pointer) {.cdecl.} = 42 | let widget = cast[basetyp](data) 43 | if widget.on != nil: widget.on() 44 | 45 | template intCallback(name, supertyp, basetyp, on) {.dirty.} = 46 | proc name(w: ptr rawui.supertyp; data: pointer) {.cdecl.} = 47 | let widget = cast[basetyp](data) 48 | if widget.on != nil: widget.on(widget.value) 49 | 50 | template genImplProcs(t: untyped) {.dirty.}= 51 | type `Raw t` = ptr[rawui.t] 52 | func impl*(b: t): `Raw t` = cast[`Raw t`](b.internalImpl) 53 | func `impl=`*(b: t, r: `Raw t`) = b.internalImpl = pointer(r) 54 | 55 | # ------------------- Button -------------------------------------- 56 | type 57 | Button* = ref object of Widget 58 | onclick*: proc () {.closure.} 59 | 60 | voidCallback(wrapOnClick, Button, Button, onclick) 61 | 62 | genImplProcs(Button) 63 | 64 | proc text*(b: Button): string = 65 | ## Gets the button's text. 66 | $buttonText(b.impl) 67 | 68 | proc `text=`*(b: Button; text: string) = 69 | ## Sets the button's text. 70 | buttonSetText(b.impl, text) 71 | 72 | proc newButton*(text: string; onclick: proc() = nil): Button = 73 | newFinal(result) 74 | result.impl = rawui.newButton(text) 75 | result.impl.buttonOnClicked(wrapOnClick, cast[pointer](result)) 76 | result.onclick = onclick 77 | 78 | # ------------------------ RadioButtons ---------------------------- 79 | 80 | type 81 | RadioButtons* = ref object of Widget 82 | onRadioButtonClick*: proc() {.closure.} 83 | 84 | voidCallback(wrapOnRadioButtonClick, RadioButtons, RadioButtons, onRadioButtonClick) 85 | 86 | genImplProcs(RadioButtons) 87 | 88 | proc add*(r: RadioButtons; text: string) = 89 | radioButtonsAppend(r.impl, text) 90 | 91 | proc radioButtonsSelected*(r: RadioButtons): int = 92 | radioButtonsSelected(r.impl) 93 | 94 | proc newRadioButtons*(onclick: proc() = nil): RadioButtons = 95 | newFinal(result) 96 | result.impl = rawui.newRadioButtons() 97 | result.impl.radioButtonsOnSelected(wrapOnRadioButtonClick, cast[pointer](result)) 98 | result.onRadioButtonClick = onclick 99 | 100 | # ----------------- Window ------------------------------------------- 101 | 102 | type 103 | Window* = ref object of Widget 104 | onclosing*: proc (): bool 105 | child: Widget 106 | 107 | genImplProcs(Window) 108 | 109 | proc title*(w: Window): string = 110 | ## Gets the window's title. 111 | $windowTitle(w.impl) 112 | 113 | proc `title=`*(w: Window; text: string) = 114 | ## Sets the window's title. 115 | windowSetTitle(w.impl, text) 116 | 117 | proc destroy*(w: Window) = 118 | ## this needs to be called if the callback passed to addQuitItem returns 119 | ## true. Don't ask... 120 | controlDestroy(w.impl) 121 | 122 | proc onclosingWrapper(rw: ptr rawui.Window; data: pointer): cint {.cdecl.} = 123 | let w = cast[Window](data) 124 | if w.onclosing != nil: 125 | if w.onclosing(): 126 | controlDestroy(w.impl) 127 | rawui.quit() 128 | system.quit() 129 | 130 | proc newWindow*(title: string; width, height: int; hasMenubar: bool): Window = 131 | newFinal(result) 132 | result.impl = rawui.newWindow(title, cint width, cint height, 133 | cint hasMenubar) 134 | windowOnClosing(result.impl, onClosingWrapper, cast[pointer](result)) 135 | 136 | proc margined*(w: Window): bool = windowMargined(w.impl) != 0 137 | proc `margined=`*(w: Window; x: bool) = windowSetMargined(w.impl, cint(x)) 138 | 139 | proc setChild*(w: Window; child: Widget) = 140 | windowSetChild(w.impl, child.impl) 141 | w.child = child 142 | 143 | proc openFile*(parent: Window): string = 144 | let x = openFile(parent.impl) 145 | result = $x 146 | if x != nil: freeText(x) 147 | 148 | proc saveFile*(parent: Window): string = 149 | let x = saveFile(parent.impl) 150 | result = $x 151 | if x != nil: freeText(x) 152 | 153 | proc msgBox*(parent: Window; title, desc: string) = 154 | msgBox(parent.impl, title, desc) 155 | proc msgBoxError*(parent: Window; title, desc: string) = 156 | msgBoxError(parent.impl, title, desc) 157 | 158 | # ------------------------- Box ------------------------------------------ 159 | 160 | type 161 | Box* = ref object of Widget 162 | children*: seq[Widget] 163 | 164 | genImplProcs(Box) 165 | 166 | proc add*(b: Box; child: Widget; stretchy=false) = 167 | boxAppend(b.impl, child.impl, cint(stretchy)) 168 | b.children.add child 169 | 170 | proc delete*(b: Box; index: int) = boxDelete(b.impl, index.cint) 171 | proc padded*(b: Box): bool = boxPadded(b.impl) != 0 172 | proc `padded=`*(b: Box; x: bool) = boxSetPadded(b.impl, x.cint) 173 | 174 | proc newHorizontalBox*(padded = false): Box = 175 | newFinal(result) 176 | result.impl = rawui.newHorizontalBox() 177 | result.children = @[] 178 | boxSetPadded(result.impl, padded.cint) 179 | 180 | proc newVerticalBox*(padded = false): Box = 181 | newFinal(result) 182 | result.impl = rawui.newVerticalBox() 183 | result.children = @[] 184 | boxSetPadded(result.impl, padded.cint) 185 | 186 | # -------------------- Checkbox ---------------------------------- 187 | 188 | type 189 | Checkbox* = ref object of Widget 190 | ontoggled*: proc () 191 | 192 | genImplProcs(Checkbox) 193 | 194 | proc text*(c: Checkbox): string = $checkboxText(c.impl) 195 | proc `text=`*(c: Checkbox; text: string) = checkboxSetText(c.impl, text) 196 | 197 | voidCallback(wrapOntoggled, Checkbox, Checkbox, ontoggled) 198 | 199 | proc checked*(c: Checkbox): bool = checkboxChecked(c.impl) != 0 200 | 201 | proc `checked=`*(c: Checkbox; x: bool) = 202 | checkboxSetChecked(c.impl, cint(x)) 203 | 204 | proc newCheckbox*(text: string; ontoggled: proc() = nil): Checkbox = 205 | newFinal(result) 206 | result.impl = rawui.newCheckbox(text) 207 | result.ontoggled = ontoggled 208 | checkboxOnToggled(result.impl, wrapOntoggled, cast[pointer](result)) 209 | 210 | # ------------------ Entry --------------------------------------- 211 | 212 | type 213 | Entry* = ref object of Widget 214 | onchanged*: proc () 215 | 216 | genImplProcs(Entry) 217 | 218 | proc text*(e: Entry): string = $entryText(e.impl) 219 | proc `text=`*(e: Entry; text: string) = entrySetText(e.impl, text) 220 | 221 | voidCallback(wrapOnchanged, Entry, Entry, onchanged) 222 | 223 | proc readOnly*(e: Entry): bool = entryReadOnly(e.impl) != 0 224 | 225 | proc `readOnly=`*(e: Entry; x: bool) = 226 | entrySetReadOnly(e.impl, cint(x)) 227 | 228 | proc newEntry*(text: string; onchanged: proc() = nil): Entry = 229 | newFinal(result) 230 | result.impl = rawui.newEntry() 231 | result.impl.entryOnChanged(wrapOnchanged, cast[pointer](result)) 232 | result.onchanged = onchanged 233 | entrySetText(result.impl, text) 234 | 235 | # ----------------- Label ---------------------------------------- 236 | 237 | type 238 | Label* = ref object of Widget 239 | 240 | genImplProcs(Label) 241 | 242 | proc text*(L: Label): string = $labelText(L.impl) 243 | proc `text=`*(L: Label; text: string) = labelSetText(L.impl, text) 244 | proc newLabel*(text: string): Label = 245 | newFinal(result) 246 | result.impl = rawui.newLabel(text) 247 | 248 | # ---------------- Tab -------------------------------------------- 249 | 250 | type 251 | Tab* = ref object of Widget 252 | children*: seq[Widget] 253 | 254 | genImplProcs(Tab) 255 | 256 | proc add*(t: Tab; name: string; c: Widget) = 257 | tabAppend t.impl, name, c.impl 258 | t.children.add c 259 | 260 | proc insertAt*(t: Tab; name: string; at: int; c: Widget) = 261 | tabInsertAt(t.impl, name, at.cint, c.impl) 262 | t.children.insert(c, at) 263 | 264 | proc delete*(t: Tab; index: int) = 265 | tabDelete(t.impl, index.cint) 266 | t.children.delete(index) 267 | 268 | proc numPages*(t: Tab): int = tabNumPages(t.impl).int 269 | proc margined*(t: Tab; page: int): bool = 270 | tabMargined(t.impl, page.cint) != 0 271 | proc `margined=`*(t: Tab; page: int; x: bool) = 272 | tabSetMargined(t.impl, page.cint, cint(x)) 273 | proc newTab*(): Tab = 274 | newFinal result 275 | result.impl = rawui.newTab() 276 | result.children = @[] 277 | 278 | # ------------- Group -------------------------------------------------- 279 | 280 | type 281 | Group* = ref object of Widget 282 | child: Widget 283 | 284 | genImplProcs(Group) 285 | 286 | proc title*(g: Group): string = $groupTitle(g.impl) 287 | proc `title=`*(g: Group; title: string) = 288 | groupSetTitle(g.impl, title) 289 | proc `child=`*(g: Group; c: Widget) = 290 | groupSetChild(g.impl, c.impl) 291 | g.child = c 292 | proc margined*(g: Group): bool = groupMargined(g.impl) != 0 293 | proc `margined=`*(g: Group; x: bool) = 294 | groupSetMargined(g.impl, x.cint) 295 | 296 | proc newGroup*(title: string; margined=false): Group = 297 | newFinal result 298 | result.impl = rawui.newGroup(title) 299 | groupSetMargined(result.impl, margined.cint) 300 | 301 | # ----------------------- Spinbox --------------------------------------- 302 | 303 | type 304 | Spinbox* = ref object of Widget 305 | onchanged*: proc(newvalue: int) 306 | 307 | genImplProcs(Spinbox) 308 | 309 | proc value*(s: Spinbox): int = spinboxValue(s.impl) 310 | proc `value=`*(s: Spinbox; value: int) = spinboxSetValue(s.impl, value.cint) 311 | 312 | intCallback wrapsbOnChanged, Spinbox, Spinbox, onchanged 313 | 314 | proc newSpinbox*(min, max: int; onchanged: proc (newvalue: int) = nil): Spinbox = 315 | newFinal result 316 | result.impl = rawui.newSpinbox(cint min, cint max) 317 | spinboxOnChanged result.impl, wrapsbOnChanged, cast[pointer](result) 318 | result.onchanged = onchanged 319 | 320 | # ---------------------- Slider --------------------------------------- 321 | 322 | type 323 | Slider* = ref object of Widget 324 | onchanged*: proc(newvalue: int) 325 | 326 | genImplProcs(Slider) 327 | 328 | proc value*(s: Slider): int = sliderValue(s.impl) 329 | proc `value=`*(s: Slider; value: int) = sliderSetValue(s.impl, cint value) 330 | 331 | intCallback wrapslOnChanged, Slider, Slider, onchanged 332 | 333 | proc newSlider*(min, max: int; onchanged: proc (newvalue: int) = nil): Slider = 334 | newFinal result 335 | result.impl = rawui.newSlider(cint min, cint max) 336 | sliderOnChanged result.impl, wrapslOnChanged, cast[pointer](result) 337 | result.onchanged = onchanged 338 | 339 | # ------------------- Progressbar --------------------------------- 340 | 341 | type 342 | ProgressBar* = ref object of Widget 343 | 344 | genImplProcs(ProgressBar) 345 | 346 | proc `value=`*(p: ProgressBar; n: int) = 347 | progressBarSetValue p.impl, n.cint 348 | 349 | proc newProgressBar*(): ProgressBar = 350 | newFinal result 351 | result.impl = rawui.newProgressBar() 352 | 353 | # ------------------------- Separator ---------------------------- 354 | 355 | type 356 | Separator* = ref object of Widget 357 | 358 | genImplProcs(Separator) 359 | 360 | proc newHorizontalSeparator*(): Separator = 361 | newFinal result 362 | result.impl = rawui.newHorizontalSeparator() 363 | 364 | # ------------------------ Combobox ------------------------------ 365 | 366 | type 367 | Combobox* = ref object of Widget 368 | onselected*: proc () 369 | 370 | genImplProcs(Combobox) 371 | 372 | proc add*(c: Combobox; text: string) = 373 | c.impl.comboboxAppend text 374 | proc selected*(c: Combobox): int = comboboxSelected(c.impl) 375 | proc `selected=`*(c: Combobox; n: int) = 376 | comboboxSetSelected c.impl, cint n 377 | 378 | voidCallback wrapbbOnSelected, Combobox, Combobox, onselected 379 | 380 | proc newCombobox*(onSelected: proc() = nil): Combobox = 381 | newFinal result 382 | result.impl = rawui.newCombobox() 383 | result.onSelected = onSelected 384 | comboboxOnSelected(result.impl, wrapbbOnSelected, cast[pointer](result)) 385 | 386 | # ----------------------- EditableCombobox ---------------------- 387 | 388 | type 389 | EditableCombobox* = ref object of Widget 390 | onchanged*: proc () 391 | 392 | genImplProcs(EditableCombobox) 393 | 394 | proc add*(c: EditableCombobox; text: string) = 395 | editableComboboxAppend(c.impl, text) 396 | 397 | proc text*(c: EditableCombobox): string = 398 | $editableComboboxText(c.impl) 399 | 400 | proc `text=`*(c: EditableCombobox; text: string) = 401 | editableComboboxSetText(c.impl, text) 402 | 403 | voidCallback wrapecbOnchanged, EditableCombobox, EditableCombobox, onchanged 404 | 405 | proc newEditableCombobox*(onchanged: proc () = nil): EditableCombobox = 406 | newFinal result 407 | result.impl = rawui.newEditableCombobox() 408 | result.onchanged = onchanged 409 | editableComboboxOnChanged result.impl, wrapecbOnchanged, cast[pointer](result) 410 | 411 | # ------------------------ MultilineEntry ------------------------------ 412 | 413 | type 414 | MultilineEntry* = ref object of Widget 415 | onchanged*: proc () 416 | 417 | genImplProcs(MultilineEntry) 418 | 419 | proc text*(e: MultilineEntry): string = 420 | $multilineEntryText(e.impl) 421 | proc `text=`*(e: MultilineEntry; text: string) = 422 | multilineEntrySetText(e.impl, text) 423 | proc add*(e: MultilineEntry; text: string) = 424 | multilineEntryAppend(e.impl, text) 425 | 426 | voidCallback wrapmeOnchanged, MultilineEntry, MultilineEntry, onchanged 427 | 428 | proc readonly*(e: MultilineEntry): bool = 429 | multilineEntryReadOnly(e.impl) != 0 430 | proc `readonly=`*(e: MultilineEntry; x: bool) = 431 | multilineEntrySetReadOnly(e.impl, cint(x)) 432 | 433 | proc newMultilineEntry*(): MultilineEntry = 434 | newFinal result 435 | result.impl = rawui.newMultilineEntry() 436 | multilineEntryOnChanged(result.impl, wrapmeOnchanged, cast[pointer](result)) 437 | 438 | proc newNonWrappingMultilineEntry*(): MultilineEntry = 439 | newFinal result 440 | result.impl = rawui.newNonWrappingMultilineEntry() 441 | multilineEntryOnChanged(result.impl, wrapmeOnchanged, cast[pointer](result)) 442 | 443 | # ---------------------- MenuItem --------------------------------------- 444 | 445 | type 446 | MenuItem* = ref object of Widget 447 | onclicked*: proc () 448 | 449 | genImplProcs(MenuItem) 450 | 451 | proc enable*(m: MenuItem) = menuItemEnable(m.impl) 452 | proc disable*(m: MenuItem) = menuItemDisable(m.impl) 453 | 454 | proc wrapmeOnclicked(sender: ptr rawui.MenuItem; 455 | window: ptr rawui.Window; data: pointer) {.cdecl.} = 456 | let m = cast[MenuItem](data) 457 | if m.onclicked != nil: m.onclicked() 458 | 459 | proc checked*(m: MenuItem): bool = menuItemChecked(m.impl) != 0 460 | proc `checked=`*(m: MenuItem; x: bool) = menuItemSetChecked(m.impl, cint(x)) 461 | 462 | # -------------------- Menu --------------------------------------------- 463 | 464 | type 465 | Menu* = ref object of Widget 466 | children*: seq[MenuItem] 467 | 468 | genImplProcs(Menu) 469 | 470 | template addMenuItemImpl(ex) = 471 | newFinal result 472 | result.impl = ex 473 | menuItemOnClicked(result.impl, wrapmeOnclicked, cast[pointer](result)) 474 | m.children.add result 475 | 476 | proc addItem*(m: Menu; name: string, onclicked: proc()): MenuItem {.discardable.} = 477 | addMenuItemImpl(menuAppendItem(m.impl, name)) 478 | result.onclicked = onclicked 479 | 480 | proc addCheckItem*(m: Menu; name: string, onclicked: proc()): MenuItem {.discardable.} = 481 | addMenuItemImpl(menuAppendCheckItem(m.impl, name)) 482 | result.onclicked = onclicked 483 | 484 | type 485 | ShouldQuitClosure = ref object 486 | fn: proc(): bool 487 | 488 | proc wrapOnShouldQuit(data: pointer): cint {.cdecl.} = 489 | let c = cast[ShouldQuitClosure](data) 490 | result = cint(c.fn()) 491 | if result == 1: 492 | GC_unref c 493 | 494 | proc addQuitItem*(m: Menu, shouldQuit: proc(): bool): MenuItem {.discardable.} = 495 | newFinal result 496 | result.impl = menuAppendQuitItem(m.impl) 497 | m.children.add result 498 | var cl = ShouldQuitClosure(fn: shouldQuit) 499 | GC_ref cl 500 | onShouldQuit(wrapOnShouldQuit, cast[pointer](cl)) 501 | 502 | proc addPreferencesItem*(m: Menu, onclicked: proc()): MenuItem {.discardable.} = 503 | addMenuItemImpl(menuAppendPreferencesItem(m.impl)) 504 | result.onclicked = onclicked 505 | 506 | proc addAboutItem*(m: Menu, onclicked: proc()): MenuItem {.discardable.} = 507 | addMenuItemImpl(menuAppendAboutItem(m.impl)) 508 | result.onclicked = onclicked 509 | 510 | proc addSeparator*(m: Menu) = 511 | menuAppendSeparator m.impl 512 | 513 | proc newMenu*(name: string): Menu = 514 | newFinal result 515 | result.impl = rawui.newMenu(name) 516 | result.children = @[] 517 | 518 | # -------------------- Image -------------------------------------- 519 | 520 | type 521 | Image* = ref object of Widget 522 | 523 | genImplProcs(Image) 524 | proc newImage*(width, height: float): Image = 525 | newFinal result 526 | result.impl = rawui.newImage(width.cdouble, height.cdouble) 527 | 528 | # -------------------- Table -------------------------------------- 529 | 530 | export TableModelHandler, TableModel, TableParams, TableTextColumnOptionalParams, TableColumnType, TableValueType, TableValue 531 | export newTableModel, freeTableModel 532 | 533 | const 534 | TableModelColumnNeverEditable* = (-1) 535 | TableModelColumnAlwaysEditable* = (-2) 536 | 537 | 538 | type 539 | Table* = ref object of Widget 540 | 541 | genImplProcs(Table) 542 | 543 | 544 | proc tableValueGetType*(v: ptr TableValue): TableValueType {.inline.} = rawui.tableValueGetType(v) 545 | 546 | proc newTableValueString*(s: string): ptr TableValue {.inline.} = rawui.newTableValueString(s.cstring) 547 | proc tableValueString*(v: ptr TableValue): string {.inline.} = $rawui.tableValueString(v) 548 | 549 | proc newTableValueImage*(img: Image): ptr TableValue = rawui.newTableValueImage(img.impl) 550 | proc tableValueImage*(v: ptr TableValue): Image = 551 | newFinal result 552 | result.impl = rawui.tableValueImage(v) 553 | 554 | proc newTableValueInt*(i: int): ptr TableValue {.inline.} = rawui.newTableValueInt(i.cint) 555 | proc tableValueInt*(v: ptr TableValue): int {.inline.} = rawui.tableValueInt(v) 556 | 557 | proc newTableValueColor*(r: float; g: float; b: float; a: float): ptr TableValue {.inline.} = rawui.newTableValueColor(r, g, b, a) 558 | proc tableValueColor*(v: ptr TableValue; r: ptr float; g: ptr float; 559 | b: ptr float; a: ptr float) {.inline.} = rawui.tableValueColor(v, r, g, b, a) 560 | 561 | 562 | proc rowInserted*(m: TableModel; newIndex: int) {.inline.} = rawui.tableModelRowInserted(m, newIndex.cint) 563 | proc rowChanged*(m: TableModel; index: int) {.inline.} = rawui.tableModelRowChanged(m, index.cint) 564 | proc rowDeleted*(m: TableModel; oldIndex: int) {.inline.} = rawui.tableModelRowDeleted(m, oldIndex.cint) 565 | 566 | 567 | proc appendTextColumn*(table: Table, title: string, index, editableMode: int, textParams: ptr TableTextColumnOptionalParams) = 568 | table.impl.tableAppendTextColumn(title, index.cint, editableMode.cint, textParams) 569 | 570 | proc appendImageColumn*(table: Table, title: string, index: int) = 571 | table.impl.tableAppendImageColumn(title, index.cint) 572 | 573 | proc appendImageTextColumn*(table: Table, title: string, imageIndex, textIndex, editableMode: int, textParams: ptr TableTextColumnOptionalParams) = 574 | table.impl.tableAppendImageTextColumn(title, imageIndex.cint, textIndex.cint, editableMode.cint, textParams) 575 | 576 | proc appendCheckboxColumn*(table: Table, title: string, index, editableMode: int) = 577 | table.impl.tableAppendCheckboxColumn(title, index.cint, editableMode.cint) 578 | 579 | proc appendProgressBarColumn*(table: Table, title: string, index: int) = 580 | table.impl.tableAppendProgressBarColumn(title, index.cint) 581 | 582 | proc appendButtonColumn*(table: Table, title: string, index, clickableMode: int) = 583 | table.impl.tableAppendButtonColumn(title, index.cint, clickableMode.cint) 584 | 585 | proc newTable*(params: ptr TableParams): Table = 586 | newFinal result 587 | result.impl = rawui.newTable(params) 588 | 589 | 590 | # -------------------- Generics ------------------------------------ 591 | 592 | proc show*[W: Widget](w: W) = 593 | rawui.controlShow(w.impl) 594 | 595 | proc hide*[W: Widget](w: W) = 596 | rawui.controlHide(w.impl) 597 | 598 | proc enable*[W: Widget](w: W) = 599 | rawui.controlEnable(w.impl) 600 | 601 | proc disable*[W: Widget](w: W) = 602 | rawui.controlDisable(w.impl) 603 | 604 | # -------------------- DateTimePicker ------------------------------ 605 | 606 | when false: 607 | # XXX no way yet to get the date out of this? 608 | type 609 | DateTimePicker* = ref object of Widget 610 | 611 | genImplProcs(DateTimePicker) 612 | 613 | proc dateTimePickerTime*(p: DateTimePicker) 614 | 615 | proc newDateTimePicker*(): DateTimePicker = 616 | newFinal result 617 | result.impl = rawui.newDateTimePicker() 618 | 619 | proc newDatePicker*(): DateTimePicker = 620 | newFinal result 621 | result.impl = rawui.newDatePicker() 622 | 623 | proc newTimePicker*(): DateTimePicker = 624 | newFinal result 625 | result.impl = rawui.newTimePicker() 626 | 627 | proc time*(P: DateTimePicker): StructTm = dateTimePickerTime(P.impl, addr result) 628 | proc `time=`*(P: DateTimePicker, time: ptr StructTm) = dateTimePickerSetTime(P.impl, time) 629 | #proc onchanged*(P: DateTimePicker) 630 | -------------------------------------------------------------------------------- /ui.nimble: -------------------------------------------------------------------------------- 1 | # Package 2 | 3 | version = "0.9.4" 4 | author = "Andreas Rumpf" 5 | description = "Nim\'s official UI library" 6 | license = "MIT" 7 | 8 | installDirs = @["ui","res"] 9 | installFiles = @["ui.nim"] 10 | 11 | # Dependencies 12 | 13 | requires "nim >= 0.19.4" 14 | 15 | -------------------------------------------------------------------------------- /ui/rawui.nim: -------------------------------------------------------------------------------- 1 | when defined(useLibUiDll): 2 | when defined(windows): 3 | const 4 | dllName* = "libui.dll" 5 | elif defined(macosx): 6 | const 7 | dllName* = "libui.dylib" 8 | else: 9 | const 10 | dllName* = "libui.so" 11 | {.pragma: mylib, dynlib: dllName.} 12 | else: 13 | {.pragma: mylib.} 14 | when defined(linux): 15 | # thanks to 'import math' missing linking flags are added 16 | import math 17 | from strutils import replace 18 | const cflags = (staticExec"pkg-config --cflags gtk+-3.0").replace('\L', ' ') 19 | const lflags = (staticExec"pkg-config --libs gtk+-3.0").replace('\L', ' ') 20 | {.passC: cflags.} 21 | {.passL: lflags.} 22 | 23 | {.compile: ("./libui/common/*.c", "common_$#.obj").} 24 | when defined(windows): 25 | {.compile: ("./libui/windows/*.cpp", "win_$#.obj").} 26 | elif defined(macosx): 27 | {.compile: ("./libui/darwin/*.m", "osx_$#.obj").} 28 | 29 | {.passL: "-framework OpenGL".} 30 | {.passL: "-framework CoreAudio".} 31 | {.passL: "-framework AudioToolbox".} 32 | {.passL: "-framework AudioUnit".} 33 | {.passL: "-framework Carbon".} 34 | {.passL: "-framework IOKit".} 35 | {.passL: "-framework Cocoa".} 36 | else: 37 | {.compile: ("./libui/unix/*.c", "unix_$#.obj").} 38 | when defined(gcc) and defined(windows): 39 | #{.passL: r"C:\Users\rumpf\projects\mingw64\x86_64-w64-mingw32\lib\liboleaut32.a".} 40 | {.passL: r"-lwinspool".} 41 | {.passL: r"-lcomdlg32".} 42 | {.passL: r"-ladvapi32".} 43 | {.passL: r"-lshell32".} 44 | {.passL: r"-lole32".} 45 | {.passL: r"-loleaut32".} 46 | 47 | {.passL: r"-luuid".} 48 | {.passL: r"-lcomctl32".} 49 | {.passL: r"-ld2d1".} 50 | {.passL: r"-ldwrite".} 51 | {.passL: r"-lUxTheme".} 52 | {.passL: r"-lUsp10".} 53 | {.passL: r"-lgdi32".} 54 | {.passL: r"-luser32".} 55 | {.passL: r"-lkernel32".} 56 | {.link: r"..\res\resources.o".} 57 | 58 | when defined(vcc): 59 | {.passC: "/EHsc".} 60 | when false: 61 | const arch = when defined(cpu32): "x86" else: "x64" 62 | {.link: r"C:\Program Files (x86)\Windows Kits\8.1\Lib\winv6.3\um\" & arch & r"\d2d1.lib".} 63 | {.link: r"C:\Program Files (x86)\Windows Kits\8.1\Lib\winv6.3\um\" & arch & r"\dwrite.lib".} 64 | {.link: r"C:\Program Files (x86)\Windows Kits\8.1\Lib\winv6.3\um\" & arch & r"\UxTheme.lib".} 65 | {.link: r"C:\Program Files (x86)\Windows Kits\8.1\Lib\winv6.3\um\" & arch & r"\Usp10.lib".} 66 | 67 | {.link: r"kernel32.lib".} 68 | {.link: r"user32.lib".} 69 | {.link: r"gdi32.lib".} 70 | {.link: r"winspool.lib".} 71 | {.link: r"comdlg32.lib".} 72 | {.link: r"advapi32.lib".} 73 | {.link: r"shell32.lib".} 74 | {.link: r"ole32.lib".} 75 | {.link: r"oleaut32.lib".} 76 | {.link: r"uuid.lib".} 77 | {.link: r"comctl32.lib".} 78 | 79 | {.link: r"d2d1.lib".} 80 | {.link: r"dwrite.lib".} 81 | {.link: r"UxTheme.lib".} 82 | {.link: r"Usp10.lib".} 83 | {.link: r"..\res\resources.res".} 84 | 85 | import times 86 | 87 | type 88 | ForEach* {.size: sizeof(cint).} = enum 89 | ForEachContinue, 90 | ForEachStop, 91 | 92 | InitOptions* = object 93 | size*: csize 94 | 95 | {.deadCodeElim: on.} 96 | 97 | proc init*(options: ptr InitOptions): cstring {.cdecl, importc: "uiInit", 98 | mylib.} 99 | proc uninit*() {.cdecl, importc: "uiUninit", mylib.} 100 | proc freeInitError*(err: cstring) {.cdecl, importc: "uiFreeInitError", mylib.} 101 | proc main*() {.cdecl, importc: "uiMain", mylib.} 102 | proc mainSteps*() {.cdecl, importc: "uiMainSteps", mylib.} 103 | proc mainStep*(wait: cint): cint {.cdecl, importc: "uiMainStep", mylib.} 104 | proc quit*() {.cdecl, importc: "uiQuit", mylib.} 105 | proc queueMain*(f: proc (data: pointer) {.cdecl.}; data: pointer) {.cdecl, 106 | importc: "uiQueueMain", mylib.} 107 | 108 | proc timer*(milliseconds: cint, f: proc (data: pointer): cint {.cdecl.}; data: pointer) {.cdecl, 109 | importc: "uiTimer", mylib.} 110 | 111 | proc onShouldQuit*(f: proc (data: pointer): cint {.cdecl.}; data: pointer) {.cdecl, 112 | importc: "uiOnShouldQuit", mylib.} 113 | proc freeText*(text: cstring) {.cdecl, importc: "uiFreeText", mylib.} 114 | type 115 | Control* {.inheritable, pure.} = object 116 | signature*: uint32 117 | oSSignature*: uint32 118 | typeSignature*: uint32 119 | destroy*: proc (a2: ptr Control) {.cdecl.} 120 | handle*: proc (a2: ptr Control): int {.cdecl.} 121 | parent*: proc (a2: ptr Control): ptr Control {.cdecl.} 122 | setParent*: proc (a2: ptr Control; a3: ptr Control) {.cdecl.} 123 | toplevel*: proc (a2: ptr Control): cint {.cdecl.} 124 | visible*: proc (a2: ptr Control): cint {.cdecl.} 125 | show*: proc (a2: ptr Control) {.cdecl.} 126 | hide*: proc (a2: ptr Control) {.cdecl.} 127 | enabled*: proc (a2: ptr Control): cint {.cdecl.} 128 | enable*: proc (a2: ptr Control) {.cdecl.} 129 | disable*: proc (a2: ptr Control) {.cdecl.} 130 | 131 | 132 | 133 | template toUiControl*(this: untyped): untyped = 134 | (cast[ptr Control]((this))) 135 | 136 | proc controlDestroy*(a2: ptr Control) {.cdecl, importc: "uiControlDestroy", 137 | mylib.} 138 | proc controlHandle*(a2: ptr Control): int {.cdecl, importc: "uiControlHandle", 139 | mylib.} 140 | proc controlParent*(a2: ptr Control): ptr Control {.cdecl, importc: "uiControlParent", 141 | mylib.} 142 | proc controlSetParent*(a2: ptr Control; a3: ptr Control) {.cdecl, 143 | importc: "uiControlSetParent", mylib.} 144 | proc controlToplevel*(a2: ptr Control): cint {.cdecl, importc: "uiControlToplevel", 145 | mylib.} 146 | proc controlVisible*(a2: ptr Control): cint {.cdecl, importc: "uiControlVisible", 147 | mylib.} 148 | proc controlShow*(a2: ptr Control) {.cdecl, importc: "uiControlShow", mylib.} 149 | proc controlHide*(a2: ptr Control) {.cdecl, importc: "uiControlHide", mylib.} 150 | proc controlEnabled*(a2: ptr Control): cint {.cdecl, importc: "uiControlEnabled", 151 | mylib.} 152 | proc controlEnable*(a2: ptr Control) {.cdecl, importc: "uiControlEnable", 153 | mylib.} 154 | proc controlDisable*(a2: ptr Control) {.cdecl, importc: "uiControlDisable", 155 | mylib.} 156 | proc allocControl*(n: csize; oSsig: uint32; typesig: uint32; typenamestr: cstring): ptr Control {. 157 | cdecl, importc: "uiAllocControl", mylib.} 158 | proc freeControl*(a2: ptr Control) {.cdecl, importc: "uiFreeControl", mylib.} 159 | 160 | proc controlVerifySetParent*(a2: ptr Control; a3: ptr Control) {.cdecl, 161 | importc: "uiControlVerifySetParent", mylib.} 162 | proc controlEnabledToUser*(a2: ptr Control): cint {.cdecl, 163 | importc: "uiControlEnabledToUser", mylib.} 164 | proc userBugCannotSetParentOnToplevel*(`type`: cstring) {.cdecl, 165 | importc: "uiUserBugCannotSetParentOnToplevel", mylib.} 166 | type 167 | Window* = object of Control 168 | 169 | 170 | template toUiWindow*(this: untyped): untyped = 171 | (cast[ptr Window]((this))) 172 | 173 | proc windowTitle*(w: ptr Window): cstring {.cdecl, importc: "uiWindowTitle", 174 | mylib.} 175 | proc windowSetTitle*(w: ptr Window; title: cstring) {.cdecl, 176 | importc: "uiWindowSetTitle", mylib.} 177 | proc windowContentSize*(w: ptr Window; width: ptr cint; height: ptr cint) {.cdecl, 178 | importc: "uiWindowContentSize", mylib.} 179 | proc windowSetContentSize*(w: ptr Window; width: cint; height: cint) {.cdecl, 180 | importc: "uiWindowSetContentSize", mylib.} 181 | proc windowFullscreen*(w: ptr Window): cint {.cdecl, importc: "uiWindowFullscreen", 182 | mylib.} 183 | proc windowSetFullscreen*(w: ptr Window; fullscreen: cint) {.cdecl, 184 | importc: "uiWindowSetFullscreen", mylib.} 185 | proc windowOnContentSizeChanged*(w: ptr Window; 186 | f: proc (a2: ptr Window; a3: pointer) {.cdecl.}; 187 | data: pointer) {.cdecl, 188 | importc: "uiWindowOnContentSizeChanged", mylib.} 189 | proc windowOnClosing*(w: ptr Window; 190 | f: proc (w: ptr Window; data: pointer): cint {.cdecl.}; 191 | data: pointer) {.cdecl, importc: "uiWindowOnClosing", 192 | mylib.} 193 | proc windowBorderless*(w: ptr Window): cint {.cdecl, importc: "uiWindowBorderless", 194 | mylib.} 195 | proc windowSetBorderless*(w: ptr Window; borderless: cint) {.cdecl, 196 | importc: "uiWindowSetBorderless", mylib.} 197 | proc windowSetChild*(w: ptr Window; child: ptr Control) {.cdecl, 198 | importc: "uiWindowSetChild", mylib.} 199 | proc windowMargined*(w: ptr Window): cint {.cdecl, importc: "uiWindowMargined", 200 | mylib.} 201 | proc windowSetMargined*(w: ptr Window; margined: cint) {.cdecl, 202 | importc: "uiWindowSetMargined", mylib.} 203 | proc newWindow*(title: cstring; width: cint; height: cint; hasMenubar: cint): ptr Window {. 204 | cdecl, importc: "uiNewWindow", mylib.} 205 | type 206 | Button* = object of Control 207 | 208 | 209 | template toUiButton*(this: untyped): untyped = 210 | (cast[ptr Button]((this))) 211 | 212 | proc buttonText*(b: ptr Button): cstring {.cdecl, importc: "uiButtonText", 213 | mylib.} 214 | proc buttonSetText*(b: ptr Button; text: cstring) {.cdecl, importc: "uiButtonSetText", 215 | mylib.} 216 | proc buttonOnClicked*(b: ptr Button; 217 | f: proc (b: ptr Button; data: pointer) {.cdecl.}; data: pointer) {. 218 | cdecl, importc: "uiButtonOnClicked", mylib.} 219 | proc newButton*(text: cstring): ptr Button {.cdecl, importc: "uiNewButton", 220 | mylib.} 221 | type 222 | Box* = object of Control 223 | 224 | 225 | template toUiBox*(this: untyped): untyped = 226 | (cast[ptr Box]((this))) 227 | 228 | proc boxAppend*(b: ptr Box; child: ptr Control; stretchy: cint) {.cdecl, 229 | importc: "uiBoxAppend", mylib.} 230 | proc boxDelete*(b: ptr Box; index: cint) {.cdecl, importc: "uiBoxDelete", mylib.} 231 | proc boxPadded*(b: ptr Box): cint {.cdecl, importc: "uiBoxPadded", mylib.} 232 | proc boxSetPadded*(b: ptr Box; padded: cint) {.cdecl, importc: "uiBoxSetPadded", 233 | mylib.} 234 | proc newHorizontalBox*(): ptr Box {.cdecl, importc: "uiNewHorizontalBox", 235 | mylib.} 236 | proc newVerticalBox*(): ptr Box {.cdecl, importc: "uiNewVerticalBox", mylib.} 237 | type 238 | Checkbox* = object of Control 239 | 240 | 241 | template toUiCheckbox*(this: untyped): untyped = 242 | (cast[ptr Checkbox]((this))) 243 | 244 | proc checkboxText*(c: ptr Checkbox): cstring {.cdecl, importc: "uiCheckboxText", 245 | mylib.} 246 | proc checkboxSetText*(c: ptr Checkbox; text: cstring) {.cdecl, 247 | importc: "uiCheckboxSetText", mylib.} 248 | proc checkboxOnToggled*(c: ptr Checkbox; 249 | f: proc (c: ptr Checkbox; data: pointer) {.cdecl.}; data: pointer) {. 250 | cdecl, importc: "uiCheckboxOnToggled", mylib.} 251 | proc checkboxChecked*(c: ptr Checkbox): cint {.cdecl, importc: "uiCheckboxChecked", 252 | mylib.} 253 | proc checkboxSetChecked*(c: ptr Checkbox; checked: cint) {.cdecl, 254 | importc: "uiCheckboxSetChecked", mylib.} 255 | proc newCheckbox*(text: cstring): ptr Checkbox {.cdecl, importc: "uiNewCheckbox", 256 | mylib.} 257 | type 258 | Entry* = object of Control 259 | 260 | 261 | template toUiEntry*(this: untyped): untyped = 262 | (cast[ptr Entry]((this))) 263 | 264 | proc entryText*(e: ptr Entry): cstring {.cdecl, importc: "uiEntryText", mylib.} 265 | proc entrySetText*(e: ptr Entry; text: cstring) {.cdecl, importc: "uiEntrySetText", 266 | mylib.} 267 | proc entryOnChanged*(e: ptr Entry; f: proc (e: ptr Entry; data: pointer) {.cdecl.}; 268 | data: pointer) {.cdecl, importc: "uiEntryOnChanged", 269 | mylib.} 270 | proc entryReadOnly*(e: ptr Entry): cint {.cdecl, importc: "uiEntryReadOnly", 271 | mylib.} 272 | proc entrySetReadOnly*(e: ptr Entry; readonly: cint) {.cdecl, 273 | importc: "uiEntrySetReadOnly", mylib.} 274 | proc newEntry*(): ptr Entry {.cdecl, importc: "uiNewEntry", mylib.} 275 | proc newPasswordEntry*(): ptr Entry {.cdecl, importc: "uiNewPasswordEntry", 276 | mylib.} 277 | proc newSearchEntry*(): ptr Entry {.cdecl, importc: "uiNewSearchEntry", mylib.} 278 | type 279 | Label* = object of Control 280 | 281 | 282 | template toUiLabel*(this: untyped): untyped = 283 | (cast[ptr Label]((this))) 284 | 285 | proc labelText*(label: ptr Label): cstring {.cdecl, importc: "uiLabelText", 286 | mylib.} 287 | proc labelSetText*(label: ptr Label; text: cstring) {.cdecl, importc: "uiLabelSetText", 288 | mylib.} 289 | proc newLabel*(text: cstring): ptr Label {.cdecl, importc: "uiNewLabel", mylib.} 290 | type 291 | Tab* = object of Control 292 | 293 | 294 | template toUiTab*(this: untyped): untyped = 295 | (cast[ptr Tab]((this))) 296 | 297 | proc tabAppend*(t: ptr Tab; name: cstring; c: ptr Control) {.cdecl, 298 | importc: "uiTabAppend", mylib.} 299 | proc tabInsertAt*(t: ptr Tab; name: cstring; before: cint; c: ptr Control) {.cdecl, 300 | importc: "uiTabInsertAt", mylib.} 301 | proc tabDelete*(t: ptr Tab; index: cint) {.cdecl, importc: "uiTabDelete", mylib.} 302 | proc tabNumPages*(t: ptr Tab): cint {.cdecl, importc: "uiTabNumPages", mylib.} 303 | proc tabMargined*(t: ptr Tab; page: cint): cint {.cdecl, importc: "uiTabMargined", 304 | mylib.} 305 | proc tabSetMargined*(t: ptr Tab; page: cint; margined: cint) {.cdecl, 306 | importc: "uiTabSetMargined", mylib.} 307 | proc newTab*(): ptr Tab {.cdecl, importc: "uiNewTab", mylib.} 308 | type 309 | Group* = object of Control 310 | 311 | 312 | template toUiGroup*(this: untyped): untyped = 313 | (cast[ptr Group]((this))) 314 | 315 | proc groupTitle*(g: ptr Group): cstring {.cdecl, importc: "uiGroupTitle", 316 | mylib.} 317 | proc groupSetTitle*(g: ptr Group; title: cstring) {.cdecl, importc: "uiGroupSetTitle", 318 | mylib.} 319 | proc groupSetChild*(g: ptr Group; c: ptr Control) {.cdecl, importc: "uiGroupSetChild", 320 | mylib.} 321 | proc groupMargined*(g: ptr Group): cint {.cdecl, importc: "uiGroupMargined", 322 | mylib.} 323 | proc groupSetMargined*(g: ptr Group; margined: cint) {.cdecl, 324 | importc: "uiGroupSetMargined", mylib.} 325 | proc newGroup*(title: cstring): ptr Group {.cdecl, importc: "uiNewGroup", 326 | mylib.} 327 | 328 | type 329 | Spinbox* = object of Control 330 | 331 | 332 | template toUiSpinbox*(this: untyped): untyped = 333 | (cast[ptr Spinbox]((this))) 334 | 335 | proc spinboxValue*(s: ptr Spinbox): cint {.cdecl, importc: "uiSpinboxValue", 336 | mylib.} 337 | proc spinboxSetValue*(s: ptr Spinbox; value: cint) {.cdecl, 338 | importc: "uiSpinboxSetValue", mylib.} 339 | proc spinboxOnChanged*(s: ptr Spinbox; 340 | f: proc (s: ptr Spinbox; data: pointer) {.cdecl.}; data: pointer) {. 341 | cdecl, importc: "uiSpinboxOnChanged", mylib.} 342 | proc newSpinbox*(min: cint; max: cint): ptr Spinbox {.cdecl, importc: "uiNewSpinbox", 343 | mylib.} 344 | type 345 | Slider* = object of Control 346 | 347 | 348 | template toUiSlider*(this: untyped): untyped = 349 | (cast[ptr Slider]((this))) 350 | 351 | proc sliderValue*(s: ptr Slider): cint {.cdecl, importc: "uiSliderValue", 352 | mylib.} 353 | proc sliderSetValue*(s: ptr Slider; value: cint) {.cdecl, importc: "uiSliderSetValue", 354 | mylib.} 355 | proc sliderOnChanged*(s: ptr Slider; 356 | f: proc (s: ptr Slider; data: pointer) {.cdecl.}; data: pointer) {. 357 | cdecl, importc: "uiSliderOnChanged", mylib.} 358 | proc newSlider*(min: cint; max: cint): ptr Slider {.cdecl, importc: "uiNewSlider", 359 | mylib.} 360 | type 361 | ProgressBar* = object of Control 362 | 363 | 364 | template toUiProgressBar*(this: untyped): untyped = 365 | (cast[ptr ProgressBar]((this))) 366 | 367 | proc progressBarValue*(p: ptr ProgressBar): cint {.cdecl, 368 | importc: "uiProgressBarValue", mylib.} 369 | proc progressBarSetValue*(p: ptr ProgressBar; n: cint) {.cdecl, 370 | importc: "uiProgressBarSetValue", mylib.} 371 | proc newProgressBar*(): ptr ProgressBar {.cdecl, importc: "uiNewProgressBar", 372 | mylib.} 373 | type 374 | Separator* = object of Control 375 | 376 | 377 | template toUiSeparator*(this: untyped): untyped = 378 | (cast[ptr Separator]((this))) 379 | 380 | proc newHorizontalSeparator*(): ptr Separator {.cdecl, 381 | importc: "uiNewHorizontalSeparator", mylib.} 382 | proc newVerticalSeparator*(): ptr Separator {.cdecl, 383 | importc: "uiNewVerticalSeparator", mylib.} 384 | type 385 | Combobox* = object of Control 386 | 387 | 388 | template toUiCombobox*(this: untyped): untyped = 389 | (cast[ptr Combobox]((this))) 390 | 391 | proc comboboxAppend*(c: ptr Combobox; text: cstring) {.cdecl, 392 | importc: "uiComboboxAppend", mylib.} 393 | proc comboboxSelected*(c: ptr Combobox): cint {.cdecl, importc: "uiComboboxSelected", 394 | mylib.} 395 | proc comboboxSetSelected*(c: ptr Combobox; n: cint) {.cdecl, 396 | importc: "uiComboboxSetSelected", mylib.} 397 | proc comboboxOnSelected*(c: ptr Combobox; 398 | f: proc (c: ptr Combobox; data: pointer) {.cdecl.}; 399 | data: pointer) {.cdecl, importc: "uiComboboxOnSelected", 400 | mylib.} 401 | proc newCombobox*(): ptr Combobox {.cdecl, importc: "uiNewCombobox", mylib.} 402 | type 403 | EditableCombobox* = object of Control 404 | 405 | 406 | template toUiEditableCombobox*(this: untyped): untyped = 407 | (cast[ptr EditableCombobox]((this))) 408 | 409 | proc editableComboboxAppend*(c: ptr EditableCombobox; text: cstring) {.cdecl, 410 | importc: "uiEditableComboboxAppend", mylib.} 411 | proc editableComboboxText*(c: ptr EditableCombobox): cstring {.cdecl, 412 | importc: "uiEditableComboboxText", mylib.} 413 | proc editableComboboxSetText*(c: ptr EditableCombobox; text: cstring) {.cdecl, 414 | importc: "uiEditableComboboxSetText", mylib.} 415 | 416 | proc editableComboboxOnChanged*(c: ptr EditableCombobox; f: proc ( 417 | c: ptr EditableCombobox; data: pointer) {.cdecl.}; data: pointer) {.cdecl, 418 | importc: "uiEditableComboboxOnChanged", mylib.} 419 | proc newEditableCombobox*(): ptr EditableCombobox {.cdecl, 420 | importc: "uiNewEditableCombobox", mylib.} 421 | type 422 | RadioButtons* = object of Control 423 | 424 | 425 | template toUiRadioButtons*(this: untyped): untyped = 426 | (cast[ptr RadioButtons]((this))) 427 | 428 | proc radioButtonsAppend*(r: ptr RadioButtons; text: cstring) {.cdecl, 429 | importc: "uiRadioButtonsAppend", mylib.} 430 | proc radioButtonsSelected*(r: ptr RadioButtons): cint {.cdecl, 431 | importc: "uiRadioButtonsSelected", mylib.} 432 | proc radioButtonsSetSelected*(r: ptr RadioButtons; n: cint) {.cdecl, 433 | importc: "uiRadioButtonsSetSelected", mylib.} 434 | proc radioButtonsOnSelected*(r: ptr RadioButtons; f: proc (a2: ptr RadioButtons; 435 | a3: pointer) {.cdecl.}; data: pointer) {.cdecl, 436 | importc: "uiRadioButtonsOnSelected", 437 | mylib.} 438 | proc newRadioButtons*(): ptr RadioButtons {.cdecl, importc: "uiNewRadioButtons", 439 | mylib.} 440 | type 441 | StructTm* = object 442 | DateTimePicker* = object of Control 443 | 444 | 445 | template toUiDateTimePicker*(this: untyped): untyped = 446 | (cast[ptr DateTimePicker]((this))) 447 | 448 | proc dateTimePickerTime*(d: ptr DateTimePicker, 449 | time: ptr StructTm){.cdecl, importc: "uiDateTimePickerTime", 450 | mylib.} 451 | proc dateTimePickerSetTime*(d: ptr DateTimePicker, 452 | time: ptr StructTm){.cdecl, importc: "uiDateTimePickerSetTime", 453 | mylib.} 454 | proc dateTimePickerOnChanged*(d: ptr DateTimePicker, 455 | f: proc (a1: ptr DateTimePicker; a2: pointer), 456 | data: pointer){.cdecl, importc: "uiDateTimePickerOnChanged", 457 | mylib.} 458 | proc newDateTimePicker*(): ptr DateTimePicker {.cdecl, 459 | importc: "uiNewDateTimePicker", mylib.} 460 | proc newDatePicker*(): ptr DateTimePicker {.cdecl, importc: "uiNewDatePicker", 461 | mylib.} 462 | proc newTimePicker*(): ptr DateTimePicker {.cdecl, importc: "uiNewTimePicker", 463 | mylib.} 464 | 465 | type 466 | MultilineEntry* = object of Control 467 | 468 | 469 | template toUiMultilineEntry*(this: untyped): untyped = 470 | (cast[ptr MultilineEntry]((this))) 471 | 472 | proc multilineEntryText*(e: ptr MultilineEntry): cstring {.cdecl, 473 | importc: "uiMultilineEntryText", mylib.} 474 | proc multilineEntrySetText*(e: ptr MultilineEntry; text: cstring) {.cdecl, 475 | importc: "uiMultilineEntrySetText", mylib.} 476 | proc multilineEntryAppend*(e: ptr MultilineEntry; text: cstring) {.cdecl, 477 | importc: "uiMultilineEntryAppend", mylib.} 478 | proc multilineEntryOnChanged*(e: ptr MultilineEntry; f: proc (e: ptr MultilineEntry; 479 | data: pointer) {.cdecl.}; data: pointer) {.cdecl, 480 | importc: "uiMultilineEntryOnChanged", mylib.} 481 | proc multilineEntryReadOnly*(e: ptr MultilineEntry): cint {.cdecl, 482 | importc: "uiMultilineEntryReadOnly", mylib.} 483 | proc multilineEntrySetReadOnly*(e: ptr MultilineEntry; readonly: cint) {.cdecl, 484 | importc: "uiMultilineEntrySetReadOnly", mylib.} 485 | proc newMultilineEntry*(): ptr MultilineEntry {.cdecl, 486 | importc: "uiNewMultilineEntry", mylib.} 487 | proc newNonWrappingMultilineEntry*(): ptr MultilineEntry {.cdecl, 488 | importc: "uiNewNonWrappingMultilineEntry", mylib.} 489 | type 490 | MenuItem* = object of Control 491 | 492 | 493 | template toUiMenuItem*(this: untyped): untyped = 494 | (cast[ptr MenuItem]((this))) 495 | 496 | proc menuItemEnable*(m: ptr MenuItem) {.cdecl, importc: "uiMenuItemEnable", 497 | mylib.} 498 | proc menuItemDisable*(m: ptr MenuItem) {.cdecl, importc: "uiMenuItemDisable", 499 | mylib.} 500 | proc menuItemOnClicked*(m: ptr MenuItem; f: proc (sender: ptr MenuItem; 501 | window: ptr Window; data: pointer) {.cdecl.}; data: pointer) {.cdecl, 502 | importc: "uiMenuItemOnClicked", mylib.} 503 | proc menuItemChecked*(m: ptr MenuItem): cint {.cdecl, importc: "uiMenuItemChecked", 504 | mylib.} 505 | proc menuItemSetChecked*(m: ptr MenuItem; checked: cint) {.cdecl, 506 | importc: "uiMenuItemSetChecked", mylib.} 507 | type 508 | Menu* = object of Control 509 | 510 | 511 | template toUiMenu*(this: untyped): untyped = 512 | (cast[ptr Menu]((this))) 513 | 514 | proc menuAppendItem*(m: ptr Menu; name: cstring): ptr MenuItem {.cdecl, 515 | importc: "uiMenuAppendItem", mylib.} 516 | proc menuAppendCheckItem*(m: ptr Menu; name: cstring): ptr MenuItem {.cdecl, 517 | importc: "uiMenuAppendCheckItem", mylib.} 518 | proc menuAppendQuitItem*(m: ptr Menu): ptr MenuItem {.cdecl, 519 | importc: "uiMenuAppendQuitItem", mylib.} 520 | proc menuAppendPreferencesItem*(m: ptr Menu): ptr MenuItem {.cdecl, 521 | importc: "uiMenuAppendPreferencesItem", mylib.} 522 | proc menuAppendAboutItem*(m: ptr Menu): ptr MenuItem {.cdecl, 523 | importc: "uiMenuAppendAboutItem", mylib.} 524 | proc menuAppendSeparator*(m: ptr Menu) {.cdecl, importc: "uiMenuAppendSeparator", 525 | mylib.} 526 | proc newMenu*(name: cstring): ptr Menu {.cdecl, importc: "uiNewMenu", mylib.} 527 | proc openFile*(parent: ptr Window): cstring {.cdecl, importc: "uiOpenFile", 528 | mylib.} 529 | proc saveFile*(parent: ptr Window): cstring {.cdecl, importc: "uiSaveFile", 530 | mylib.} 531 | proc msgBox*(parent: ptr Window; title: cstring; description: cstring) {.cdecl, 532 | importc: "uiMsgBox", mylib.} 533 | proc msgBoxError*(parent: ptr Window; title: cstring; description: cstring) {.cdecl, 534 | importc: "uiMsgBoxError", mylib.} 535 | type 536 | Area* = object of Control 537 | 538 | Modifiers* {.size: sizeof(cint).} = enum 539 | ModifierCtrl = 1 shl 0, ModifierAlt = 1 shl 1, ModifierShift = 1 shl 2, 540 | ModifierSuper = 1 shl 3 541 | 542 | 543 | 544 | type 545 | AreaMouseEvent* = object 546 | x*: cdouble 547 | y*: cdouble 548 | areaWidth*: cdouble 549 | areaHeight*: cdouble 550 | down*: cint 551 | up*: cint 552 | count*: cint 553 | modifiers*: Modifiers 554 | held1To64*: uint64 555 | 556 | ExtKey* {.size: sizeof(cint).} = enum 557 | ExtKeyEscape = 1, ExtKeyInsert, ExtKeyDelete, ExtKeyHome, ExtKeyEnd, ExtKeyPageUp, 558 | ExtKeyPageDown, ExtKeyUp, ExtKeyDown, ExtKeyLeft, ExtKeyRight, ExtKeyF1, ExtKeyF2, 559 | ExtKeyF3, ExtKeyF4, ExtKeyF5, ExtKeyF6, ExtKeyF7, ExtKeyF8, ExtKeyF9, ExtKeyF10, 560 | ExtKeyF11, ExtKeyF12, ExtKeyN0, ExtKeyN1, ExtKeyN2, ExtKeyN3, ExtKeyN4, ExtKeyN5, 561 | ExtKeyN6, ExtKeyN7, ExtKeyN8, ExtKeyN9, ExtKeyNDot, ExtKeyNEnter, ExtKeyNAdd, 562 | ExtKeyNSubtract, ExtKeyNMultiply, ExtKeyNDivide 563 | 564 | 565 | type 566 | AreaKeyEvent* = object 567 | key*: char 568 | extKey*: ExtKey 569 | modifier*: Modifiers 570 | modifiers*: Modifiers 571 | up*: cint 572 | 573 | DrawContext* = object 574 | 575 | AreaDrawParams* = object 576 | context*: ptr DrawContext 577 | areaWidth*: cdouble 578 | areaHeight*: cdouble 579 | clipX*: cdouble 580 | clipY*: cdouble 581 | clipWidth*: cdouble 582 | clipHeight*: cdouble 583 | 584 | AreaHandler* = object 585 | draw*: proc (a2: ptr AreaHandler; a3: ptr Area; a4: ptr AreaDrawParams) {.cdecl.} 586 | mouseEvent*: proc (a2: ptr AreaHandler; a3: ptr Area; a4: ptr AreaMouseEvent) {.cdecl.} 587 | mouseCrossed*: proc (a2: ptr AreaHandler; a3: ptr Area; left: cint) {.cdecl.} 588 | dragBroken*: proc (a2: ptr AreaHandler; a3: ptr Area) {.cdecl.} 589 | keyEvent*: proc (a2: ptr AreaHandler; a3: ptr Area; a4: ptr AreaKeyEvent): cint {.cdecl.} 590 | 591 | 592 | template toUiArea*(this: untyped): untyped = 593 | (cast[ptr Area]((this))) 594 | 595 | 596 | proc areaSetSize*(a: ptr Area; width: cint; height: cint) {.cdecl, 597 | importc: "uiAreaSetSize", mylib.} 598 | 599 | proc areaQueueRedrawAll*(a: ptr Area) {.cdecl, importc: "uiAreaQueueRedrawAll", 600 | mylib.} 601 | proc areaScrollTo*(a: ptr Area; x: cdouble; y: cdouble; width: cdouble; height: cdouble) {. 602 | cdecl, importc: "uiAreaScrollTo", mylib.} 603 | proc newArea*(ah: ptr AreaHandler): ptr Area {.cdecl, importc: "uiNewArea", 604 | mylib.} 605 | proc newScrollingArea*(ah: ptr AreaHandler; width: cint; height: cint): ptr Area {.cdecl, 606 | importc: "uiNewScrollingArea", mylib.} 607 | type 608 | DrawPath* = object 609 | 610 | DrawBrushType* {.size: sizeof(cint).} = enum 611 | DrawBrushTypeSolid, DrawBrushTypeLinearGradient, DrawBrushTypeRadialGradient, 612 | DrawBrushTypeImage 613 | 614 | 615 | type 616 | DrawLineCap* {.size: sizeof(cint).} = enum 617 | DrawLineCapFlat, DrawLineCapRound, DrawLineCapSquare 618 | 619 | 620 | type 621 | DrawLineJoin* {.size: sizeof(cint).} = enum 622 | DrawLineJoinMiter, DrawLineJoinRound, DrawLineJoinBevel 623 | 624 | 625 | 626 | const 627 | DrawDefaultMiterLimit* = 10.0 628 | 629 | type 630 | DrawFillMode* {.size: sizeof(cint).} = enum 631 | DrawFillModeWinding, DrawFillModeAlternate 632 | 633 | 634 | type 635 | DrawMatrix* = object 636 | m11*: cdouble 637 | m12*: cdouble 638 | m21*: cdouble 639 | m22*: cdouble 640 | m31*: cdouble 641 | m32*: cdouble 642 | 643 | DrawBrush* = object 644 | `type`*: DrawBrushType 645 | r*: cdouble 646 | g*: cdouble 647 | b*: cdouble 648 | a*: cdouble 649 | x0*: cdouble 650 | y0*: cdouble 651 | x1*: cdouble 652 | y1*: cdouble 653 | outerRadius*: cdouble 654 | stops*: ptr DrawBrushGradientStop 655 | numStops*: csize 656 | 657 | DrawBrushGradientStop* = object 658 | pos*: cdouble 659 | r*: cdouble 660 | g*: cdouble 661 | b*: cdouble 662 | a*: cdouble 663 | 664 | DrawStrokeParams* = object 665 | cap*: DrawLineCap 666 | join*: DrawLineJoin 667 | thickness*: cdouble 668 | miterLimit*: cdouble 669 | dashes*: ptr cdouble 670 | numDashes*: csize 671 | dashPhase*: cdouble 672 | 673 | 674 | proc drawNewPath*(fillMode: DrawFillMode): ptr DrawPath {.cdecl, 675 | importc: "uiDrawNewPath", mylib.} 676 | proc drawFreePath*(p: ptr DrawPath) {.cdecl, importc: "uiDrawFreePath", mylib.} 677 | proc drawPathNewFigure*(p: ptr DrawPath; x: cdouble; y: cdouble) {.cdecl, 678 | importc: "uiDrawPathNewFigure", mylib.} 679 | proc drawPathNewFigureWithArc*(p: ptr DrawPath; xCenter: cdouble; yCenter: cdouble; 680 | radius: cdouble; startAngle: cdouble; sweep: cdouble; 681 | negative: cint) {.cdecl, 682 | importc: "uiDrawPathNewFigureWithArc", mylib.} 683 | proc drawPathLineTo*(p: ptr DrawPath; x: cdouble; y: cdouble) {.cdecl, 684 | importc: "uiDrawPathLineTo", mylib.} 685 | 686 | proc drawPathArcTo*(p: ptr DrawPath; xCenter: cdouble; yCenter: cdouble; 687 | radius: cdouble; startAngle: cdouble; sweep: cdouble; 688 | negative: cint) {.cdecl, importc: "uiDrawPathArcTo", 689 | mylib.} 690 | proc drawPathBezierTo*(p: ptr DrawPath; c1x: cdouble; c1y: cdouble; c2x: cdouble; 691 | c2y: cdouble; endX: cdouble; endY: cdouble) {.cdecl, 692 | importc: "uiDrawPathBezierTo", mylib.} 693 | 694 | proc drawPathCloseFigure*(p: ptr DrawPath) {.cdecl, importc: "uiDrawPathCloseFigure", 695 | mylib.} 696 | 697 | proc drawPathAddRectangle*(p: ptr DrawPath; x: cdouble; y: cdouble; width: cdouble; 698 | height: cdouble) {.cdecl, 699 | importc: "uiDrawPathAddRectangle", mylib.} 700 | proc drawPathEnd*(p: ptr DrawPath) {.cdecl, importc: "uiDrawPathEnd", mylib.} 701 | proc drawStroke*(c: ptr DrawContext; path: ptr DrawPath; b: ptr DrawBrush; 702 | p: ptr DrawStrokeParams) {.cdecl, importc: "uiDrawStroke", 703 | mylib.} 704 | proc drawFill*(c: ptr DrawContext; path: ptr DrawPath; b: ptr DrawBrush) {.cdecl, 705 | importc: "uiDrawFill", mylib.} 706 | 707 | proc drawMatrixSetIdentity*(m: ptr DrawMatrix) {.cdecl, 708 | importc: "uiDrawMatrixSetIdentity", mylib.} 709 | proc drawMatrixTranslate*(m: ptr DrawMatrix; x: cdouble; y: cdouble) {.cdecl, 710 | importc: "uiDrawMatrixTranslate", mylib.} 711 | proc drawMatrixScale*(m: ptr DrawMatrix; xCenter: cdouble; yCenter: cdouble; x: cdouble; 712 | y: cdouble) {.cdecl, importc: "uiDrawMatrixScale", 713 | mylib.} 714 | proc drawMatrixRotate*(m: ptr DrawMatrix; x: cdouble; y: cdouble; amount: cdouble) {. 715 | cdecl, importc: "uiDrawMatrixRotate", mylib.} 716 | proc drawMatrixSkew*(m: ptr DrawMatrix; x: cdouble; y: cdouble; xamount: cdouble; 717 | yamount: cdouble) {.cdecl, importc: "uiDrawMatrixSkew", 718 | mylib.} 719 | proc drawMatrixMultiply*(dest: ptr DrawMatrix; src: ptr DrawMatrix) {.cdecl, 720 | importc: "uiDrawMatrixMultiply", mylib.} 721 | proc drawMatrixInvertible*(m: ptr DrawMatrix): cint {.cdecl, 722 | importc: "uiDrawMatrixInvertible", mylib.} 723 | proc drawMatrixInvert*(m: ptr DrawMatrix): cint {.cdecl, 724 | importc: "uiDrawMatrixInvert", mylib.} 725 | proc drawMatrixTransformPoint*(m: ptr DrawMatrix; x: ptr cdouble; y: ptr cdouble) {.cdecl, 726 | importc: "uiDrawMatrixTransformPoint", mylib.} 727 | proc drawMatrixTransformSize*(m: ptr DrawMatrix; x: ptr cdouble; y: ptr cdouble) {.cdecl, 728 | importc: "uiDrawMatrixTransformSize", mylib.} 729 | proc drawTransform*(c: ptr DrawContext; m: ptr DrawMatrix) {.cdecl, 730 | importc: "uiDrawTransform", mylib.} 731 | 732 | proc drawClip*(c: ptr DrawContext; path: ptr DrawPath) {.cdecl, importc: "uiDrawClip", 733 | mylib.} 734 | proc drawSave*(c: ptr DrawContext) {.cdecl, importc: "uiDrawSave", mylib.} 735 | proc drawRestore*(c: ptr DrawContext) {.cdecl, importc: "uiDrawRestore", 736 | mylib.} 737 | 738 | type 739 | Attribute* = object 740 | AttributedString* = object 741 | 742 | 743 | proc freeAttribute*(a1: ptr Attribute): cstring {.cdecl, 744 | importc: "uiFreeAttribute", mylib.} 745 | 746 | type 747 | AttributeType* {.size: sizeof(cint).} = enum 748 | AttributeTypeFamily, AttributeTypeSize, AttributeTypeWeight, 749 | AttributeTypeItalic, AttributeTypeStretch, AttributeTypeColor, 750 | AttributeTypeBackground, AttributeTypeUnderline, AttributeTypeUnderlineColor, 751 | AttributeTypeFeatures 752 | 753 | proc AttributeGetType*(a: ptr Attribute): AttributeType {.cdecl, 754 | importc: "uiAttributeGetType", mylib.} 755 | 756 | proc newFamilyAttribute*(family: cstring): ptr Attribute {.cdecl, 757 | importc: "uiNewFamilyAttribute", mylib.} 758 | 759 | proc attributeFamily*(a: ptr Attribute): cstring {.cdecl, 760 | importc: "uiAttributeFamily", mylib.} 761 | 762 | proc newSizeAttribute*(size: cdouble): ptr Attribute {.cdecl, 763 | importc: "uiNewSizeAttribute", mylib.} 764 | 765 | proc attributeSize*(a: ptr Attribute): cdouble {.cdecl, 766 | importc: "uiAttributeSize", mylib.} 767 | 768 | type 769 | DrawTextFont* = object 770 | 771 | TextWeight* {.size: sizeof(cint).} = enum 772 | TextWeightMinimum = 0 773 | TextWeightThin = 100 774 | TextWeightUltraLight = 200 775 | TextWeightLight = 300 776 | TextWeightBook = 350 777 | TextWeightNormal = 400 778 | TextWeightMedium = 500 779 | TextWeightSemiBold = 600 780 | TextWeightBold = 700 781 | TextWeightUltraBold = 800 782 | TextWeightHeavy = 900 783 | TextWeightUltraHeavy = 950 784 | TextWeightMaximum = 1000 785 | 786 | proc newWeightAttribute*(weight: TextWeight): ptr Attribute {.cdecl, 787 | importc: "uiNewWeightAttribute", mylib.} 788 | proc attributeWeight*(a: ptr Attribute): TextWeight {.cdecl, 789 | importc: "uiAttributeWeight", mylib.} 790 | 791 | type 792 | TextItalic* {.size: sizeof(cint).} = enum 793 | TextItalicNormal, TextItalicOblique, TextItalicItalic 794 | 795 | proc newItalicAttribute*(italic: TextItalic): ptr Attribute {.cdecl, 796 | importc: "uiNewItalicAttribute", mylib.} 797 | proc attributeItalic*(a: ptr Attribute): TextItalic {.cdecl, 798 | importc: "uiAttributeItalic", mylib.} 799 | 800 | type 801 | TextStretch* {.size: sizeof(cint).} = enum 802 | TextStretchUltraCondensed, TextStretchExtraCondensed, 803 | TextStretchCondensed, TextStretchSemiCondensed, TextStretchNormal, 804 | TextStretchSemiExpanded, TextStretchExpanded, 805 | TextStretchExtraExpanded, TextStretchUltraExpanded 806 | 807 | proc newStretchAttribute*(stretch: TextStretch): ptr Attribute {.cdecl, 808 | importc: "uiNewStretchAttribute", mylib.} 809 | proc attributeStretch*(a: ptr Attribute): TextStretch {.cdecl, 810 | importc: "uiAttributeStretch", mylib.} 811 | proc newColorAttribute*(r: cdouble; g: cdouble; b: cdouble; a: cdouble): ptr Attribute {.cdecl, 812 | importc: "uiNewColorAttribute", mylib.} 813 | proc attributeColor*(a: ptr Attribute; r: ptr cdouble; g: ptr cdouble; b: ptr cdouble; 814 | alpha: ptr cdouble) {.cdecl, 815 | importc: "uiAttributeColor", mylib.} 816 | proc newBackgroundAttribute*(r: cdouble; g: cdouble; b: cdouble; a: cdouble): ptr Attribute {.cdecl, 817 | importc: "uiNewBackgroundAttribute", mylib.} 818 | 819 | type 820 | Underline* {.size: sizeof(cint).} = enum 821 | UnderlineNone, UnderlineSingle, 822 | UnderlineDouble, UnderlineSuggestion 823 | 824 | proc newUnderlineAttribute*(u: Underline): ptr Attribute {.cdecl, importc: "uiNewUnderlineAttribute", mylib.} 825 | proc attributeUnderline*(a: ptr Attribute): Underline {.cdecl, importc: "uiAttributeUnderline", mylib.} 826 | 827 | type 828 | UnderlineColor* {.size: sizeof(cint).} = enum 829 | UnderlineColorCustom, UnderlineColorSpelling, 830 | UnderlineColorGrammar, UnderlineColorAuxiliary 831 | 832 | proc newUnderlineColorAttribute*(u: UnderlineColor; r: cdouble; g: cdouble; 833 | b: cdouble; a: cdouble): ptr Attribute {.cdecl, importc: "uiNewUnderlineColorAttribute", mylib.} 834 | proc attributeUnderlineColor*(a: ptr Attribute; u: ptr UnderlineColor; 835 | r: ptr cdouble; g: ptr cdouble; b: ptr cdouble; 836 | alpha: ptr cdouble) {.cdecl, importc: "uiAttributeUnderlineColor", mylib.} 837 | type 838 | OpenTypeFeatures* = object 839 | OpenTypeFeaturesForEachFunc* = proc (otf: ptr OpenTypeFeatures; a: char; b: char; 840 | c: char; d: char; value: uint32; data: pointer): ForEach 841 | 842 | proc newOpenTypeFeatures*(): ptr OpenTypeFeatures {.cdecl, importc: "uiNewOpenTypeFeatures", mylib.} 843 | proc freeOpenTypeFeatures*(otf: ptr OpenTypeFeatures) {.cdecl, importc: "uiFreeOpenTypeFeatures", mylib.} 844 | proc openTypeFeaturesClone*(otf: ptr OpenTypeFeatures): ptr OpenTypeFeatures {.cdecl, importc: "uiOpenTypeFeaturesClone", mylib.} 845 | proc openTypeFeaturesAdd*(otf: ptr OpenTypeFeatures; a: char; b: char; c: char; 846 | d: char; value: uint32) {.cdecl, importc: "uiOpenTypeFeaturesAdd", mylib.} 847 | proc openTypeFeaturesRemove*(otf: ptr OpenTypeFeatures; a: char; b: char; c: char; 848 | d: char) {.cdecl, importc: "uiOpenTypeFeaturesRemove", mylib.} 849 | proc openTypeFeaturesGet*(otf: ptr OpenTypeFeatures; a: char; b: char; c: char; 850 | d: char; value: ptr uint32): cint {.cdecl, importc: "uiOpenTypeFeaturesGet", mylib.} 851 | proc openTypeFeaturesForEach*(otf: ptr OpenTypeFeatures; 852 | f: OpenTypeFeaturesForEachFunc; data: pointer) {.cdecl, importc: "uiOpenTypeFeaturesForEach", mylib.} 853 | proc newFeaturesAttribute*(otf: ptr OpenTypeFeatures): ptr Attribute {.cdecl, importc: "uiNewFeaturesAttribute", mylib.} 854 | proc attributeFeatures*(a: ptr Attribute): ptr OpenTypeFeatures {.cdecl, importc: "uiAttributeFeatures", mylib.} 855 | 856 | type 857 | AttributedStringForEachAttributeFunc* = proc (s: ptr AttributedString; 858 | a: ptr Attribute; start: csize; `end`: csize; data: pointer): ForEach 859 | 860 | proc newAttributedString*(initialString: cstring): ptr AttributedString {.cdecl, importc: "uiNewAttributedString", mylib.} 861 | proc freeAttributedString*(s: ptr AttributedString) {.cdecl, importc: "uiFreeAttributedString", mylib.} 862 | proc attributedStringString*(s: ptr AttributedString): cstring {.cdecl, importc: "uiAttributedStringString", mylib.} 863 | proc attributedStringLen*(s: ptr AttributedString): csize {.cdecl, importc: "uiAttributedStringLen", mylib.} 864 | proc attributedStringAppendUnattributed*(s: ptr AttributedString; str: cstring) {.cdecl, importc: "uiAttributedStringAppendUnattributed", mylib.} 865 | proc attributedStringInsertAtUnattributed*(s: ptr AttributedString; 866 | str: cstring; at: csize) {.cdecl, importc: "uiAttributedStringInsertAtUnattributed", mylib.} 867 | proc attributedStringDelete*(s: ptr AttributedString; start: csize; `end`: csize) {.cdecl, importc: "uiAttributedStringDelete", mylib.} 868 | proc attributedStringSetAttribute*(s: ptr AttributedString; a: ptr Attribute; 869 | start: csize; `end`: csize) {.cdecl, importc: "uiAttributedStringSetAttribute", mylib.} 870 | proc attributedStringForEachAttribute*(s: ptr AttributedString; f: AttributedStringForEachAttributeFunc; 871 | data: pointer) {.cdecl, importc: "uiDruiAttributedStringForEachAttributeawSave", mylib.} 872 | proc attributedStringNumGraphemes*(s: ptr AttributedString): csize {.cdecl, importc: "uiAttributedStringNumGraphemes", mylib.} 873 | proc attributedStringByteIndexToGrapheme*(s: ptr AttributedString; pos: csize): csize {.cdecl, importc: "uiAttributedStringByteIndexToGrapheme", mylib.} 874 | proc attributedStringGraphemeToByteIndex*(s: ptr AttributedString; pos: csize): csize {.cdecl, importc: "uiAttributedStringGraphemeToByteIndex", mylib.} 875 | 876 | type 877 | FontDescriptor* = object 878 | family*: cstring 879 | size*: cdouble 880 | weight*: TextWeight 881 | italic*: TextItalic 882 | stretch*: TextStretch 883 | 884 | type 885 | DrawTextLayout* = object 886 | DrawTextAlign* {.size: sizeof(cint).} = enum 887 | DrawTextAlignLeft, 888 | DrawTextAlignCenter 889 | DrawTextAlignRight 890 | 891 | DrawTextLayoutParams* {.bycopy.} = object 892 | str*: ptr AttributedString 893 | defaultFont*: ptr FontDescriptor 894 | width*: cdouble 895 | align*: DrawTextAlign 896 | 897 | proc drawNewTextLayout*(params: ptr DrawTextLayoutParams): ptr DrawTextLayout {. 898 | cdecl, importc: "uiDrawNewTextLayout", mylib.} 899 | 900 | proc drawFreeTextLayout*(tl: ptr DrawTextLayout) {.cdecl, importc: "uiDrawFreeTextLayout", mylib.} 901 | proc drawText*(c: ptr DrawContext; tl: ptr DrawTextLayout; x: cdouble; y: cdouble) {.cdecl, importc: "uiDrawText", mylib.} 902 | proc drawTextLayoutExtents*(tl: ptr DrawTextLayout; width: ptr cdouble; 903 | height: ptr cdouble) {.cdecl, importc: "uiDrawTextLayoutExtents", mylib.} 904 | 905 | type 906 | FontButton* = object of Control 907 | 908 | template toUiFontButton*(this: untyped): untyped = 909 | (cast[ptr FontButton]((this))) 910 | 911 | proc fontButtonFont*(b: ptr FontButton; desc: ptr FontDescriptor) {.cdecl, importc: "uiFontButtonFont", mylib.} 912 | proc fontButtonOnChanged*(b: ptr FontButton, 913 | f: proc (a1: ptr FontButton; a2: pointer); data: pointer) {.cdecl, importc: "uiFontButtonOnChanged", mylib.} 914 | proc newFontButton*(): ptr FontButton {.cdecl, importc: "uiNewFontButton", mylib.} 915 | proc freeFontButtonFont*(desc: ptr FontDescriptor) {.cdecl, importc: "uiFreeFontButtonFont", mylib.} 916 | 917 | type 918 | ColorButton* = object of Control 919 | 920 | 921 | template toUiColorButton*(this: untyped): untyped = 922 | (cast[ptr ColorButton]((this))) 923 | 924 | proc colorButtonColor*(b: ptr ColorButton; r: ptr cdouble; g: ptr cdouble; 925 | bl: ptr cdouble; a: ptr cdouble) {.cdecl, 926 | importc: "uiColorButtonColor", mylib.} 927 | proc colorButtonSetColor*(b: ptr ColorButton; r: cdouble; g: cdouble; bl: cdouble; 928 | a: cdouble) {.cdecl, importc: "uiColorButtonSetColor", 929 | mylib.} 930 | proc colorButtonOnChanged*(b: ptr ColorButton; 931 | f: proc (a2: ptr ColorButton; a3: pointer) {.cdecl.}; 932 | data: pointer) {.cdecl, 933 | importc: "uiColorButtonOnChanged", mylib.} 934 | proc newColorButton*(): ptr ColorButton {.cdecl, importc: "uiNewColorButton", 935 | mylib.} 936 | type 937 | Form* = object of Control 938 | 939 | 940 | template toUiForm*(this: untyped): untyped = 941 | (cast[ptr Form]((this))) 942 | 943 | proc formAppend*(f: ptr Form; label: cstring; c: ptr Control; stretchy: cint) {.cdecl, 944 | importc: "uiFormAppend", mylib.} 945 | proc formDelete*(f: ptr Form; index: cint) {.cdecl, importc: "uiFormDelete", 946 | mylib.} 947 | proc formPadded*(f: ptr Form): cint {.cdecl, importc: "uiFormPadded", mylib.} 948 | proc formSetPadded*(f: ptr Form; padded: cint) {.cdecl, importc: "uiFormSetPadded", 949 | mylib.} 950 | proc newForm*(): ptr Form {.cdecl, importc: "uiNewForm", mylib.} 951 | type 952 | Align* {.size: sizeof(cint).} = enum 953 | AlignFill, AlignStart, AlignCenter, AlignEnd 954 | 955 | 956 | type 957 | At* {.size: sizeof(cint).} = enum 958 | AtLeading, AtTop, AtTrailing, AtBottom 959 | 960 | 961 | type 962 | Grid* = object of Control 963 | 964 | 965 | template toUiGrid*(this: untyped): untyped = 966 | (cast[ptr Grid]((this))) 967 | 968 | proc gridAppend*(g: ptr Grid; c: ptr Control; left: cint; top: cint; xspan: cint; 969 | yspan: cint; hexpand: cint; halign: Align; vexpand: cint; valign: Align) {. 970 | cdecl, importc: "uiGridAppend", mylib.} 971 | proc gridInsertAt*(g: ptr Grid; c: ptr Control; existing: ptr Control; at: At; xspan: cint; 972 | yspan: cint; hexpand: cint; halign: Align; vexpand: cint; 973 | valign: Align) {.cdecl, importc: "uiGridInsertAt", mylib.} 974 | proc gridPadded*(g: ptr Grid): cint {.cdecl, importc: "uiGridPadded", mylib.} 975 | proc gridSetPadded*(g: ptr Grid; padded: cint) {.cdecl, importc: "uiGridSetPadded", 976 | mylib.} 977 | proc newGrid*(): ptr Grid {.cdecl, importc: "uiNewGrid", mylib.} 978 | 979 | type 980 | Image* = object 981 | 982 | proc newImage*(width: cdouble; height: cdouble): ptr Image {.cdecl, importc: "uiNewImage", mylib.} 983 | proc freeImage*(i: ptr Image) {.cdecl, importc: "uiFreeImage", mylib.} 984 | proc imageAppend*(i: ptr Image; pixels: pointer; pixelWidth: cint; 985 | pixelHeight: cint; byteStride: cint) {.cdecl, importc: "uiImageAppend", mylib.} 986 | 987 | type 988 | Table* = object of Control 989 | TableValueType* = enum 990 | TableValueTypeString, 991 | TableValueTypeImage, 992 | TableValueTypeInt, 993 | TableValueTypeColor 994 | 995 | Color* {.bycopy.} = object 996 | r*: cdouble 997 | g*: cdouble 998 | b*: cdouble 999 | a*: cdouble 1000 | 1001 | TableValueInner* {.bycopy, union.} = object 1002 | str*: cstring 1003 | img*: ptr Image 1004 | i*: cint 1005 | color*: Color 1006 | 1007 | TableValue* {.bycopy.} = object 1008 | kind*: TableValueType 1009 | u*: TableValueInner 1010 | TableModel* = pointer 1011 | 1012 | proc freeTableValue*(v: ptr TableValue) {.cdecl, importc: "uiFreeTableValue", mylib.} 1013 | 1014 | proc tableValueGetType*(v: ptr TableValue): TableValueType {.cdecl, importc: "uiTableValueGetType", mylib.} 1015 | 1016 | proc newTableValueString*(str: cstring): ptr TableValue {.cdecl, importc: "uiNewTableValueString", mylib.} 1017 | proc tableValueString*(v: ptr TableValue): cstring {.cdecl, importc: "uiTableValueString", mylib.} 1018 | 1019 | proc newTableValueImage*(img: ptr Image): ptr TableValue {.cdecl, importc: "uiNewTableValueImage", mylib.} 1020 | proc tableValueImage*(v: ptr TableValue): ptr Image {.cdecl, importc: "uiTableValueImage", mylib.} 1021 | 1022 | proc newTableValueInt*(i: cint): ptr TableValue {.cdecl, importc: "uiNewTableValueInt", mylib.} 1023 | proc tableValueInt*(v: ptr TableValue): int {.cdecl, importc: "uiTableValueInt", mylib.} 1024 | 1025 | proc newTableValueColor*(r: float; g: float; b: float; a: float): ptr TableValue {.cdecl, importc: "uiNewTableValueColor", mylib.} 1026 | proc tableValueColor*(v: ptr TableValue; r: ptr float; g: ptr float; 1027 | b: ptr float; a: ptr float) {.cdecl, importc: "uiTableValueColor", mylib.} 1028 | type 1029 | TableNumColumns* = proc (mh: ptr TableModelHandler, m: TableModel): int {.cdecl.} 1030 | TableColumnType* = proc (mh: ptr TableModelHandler, m: TableModel, col: int): TableValueType {.noconv.} 1031 | TableNumRows* = proc (mh: ptr TableModelHandler, m: TableModel): int {.cdecl.} 1032 | TableCellValue* = proc (mh: ptr TableModelHandler, m: TableModel, row, col: int): ptr TableValue {.noconv.} 1033 | TableSetCellValue* = proc (mh: ptr TableModelHandler, m: TableModel, row, col: int, val: ptr TableValue) {.cdecl.} 1034 | 1035 | TableModelHandler* {.pure.} = object 1036 | numColumns*: TableNumColumns 1037 | columnType*: TableColumnType 1038 | numRows*: TableNumRows 1039 | cellValue*: TableCellValue 1040 | setCellValue*: TableSetCellValue 1041 | 1042 | 1043 | proc newTableModel*(mh: ptr TableModelHandler): TableModel {.cdecl, importc: "uiNewTableModel", mylib.} 1044 | proc freeTableModel*(m: TableModel) {.cdecl, importc: "uiFreeTableModel", mylib.} 1045 | proc tableModelRowInserted*(m: TableModel; newIndex: cint) {.cdecl, importc: "uiTableModelRowInserted", mylib.} 1046 | proc tableModelRowChanged*(m: TableModel; index: cint) {.cdecl, importc: "uiTableModelRowChanged", mylib.} 1047 | proc tableModelRowDeleted*(m: TableModel; oldIndex: cint) {.cdecl, importc: "uiTableModelRowDeleted", mylib.} 1048 | 1049 | 1050 | type 1051 | TableTextColumnOptionalParams* {.bycopy.} = object 1052 | ColorModelColumn*: int 1053 | 1054 | TableParams* = object 1055 | model*: TableModel 1056 | rowBackgroundColorModelColumn*: cint 1057 | 1058 | 1059 | template toUiTable*(this: untyped): untyped = 1060 | (cast[ptr Table]((this))) 1061 | 1062 | proc tableAppendTextColumn*(t: ptr Table; name: cstring; textModelColumn: cint; 1063 | textEditableModelColumn: cint; 1064 | textParams: ptr TableTextColumnOptionalParams) {.cdecl, importc: "uiTableAppendTextColumn", mylib.} 1065 | proc tableAppendImageColumn*(t: ptr Table; name: cstring; imageModelColumn: cint) {.cdecl, importc: "uiTableAppendImageColumn", mylib.} 1066 | proc tableAppendImageTextColumn*(t: ptr Table; name: cstring; 1067 | imageModelColumn: cint; textModelColumn: cint; 1068 | textEditableModelColumn: cint; textParams: ptr TableTextColumnOptionalParams) {.cdecl, importc: "uiTableAppendImageTextColumn", mylib.} 1069 | proc tableAppendCheckboxColumn*(t: ptr Table; name: cstring; 1070 | checkboxModelColumn: cint; 1071 | checkboxEditableModelColumn: cint) {.cdecl, importc: "uiTableAppendCheckboxColumn", mylib.} 1072 | proc tableAppendCheckboxTextColumn*(t: ptr Table; name: cstring; checkboxModelColumn: cint; checkboxEditableModelColumn: cint; 1073 | textModelColumn: cint; textEditableModelColumn: cint; textParams: ptr TableTextColumnOptionalParams) {.cdecl, importc: "uiTableAppendCheckboxTextColumn", mylib.} 1074 | proc tableAppendProgressBarColumn*(t: ptr Table; name: cstring; progressModelColumn: cint) {.cdecl, importc: "uiTableAppendProgressBarColumn", mylib.} 1075 | proc tableAppendButtonColumn*(t: ptr Table; name: cstring; buttonModelColumn: cint; buttonClickableModelColumn: cint) {.cdecl, importc: "uiTableAppendButtonColumn", mylib.} 1076 | proc newTable*(params: ptr TableParams): ptr Table {.cdecl, importc: "uiNewTable", mylib.} 1077 | --------------------------------------------------------------------------------