Hello, everybody. Happy to introduce my new project- wNim.
It is a Windows GUI Framework based on my own Winim library. I started this project because I wanted to test and prove the winim library. As time goes on, it is full featured now.
Main features are:
Code Examples
Basic structure:
import wNim
let app = App()
let frame = Frame(title="Hello World", size=(400, 300))
frame.center()
frame.show()
app.mainLoop()
Event handler:
button.wEvent_Button do ():
frame.delete()
frame.wIdExit do ():
frame.delete()
frame.wEvent_Size do ():
layout()
Layout DSL:
panel.layout:
staticText:
top = panel.top + 10
left = panel.left + 10
button:
right + 10 = panel.right
bottom + 10 = panel.bottom
Screenshot
More example on github webside. Feedback is welcome. Happy coding with Nim!
Nice! I'm a Linux user, but we definitely need some more love for Windows, too.
This might be far fetched, but has anyone considered using the common functionality between this library and GTK+ 2/3 to make a cross platform toolkit?
OH, and I'm loving the DSL for the layout.
Awesome!
If I recall rightly, winim didn't include menubar functionality.
Can you include that in your demo?
In wNim, all controls are subclassed internally, so you are right, you can use all type of events(aka windows messages) in all type of controls. For example:
let button = Button(panel, label="Button")
button.WM_LBUTTONDOWN do (event: wEvent):
# do something.
event.skip() # if you don't skip it, no wEvent_Button will be generated.
Hmm, in fact not every event/message. For example, you cannot connect to WM_CREATE. Because you had already missed it when you got a button object.
Most useful windows message are already wrapped into wNim event type. But you can deal with some low-level event by this skill. It also demonstrates in examples/lowlevel.nim.
All codes about windows message/event handler are in the wWindow.nim. wWndProc() is WndProc for wWindow object, wSubProc() is WndProc for subclassed control object. They call processMessage() to generate the event object, and then pass to processEvent(). The connected event handlers are invoked in processEvent().
I am starting to write some beginner tutorial for wNim
It is great that there is some progress with your Windows GUI.
How do you manage memory resources? I have seen no manual free() in your example code, so I assume that you have implemented finalizers like I did for GTK, using GC_ref() and all that. So do you have already ideas how it can work with newruntime and owned refs? I was told there will be no GC_Ref() with newruntime, so it is not that easy. What are your ideas ans plans?
I finished a project by using Layout DSL ( the function goodLayout in https://github.com/retsyo/wNim_sample/blob/master/bug_gui.nim ), however the code is very long
I used Layout DSL because I still can't master autolayout well. Can anyone point out what is the problem in my following code(badLayout in https://github.com/retsyo/wNim_sample/blob/master/bug_gui.nim)? Thanks
In my application, everything lives in notebook, the desired GUI seems like
so firstly I write
notebook[0].autolayout """
H:|-[staticbox1(staticbox2,cboxIndex,staticbox3)]-|
V:|-[staticbox1(staticbox2,cboxIndex*5,staticbox3)]-[staticbox2]-[cboxIndex]-[staticbox3]-|
"""
which almost works as expected(all widgets have the same width; staticbox1~3 have save height, and equals to cboxIndex.height*5), but a flaw, or the first problem I met, is the space of staticbox1~left > staticbox2~left.
then I add widgets layout inside staticbox1~3. In fact widgets inside staticbox1~2 have a similar layout
notebook[0].autolayout """
H:|-[staticbox1(staticbox2,cboxIndex,staticbox3)]-|
V:|-[staticbox1(staticbox2,cboxIndex*5,staticbox3)]-[staticbox2]-[cboxIndex]-[staticbox3]-|
outer: staticbox1
V:|-[{file1:[textFile1,btnFile1]}(sheet1*2, cr1)]-{sheet1:[lblSheet1,cboxSheet1]}-{cr1:[lblCol1,txtCol1,lblStartRow1,txtStartRow1,lblEndRow1,txtEndRow1]}-|
H:|-[file1(sheet1,cr1)]-|
however, the new added widgets are not placed in staticbox1~3 at all!
I have learned autolayoutEditor.nim coming with wNim source code, and struggled to write several version of my own autolayout code in my above application, but none works as expected :(
So which part is misunderstood in my code? Thanks
well, I solved my problem. The code is not as short as I expected, but is still much shorter than Layout DSL version. the main changes lies in 2 parts:
btw, we can't use V:|-[file2(sheet2,cr2)]-[sheet2]-[cr2]-|
outer: staticbox2
H:|-{file2:[textFile2(btnFile2*5)]-[btnFile2]}-|
H:|-{sheet2:[lblSheet2(cboxSheet2/5)]-[cboxSheet2]}-|
H:|-{cr2:[lblCol2(txtCol2,lblStartRow2,txtStartRow2,lblEndRow2,txtEndRow2)]-[txtCol2]-[lblStartRow2]-[txtStartRow2]-[lblEndRow2]-[txtEndRow2]}-|
V:|-[file2]-[sheet2]-[cr2]-|
C: textFile2.height = lblSheet2.height
C: lblSheet2.height = lblCol2.height