Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -266,5 +266,7 @@ nimcache/
# wxnim - Linux doesn't need .exe or similar file ending. Putting this here until a better solution is found
examples/genuimacro/controlgallery
examples/genuimacro/threads
examples/genuimacro/string_interop
examples/purewx/example1
examples/purewx/example2

41 changes: 37 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Still in development, is shown to work fine, but needs more testing!
- [Installation](#installation)
* [Installation on Linux](#installation-on-linux)
* [Installation on Windows](#installation-on-windows)
* [Installation on macOS](#installation-on-macOS)
- [Examples](#examples)
* [With GenUI macro](#with-genui-macro)
* [Running work on background threads](#running-work-on-background-threads)
Expand All @@ -22,7 +23,7 @@ Still in development, is shown to work fine, but needs more testing!


# Installation
wxWidgets works across all major platforms but the build process is slightly different. Below follows instructions on how to build for Linux and Windows. If you use Mac OSX it would be great if you shared how to build on a Mac and it can be added here as well. Since a simple nim.cfg file doesn't quite cut it here we use the file wxCompile.nim to decide which flags to pass so you would have to modify that to make changes.
wxWidgets works across all major platforms but the build process is slightly different. Below are instructions for building on Linux, Windows, and macOS. Since a simple nim.cfg file doesn't quite cut it here we use the file wxCompile.nim to decide which flags to pass so you would have to modify that to make changes.

## Installation on Linux

Expand All @@ -39,6 +40,33 @@ More details can be found here:

https://wiki.wxwidgets.org/Compiling_wxWidgets_with_MinGW

## Installation on macOS

Both methods below work for Apple Silicon (M1) as well as x86_64.

### Method 1: Install wxWidgets with Homebrew
``brew install wxmac``

This installs 3.0.5, which doesn't support dark mode.
If you want to support dark mode, you need version 3.1.x by building it yourself. See steps below.

### Method 2: Build wxWidgets yourself (recommended)

The following steps work even if you have already installed wxWidgets via Homebrew (they can live side-by-side).

1. Get [latest development release](https://www.wxwidgets.org/downloads/) (3.1.4 as of this writing)
2. Unarchive into an appropriate directory. For remaining steps, assume /usr/local
3. ``cd /usr/local/wxWidgets-3.1.4``
4. ``mkdir build_macOS && cd build_macOS`` (make a build output directory and cd into it)
5. ``../configure CXXFLAGS="-I/opt/homebrew/include"`` (pass include directory for brew-installed libs like ``libtiff``)
6. ``make``

wxWidgets is now built in ``/usr/local/wxWidgets-3.1.4/build_macOS/``.
To build your Nim/wxWidgets project, pass this path to the nim compiler.

For instance, to build the ``controlgallery.nim`` example, execute ``nim cpp -r -d:"wxWidgetsPath:/usr/local/wxWidgets-3.1.4/build_macOS" controlgallery.nim``


# Examples

## With GenUI macro
Expand All @@ -49,16 +77,21 @@ This module ships with a macro to easily create GUIs. To see it in use look at o

nim cpp -r controlgallery.nim

The output of the macro should look like these images from Linux and Windows respectively:
The output of the macro should look like these images from Linux, Windows, and macOS:

On Linux wxWidgets uses GTK+ as it's backend and looks will vary greatly depending on theme (this screenshot is taken with the Arc theme and M+ 2p font).
On Linux, wxWidgets uses GTK+ as it's backend and looks will vary greatly depending on theme (this screenshot is taken with the Arc theme and M+ 2p font).

![Linux](/screenshots/linux.png)

On Windows wxWidgets uses Win32 Forms, so looks might change depending on Windows version, this is from Windows 10:
On Windows, wxWidgets uses Win32 Forms, so looks might change depending on Windows version, this is from Windows 10:

![Windows](/screenshots/windows.png)

On macOS, wxWidgets uses Apple's Cocoa toolkit.

![macOS-darkmode](/screenshots/macOS-darkmode.png)
![macOS-lightmode](/screenshots/macOS-lightmode.png)

## Running work on background threads

Since wxWidgets requires the main thread to perform UI actions you would want to perform long running tasks in threads. To see an example of how you can use threads with wxWidgets look at the ``threads`` example found in ``examples/genuimacro``.
Expand Down
24 changes: 24 additions & 0 deletions examples/genuimacro/string_interop.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@

import "../../wxnim/wx", "../../wxnim/genui"

{.experimental.}

var
textCtrl: ptr WxTextCtrl


proc buttonClicked(e: var WxCommandEvent) =
var
theText = string(textCtrl.getValue())
echo theText


genui:
mainFrame % Frame(title = "Hello World"):
Panel | BoxSizer(orient = wxHorizontal):
StaticBox(label = "Basic controls") | StaticBoxSizer(orient = wxVertical):
textCtrl % TextCtrl
theButton % Button -> (wxEVT_BUTTON, buttonClicked): "Click me"

mainFrame.show()
runMainLoop()
Binary file added screenshots/macOS-darkmode.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/macOS-lightmode.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 24 additions & 0 deletions wxnim/wx.nim
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,30 @@ include private/string
converter toWxString*(s: string): WxString =
result = constructWxString(cstring(s), s.len)

converter toString*(s: WxString): string =
#[
Context about wxString handling:
- wxString class reference, particularly .ToUTF8() method
https://docs.wxwidgets.org/3.0/classwx_string.html
- wxScopedCharTypeBuffer<T> reference, particularly .data() method
https://docs.wxwidgets.org/3.0/classwx_scoped_char_type_buffer.html#a7cd7ba0ab32e9f63779f602c2bdfd9b8

Nim emit pragma for embedding C++ code:
- https://nim-lang.github.io/Nim/manual.html#implementation-specific-pragmas-emit-pragma

C++11 limits on implicit conversion from const char* to char*
- https://stackoverflow.com/questions/48554625/vs-2017-doesnt-implicitly-convert-const-char-to-char/48554786
- https://en.cppreference.com/w/cpp/language/const_cast
]#
var r: cstring

{.emit: """
`r` = const_cast<char*>((const char*)s.ToUTF8().data());
""".}

result = $r #convert cstring to string


converter wxOrientationToClong*(inType:WxOrientation): clong = cast[clong](inType)

converter wxStretchToCint*(inType:WxStretch): cint = cast[cint](inType)
Expand Down
2 changes: 1 addition & 1 deletion wxnim/wxCompile.nim
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,4 @@ elif defined(gcc) or defined(clang):
"wx-config"
const wxConfigOptions {.strdefine.}: string = ""
{.passC: "`" & wxConfig & " " & wxConfigOptions & " --cppflags`".}
{.passL: "`" & wxConfig & " " & wxConfigOptions & " --libs`".}
{.passL: "`" & wxConfig & " " & wxConfigOptions & " --libs all`".}