aboutsummaryrefslogtreecommitdiff
path: root/src/libui_sdl/libui/examples
diff options
context:
space:
mode:
authorStapleButter <thetotalworm@gmail.com>2017-09-09 02:30:51 +0200
committerStapleButter <thetotalworm@gmail.com>2017-09-09 02:30:51 +0200
commit70e4841d311d68689724768157cc9cbfbde7a9fc (patch)
treeba9499f77d1258530a7e60aa6e1732c41d98161c /src/libui_sdl/libui/examples
parent81747d6c34eb159481a6ca3f283d065fa3568617 (diff)
another UI attempt, I guess.
sorry.
Diffstat (limited to 'src/libui_sdl/libui/examples')
-rw-r--r--src/libui_sdl/libui/examples/CMakeLists.txt38
-rw-r--r--src/libui_sdl/libui/examples/controlgallery/darwin.pngbin0 -> 97260 bytes
-rw-r--r--src/libui_sdl/libui/examples/controlgallery/main.c540
-rw-r--r--src/libui_sdl/libui/examples/controlgallery/unix.pngbin0 -> 41757 bytes
-rw-r--r--src/libui_sdl/libui/examples/controlgallery/windows.pngbin0 -> 48217 bytes
-rw-r--r--src/libui_sdl/libui/examples/cpp-multithread/main.cpp92
-rw-r--r--src/libui_sdl/libui/examples/example.manifest20
-rw-r--r--src/libui_sdl/libui/examples/example.static.manifest32
-rw-r--r--src/libui_sdl/libui/examples/histogram/main.c309
-rw-r--r--src/libui_sdl/libui/examples/resources.rc13
10 files changed, 1044 insertions, 0 deletions
diff --git a/src/libui_sdl/libui/examples/CMakeLists.txt b/src/libui_sdl/libui/examples/CMakeLists.txt
new file mode 100644
index 0000000..3a9ec4c
--- /dev/null
+++ b/src/libui_sdl/libui/examples/CMakeLists.txt
@@ -0,0 +1,38 @@
+# 3 june 2016
+
+if(WIN32)
+ set(_EXAMPLE_RESOURCES_RC resources.rc)
+endif()
+
+macro(_add_example _name)
+ _add_exec(${_name} ${ARGN})
+ # because Microsoft's toolchain is dumb
+ if(MSVC)
+ set_property(TARGET ${_name} APPEND_STRING PROPERTY
+ LINK_FLAGS " /ENTRY:mainCRTStartup")
+ endif()
+endmacro()
+
+_add_example(controlgallery
+ controlgallery/main.c
+ ${_EXAMPLE_RESOURCES_RC}
+)
+
+_add_example(histogram
+ histogram/main.c
+ ${_EXAMPLE_RESOURCES_RC}
+)
+
+_add_example(cpp-multithread
+ cpp-multithread/main.cpp
+ ${_EXAMPLE_RESOURCES_RC}
+)
+if(NOT WIN32)
+ target_link_libraries(cpp-multithread pthread)
+endif()
+
+add_custom_target(examples
+ DEPENDS
+ controlgallery
+ histogram
+ cpp-multithread)
diff --git a/src/libui_sdl/libui/examples/controlgallery/darwin.png b/src/libui_sdl/libui/examples/controlgallery/darwin.png
new file mode 100644
index 0000000..f61b54b
--- /dev/null
+++ b/src/libui_sdl/libui/examples/controlgallery/darwin.png
Binary files differ
diff --git a/src/libui_sdl/libui/examples/controlgallery/main.c b/src/libui_sdl/libui/examples/controlgallery/main.c
new file mode 100644
index 0000000..c0d536c
--- /dev/null
+++ b/src/libui_sdl/libui/examples/controlgallery/main.c
@@ -0,0 +1,540 @@
+// 2 september 2015
+#include <stdio.h>
+#include <string.h>
+#include "../../ui.h"
+
+static int onClosing(uiWindow *w, void *data)
+{
+ uiQuit();
+ return 1;
+}
+
+static int onShouldQuit(void *data)
+{
+ uiWindow *mainwin = uiWindow(data);
+
+ uiControlDestroy(uiControl(mainwin));
+ return 1;
+}
+
+static uiControl *makeBasicControlsPage(void)
+{
+ uiBox *vbox;
+ uiBox *hbox;
+ uiGroup *group;
+ uiForm *entryForm;
+
+ vbox = uiNewVerticalBox();
+ uiBoxSetPadded(vbox, 1);
+
+ hbox = uiNewHorizontalBox();
+ uiBoxSetPadded(hbox, 1);
+ uiBoxAppend(vbox, uiControl(hbox), 0);
+
+ uiBoxAppend(hbox,
+ uiControl(uiNewButton("Button")),
+ 0);
+ uiBoxAppend(hbox,
+ uiControl(uiNewCheckbox("Checkbox")),
+ 0);
+
+ uiBoxAppend(vbox,
+ uiControl(uiNewLabel("This is a label. Right now, labels can only span one line.")),
+ 0);
+
+ uiBoxAppend(vbox,
+ uiControl(uiNewHorizontalSeparator()),
+ 0);
+
+ group = uiNewGroup("Entries");
+ uiGroupSetMargined(group, 1);
+ uiBoxAppend(vbox, uiControl(group), 1);
+
+ entryForm = uiNewForm();
+ uiFormSetPadded(entryForm, 1);
+ uiGroupSetChild(group, uiControl(entryForm));
+
+ uiFormAppend(entryForm,
+ "Entry",
+ uiControl(uiNewEntry()),
+ 0);
+ uiFormAppend(entryForm,
+ "Password Entry",
+ uiControl(uiNewPasswordEntry()),
+ 0);
+ uiFormAppend(entryForm,
+ "Search Entry",
+ uiControl(uiNewSearchEntry()),
+ 0);
+ uiFormAppend(entryForm,
+ "Multiline Entry",
+ uiControl(uiNewMultilineEntry()),
+ 1);
+ uiFormAppend(entryForm,
+ "Multiline Entry No Wrap",
+ uiControl(uiNewNonWrappingMultilineEntry()),
+ 1);
+
+ return uiControl(vbox);
+}
+
+// TODO make these not global
+static uiSpinbox *spinbox;
+static uiSlider *slider;
+static uiProgressBar *pbar;
+
+static void onSpinboxChanged(uiSpinbox *s, void *data)
+{
+ uiSliderSetValue(slider, uiSpinboxValue(s));
+ uiProgressBarSetValue(pbar, uiSpinboxValue(s));
+}
+
+static void onSliderChanged(uiSlider *s, void *data)
+{
+ uiSpinboxSetValue(spinbox, uiSliderValue(s));
+ uiProgressBarSetValue(pbar, uiSliderValue(s));
+}
+
+static uiControl *makeNumbersPage()
+{
+ uiBox *hbox;
+ uiGroup *group;
+ uiBox *vbox;
+ uiProgressBar *ip;
+ uiCombobox *cbox;
+ uiEditableCombobox *ecbox;
+ uiRadioButtons *rb;
+
+ hbox = uiNewHorizontalBox();
+ uiBoxSetPadded(hbox, 1);
+
+ group = uiNewGroup("Numbers");
+ uiGroupSetMargined(group, 1);
+ uiBoxAppend(hbox, uiControl(group), 1);
+
+ vbox = uiNewVerticalBox();
+ uiBoxSetPadded(vbox, 1);
+ uiGroupSetChild(group, uiControl(vbox));
+
+ spinbox = uiNewSpinbox(0, 100);
+ slider = uiNewSlider(0, 100);
+ pbar = uiNewProgressBar();
+ uiSpinboxOnChanged(spinbox, onSpinboxChanged, NULL);
+ uiSliderOnChanged(slider, onSliderChanged, NULL);
+ uiBoxAppend(vbox, uiControl(spinbox), 0);
+ uiBoxAppend(vbox, uiControl(slider), 0);
+ uiBoxAppend(vbox, uiControl(pbar), 0);
+
+ ip = uiNewProgressBar();
+ uiProgressBarSetValue(ip, -1);
+ uiBoxAppend(vbox, uiControl(ip), 0);
+
+ group = uiNewGroup("Lists");
+ uiGroupSetMargined(group, 1);
+ uiBoxAppend(hbox, uiControl(group), 1);
+
+ vbox = uiNewVerticalBox();
+ uiBoxSetPadded(vbox, 1);
+ uiGroupSetChild(group, uiControl(vbox));
+
+ cbox = uiNewCombobox();
+ uiComboboxAppend(cbox, "Combobox Item 1");
+ uiComboboxAppend(cbox, "Combobox Item 2");
+ uiComboboxAppend(cbox, "Combobox Item 3");
+ uiBoxAppend(vbox, uiControl(cbox), 0);
+
+ ecbox = uiNewEditableCombobox();
+ uiEditableComboboxAppend(ecbox, "Editable Item 1");
+ uiEditableComboboxAppend(ecbox, "Editable Item 2");
+ uiEditableComboboxAppend(ecbox, "Editable Item 3");
+ uiBoxAppend(vbox, uiControl(ecbox), 0);
+
+ rb = uiNewRadioButtons();
+ uiRadioButtonsAppend(rb, "Radio Button 1");
+ uiRadioButtonsAppend(rb, "Radio Button 2");
+ uiRadioButtonsAppend(rb, "Radio Button 3");
+ uiBoxAppend(vbox, uiControl(rb), 0);
+
+ return uiControl(hbox);
+}
+
+// TODO make this not global
+static uiWindow *mainwin;
+
+static void onOpenFileClicked(uiButton *b, void *data)
+{
+ uiEntry *entry = uiEntry(data);
+ char *filename;
+
+ filename = uiOpenFile(mainwin);
+ if (filename == NULL) {
+ uiEntrySetText(entry, "(cancelled)");
+ return;
+ }
+ uiEntrySetText(entry, filename);
+ uiFreeText(filename);
+}
+
+static void onSaveFileClicked(uiButton *b, void *data)
+{
+ uiEntry *entry = uiEntry(data);
+ char *filename;
+
+ filename = uiSaveFile(mainwin);
+ if (filename == NULL) {
+ uiEntrySetText(entry, "(cancelled)");
+ return;
+ }
+ uiEntrySetText(entry, filename);
+ uiFreeText(filename);
+}
+
+static void onMsgBoxClicked(uiButton *b, void *data)
+{
+ uiMsgBox(mainwin,
+ "This is a normal message box.",
+ "More detailed information can be shown here.");
+}
+
+static void onMsgBoxErrorClicked(uiButton *b, void *data)
+{
+ uiMsgBoxError(mainwin,
+ "This message box describes an error.",
+ "More detailed information can be shown here.");
+}
+
+static uiControl *makeDataChoosersPage(void)
+{
+ uiBox *hbox;
+ uiBox *vbox;
+ uiGrid *grid;
+ uiButton *button;
+ uiEntry *entry;
+ uiGrid *msggrid;
+
+ hbox = uiNewHorizontalBox();
+ uiBoxSetPadded(hbox, 1);
+
+ vbox = uiNewVerticalBox();
+ uiBoxSetPadded(vbox, 1);
+ uiBoxAppend(hbox, uiControl(vbox), 0);
+
+ uiBoxAppend(vbox,
+ uiControl(uiNewDatePicker()),
+ 0);
+ uiBoxAppend(vbox,
+ uiControl(uiNewTimePicker()),
+ 0);
+ uiBoxAppend(vbox,
+ uiControl(uiNewDateTimePicker()),
+ 0);
+
+ uiBoxAppend(vbox,
+ uiControl(uiNewFontButton()),
+ 0);
+ uiBoxAppend(vbox,
+ uiControl(uiNewColorButton()),
+ 0);
+
+ uiBoxAppend(hbox,
+ uiControl(uiNewVerticalSeparator()),
+ 0);
+
+ vbox = uiNewVerticalBox();
+ uiBoxSetPadded(vbox, 1);
+ uiBoxAppend(hbox, uiControl(vbox), 1);
+
+ grid = uiNewGrid();
+ uiGridSetPadded(grid, 1);
+ uiBoxAppend(vbox, uiControl(grid), 0);
+
+ button = uiNewButton("Open File");
+ entry = uiNewEntry();
+ uiEntrySetReadOnly(entry, 1);
+ uiButtonOnClicked(button, onOpenFileClicked, entry);
+ uiGridAppend(grid, uiControl(button),
+ 0, 0, 1, 1,
+ 0, uiAlignFill, 0, uiAlignFill);
+ uiGridAppend(grid, uiControl(entry),
+ 1, 0, 1, 1,
+ 1, uiAlignFill, 0, uiAlignFill);
+
+ button = uiNewButton("Save File");
+ entry = uiNewEntry();
+ uiEntrySetReadOnly(entry, 1);
+ uiButtonOnClicked(button, onSaveFileClicked, entry);
+ uiGridAppend(grid, uiControl(button),
+ 0, 1, 1, 1,
+ 0, uiAlignFill, 0, uiAlignFill);
+ uiGridAppend(grid, uiControl(entry),
+ 1, 1, 1, 1,
+ 1, uiAlignFill, 0, uiAlignFill);
+
+ msggrid = uiNewGrid();
+ uiGridSetPadded(msggrid, 1);
+ uiGridAppend(grid, uiControl(msggrid),
+ 0, 2, 2, 1,
+ 0, uiAlignCenter, 0, uiAlignStart);
+
+ button = uiNewButton("Message Box");
+ uiButtonOnClicked(button, onMsgBoxClicked, NULL);
+ uiGridAppend(msggrid, uiControl(button),
+ 0, 0, 1, 1,
+ 0, uiAlignFill, 0, uiAlignFill);
+ button = uiNewButton("Error Box");
+ uiButtonOnClicked(button, onMsgBoxErrorClicked, NULL);
+ uiGridAppend(msggrid, uiControl(button),
+ 1, 0, 1, 1,
+ 0, uiAlignFill, 0, uiAlignFill);
+
+ return uiControl(hbox);
+}
+
+int main(void)
+{
+ uiInitOptions options;
+ const char *err;
+ uiTab *tab;
+
+ memset(&options, 0, sizeof (uiInitOptions));
+ err = uiInit(&options);
+ if (err != NULL) {
+ fprintf(stderr, "error initializing libui: %s", err);
+ uiFreeInitError(err);
+ return 1;
+ }
+
+ mainwin = uiNewWindow("libui Control Gallery", 640, 480, 1);
+ uiWindowOnClosing(mainwin, onClosing, NULL);
+ uiOnShouldQuit(onShouldQuit, mainwin);
+
+ tab = uiNewTab();
+ uiWindowSetChild(mainwin, uiControl(tab));
+ uiWindowSetMargined(mainwin, 1);
+
+ uiTabAppend(tab, "Basic Controls", makeBasicControlsPage());
+ uiTabSetMargined(tab, 0, 1);
+
+ uiTabAppend(tab, "Numbers and Lists", makeNumbersPage());
+ uiTabSetMargined(tab, 1, 1);
+
+ uiTabAppend(tab, "Data Choosers", makeDataChoosersPage());
+ uiTabSetMargined(tab, 2, 1);
+
+ uiControlShow(uiControl(mainwin));
+ uiMain();
+ return 0;
+}
+
+#if 0
+
+static void openClicked(uiMenuItem *item, uiWindow *w, void *data)
+{
+ char *filename;
+
+ filename = uiOpenFile(mainwin);
+ if (filename == NULL) {
+ uiMsgBoxError(mainwin, "No file selected", "Don't be alarmed!");
+ return;
+ }
+ uiMsgBox(mainwin, "File selected", filename);
+ uiFreeText(filename);
+}
+
+static void saveClicked(uiMenuItem *item, uiWindow *w, void *data)
+{
+ char *filename;
+
+ filename = uiSaveFile(mainwin);
+ if (filename == NULL) {
+ uiMsgBoxError(mainwin, "No file selected", "Don't be alarmed!");
+ return;
+ }
+ uiMsgBox(mainwin, "File selected (don't worry, it's still there)", filename);
+ uiFreeText(filename);
+}
+
+static uiSpinbox *spinbox;
+static uiSlider *slider;
+static uiProgressBar *progressbar;
+
+static void update(int value)
+{
+ uiSpinboxSetValue(spinbox, value);
+ uiSliderSetValue(slider, value);
+ uiProgressBarSetValue(progressbar, value);
+}
+
+static void onSpinboxChanged(uiSpinbox *s, void *data)
+{
+ update(uiSpinboxValue(spinbox));
+}
+
+static void onSliderChanged(uiSlider *s, void *data)
+{
+ update(uiSliderValue(slider));
+}
+
+int main(void)
+{
+ uiInitOptions o;
+ const char *err;
+ uiMenu *menu;
+ uiMenuItem *item;
+ uiBox *box;
+ uiBox *hbox;
+ uiGroup *group;
+ uiBox *inner;
+ uiBox *inner2;
+ uiEntry *entry;
+ uiCombobox *cbox;
+ uiEditableCombobox *ecbox;
+ uiRadioButtons *rb;
+ uiTab *tab;
+
+ memset(&o, 0, sizeof (uiInitOptions));
+ err = uiInit(&o);
+ if (err != NULL) {
+ fprintf(stderr, "error initializing ui: %s\n", err);
+ uiFreeInitError(err);
+ return 1;
+ }
+
+ menu = uiNewMenu("File");
+ item = uiMenuAppendItem(menu, "Open");
+ uiMenuItemOnClicked(item, openClicked, NULL);
+ item = uiMenuAppendItem(menu, "Save");
+ uiMenuItemOnClicked(item, saveClicked, NULL);
+ item = uiMenuAppendQuitItem(menu);
+ uiOnShouldQuit(shouldQuit, NULL);
+
+ menu = uiNewMenu("Edit");
+ item = uiMenuAppendCheckItem(menu, "Checkable Item");
+ uiMenuAppendSeparator(menu);
+ item = uiMenuAppendItem(menu, "Disabled Item");
+ uiMenuItemDisable(item);
+ item = uiMenuAppendPreferencesItem(menu);
+
+ menu = uiNewMenu("Help");
+ item = uiMenuAppendItem(menu, "Help");
+ item = uiMenuAppendAboutItem(menu);
+
+ mainwin = uiNewWindow("libui Control Gallery", 640, 480, 1);
+ uiWindowSetMargined(mainwin, 1);
+ uiWindowOnClosing(mainwin, onClosing, NULL);
+
+ box = uiNewVerticalBox();
+ uiBoxSetPadded(box, 1);
+ uiWindowSetChild(mainwin, uiControl(box));
+
+ hbox = uiNewHorizontalBox();
+ uiBoxSetPadded(hbox, 1);
+ uiBoxAppend(box, uiControl(hbox), 1);
+
+ group = uiNewGroup("Basic Controls");
+ uiGroupSetMargined(group, 1);
+ uiBoxAppend(hbox, uiControl(group), 0);
+
+ inner = uiNewVerticalBox();
+ uiBoxSetPadded(inner, 1);
+ uiGroupSetChild(group, uiControl(inner));
+
+ uiBoxAppend(inner,
+ uiControl(uiNewButton("Button")),
+ 0);
+ uiBoxAppend(inner,
+ uiControl(uiNewCheckbox("Checkbox")),
+ 0);
+ entry = uiNewEntry();
+ uiEntrySetText(entry, "Entry");
+ uiBoxAppend(inner,
+ uiControl(entry),
+ 0);
+ uiBoxAppend(inner,
+ uiControl(uiNewLabel("Label")),
+ 0);
+
+ uiBoxAppend(inner,
+ uiControl(uiNewHorizontalSeparator()),
+ 0);
+
+ uiBoxAppend(inner,
+ uiControl(uiNewDatePicker()),
+ 0);
+ uiBoxAppend(inner,
+ uiControl(uiNewTimePicker()),
+ 0);
+ uiBoxAppend(inner,
+ uiControl(uiNewDateTimePicker()),
+ 0);
+
+ uiBoxAppend(inner,
+ uiControl(uiNewFontButton()),
+ 0);
+
+ uiBoxAppend(inner,
+ uiControl(uiNewColorButton()),
+ 0);
+
+ inner2 = uiNewVerticalBox();
+ uiBoxSetPadded(inner2, 1);
+ uiBoxAppend(hbox, uiControl(inner2), 1);
+
+ group = uiNewGroup("Numbers");
+ uiGroupSetMargined(group, 1);
+ uiBoxAppend(inner2, uiControl(group), 0);
+
+ inner = uiNewVerticalBox();
+ uiBoxSetPadded(inner, 1);
+ uiGroupSetChild(group, uiControl(inner));
+
+ spinbox = uiNewSpinbox(0, 100);
+ uiSpinboxOnChanged(spinbox, onSpinboxChanged, NULL);
+ uiBoxAppend(inner, uiControl(spinbox), 0);
+
+ slider = uiNewSlider(0, 100);
+ uiSliderOnChanged(slider, onSliderChanged, NULL);
+ uiBoxAppend(inner, uiControl(slider), 0);
+
+ progressbar = uiNewProgressBar();
+ uiBoxAppend(inner, uiControl(progressbar), 0);
+
+ group = uiNewGroup("Lists");
+ uiGroupSetMargined(group, 1);
+ uiBoxAppend(inner2, uiControl(group), 0);
+
+ inner = uiNewVerticalBox();
+ uiBoxSetPadded(inner, 1);
+ uiGroupSetChild(group, uiControl(inner));
+
+ cbox = uiNewCombobox();
+ uiComboboxAppend(cbox, "Combobox Item 1");
+ uiComboboxAppend(cbox, "Combobox Item 2");
+ uiComboboxAppend(cbox, "Combobox Item 3");
+ uiBoxAppend(inner, uiControl(cbox), 0);
+
+ ecbox = uiNewEditableCombobox();
+ uiEditableComboboxAppend(ecbox, "Editable Item 1");
+ uiEditableComboboxAppend(ecbox, "Editable Item 2");
+ uiEditableComboboxAppend(ecbox, "Editable Item 3");
+ uiBoxAppend(inner, uiControl(ecbox), 0);
+
+ rb = uiNewRadioButtons();
+ uiRadioButtonsAppend(rb, "Radio Button 1");
+ uiRadioButtonsAppend(rb, "Radio Button 2");
+ uiRadioButtonsAppend(rb, "Radio Button 3");
+ uiBoxAppend(inner, uiControl(rb), 1);
+
+ tab = uiNewTab();
+ uiTabAppend(tab, "Page 1", uiControl(uiNewHorizontalBox()));
+ uiTabAppend(tab, "Page 2", uiControl(uiNewHorizontalBox()));
+ uiTabAppend(tab, "Page 3", uiControl(uiNewHorizontalBox()));
+ uiBoxAppend(inner2, uiControl(tab), 1);
+
+ uiControlShow(uiControl(mainwin));
+ uiMain();
+ uiUninit();
+ return 0;
+}
+
+#endif
diff --git a/src/libui_sdl/libui/examples/controlgallery/unix.png b/src/libui_sdl/libui/examples/controlgallery/unix.png
new file mode 100644
index 0000000..0c58d09
--- /dev/null
+++ b/src/libui_sdl/libui/examples/controlgallery/unix.png
Binary files differ
diff --git a/src/libui_sdl/libui/examples/controlgallery/windows.png b/src/libui_sdl/libui/examples/controlgallery/windows.png
new file mode 100644
index 0000000..4be832f
--- /dev/null
+++ b/src/libui_sdl/libui/examples/controlgallery/windows.png
Binary files differ
diff --git a/src/libui_sdl/libui/examples/cpp-multithread/main.cpp b/src/libui_sdl/libui/examples/cpp-multithread/main.cpp
new file mode 100644
index 0000000..f97bc6f
--- /dev/null
+++ b/src/libui_sdl/libui/examples/cpp-multithread/main.cpp
@@ -0,0 +1,92 @@
+// 6 december 2015
+#include <thread>
+#include <chrono>
+#include <mutex>
+#include <condition_variable>
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+#include "../../ui.h"
+using namespace std;
+
+uiMultilineEntry *e;
+condition_variable cv;
+mutex m;
+unique_lock<mutex> ourlock(m);
+thread *timeThread;
+
+void sayTime(void *data)
+{
+ char *s = (char *) data;
+
+ uiMultilineEntryAppend(e, s);
+ delete s;
+}
+
+void threadproc(void)
+{
+ ourlock.lock();
+ while (cv.wait_for(ourlock, chrono::seconds(1)) == cv_status::timeout) {
+ time_t t;
+ char *base;
+ char *s;
+
+ t = time(NULL);
+ base = ctime(&t);
+ s = new char[strlen(base) + 1];
+ strcpy(s, base);
+ uiQueueMain(sayTime, s);
+ }
+}
+
+int onClosing(uiWindow *w, void *data)
+{
+ cv.notify_all();
+ // C++ throws a hissy fit if you don't do this
+ // we might as well, to ensure no uiQueueMain() gets in after uiQuit()
+ timeThread->join();
+ uiQuit();
+ return 1;
+}
+
+void saySomething(uiButton *b, void *data)
+{
+ uiMultilineEntryAppend(e, "Saying something\n");
+}
+
+int main(void)
+{
+ uiInitOptions o;
+ uiWindow *w;
+ uiBox *b;
+ uiButton *btn;
+
+ memset(&o, 0, sizeof (uiInitOptions));
+ if (uiInit(&o) != NULL)
+ abort();
+
+ w = uiNewWindow("Hello", 320, 240, 0);
+ uiWindowSetMargined(w, 1);
+
+ b = uiNewVerticalBox();
+ uiBoxSetPadded(b, 1);
+ uiWindowSetChild(w, uiControl(b));
+
+ e = uiNewMultilineEntry();
+ uiMultilineEntrySetReadOnly(e, 1);
+
+ btn = uiNewButton("Say Something");
+ uiButtonOnClicked(btn, saySomething, NULL);
+ uiBoxAppend(b, uiControl(btn), 0);
+
+ uiBoxAppend(b, uiControl(e), 1);
+
+ // timeThread needs to lock ourlock itself - see http://stackoverflow.com/a/34121629/3408572
+ ourlock.unlock();
+ timeThread = new thread(threadproc);
+
+ uiWindowOnClosing(w, onClosing, NULL);
+ uiControlShow(uiControl(w));
+ uiMain();
+ return 0;
+}
diff --git a/src/libui_sdl/libui/examples/example.manifest b/src/libui_sdl/libui/examples/example.manifest
new file mode 100644
index 0000000..41e7c9c
--- /dev/null
+++ b/src/libui_sdl/libui/examples/example.manifest
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+<assemblyIdentity
+ version="1.0.0.0"
+ processorArchitecture="*"
+ name="CompanyName.ProductName.YourApplication"
+ type="win32"
+/>
+<description>Your application description here.</description>
+<!-- do NOT include the comctl6 dependency here; this lets us find bugs related to theming -->
+<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
+ <application>
+ <!--The ID below indicates application support for Windows Vista -->
+ <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
+ <!--The ID below indicates application support for Windows 7 -->
+ <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
+ </application>
+</compatibility>
+</assembly>
+
diff --git a/src/libui_sdl/libui/examples/example.static.manifest b/src/libui_sdl/libui/examples/example.static.manifest
new file mode 100644
index 0000000..d8e83a8
--- /dev/null
+++ b/src/libui_sdl/libui/examples/example.static.manifest
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+<assemblyIdentity
+ version="1.0.0.0"
+ processorArchitecture="*"
+ name="CompanyName.ProductName.YourApplication"
+ type="win32"
+/>
+<description>Your application description here.</description>
+<!-- we DO need comctl6 in the static case -->
+<dependency>
+ <dependentAssembly>
+ <assemblyIdentity
+ type="win32"
+ name="Microsoft.Windows.Common-Controls"
+ version="6.0.0.0"
+ processorArchitecture="*"
+ publicKeyToken="6595b64144ccf1df"
+ language="*"
+ />
+ </dependentAssembly>
+</dependency>
+<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
+ <application>
+ <!--The ID below indicates application support for Windows Vista -->
+ <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
+ <!--The ID below indicates application support for Windows 7 -->
+ <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
+ </application>
+</compatibility>
+</assembly>
+
diff --git a/src/libui_sdl/libui/examples/histogram/main.c b/src/libui_sdl/libui/examples/histogram/main.c
new file mode 100644
index 0000000..f2b0e79
--- /dev/null
+++ b/src/libui_sdl/libui/examples/histogram/main.c
@@ -0,0 +1,309 @@
+// 13 october 2015
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+#include "../../ui.h"
+
+uiWindow *mainwin;
+uiArea *histogram;
+uiAreaHandler handler;
+uiSpinbox *datapoints[10];
+uiColorButton *colorButton;
+int currentPoint = -1;
+
+// some metrics
+#define xoffLeft 20 /* histogram margins */
+#define yoffTop 20
+#define xoffRight 20
+#define yoffBottom 20
+#define pointRadius 5
+
+// helper to quickly set a brush color
+static void setSolidBrush(uiDrawBrush *brush, uint32_t color, double alpha)
+{
+ uint8_t component;
+
+ brush->Type = uiDrawBrushTypeSolid;
+ component = (uint8_t) ((color >> 16) & 0xFF);
+ brush->R = ((double) component) / 255;
+ component = (uint8_t) ((color >> 8) & 0xFF);
+ brush->G = ((double) component) / 255;
+ component = (uint8_t) (color & 0xFF);
+ brush->B = ((double) component) / 255;
+ brush->A = alpha;
+}
+
+// and some colors
+// names and values from https://msdn.microsoft.com/en-us/library/windows/desktop/dd370907%28v=vs.85%29.aspx
+#define colorWhite 0xFFFFFF
+#define colorBlack 0x000000
+#define colorDodgerBlue 0x1E90FF
+
+static void pointLocations(double width, double height, double *xs, double *ys)
+{
+ double xincr, yincr;
+ int i, n;
+
+ xincr = width / 9; // 10 - 1 to make the last point be at the end
+ yincr = height / 100;
+
+ for (i = 0; i < 10; i++) {
+ // get the value of the point
+ n = uiSpinboxValue(datapoints[i]);
+ // because y=0 is the top but n=0 is the bottom, we need to flip
+ n = 100 - n;
+ xs[i] = xincr * i;
+ ys[i] = yincr * n;
+ }
+}
+
+static uiDrawPath *constructGraph(double width, double height, int extend)
+{
+ uiDrawPath *path;
+ double xs[10], ys[10];
+ int i;
+
+ pointLocations(width, height, xs, ys);
+
+ path = uiDrawNewPath(uiDrawFillModeWinding);
+
+ uiDrawPathNewFigure(path, xs[0], ys[0]);
+ for (i = 1; i < 10; i++)
+ uiDrawPathLineTo(path, xs[i], ys[i]);
+
+ if (extend) {
+ uiDrawPathLineTo(path, width, height);
+ uiDrawPathLineTo(path, 0, height);
+ uiDrawPathCloseFigure(path);
+ }
+
+ uiDrawPathEnd(path);
+ return path;
+}
+
+static void graphSize(double clientWidth, double clientHeight, double *graphWidth, double *graphHeight)
+{
+ *graphWidth = clientWidth - xoffLeft - xoffRight;
+ *graphHeight = clientHeight - yoffTop - yoffBottom;
+}
+
+static void handlerDraw(uiAreaHandler *a, uiArea *area, uiAreaDrawParams *p)
+{
+ uiDrawPath *path;
+ uiDrawBrush brush;
+ uiDrawStrokeParams sp;
+ uiDrawMatrix m;
+ double graphWidth, graphHeight;
+ double graphR, graphG, graphB, graphA;
+
+ // fill the area with white
+ setSolidBrush(&brush, colorWhite, 1.0);
+ path = uiDrawNewPath(uiDrawFillModeWinding);
+ uiDrawPathAddRectangle(path, 0, 0, p->AreaWidth, p->AreaHeight);
+ uiDrawPathEnd(path);
+ uiDrawFill(p->Context, path, &brush);
+ uiDrawFreePath(path);
+
+ // figure out dimensions
+ graphSize(p->AreaWidth, p->AreaHeight, &graphWidth, &graphHeight);
+
+ // clear sp to avoid passing garbage to uiDrawStroke()
+ // for example, we don't use dashing
+ memset(&sp, 0, sizeof (uiDrawStrokeParams));
+
+ // make a stroke for both the axes and the histogram line
+ sp.Cap = uiDrawLineCapFlat;
+ sp.Join = uiDrawLineJoinMiter;
+ sp.Thickness = 2;
+ sp.MiterLimit = uiDrawDefaultMiterLimit;
+
+ // draw the axes
+ setSolidBrush(&brush, colorBlack, 1.0);
+ path = uiDrawNewPath(uiDrawFillModeWinding);
+ uiDrawPathNewFigure(path,
+ xoffLeft, yoffTop);
+ uiDrawPathLineTo(path,
+ xoffLeft, yoffTop + graphHeight);
+ uiDrawPathLineTo(path,
+ xoffLeft + graphWidth, yoffTop + graphHeight);
+ uiDrawPathEnd(path);
+ uiDrawStroke(p->Context, path, &brush, &sp);
+ uiDrawFreePath(path);
+
+ // now transform the coordinate space so (0, 0) is the top-left corner of the graph
+ uiDrawMatrixSetIdentity(&m);
+ uiDrawMatrixTranslate(&m, xoffLeft, yoffTop);
+ uiDrawTransform(p->Context, &m);
+
+ // now get the color for the graph itself and set up the brush
+ uiColorButtonColor(colorButton, &graphR, &graphG, &graphB, &graphA);
+ brush.Type = uiDrawBrushTypeSolid;
+ brush.R = graphR;
+ brush.G = graphG;
+ brush.B = graphB;
+ // we set brush->A below to different values for the fill and stroke
+
+ // now create the fill for the graph below the graph line
+ path = constructGraph(graphWidth, graphHeight, 1);
+ brush.A = graphA / 2;
+ uiDrawFill(p->Context, path, &brush);
+ uiDrawFreePath(path);
+
+ // now draw the histogram line
+ path = constructGraph(graphWidth, graphHeight, 0);
+ brush.A = graphA;
+ uiDrawStroke(p->Context, path, &brush, &sp);
+ uiDrawFreePath(path);
+
+ // now draw the point being hovered over
+ if (currentPoint != -1) {
+ double xs[10], ys[10];
+
+ pointLocations(graphWidth, graphHeight, xs, ys);
+ path = uiDrawNewPath(uiDrawFillModeWinding);
+ uiDrawPathNewFigureWithArc(path,
+ xs[currentPoint], ys[currentPoint],
+ pointRadius,
+ 0, 6.23, // TODO pi
+ 0);
+ uiDrawPathEnd(path);
+ // use the same brush as for the histogram lines
+ uiDrawFill(p->Context, path, &brush);
+ uiDrawFreePath(path);
+ }
+}
+
+static int inPoint(double x, double y, double xtest, double ytest)
+{
+ // TODO switch to using a matrix
+ x -= xoffLeft;
+ y -= yoffTop;
+ return (x >= xtest - pointRadius) &&
+ (x <= xtest + pointRadius) &&
+ (y >= ytest - pointRadius) &&
+ (y <= ytest + pointRadius);
+}
+
+static void handlerMouseEvent(uiAreaHandler *a, uiArea *area, uiAreaMouseEvent *e)
+{
+ double graphWidth, graphHeight;
+ double xs[10], ys[10];
+ int i;
+
+ graphSize(e->AreaWidth, e->AreaHeight, &graphWidth, &graphHeight);
+ pointLocations(graphWidth, graphHeight, xs, ys);
+
+ for (i = 0; i < 10; i++)
+ if (inPoint(e->X, e->Y, xs[i], ys[i]))
+ break;
+ if (i == 10) // not in a point
+ i = -1;
+
+ currentPoint = i;
+ // TODO only redraw the relevant area
+ uiAreaQueueRedrawAll(histogram);
+}
+
+static void handlerMouseCrossed(uiAreaHandler *ah, uiArea *a, int left)
+{
+ // do nothing
+}
+
+static void handlerDragBroken(uiAreaHandler *ah, uiArea *a)
+{
+ // do nothing
+}
+
+static int handlerKeyEvent(uiAreaHandler *ah, uiArea *a, uiAreaKeyEvent *e)
+{
+ // reject all keys
+ return 0;
+}
+
+static void onDatapointChanged(uiSpinbox *s, void *data)
+{
+ uiAreaQueueRedrawAll(histogram);
+}
+
+static void onColorChanged(uiColorButton *b, void *data)
+{
+ uiAreaQueueRedrawAll(histogram);
+}
+
+static int onClosing(uiWindow *w, void *data)
+{
+ uiControlDestroy(uiControl(mainwin));
+ uiQuit();
+ return 0;
+}
+
+static int shouldQuit(void *data)
+{
+ uiControlDestroy(uiControl(mainwin));
+ return 1;
+}
+
+int main(void)
+{
+ uiInitOptions o;
+ const char *err;
+ uiBox *hbox, *vbox;
+ int i;
+ uiDrawBrush brush;
+
+ handler.Draw = handlerDraw;
+ handler.MouseEvent = handlerMouseEvent;
+ handler.MouseCrossed = handlerMouseCrossed;
+ handler.DragBroken = handlerDragBroken;
+ handler.KeyEvent = handlerKeyEvent;
+
+ memset(&o, 0, sizeof (uiInitOptions));
+ err = uiInit(&o);
+ if (err != NULL) {
+ fprintf(stderr, "error initializing ui: %s\n", err);
+ uiFreeInitError(err);
+ return 1;
+ }
+
+ uiOnShouldQuit(shouldQuit, NULL);
+
+ mainwin = uiNewWindow("libui Histogram Example", 640, 480, 1);
+ uiWindowSetMargined(mainwin, 1);
+ uiWindowOnClosing(mainwin, onClosing, NULL);
+
+ hbox = uiNewHorizontalBox();
+ uiBoxSetPadded(hbox, 1);
+ uiWindowSetChild(mainwin, uiControl(hbox));
+
+ vbox = uiNewVerticalBox();
+ uiBoxSetPadded(vbox, 1);
+ uiBoxAppend(hbox, uiControl(vbox), 0);
+
+ srand(time(NULL));
+ for (i = 0; i < 10; i++) {
+ datapoints[i] = uiNewSpinbox(0, 100);
+ uiSpinboxSetValue(datapoints[i], rand() % 101);
+ uiSpinboxOnChanged(datapoints[i], onDatapointChanged, NULL);
+ uiBoxAppend(vbox, uiControl(datapoints[i]), 0);
+ }
+
+ colorButton = uiNewColorButton();
+ // TODO inline these
+ setSolidBrush(&brush, colorDodgerBlue, 1.0);
+ uiColorButtonSetColor(colorButton,
+ brush.R,
+ brush.G,
+ brush.B,
+ brush.A);
+ uiColorButtonOnChanged(colorButton, onColorChanged, NULL);
+ uiBoxAppend(vbox, uiControl(colorButton), 0);
+
+ histogram = uiNewArea(&handler);
+ uiBoxAppend(hbox, uiControl(histogram), 1);
+
+ uiControlShow(uiControl(mainwin));
+ uiMain();
+ uiUninit();
+ return 0;
+}
diff --git a/src/libui_sdl/libui/examples/resources.rc b/src/libui_sdl/libui/examples/resources.rc
new file mode 100644
index 0000000..49f486c
--- /dev/null
+++ b/src/libui_sdl/libui/examples/resources.rc
@@ -0,0 +1,13 @@
+// 30 may 2015
+
+// this is a UTF-8 file
+#pragma code_page(65001)
+
+// this is the Common Controls 6 manifest
+// TODO set up the string values here
+// 1 is the value of CREATEPROCESS_MANIFEST_RESOURCE_ID and 24 is the value of RT_MANIFEST; we use it directly to avoid needing to share winapi.h with the tests and examples
+#ifndef _UI_STATIC
+1 24 "example.manifest"
+#else
+1 24 "example.static.manifest"
+#endif