another UI attempt, I guess.

sorry.
This commit is contained in:
StapleButter
2017-09-09 02:30:51 +02:00
parent 81747d6c34
commit 70e4841d31
244 changed files with 35965 additions and 0 deletions

View File

@ -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)

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View File

@ -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;
}

View File

@ -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>

View File

@ -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>

View File

@ -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;
}

View File

@ -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