Decided not to bother with winforms either.
This commit is contained in:
parent
284c96a72a
commit
923c4c091e
|
@ -1,93 +0,0 @@
|
||||||
// 4 december 2014
|
|
||||||
#ifdef __cplusplus
|
|
||||||
#error msbuild is being dumb and making this a C++ file
|
|
||||||
#endif
|
|
||||||
#include "unmanaged.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
// wrappers for allocator of choice
|
|
||||||
// panics on memory exhausted, undefined on heap corruption or other unreliably-detected malady (see http://stackoverflow.com/questions/28761680/is-there-a-windows-api-memory-allocator-deallocator-i-can-use-that-will-just-giv)
|
|
||||||
// new memory is set to zero
|
|
||||||
// passing NULL to tableRealloc() acts like tableAlloc()
|
|
||||||
// passing NULL to tableFree() is a no-op
|
|
||||||
|
|
||||||
static HANDLE heap;
|
|
||||||
|
|
||||||
int initAlloc(void)
|
|
||||||
{
|
|
||||||
heap = HeapCreate(0, 0, 0);
|
|
||||||
return heap != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define UINT8(p) ((uint8_t *) (p))
|
|
||||||
#define PVOID(p) ((void *) (p))
|
|
||||||
#define EXTRA (sizeof (const char **))
|
|
||||||
#define DATA(p) PVOID(UINT8(p) + EXTRA)
|
|
||||||
#define BASE(p) PVOID(UINT8(p) - EXTRA)
|
|
||||||
#define CCHAR(p) ((const char **) (p))
|
|
||||||
#define TYPE(p) CCHAR(UINT8(p))
|
|
||||||
|
|
||||||
void uninitAlloc(void)
|
|
||||||
{
|
|
||||||
BOOL hasEntry;
|
|
||||||
PROCESS_HEAP_ENTRY phe;
|
|
||||||
DWORD le;
|
|
||||||
|
|
||||||
hasEntry = FALSE;
|
|
||||||
ZeroMemory(&phe, sizeof (PROCESS_HEAP_ENTRY));
|
|
||||||
while (HeapWalk(heap, &phe) != 0) {
|
|
||||||
// skip non-allocations
|
|
||||||
if ((phe.wFlags & PROCESS_HEAP_ENTRY_BUSY) == 0)
|
|
||||||
continue;
|
|
||||||
if (!hasEntry) {
|
|
||||||
fprintf(stderr, "[libui] leaked allocations:\n");
|
|
||||||
hasEntry = TRUE;
|
|
||||||
}
|
|
||||||
fprintf(stderr, "[libui] %p %s\n", phe.lpData, *TYPE(phe.lpData));
|
|
||||||
}
|
|
||||||
le = GetLastError();
|
|
||||||
SetLastError(le); // just in case
|
|
||||||
if (le != ERROR_NO_MORE_ITEMS)
|
|
||||||
logLastError("error walking heap in uninitAlloc()");
|
|
||||||
if (hasEntry)
|
|
||||||
complain("either you left something around or there's a bug in libui");
|
|
||||||
if (HeapDestroy(heap) == 0)
|
|
||||||
logLastError("error destroying heap in uninitAlloc()");
|
|
||||||
}
|
|
||||||
|
|
||||||
void *uiAlloc(size_t size, const char *type)
|
|
||||||
{
|
|
||||||
void *out;
|
|
||||||
|
|
||||||
out = HeapAlloc(heap, HEAP_ZERO_MEMORY, EXTRA + size);
|
|
||||||
if (out == NULL) {
|
|
||||||
fprintf(stderr, "memory exhausted in uiAlloc()\n");
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
*TYPE(out) = type;
|
|
||||||
return DATA(out);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *uiRealloc(void *p, size_t size, const char *type)
|
|
||||||
{
|
|
||||||
void *out;
|
|
||||||
|
|
||||||
if (p == NULL)
|
|
||||||
return uiAlloc(size, type);
|
|
||||||
p = BASE(p);
|
|
||||||
out = HeapReAlloc(heap, HEAP_ZERO_MEMORY, p, EXTRA + size);
|
|
||||||
if (out == NULL) {
|
|
||||||
fprintf(stderr, "memory exhausted in uiRealloc()\n");
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
return DATA(out);
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiFree(void *p)
|
|
||||||
{
|
|
||||||
if (p == NULL)
|
|
||||||
complain("attempt to uiFree(NULL); there's a bug somewhere");
|
|
||||||
p = BASE(p);
|
|
||||||
if (HeapFree(heap, 0, p) == 0)
|
|
||||||
logLastError("error freeing memory in uiFree()");
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
// 26 november 2015
|
|
||||||
#include "uipriv_winforms.hpp"
|
|
||||||
|
|
||||||
struct uiArea {
|
|
||||||
uiWindowsControl c;
|
|
||||||
DUMMY dummy;
|
|
||||||
uiAreaHandler *ah;
|
|
||||||
};
|
|
||||||
|
|
||||||
uiWindowsDefineControl(
|
|
||||||
uiArea, // type name
|
|
||||||
uiAreaType, // type function
|
|
||||||
dummy // handle
|
|
||||||
)
|
|
||||||
|
|
||||||
void uiAreaUpdateScroll(uiArea *a)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiAreaQueueRedrawAll(uiArea *a)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
uiArea *uiNewArea(uiAreaHandler *ah)
|
|
||||||
{
|
|
||||||
uiArea *a;
|
|
||||||
|
|
||||||
a = (uiArea *) uiNewControl(uiAreaType());
|
|
||||||
|
|
||||||
a->ah = ah;
|
|
||||||
|
|
||||||
a->dummy = mkdummy(L"uiArea");
|
|
||||||
|
|
||||||
uiWindowsFinishNewControl(a, uiArea, dummy);
|
|
||||||
|
|
||||||
return a;
|
|
||||||
}
|
|
195
winforms/box.cpp
195
winforms/box.cpp
|
@ -1,195 +0,0 @@
|
||||||
// 26 november 2015
|
|
||||||
#include "uipriv_winforms.hpp"
|
|
||||||
|
|
||||||
using namespace System::Collections::Generic;
|
|
||||||
|
|
||||||
// TODO
|
|
||||||
// - save Alignment of children?
|
|
||||||
// - SnapsToDevicePixels? http://stackoverflow.com/questions/10718985/grid-border-gap-between-cells
|
|
||||||
|
|
||||||
ref class boxChild {
|
|
||||||
public:
|
|
||||||
uiControl *c;
|
|
||||||
Border ^border;
|
|
||||||
int stretchy;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct uiBox {
|
|
||||||
uiWindowsControl c;
|
|
||||||
// we could've used StackPanel but that doesn't care about available size
|
|
||||||
gcroot<Grid ^> *grid;
|
|
||||||
gcroot<List<boxChild ^> ^> *children;
|
|
||||||
int vertical;
|
|
||||||
int padded;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void onDestroy(uiBox *b);
|
|
||||||
|
|
||||||
uiWindowsDefineControlWithOnDestroy(
|
|
||||||
uiBox, // type name
|
|
||||||
uiBoxType, // type function
|
|
||||||
grid, // handle
|
|
||||||
onDestroy(hthis); // on destroy
|
|
||||||
)
|
|
||||||
|
|
||||||
static void onDestroy(uiBox *b)
|
|
||||||
{
|
|
||||||
List<boxChild ^> ^children;
|
|
||||||
|
|
||||||
children = *(b->children);
|
|
||||||
while (children->Count != 0) {
|
|
||||||
children[0]->border->Child = nullptr;
|
|
||||||
uiControlSetParent(children[0]->c, NULL);
|
|
||||||
uiControlDestroy(children[0]->c);
|
|
||||||
children->RemoveAt(0);
|
|
||||||
}
|
|
||||||
delete b->children;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void boxContainerUpdateState(uiControl *c)
|
|
||||||
{
|
|
||||||
uiBox *b = uiBox(c);
|
|
||||||
List<boxChild ^> ^children;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
children = *(b->children);
|
|
||||||
for (i = 0; i < children->Count; i++)
|
|
||||||
controlUpdateState(children[i]->c);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Grid unfortunately does not have a way to set the spacing between rows and columns.
|
|
||||||
// This means we have to do padding ourselves.
|
|
||||||
// TODO this doesn't work right for visibility purposes
|
|
||||||
static void resetMargins(uiBox *b)
|
|
||||||
{
|
|
||||||
double paddingUnit;
|
|
||||||
Thickness first;
|
|
||||||
Thickness after;
|
|
||||||
List<boxChild ^> ^children;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
children = *(b->children);
|
|
||||||
if (children->Count == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
paddingUnit = 0;
|
|
||||||
if (b->padded)
|
|
||||||
paddingUnit = 5;
|
|
||||||
first = Thickness(0, 0, 0, 0);
|
|
||||||
after = Thickness(paddingUnit, 0, 0, 0);
|
|
||||||
if (b->vertical)
|
|
||||||
after = Thickness(0, paddingUnit, 0, 0);
|
|
||||||
|
|
||||||
// TODO padding?
|
|
||||||
children[0]->border->Margin = first;
|
|
||||||
for (i = 1; i < children->Count; i++)
|
|
||||||
children[i]->border->Margin = after;
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiBoxAppend(uiBox *b, uiControl *c, int stretchy)
|
|
||||||
{
|
|
||||||
Grid ^g;
|
|
||||||
boxChild ^bc;
|
|
||||||
int pos;
|
|
||||||
|
|
||||||
bc = gcnew boxChild();
|
|
||||||
bc->c = c;
|
|
||||||
bc->border = gcnew Border();
|
|
||||||
bc->stretchy = stretchy;
|
|
||||||
|
|
||||||
bc->border->Child = genericHandle(bc->c);
|
|
||||||
|
|
||||||
g = *(b->grid);
|
|
||||||
|
|
||||||
// get position before adding the child so that we get the right count value
|
|
||||||
pos = g->ColumnDefinitions->Count;
|
|
||||||
if (b->vertical)
|
|
||||||
pos = g->RowDefinitions->Count;
|
|
||||||
|
|
||||||
g->Children->Add(bc->border);
|
|
||||||
|
|
||||||
if (b->vertical) {
|
|
||||||
g->SetRow(bc->border, pos);
|
|
||||||
g->SetColumn(bc->border, 0);
|
|
||||||
// apparently we have to do this ourselves...
|
|
||||||
g->RowDefinitions->Add(gcnew RowDefinition());
|
|
||||||
if (bc->stretchy)
|
|
||||||
g->RowDefinitions[pos]->Height = GridLength(1, GridUnitType::Star);
|
|
||||||
else
|
|
||||||
g->RowDefinitions[pos]->Height = GridLength(1, GridUnitType::Auto);
|
|
||||||
} else {
|
|
||||||
g->SetRow(bc->border, 0);
|
|
||||||
g->SetColumn(bc->border, pos);
|
|
||||||
g->ColumnDefinitions->Add(gcnew ColumnDefinition());
|
|
||||||
if (bc->stretchy)
|
|
||||||
g->ColumnDefinitions[pos]->Width = GridLength(1, GridUnitType::Star);
|
|
||||||
else
|
|
||||||
g->ColumnDefinitions[pos]->Width = GridLength(1, GridUnitType::Auto);
|
|
||||||
}
|
|
||||||
|
|
||||||
uiControlSetParent(bc->c, uiControl(b));
|
|
||||||
(*(b->children))->Add(bc);
|
|
||||||
resetMargins(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiBoxDelete(uiBox *b, uintmax_t index)
|
|
||||||
{
|
|
||||||
boxChild ^bc;
|
|
||||||
List<boxChild ^> ^children;
|
|
||||||
|
|
||||||
children = *(b->children);
|
|
||||||
bc = children[index];
|
|
||||||
children->RemoveAt(index);
|
|
||||||
uiControlSetParent(bc->c, NULL);
|
|
||||||
bc->border->Child = nullptr;
|
|
||||||
(*(b->grid))->Children->RemoveAt(index);
|
|
||||||
resetMargins(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
int uiBoxPadded(uiBox *b)
|
|
||||||
{
|
|
||||||
return b->padded;
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiBoxSetPadded(uiBox *b, int padded)
|
|
||||||
{
|
|
||||||
b->padded = padded;
|
|
||||||
resetMargins(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
static uiBox *finishNewBox(int vertical)
|
|
||||||
{
|
|
||||||
uiBox *b;
|
|
||||||
|
|
||||||
b = (uiBox *) uiNewControl(uiBoxType());
|
|
||||||
|
|
||||||
b->grid = new gcroot<Grid ^>();
|
|
||||||
*(b->grid) = gcnew Grid();
|
|
||||||
|
|
||||||
b->vertical = vertical;
|
|
||||||
if (b->vertical) {
|
|
||||||
(*(b->grid))->ColumnDefinitions->Add(gcnew ColumnDefinition());
|
|
||||||
(*(b->grid))->ColumnDefinitions[0]->Width = GridLength(1, GridUnitType::Star);
|
|
||||||
} else {
|
|
||||||
(*(b->grid))->RowDefinitions->Add(gcnew RowDefinition());
|
|
||||||
(*(b->grid))->RowDefinitions[0]->Height = GridLength(1, GridUnitType::Star);
|
|
||||||
}
|
|
||||||
|
|
||||||
b->children = new gcroot<List<boxChild ^> ^>();
|
|
||||||
*(b->children) = gcnew List<boxChild ^>();
|
|
||||||
|
|
||||||
uiWindowsFinishNewControl(b, uiBox, grid);
|
|
||||||
uiControl(b)->ContainerUpdateState = boxContainerUpdateState;
|
|
||||||
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
uiBox *uiNewHorizontalBox(void)
|
|
||||||
{
|
|
||||||
return finishNewBox(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
uiBox *uiNewVerticalBox(void)
|
|
||||||
{
|
|
||||||
return finishNewBox(1);
|
|
||||||
}
|
|
|
@ -1,58 +0,0 @@
|
||||||
// 25 november 2015
|
|
||||||
#include "uipriv_winforms.hpp"
|
|
||||||
|
|
||||||
struct uiButton {
|
|
||||||
uiWindowsControl c;
|
|
||||||
gcroot<Button ^> *button;
|
|
||||||
void (*onClicked)(uiButton *, void *);
|
|
||||||
void *onClickedData;
|
|
||||||
};
|
|
||||||
|
|
||||||
uiWindowsDefineControl(
|
|
||||||
uiButton, // type name
|
|
||||||
uiButtonType, // type function
|
|
||||||
button // handle
|
|
||||||
)
|
|
||||||
|
|
||||||
static void defaultOnClicked(uiButton *b, void *data)
|
|
||||||
{
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
char *uiButtonText(uiButton *b)
|
|
||||||
{
|
|
||||||
String ^text;
|
|
||||||
|
|
||||||
// TOOD bad cast?
|
|
||||||
text = (String ^) ((*(b->button))->Content);
|
|
||||||
return uiWindowsCLRStringToText(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiButtonSetText(uiButton *b, const char *text)
|
|
||||||
{
|
|
||||||
(*(b->button))->Content = fromUTF8(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiButtonOnClicked(uiButton *b, void (*f)(uiButton *b, void *data), void *data)
|
|
||||||
{
|
|
||||||
b->onClicked = f;
|
|
||||||
b->onClickedData = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
uiButton *uiNewButton(const char *text)
|
|
||||||
{
|
|
||||||
uiButton *b;
|
|
||||||
|
|
||||||
b = (uiButton *) uiNewControl(uiButtonType());
|
|
||||||
|
|
||||||
b->button = new gcroot<Button ^>();
|
|
||||||
*(b->button) = gcnew Button();
|
|
||||||
(*(b->button))->Content = fromUTF8(text);
|
|
||||||
|
|
||||||
// TODO hook up events
|
|
||||||
uiButtonOnClicked(b, defaultOnClicked, NULL);
|
|
||||||
|
|
||||||
uiWindowsFinishNewControl(b, uiButton, button);
|
|
||||||
|
|
||||||
return b;
|
|
||||||
}
|
|
|
@ -1,71 +0,0 @@
|
||||||
// 26 november 2015
|
|
||||||
#include "uipriv_winforms.hpp"
|
|
||||||
|
|
||||||
struct uiCheckbox {
|
|
||||||
uiWindowsControl c;
|
|
||||||
gcroot<CheckBox ^> *checkbox;
|
|
||||||
void (*onToggled)(uiCheckbox *, void *);
|
|
||||||
void *onToggledData;
|
|
||||||
};
|
|
||||||
|
|
||||||
uiWindowsDefineControl(
|
|
||||||
uiCheckbox, // type name
|
|
||||||
uiCheckboxType, // type function
|
|
||||||
checkbox // handle
|
|
||||||
)
|
|
||||||
|
|
||||||
static void defaultOnToggled(uiCheckbox *c, void *data)
|
|
||||||
{
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
char *uiCheckboxText(uiCheckbox *c)
|
|
||||||
{
|
|
||||||
String ^text;
|
|
||||||
|
|
||||||
// TOOD bad cast?
|
|
||||||
text = (String ^) ((*(c->checkbox))->Content);
|
|
||||||
return uiWindowsCLRStringToText(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiCheckboxSetText(uiCheckbox *c, const char *text)
|
|
||||||
{
|
|
||||||
(*(c->checkbox))->Content = fromUTF8(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiCheckboxOnToggled(uiCheckbox *c, void (*f)(uiCheckbox *c, void *data), void *data)
|
|
||||||
{
|
|
||||||
c->onToggled = f;
|
|
||||||
c->onToggledData = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
int uiCheckboxChecked(uiCheckbox *c)
|
|
||||||
{
|
|
||||||
return (*(c->checkbox))->IsChecked.Value != false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiCheckboxSetChecked(uiCheckbox *c, int checked)
|
|
||||||
{
|
|
||||||
bool value;
|
|
||||||
|
|
||||||
value = checked != 0;
|
|
||||||
// TODO does this trigger an event?
|
|
||||||
(*(c->checkbox))->IsChecked = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
uiCheckbox *uiNewCheckbox(const char *text)
|
|
||||||
{
|
|
||||||
uiCheckbox *c;
|
|
||||||
|
|
||||||
c = (uiCheckbox *) uiNewControl(uiCheckboxType());
|
|
||||||
|
|
||||||
c->checkbox = new gcroot<CheckBox ^>();
|
|
||||||
*(c->checkbox) = gcnew CheckBox();
|
|
||||||
(*(c->checkbox))->Content = fromUTF8(text);
|
|
||||||
|
|
||||||
uiCheckboxOnToggled(c, defaultOnToggled, NULL);
|
|
||||||
|
|
||||||
uiWindowsFinishNewControl(c, uiCheckbox, checkbox);
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
|
@ -1,69 +0,0 @@
|
||||||
// 26 november 2015
|
|
||||||
#include "uipriv_winforms.hpp"
|
|
||||||
|
|
||||||
struct uiCombobox {
|
|
||||||
uiWindowsControl c;
|
|
||||||
gcroot<ComboBox ^> *combobox;
|
|
||||||
void (*onSelected)(uiCombobox *, void *);
|
|
||||||
void *onSelectedData;
|
|
||||||
};
|
|
||||||
|
|
||||||
uiWindowsDefineControl(
|
|
||||||
uiCombobox, // type name
|
|
||||||
uiComboboxType, // type function
|
|
||||||
combobox // handle
|
|
||||||
)
|
|
||||||
|
|
||||||
static void defaultOnSelected(uiCombobox *c, void *data)
|
|
||||||
{
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiComboboxAppend(uiCombobox *c, const char *text)
|
|
||||||
{
|
|
||||||
(*(c->combobox))->Items->Add(fromUTF8(text));
|
|
||||||
}
|
|
||||||
|
|
||||||
intmax_t uiComboboxSelected(uiCombobox *c)
|
|
||||||
{
|
|
||||||
// TODO what happens on an editable combobox?
|
|
||||||
return (*(c->combobox))->SelectedIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiComboboxSetSelected(uiCombobox *c, intmax_t n)
|
|
||||||
{
|
|
||||||
(*(c->combobox))->SelectedIndex = n;
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiComboboxOnSelected(uiCombobox *c, void (*f)(uiCombobox *c, void *data), void *data)
|
|
||||||
{
|
|
||||||
c->onSelected = f;
|
|
||||||
c->onSelectedData = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uiCombobox *finishNewCombobox(bool editable)
|
|
||||||
{
|
|
||||||
uiCombobox *c;
|
|
||||||
|
|
||||||
c = (uiCombobox *) uiNewControl(uiComboboxType());
|
|
||||||
|
|
||||||
c->combobox = new gcroot<ComboBox ^>();
|
|
||||||
*(c->combobox) = gcnew ComboBox();
|
|
||||||
(*(c->combobox))->IsEditable = editable;
|
|
||||||
|
|
||||||
uiComboboxOnSelected(c, defaultOnSelected, NULL);
|
|
||||||
|
|
||||||
uiWindowsFinishNewControl(c, uiCombobox, combobox);
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
uiCombobox *uiNewCombobox(void)
|
|
||||||
{
|
|
||||||
return finishNewCombobox(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
uiCombobox *uiNewEditableCombobox(void)
|
|
||||||
{
|
|
||||||
return finishNewCombobox(true);
|
|
||||||
}
|
|
|
@ -1,46 +0,0 @@
|
||||||
// 16 august 2015
|
|
||||||
#include "uipriv_winforms.hpp"
|
|
||||||
|
|
||||||
static uintmax_t type_uiWindowsControl = 0;
|
|
||||||
|
|
||||||
uintmax_t uiWindowsControlType(void)
|
|
||||||
{
|
|
||||||
if (type_uiWindowsControl == 0)
|
|
||||||
type_uiWindowsControl = uiRegisterType("uiWindowsControl", uiControlType(), sizeof (uiWindowsControl));
|
|
||||||
return type_uiWindowsControl;
|
|
||||||
}
|
|
||||||
|
|
||||||
Control ^genericHandle(uiControl *c)
|
|
||||||
{
|
|
||||||
gcroot<Control ^> *h;
|
|
||||||
|
|
||||||
h = (gcroot<Control ^> *) uiControlHandle(c);
|
|
||||||
return *h;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void defaultCommitShow(uiControl *c)
|
|
||||||
{
|
|
||||||
genericHandle(c)->Visibility = Visibility::Visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void defaultCommitHide(uiControl *c)
|
|
||||||
{
|
|
||||||
// TODO formally document this behavior (it's how GTK+ works)
|
|
||||||
genericHandle(c)->Visibility = Visibility::Collapsed;
|
|
||||||
}
|
|
||||||
|
|
||||||
void osCommitEnable(uiControl *c)
|
|
||||||
{
|
|
||||||
genericHandle(c)->IsEnabled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void osCommitDisable(uiControl *c)
|
|
||||||
{
|
|
||||||
genericHandle(c)->IsEnabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiWindowsFinishControl(uiControl *c)
|
|
||||||
{
|
|
||||||
c->CommitShow = defaultCommitShow;
|
|
||||||
c->CommitHide = defaultCommitHide;
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
// 26 november 2015
|
|
||||||
#include "uipriv_winforms.hpp"
|
|
||||||
|
|
||||||
// TODO TODO TODO AVAILABLE SINCE 4.0 TODO TODO TODO
|
|
||||||
|
|
||||||
struct uiDateTimePicker {
|
|
||||||
uiWindowsControl c;
|
|
||||||
// gcroot<DatePicker ^> *datePicker;
|
|
||||||
DUMMY dummy;
|
|
||||||
};
|
|
||||||
|
|
||||||
uiWindowsDefineControl(
|
|
||||||
uiDateTimePicker, // type name
|
|
||||||
uiDateTimePickerType, // type function
|
|
||||||
// datePicker // handle
|
|
||||||
dummy // handle
|
|
||||||
)
|
|
||||||
|
|
||||||
static uiDateTimePicker *finishNewDateTimePicker(/* TODO */)
|
|
||||||
{
|
|
||||||
uiDateTimePicker *d;
|
|
||||||
|
|
||||||
d = (uiDateTimePicker *) uiNewControl(uiDateTimePickerType());
|
|
||||||
|
|
||||||
/* d->datePicker = new gcroot<DatePicker ^>();
|
|
||||||
*(d->datePicker) = gcnew DatePicker();
|
|
||||||
// TODO SelectedDateFormat
|
|
||||||
*/
|
|
||||||
d->dummy = mkdummy(L"uiDatePicker");
|
|
||||||
|
|
||||||
uiWindowsFinishNewControl(d, uiDateTimePicker, dummy);//datePicker);
|
|
||||||
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
|
|
||||||
uiDateTimePicker *uiNewDateTimePicker(void)
|
|
||||||
{
|
|
||||||
return finishNewDateTimePicker();
|
|
||||||
}
|
|
||||||
|
|
||||||
uiDateTimePicker *uiNewDatePicker(void)
|
|
||||||
{
|
|
||||||
return finishNewDateTimePicker();
|
|
||||||
}
|
|
||||||
|
|
||||||
uiDateTimePicker *uiNewTimePicker(void)
|
|
||||||
{
|
|
||||||
return finishNewDateTimePicker();
|
|
||||||
}
|
|
111
winforms/debug.c
111
winforms/debug.c
|
@ -1,111 +0,0 @@
|
||||||
// 25 february 2015
|
|
||||||
#include "unmanaged.h"
|
|
||||||
|
|
||||||
// uncomment the following line to enable debug messages
|
|
||||||
#define tableDebug
|
|
||||||
// uncomment the following line to halt on a debug message
|
|
||||||
#define tableDebugStop
|
|
||||||
|
|
||||||
#ifdef tableDebug
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
HRESULT logLastError(const char *context)
|
|
||||||
{
|
|
||||||
DWORD le;
|
|
||||||
WCHAR *msg;
|
|
||||||
BOOL parenthesize = FALSE;
|
|
||||||
BOOL localFreeFailed = FALSE;
|
|
||||||
DWORD localFreeLastError;
|
|
||||||
|
|
||||||
le = GetLastError();
|
|
||||||
fprintf(stderr, "%s: ", context);
|
|
||||||
if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, le, 0, (LPWSTR) (&msg), 0, NULL) != 0) {
|
|
||||||
fprintf(stderr, "%S (", msg);
|
|
||||||
if (LocalFree(msg) != NULL) {
|
|
||||||
localFreeFailed = TRUE;
|
|
||||||
localFreeLastError = GetLastError();
|
|
||||||
}
|
|
||||||
parenthesize = TRUE;
|
|
||||||
}
|
|
||||||
fprintf(stderr, "GetLastError() == %I32u", le);
|
|
||||||
if (parenthesize)
|
|
||||||
fprintf(stderr, ")");
|
|
||||||
if (localFreeFailed)
|
|
||||||
fprintf(stderr, "; local free of system message failed with last error %I32u", localFreeLastError);
|
|
||||||
fprintf(stderr, "\n");
|
|
||||||
#ifdef tableDebugStop
|
|
||||||
DebugBreak();
|
|
||||||
#endif
|
|
||||||
SetLastError(le);
|
|
||||||
// a function does not have to set a last error
|
|
||||||
// if the last error we get is actually 0, then HRESULT_FROM_WIN32(0) will return S_OK (0 cast to an HRESULT, since 0 <= 0), which we don't want
|
|
||||||
// prevent this by returning E_FAIL, so the rest of the Table code doesn't barge onward
|
|
||||||
if (le == 0)
|
|
||||||
return E_FAIL;
|
|
||||||
return HRESULT_FROM_WIN32(le);
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT logHRESULT(const char *context, HRESULT hr)
|
|
||||||
{
|
|
||||||
WCHAR *msg;
|
|
||||||
BOOL parenthesize = FALSE;
|
|
||||||
BOOL localFreeFailed = FALSE;
|
|
||||||
DWORD localFreeLastError;
|
|
||||||
|
|
||||||
fprintf(stderr, "%s: ", context);
|
|
||||||
// this isn't technically documented, but everyone does it, including Microsoft (see the implementation of _com_error::ErrorMessage() in a copy of comdef.h that comes with the Windows DDK)
|
|
||||||
if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, (DWORD) hr, 0, (LPWSTR) (&msg), 0, NULL) != 0) {
|
|
||||||
fprintf(stderr, "%S (", msg);
|
|
||||||
if (LocalFree(msg) != NULL) {
|
|
||||||
localFreeFailed = TRUE;
|
|
||||||
localFreeLastError = GetLastError();
|
|
||||||
}
|
|
||||||
parenthesize = TRUE;
|
|
||||||
}
|
|
||||||
fprintf(stderr, "HRESULT == 0x%I32X", hr);
|
|
||||||
if (parenthesize)
|
|
||||||
fprintf(stderr, ")");
|
|
||||||
if (localFreeFailed)
|
|
||||||
fprintf(stderr, "; local free of system message failed with last error %I32u", localFreeLastError);
|
|
||||||
fprintf(stderr, "\n");
|
|
||||||
#ifdef tableDebugStop
|
|
||||||
DebugBreak();
|
|
||||||
#endif
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT logMemoryExhausted(const char *reason)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "memory exhausted %s\n", reason);
|
|
||||||
#ifdef tableDebugStop
|
|
||||||
DebugBreak();
|
|
||||||
#endif
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
HRESULT logLastError(const char *reason)
|
|
||||||
{
|
|
||||||
DWORD le;
|
|
||||||
|
|
||||||
le = GetLastError();
|
|
||||||
// we shouldn't need to do this, but let's do this anyway just to be safe
|
|
||||||
SetLastError(le);
|
|
||||||
if (le == 0)
|
|
||||||
return E_FAIL;
|
|
||||||
return HRESULT_FROM_WIN32(le);
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT logHRESULT(const char *reason, HRESULT hr)
|
|
||||||
{
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT logMemoryExhausted(const char *reason)
|
|
||||||
{
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,151 +0,0 @@
|
||||||
// 19 november 2015
|
|
||||||
#include "uipriv_winforms.hpp"
|
|
||||||
|
|
||||||
uiDrawPath *uiDrawNewPath(uiDrawFillMode fillMode)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiDrawFreePath(uiDrawPath *p)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiDrawPathNewFigure(uiDrawPath *p, double x, double y)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiDrawPathNewFigureWithArc(uiDrawPath *p, double xCenter, double yCenter, double radius, double startAngle, double sweep, int negative)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiDrawPathLineTo(uiDrawPath *p, double x, double y)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiDrawPathArcTo(uiDrawPath *p, double xCenter, double yCenter, double radius, double startAngle, double sweep, int negative)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiDrawPathBezierTo(uiDrawPath *p, double c1x, double c1y, double c2x, double c2y, double endX, double endY)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiDrawPathCloseFigure(uiDrawPath *p)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiDrawPathAddRectangle(uiDrawPath *p, double x, double y, double width, double height)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiDrawPathEnd(uiDrawPath *p)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
struct uiDrawContext {
|
|
||||||
int TODO;
|
|
||||||
};
|
|
||||||
|
|
||||||
uiDrawContext *newContext(/* TODO */)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void freeContext(uiDrawContext *c)
|
|
||||||
{
|
|
||||||
uiFree(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiDrawStroke(uiDrawContext *c, uiDrawPath *path, uiDrawBrush *b, uiDrawStrokeParams *p)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiDrawFill(uiDrawContext *c, uiDrawPath *path, uiDrawBrush *b)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiDrawMatrixSetIdentity(uiDrawMatrix *m)
|
|
||||||
{
|
|
||||||
setIdentity(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiDrawMatrixTranslate(uiDrawMatrix *m, double x, double y)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiDrawMatrixScale(uiDrawMatrix *m, double xCenter, double yCenter, double x, double y)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiDrawMatrixRotate(uiDrawMatrix *m, double x, double y, double amount)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiDrawMatrixSkew(uiDrawMatrix *m, double x, double y, double xamount, double yamount)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiDrawMatrixMultiply(uiDrawMatrix *dest, uiDrawMatrix *src)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
int uiDrawMatrixInvertible(uiDrawMatrix *m)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int uiDrawMatrixInvert(uiDrawMatrix *m)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiDrawMatrixTransformPoint(uiDrawMatrix *m, double *x, double *y)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiDrawMatrixTransformSize(uiDrawMatrix *m, double *x, double *y)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiDrawTransform(uiDrawContext *c, uiDrawMatrix *m)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO not documented on api.haiku-os.org
|
|
||||||
void uiDrawClip(uiDrawContext *c, uiDrawPath *path)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiDrawSave(uiDrawContext *c)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiDrawRestore(uiDrawContext *c)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
|
@ -1,62 +0,0 @@
|
||||||
// 26 november 2015
|
|
||||||
#include "uipriv_winforms.hpp"
|
|
||||||
|
|
||||||
struct uiEntry {
|
|
||||||
uiWindowsControl c;
|
|
||||||
gcroot<TextBox ^> *textbox;
|
|
||||||
void (*onChanged)(uiEntry *, void *);
|
|
||||||
void *onChangedData;
|
|
||||||
};
|
|
||||||
|
|
||||||
uiWindowsDefineControl(
|
|
||||||
uiEntry, // type name
|
|
||||||
uiEntryType, // type function
|
|
||||||
textbox // handle
|
|
||||||
)
|
|
||||||
|
|
||||||
static void defaultOnChanged(uiEntry *e, void *data)
|
|
||||||
{
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
char *uiEntryText(uiEntry *e)
|
|
||||||
{
|
|
||||||
return uiWindowsCLRStringToText((*(e->textbox))->Text);
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiEntrySetText(uiEntry *e, const char *text)
|
|
||||||
{
|
|
||||||
(*(e->textbox))->Text = fromUTF8(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiEntryOnChanged(uiEntry *e, void (*f)(uiEntry *e, void *data), void *data)
|
|
||||||
{
|
|
||||||
e->onChanged = f;
|
|
||||||
e->onChangedData = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
int uiEntryReadOnly(uiEntry *e)
|
|
||||||
{
|
|
||||||
return (*(e->textbox))->IsReadOnly != false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiEntrySetReadOnly(uiEntry *e, int readonly)
|
|
||||||
{
|
|
||||||
(*(e->textbox))->IsReadOnly = readonly != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uiEntry *uiNewEntry(void)
|
|
||||||
{
|
|
||||||
uiEntry *e;
|
|
||||||
|
|
||||||
e = (uiEntry *) uiNewControl(uiEntryType());
|
|
||||||
|
|
||||||
e->textbox = new gcroot<TextBox ^>();
|
|
||||||
*(e->textbox) = gcnew TextBox();
|
|
||||||
|
|
||||||
uiEntryOnChanged(e, defaultOnChanged, NULL);
|
|
||||||
|
|
||||||
uiWindowsFinishNewControl(e, uiEntry, textbox);
|
|
||||||
|
|
||||||
return e;
|
|
||||||
}
|
|
|
@ -1,86 +0,0 @@
|
||||||
// 18 november 2015
|
|
||||||
#include "uipriv_winforms.hpp"
|
|
||||||
|
|
||||||
struct uiGroup {
|
|
||||||
uiWindowsControl c;
|
|
||||||
gcroot<GroupBox ^> *groupbox;
|
|
||||||
uiControl *child;
|
|
||||||
int margined;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void onDestroy(uiGroup *);
|
|
||||||
|
|
||||||
uiWindowsDefineControlWithOnDestroy(
|
|
||||||
uiGroup, // type name
|
|
||||||
uiGroupType, // type function
|
|
||||||
groupbox, // handle
|
|
||||||
onDestroy(hthis); // on destroy
|
|
||||||
)
|
|
||||||
|
|
||||||
static void onDestroy(uiGroup *g)
|
|
||||||
{
|
|
||||||
if (g->child != NULL) {
|
|
||||||
(*(g->groupbox))->Content = nullptr;
|
|
||||||
uiControlSetParent(g->child, NULL);
|
|
||||||
uiControlDestroy(g->child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char *uiGroupTitle(uiGroup *g)
|
|
||||||
{
|
|
||||||
String ^text;
|
|
||||||
|
|
||||||
// TOOD bad cast?
|
|
||||||
text = (String ^) ((*(g->groupbox))->Header);
|
|
||||||
return uiWindowsCLRStringToText(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiGroupSetTitle(uiGroup *g, const char *title)
|
|
||||||
{
|
|
||||||
(*(g->groupbox))->Header = fromUTF8(title);
|
|
||||||
// TODO layout
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiGroupSetChild(uiGroup *g, uiControl *c)
|
|
||||||
{
|
|
||||||
if (g->child != NULL) {
|
|
||||||
uiControlSetParent(g->child, NULL);
|
|
||||||
(*(g->groupbox))->Content = nullptr;
|
|
||||||
}
|
|
||||||
g->child = c;
|
|
||||||
if (g->child != NULL) {
|
|
||||||
(*(g->groupbox))->Content = genericHandle(g->child);
|
|
||||||
uiControlSetParent(g->child, uiControl(g));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int uiGroupMargined(uiGroup *g)
|
|
||||||
{
|
|
||||||
return g->margined;
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiGroupSetMargined(uiGroup *g, int margined)
|
|
||||||
{
|
|
||||||
g->margined = margined;
|
|
||||||
// TODO Margin or Padding?
|
|
||||||
// TODO really this? or should we just use another Border?
|
|
||||||
if (g->margined)
|
|
||||||
(*(g->groupbox))->Padding = Thickness(10, 10, 10, 10);
|
|
||||||
else
|
|
||||||
(*(g->groupbox))->Padding = Thickness(0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
uiGroup *uiNewGroup(const char *title)
|
|
||||||
{
|
|
||||||
uiGroup *g;
|
|
||||||
|
|
||||||
g = (uiGroup *) uiNewControl(uiGroupType());
|
|
||||||
|
|
||||||
g->groupbox = new gcroot<GroupBox ^>();
|
|
||||||
*(g->groupbox) = gcnew GroupBox();
|
|
||||||
(*(g->groupbox))->Header = fromUTF8(title);
|
|
||||||
|
|
||||||
uiWindowsFinishNewControl(g, uiGroup, groupbox);
|
|
||||||
|
|
||||||
return g;
|
|
||||||
}
|
|
102
winforms/init.c
102
winforms/init.c
|
@ -1,102 +0,0 @@
|
||||||
// 25 november 2015
|
|
||||||
#ifdef __cplusplus
|
|
||||||
#error msbuild is being dumb and making this a C++ file
|
|
||||||
#endif
|
|
||||||
#include "unmanaged.h"
|
|
||||||
|
|
||||||
// TODO this won't work if initAlloc() failed
|
|
||||||
|
|
||||||
#define initErrorFormat L"error %s: %s%s%s %I32u (0x%I32X)%s"
|
|
||||||
#define initErrorArgs wmessage, sysmsg, beforele, label, value, value, afterle
|
|
||||||
|
|
||||||
static const char *initerr(const char *message, const WCHAR *label, DWORD value)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
return "";
|
|
||||||
#if 0
|
|
||||||
WCHAR *sysmsg;
|
|
||||||
BOOL hassysmsg;
|
|
||||||
WCHAR *beforele;
|
|
||||||
WCHAR *afterle;
|
|
||||||
int n;
|
|
||||||
WCHAR *wmessage;
|
|
||||||
WCHAR *wstr;
|
|
||||||
const char *str;
|
|
||||||
|
|
||||||
if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, value, 0, (LPWSTR) (&sysmsg), 0, NULL) != 0) {
|
|
||||||
hassysmsg = TRUE;
|
|
||||||
beforele = L" (";
|
|
||||||
afterle = L")";
|
|
||||||
} else {
|
|
||||||
hassysmsg = FALSE;
|
|
||||||
sysmsg = L"";
|
|
||||||
beforele = L"";
|
|
||||||
afterle = L"";
|
|
||||||
}
|
|
||||||
wmessage = toUTF16(message);
|
|
||||||
n = _scwprintf(initErrorFormat, initErrorArgs);
|
|
||||||
wstr = (WCHAR *) uiAlloc((n + 1) * sizeof (WCHAR), "WCHAR[]");
|
|
||||||
snwprintf(wstr, n + 1, initErrorFormat, initErrorArgs);
|
|
||||||
str = toUTF8(wstr);
|
|
||||||
uiFree(wstr);
|
|
||||||
if (hassysmsg)
|
|
||||||
if (LocalFree(sysmsg) != NULL)
|
|
||||||
logLastError("error freeing system message in loadLastError()");
|
|
||||||
uiFree(wmessage);
|
|
||||||
return str;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *loadLastError(const char *message)
|
|
||||||
{
|
|
||||||
return initerr(message, L"GetLastError() ==", GetLastError());
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *loadHRESULT(const char *message, HRESULT hr)
|
|
||||||
{
|
|
||||||
return initerr(message, L"HRESULT", (DWORD) hr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// On the subject of CoInitialize(), or why this isn't in main.cpp:
|
|
||||||
// If we don't set up the current thread otherwise, the first time .net tries to call out to unmanaged code, it will automatically set up a MTA for COM.
|
|
||||||
// This is not what we want; we need a STA instead.
|
|
||||||
// Since we're not in control of main(), we can't stick a [STAThread] on it, so we have to do it ourselves.
|
|
||||||
// This is a separate .c file for two reasons:
|
|
||||||
// 1) To avoid the unmanaged jump that a call to CoInitialize() would do (it seems to detect a call to CoInitialize()/CoInitializeEx() but let's not rely on it)
|
|
||||||
// 2) To avoid mixing Windows API headers with .net
|
|
||||||
// See also http://stackoverflow.com/questions/24348205/how-do-i-solve-this-com-issue-in-c
|
|
||||||
|
|
||||||
uiInitOptions options;
|
|
||||||
|
|
||||||
const char *uiInit(uiInitOptions *o)
|
|
||||||
{
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
options = *o;
|
|
||||||
|
|
||||||
if (initAlloc() == 0)
|
|
||||||
return loadLastError("error initializing memory allocations");
|
|
||||||
|
|
||||||
// TODO https://msdn.microsoft.com/en-us/library/5s8ee185%28v=vs.71%29.aspx use CoInitializeEx()?
|
|
||||||
hr = CoInitialize(NULL);
|
|
||||||
if (hr != S_OK && hr != S_FALSE)
|
|
||||||
return loadHRESULT("initializing COM", hr);
|
|
||||||
|
|
||||||
// now do the rest of initialization on the managed side
|
|
||||||
initWPF();
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiUninit(void)
|
|
||||||
{
|
|
||||||
uninitWPF();
|
|
||||||
CoUninitialize();
|
|
||||||
uninitTypes();
|
|
||||||
uninitAlloc();
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiFreeInitError(const char *err)
|
|
||||||
{
|
|
||||||
uiFree((void *) err);
|
|
||||||
}
|
|
|
@ -1,47 +0,0 @@
|
||||||
// 26 november 2015
|
|
||||||
#include "uipriv_winforms.hpp"
|
|
||||||
|
|
||||||
// TODO alignment
|
|
||||||
// TODO lots of padding
|
|
||||||
// TODO Label also has mnemonic value; use TextField instead
|
|
||||||
|
|
||||||
struct uiLabel {
|
|
||||||
uiWindowsControl c;
|
|
||||||
gcroot<Label ^> *label;
|
|
||||||
};
|
|
||||||
|
|
||||||
uiWindowsDefineControl(
|
|
||||||
uiLabel, // type name
|
|
||||||
uiLabelType, // type function
|
|
||||||
label // handle
|
|
||||||
)
|
|
||||||
|
|
||||||
char *uiLabelText(uiLabel *l)
|
|
||||||
{
|
|
||||||
String ^text;
|
|
||||||
|
|
||||||
// TOOD bad cast?
|
|
||||||
text = (String ^) ((*(l->label))->Content);
|
|
||||||
return uiWindowsCLRStringToText(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiLabelSetText(uiLabel *l, const char *text)
|
|
||||||
{
|
|
||||||
(*(l->label))->Content = fromUTF8(text);
|
|
||||||
// TODO does this adjust the layout?
|
|
||||||
}
|
|
||||||
|
|
||||||
uiLabel *uiNewLabel(const char *text)
|
|
||||||
{
|
|
||||||
uiLabel *l;
|
|
||||||
|
|
||||||
l = (uiLabel *) uiNewControl(uiLabelType());
|
|
||||||
|
|
||||||
l->label = new gcroot<Label ^>();
|
|
||||||
*(l->label) = gcnew Label();
|
|
||||||
(*(l->label))->Content = fromUTF8(text);
|
|
||||||
|
|
||||||
uiWindowsFinishNewControl(l, uiLabel, label);
|
|
||||||
|
|
||||||
return l;
|
|
||||||
}
|
|
|
@ -1,145 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- 24 november 2015 -->
|
|
||||||
|
|
||||||
<!-- DO NOT EDIT IN VISUAL STUDIO! -->
|
|
||||||
|
|
||||||
<!-- TODO go through all possible command line options and make sure the ones we want are enabled -->
|
|
||||||
|
|
||||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
|
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
|
||||||
<!-- TODO what does the Include clause do? -->
|
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
|
||||||
<Configuration>Debug</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<PropertyGroup Label="Globals">
|
|
||||||
<TargetFrameworkVersion>v3.0</TargetFrameworkVersion>
|
|
||||||
<ProjectGuid>{2B7F1F47-EE47-47CD-9C6C-42D9620E46E3}</ProjectGuid>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.default.props" />
|
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
|
||||||
<PlatformToolset>v120</PlatformToolset>
|
|
||||||
<CLRSupport>true</CLRSupport>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
|
||||||
|
|
||||||
<ImportGroup Label="ExtensionSettings" />
|
|
||||||
<ImportGroup Label="PropertySheets" />
|
|
||||||
<PropertyGroup Label="UserMacros" />
|
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<LinkIncremental>false</LinkIncremental>
|
|
||||||
<TargetName>libui</TargetName>
|
|
||||||
<!-- TODO will these work from any directory? -->
|
|
||||||
<OutDir>..\out\</OutDir>
|
|
||||||
<IntDir>..\.obj\</IntDir>
|
|
||||||
<EnableManagedIncrementalBuild>false</EnableManagedIncrementalBuild>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<!-- TODO should be EnableAllWarnings but that enables way too much -->
|
|
||||||
<WarningLevel>Level4</WarningLevel>
|
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
|
||||||
<PreprocessorDefinitions>_UI_EXTERN=__declspec(dllexport) extern</PreprocessorDefinitions>
|
|
||||||
<!-- TODO there's a better way for this -->
|
|
||||||
<!-- do not warn about unreferended parameters -->
|
|
||||||
<AdditionalOptions>/wd4100</AdditionalOptions>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<AdditionalDependencies>kernel32.lib;ole32.lib</AdditionalDependencies>
|
|
||||||
<SubSystem>Windows</SubSystem>
|
|
||||||
<!--TODO <MinimumRequiredVersion>600</MinimumRequiredVersion>-->
|
|
||||||
<!-- <AdditionalOptions>additional linker options %(AdditionalOptions)</AdditionalOptions>-->
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Reference Include="System" />
|
|
||||||
<Reference Include="WindowsBase" />
|
|
||||||
<Reference Include="PresentationCore" />
|
|
||||||
<Reference Include="PresentationFramework" />
|
|
||||||
|
|
||||||
<!-- TODO readd headers? -->
|
|
||||||
|
|
||||||
<ClCompile Include="alloc.c">
|
|
||||||
<CompileAsManaged>false</CompileAsManaged>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="area.cpp" />
|
|
||||||
<ClCompile Include="box.cpp" />
|
|
||||||
<ClCompile Include="button.cpp" />
|
|
||||||
<ClCompile Include="checkbox.cpp" />
|
|
||||||
<ClCompile Include="combobox.cpp" />
|
|
||||||
<ClCompile Include="control.cpp" />
|
|
||||||
<ClCompile Include="datetimepicker.cpp" />
|
|
||||||
<ClCompile Include="debug.c">
|
|
||||||
<CompileAsManaged>false</CompileAsManaged>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="draw.cpp" />
|
|
||||||
<ClCompile Include="entry.cpp" />
|
|
||||||
<ClCompile Include="group.cpp" />
|
|
||||||
<ClCompile Include="init.c">
|
|
||||||
<CompileAsManaged>false</CompileAsManaged>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="label.cpp" />
|
|
||||||
<ClCompile Include="main.cpp" />
|
|
||||||
<ClCompile Include="menu.cpp" />
|
|
||||||
<ClCompile Include="progressbar.cpp" />
|
|
||||||
<ClCompile Include="radiobuttons.cpp" />
|
|
||||||
<ClCompile Include="separator.cpp" />
|
|
||||||
<ClCompile Include="slider.cpp" />
|
|
||||||
<ClCompile Include="spinbox.cpp" />
|
|
||||||
<ClCompile Include="stddialogs.cpp" />
|
|
||||||
<ClCompile Include="tab.cpp" />
|
|
||||||
<ClCompile Include="text.cpp" />
|
|
||||||
<ClCompile Include="util.c">
|
|
||||||
<CompileAsManaged>false</CompileAsManaged>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="window.cpp" />
|
|
||||||
|
|
||||||
<!-- TODO find a way to get the basename of the source path so we can use dir_file.obj naming automatically -->
|
|
||||||
<ClCompile Include="..\common\areaevents.c">
|
|
||||||
<CompileAsManaged>false</CompileAsManaged>
|
|
||||||
<ObjectFileName>$(IntDir)common_areaevents.obj</ObjectFileName>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\common\control.c">
|
|
||||||
<CompileAsManaged>false</CompileAsManaged>
|
|
||||||
<ObjectFileName>$(IntDir)common_control.obj</ObjectFileName>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\common\matrix.c">
|
|
||||||
<CompileAsManaged>false</CompileAsManaged>
|
|
||||||
<ObjectFileName>$(IntDir)common_matrix.obj</ObjectFileName>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\common\menu.c">
|
|
||||||
<CompileAsManaged>false</CompileAsManaged>
|
|
||||||
<ObjectFileName>$(IntDir)common_menu.obj</ObjectFileName>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\common\ptrarray.c">
|
|
||||||
<CompileAsManaged>false</CompileAsManaged>
|
|
||||||
<ObjectFileName>$(IntDir)common_ptrarray.obj</ObjectFileName>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\common\shouldquit.c">
|
|
||||||
<CompileAsManaged>false</CompileAsManaged>
|
|
||||||
<ObjectFileName>$(IntDir)common_shouldquit.obj</ObjectFileName>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\common\types.c">
|
|
||||||
<CompileAsManaged>false</CompileAsManaged>
|
|
||||||
<ObjectFileName>$(IntDir)common_types.obj</ObjectFileName>
|
|
||||||
</ClCompile>
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
|
||||||
|
|
||||||
<ImportGroup Label="ExtensionTargets" />
|
|
||||||
|
|
||||||
</Project>
|
|
|
@ -1,26 +0,0 @@
|
||||||
// 25 november 2015
|
|
||||||
#include "uipriv_winforms.hpp"
|
|
||||||
|
|
||||||
void initWinForms(void)
|
|
||||||
{
|
|
||||||
// TODO anything else?
|
|
||||||
// TODO return value
|
|
||||||
// TODO needed?
|
|
||||||
// Application::EnableVisualStyles();
|
|
||||||
}
|
|
||||||
|
|
||||||
void uninitWinForms(void)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiMain(void)
|
|
||||||
{
|
|
||||||
Application::Run();
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiQuit(void)
|
|
||||||
{
|
|
||||||
// TODO does this run later?
|
|
||||||
Application::Exit();
|
|
||||||
}
|
|
|
@ -1,69 +0,0 @@
|
||||||
// 19 november 2015
|
|
||||||
#include "uipriv_winforms.hpp"
|
|
||||||
|
|
||||||
void uiMenuItemEnable(uiMenuItem *m)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiMenuItemDisable(uiMenuItem *m)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiMenuItemOnClicked(uiMenuItem *m, void (*f)(uiMenuItem *sender, uiWindow *window, void *data), void *data)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
int uiMenuItemChecked(uiMenuItem *m)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiMenuItemSetChecked(uiMenuItem *m, int checked)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
uiMenuItem *uiMenuAppendItem(uiMenu *m, const char *name)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
uiMenuItem *uiMenuAppendCheckItem(uiMenu *m, const char *name)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
uiMenuItem *uiMenuAppendQuitItem(uiMenu *m)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
uiMenuItem *uiMenuAppendPreferencesItem(uiMenu *m)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
uiMenuItem *uiMenuAppendAboutItem(uiMenu *m)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiMenuAppendSeparator(uiMenu *m)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
uiMenu *uiNewMenu(const char *name)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
return NULL;
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
// 26 november 2015
|
|
||||||
#include "uipriv_winforms.hpp"
|
|
||||||
|
|
||||||
struct uiProgressBar {
|
|
||||||
uiWindowsControl c;
|
|
||||||
DUMMY dummy;
|
|
||||||
};
|
|
||||||
|
|
||||||
uiWindowsDefineControl(
|
|
||||||
uiProgressBar, // type name
|
|
||||||
uiProgressBarType, // type function
|
|
||||||
dummy // handle
|
|
||||||
)
|
|
||||||
|
|
||||||
void uiProgressBarSetValue(uiProgressBar *p, int n)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
uiProgressBar *uiNewProgressBar(void)
|
|
||||||
{
|
|
||||||
uiProgressBar *p;
|
|
||||||
|
|
||||||
p = (uiProgressBar *) uiNewControl(uiProgressBarType());
|
|
||||||
|
|
||||||
p->dummy = mkdummy(L"uiProgressBar");
|
|
||||||
|
|
||||||
uiWindowsFinishNewControl(p, uiProgressBar, dummy);
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
// 26 november 2015
|
|
||||||
#include "uipriv_winforms.hpp"
|
|
||||||
|
|
||||||
struct uiRadioButtons {
|
|
||||||
uiWindowsControl c;
|
|
||||||
DUMMY dummy;
|
|
||||||
};
|
|
||||||
|
|
||||||
uiWindowsDefineControl(
|
|
||||||
uiRadioButtons, // type name
|
|
||||||
uiRadioButtonsType, // type function
|
|
||||||
dummy // handle
|
|
||||||
)
|
|
||||||
|
|
||||||
void uiRadioButtonsAppend(uiRadioButtons *r, const char *text)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
uiRadioButtons *uiNewRadioButtons(void)
|
|
||||||
{
|
|
||||||
uiRadioButtons *r;
|
|
||||||
|
|
||||||
r = (uiRadioButtons *) uiNewControl(uiRadioButtonsType());
|
|
||||||
|
|
||||||
r->dummy = mkdummy(L"uiRadioButtons");
|
|
||||||
|
|
||||||
uiWindowsFinishNewControl(r, uiRadioButtons, dummy);
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
// 18 november 2015
|
|
||||||
#include "uipriv_winforms.hpp"
|
|
||||||
|
|
||||||
struct uiSeparator {
|
|
||||||
uiWindowsControl c;
|
|
||||||
DUMMY dummy;
|
|
||||||
};
|
|
||||||
|
|
||||||
uiWindowsDefineControl(
|
|
||||||
uiSeparator, // type name
|
|
||||||
uiSeparatorType, // type function
|
|
||||||
dummy // handle
|
|
||||||
)
|
|
||||||
|
|
||||||
uiSeparator *uiNewHorizontalSeparator(void)
|
|
||||||
{
|
|
||||||
uiSeparator *s;
|
|
||||||
|
|
||||||
s = (uiSeparator *) uiNewControl(uiSeparatorType());
|
|
||||||
|
|
||||||
s->dummy = mkdummy(L"uiSeparator");
|
|
||||||
|
|
||||||
uiWindowsFinishNewControl(s, uiSeparator, dummy);
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
|
|
@ -1,52 +0,0 @@
|
||||||
// 18 november 2015
|
|
||||||
#include "uipriv_winforms.hpp"
|
|
||||||
|
|
||||||
struct uiSlider {
|
|
||||||
uiWindowsControl c;
|
|
||||||
DUMMY dummy;
|
|
||||||
void (*onChanged)(uiSlider *, void *);
|
|
||||||
void *onChangedData;
|
|
||||||
};
|
|
||||||
|
|
||||||
uiWindowsDefineControl(
|
|
||||||
uiSlider, // type name
|
|
||||||
uiSliderType, // type function
|
|
||||||
dummy // handle
|
|
||||||
)
|
|
||||||
|
|
||||||
static void defaultOnChanged(uiSlider *s, void *data)
|
|
||||||
{
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
intmax_t uiSliderValue(uiSlider *s)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiSliderSetValue(uiSlider *s, intmax_t value)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiSliderOnChanged(uiSlider *s, void (*f)(uiSlider *s, void *data), void *data)
|
|
||||||
{
|
|
||||||
s->onChanged = f;
|
|
||||||
s->onChangedData = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
uiSlider *uiNewSlider(intmax_t min, intmax_t max)
|
|
||||||
{
|
|
||||||
uiSlider *s;
|
|
||||||
|
|
||||||
s = (uiSlider *) uiNewControl(uiSliderType());
|
|
||||||
|
|
||||||
s->dummy = mkdummy(L"uiSlider");
|
|
||||||
|
|
||||||
uiSliderOnChanged(s, defaultOnChanged, NULL);
|
|
||||||
|
|
||||||
uiWindowsFinishNewControl(s, uiSlider, dummy);
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
|
|
@ -1,42 +0,0 @@
|
||||||
// 18 november 2015
|
|
||||||
#include "uipriv_winforms.hpp"
|
|
||||||
|
|
||||||
struct uiSpinbox {
|
|
||||||
uiWindowsControl c;
|
|
||||||
DUMMY dummy;
|
|
||||||
};
|
|
||||||
|
|
||||||
uiWindowsDefineControl(
|
|
||||||
uiSpinbox, // type name
|
|
||||||
uiSpinboxType, // type function
|
|
||||||
dummy // handle
|
|
||||||
)
|
|
||||||
|
|
||||||
intmax_t uiSpinboxValue(uiSpinbox *s)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiSpinboxSetValue(uiSpinbox *s, intmax_t value)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiSpinboxOnChanged(uiSpinbox *s, void (*f)(uiSpinbox *s, void *data), void *data)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
uiSpinbox *uiNewSpinbox(intmax_t min, intmax_t max)
|
|
||||||
{
|
|
||||||
uiSpinbox *s;
|
|
||||||
|
|
||||||
s = (uiSpinbox *) uiNewControl(uiSpinboxType());
|
|
||||||
|
|
||||||
s->dummy = mkdummy(L"uiSpinbox");
|
|
||||||
|
|
||||||
uiWindowsFinishNewControl(s, uiSpinbox, dummy);
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
|
|
@ -1,24 +0,0 @@
|
||||||
// 26 june 2015
|
|
||||||
#include "uipriv_winforms.hpp"
|
|
||||||
|
|
||||||
char *uiOpenFile(void)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *uiSaveFile(void)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiMsgBox(const char *title, const char *description)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiMsgBoxError(const char *title, const char *description)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
126
winforms/tab.cpp
126
winforms/tab.cpp
|
@ -1,126 +0,0 @@
|
||||||
// 26 november 2015
|
|
||||||
#include "uipriv_winforms.hpp"
|
|
||||||
|
|
||||||
// TODO save child alignments?
|
|
||||||
// TODO scroll tabs instead of multiline tabs
|
|
||||||
|
|
||||||
using namespace System::Collections::Generic;
|
|
||||||
|
|
||||||
ref class tabPage {
|
|
||||||
public:
|
|
||||||
TabItem ^item;
|
|
||||||
uiControl *c;
|
|
||||||
Border ^border; // see uiTabSetMargined()
|
|
||||||
int margined;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct uiTab {
|
|
||||||
uiWindowsControl c;
|
|
||||||
gcroot<TabControl ^> *tab;
|
|
||||||
gcroot<List<tabPage ^> ^> *pages;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void onDestroy(uiTab *);
|
|
||||||
|
|
||||||
uiWindowsDefineControlWithOnDestroy(
|
|
||||||
uiTab, // type name
|
|
||||||
uiTabType, // type function
|
|
||||||
tab, // handle
|
|
||||||
onDestroy(hthis); // on destroy
|
|
||||||
)
|
|
||||||
|
|
||||||
static void onDestroy(uiTab *t)
|
|
||||||
{
|
|
||||||
List<tabPage ^> ^pages;
|
|
||||||
|
|
||||||
pages = *(t->pages);
|
|
||||||
while (pages->Count != 0) {
|
|
||||||
pages[0]->border->Child = nullptr;
|
|
||||||
uiControlSetParent(pages[0]->c, NULL);
|
|
||||||
uiControlDestroy(pages[0]->c);
|
|
||||||
pages->RemoveAt(0);
|
|
||||||
(*(t->tab))->Items->RemoveAt(0);
|
|
||||||
}
|
|
||||||
delete t->pages;
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiTabAppend(uiTab *t, const char *name, uiControl *c)
|
|
||||||
{
|
|
||||||
uiTabInsertAt(t, name, (*(t->pages))->Count, c);
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiTabInsertAt(uiTab *t, const char *name, uintmax_t before, uiControl *c)
|
|
||||||
{
|
|
||||||
tabPage ^p;
|
|
||||||
|
|
||||||
p = gcnew tabPage();
|
|
||||||
p->c = c;
|
|
||||||
p->border = gcnew Border();
|
|
||||||
p->item = gcnew TabItem();
|
|
||||||
|
|
||||||
p->border->Child = genericHandle(p->c);
|
|
||||||
p->item->Content = p->border;
|
|
||||||
p->item->Header = fromUTF8(name);
|
|
||||||
|
|
||||||
uiControlSetParent(p->c, uiControl(t));
|
|
||||||
(*(t->tab))->Items->Insert(before, p->item);
|
|
||||||
(*(t->pages))->Insert(before, p);
|
|
||||||
uiControlSetParent(p->c, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiTabDelete(uiTab *t, uintmax_t index)
|
|
||||||
{
|
|
||||||
tabPage ^p;
|
|
||||||
List<tabPage ^> ^pages;
|
|
||||||
|
|
||||||
pages = (*(t->pages));
|
|
||||||
p = pages[index];
|
|
||||||
pages->RemoveAt(index);
|
|
||||||
(*(t->tab))->Items->RemoveAt(index);
|
|
||||||
p->border->Child = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
uintmax_t uiTabNumPages(uiTab *t)
|
|
||||||
{
|
|
||||||
return (*(t->pages))->Count;
|
|
||||||
}
|
|
||||||
|
|
||||||
int uiTabMargined(uiTab *t, uintmax_t page)
|
|
||||||
{
|
|
||||||
List<tabPage ^> ^pages;
|
|
||||||
|
|
||||||
pages = (*(t->pages));
|
|
||||||
return pages[page]->margined;
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiTabSetMargined(uiTab *t, uintmax_t page, int margined)
|
|
||||||
{
|
|
||||||
List<tabPage ^> ^pages;
|
|
||||||
|
|
||||||
pages = (*(t->pages));
|
|
||||||
pages[page]->margined = margined;
|
|
||||||
// TabItem margins/padding do NOT work the way we want them to
|
|
||||||
// we have to use a Border here too
|
|
||||||
// TODO Padding?
|
|
||||||
if (pages[page]->margined)
|
|
||||||
pages[page]->border->Margin = Thickness(10, 10, 10, 10);
|
|
||||||
else
|
|
||||||
pages[page]->border->Margin = Thickness(0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
uiTab *uiNewTab(void)
|
|
||||||
{
|
|
||||||
uiTab *t;
|
|
||||||
|
|
||||||
t = (uiTab *) uiNewControl(uiTabType());
|
|
||||||
|
|
||||||
t->tab = new gcroot<TabControl ^>();
|
|
||||||
*(t->tab) = gcnew TabControl();
|
|
||||||
|
|
||||||
t->pages = new gcroot<List<tabPage ^> ^>();
|
|
||||||
*(t->pages) = gcnew List<tabPage ^>();
|
|
||||||
|
|
||||||
uiWindowsFinishNewControl(t, uiTab, tab);
|
|
||||||
|
|
||||||
return t;
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
// 25 november 2015
|
|
||||||
#include "uipriv_winforms.hpp"
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
using namespace System::Text;
|
|
||||||
using namespace System::Runtime::InteropServices;
|
|
||||||
|
|
||||||
// TODO export?
|
|
||||||
String ^fromUTF8(const char *str)
|
|
||||||
{
|
|
||||||
array<Byte> ^bytes;
|
|
||||||
size_t len;
|
|
||||||
|
|
||||||
len = strlen(str);
|
|
||||||
bytes = gcnew array<Byte>(len);
|
|
||||||
// TODO avoid the cast
|
|
||||||
Marshal::Copy(IntPtr((char *) str), bytes, 0, len);
|
|
||||||
return Encoding::UTF8->GetString(bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
// see http://stackoverflow.com/questions/27526093/convert-systemstring-to-stdstring-in-utf8-which-later-converted-to-char-as
|
|
||||||
char *uiWindowsCLRStringToText(gcroot<System::String ^> str)
|
|
||||||
{
|
|
||||||
array<Byte> ^bytes;
|
|
||||||
char *cstr;
|
|
||||||
|
|
||||||
bytes = Encoding::UTF8->GetBytes(str);
|
|
||||||
cstr = (char *) uiAlloc((bytes->Length + 1) * sizeof (char), "char[]");
|
|
||||||
Marshal::Copy(bytes, 0, IntPtr(cstr), bytes->Length);
|
|
||||||
cstr[bytes->Length] = '\0';
|
|
||||||
return cstr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiFreeText(char *c)
|
|
||||||
{
|
|
||||||
uiFree(c);
|
|
||||||
}
|
|
|
@ -1,72 +0,0 @@
|
||||||
// 7 april 2015
|
|
||||||
|
|
||||||
/*
|
|
||||||
This file assumes that you have included <vccrt.h> and "ui.h" beforehand, as well as #using <System.dll> and the three WPF DLLs (TODO) (but not necessarily beforehand). It provides API-specific functions for interfacing with foreign controls in Windows.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __LIBUI_UI_WINDOWS_H__
|
|
||||||
#define __LIBUI_UI_WINDOWS_H__
|
|
||||||
|
|
||||||
#ifndef __cplusplus_cli
|
|
||||||
#error Sorry; ui_winforms.hpp can currently only be used from C++/CLI code.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
|
|
||||||
typedef struct uiWindowsSizing uiWindowsSizing;
|
|
||||||
|
|
||||||
typedef struct uiWindowsControl uiWindowsControl;
|
|
||||||
struct uiWindowsControl {
|
|
||||||
uiControl c;
|
|
||||||
// TODO make truly private
|
|
||||||
gcroot<System::Windows::UIElement ^> *genericHandle;
|
|
||||||
};
|
|
||||||
_UI_EXTERN uintmax_t uiWindowsControlType(void);
|
|
||||||
#define uiWindowsControl(this) ((uiWindowsControl *) uiIsA((this), uiWindowsControlType(), 1))
|
|
||||||
|
|
||||||
// TODO document
|
|
||||||
#define uiWindowsDefineControlWithOnDestroy(type, typefn, handle, onDestroy) \
|
|
||||||
static uintmax_t _ ## type ## Type = 0; \
|
|
||||||
uintmax_t typefn(void) \
|
|
||||||
{ \
|
|
||||||
if (_ ## type ## Type == 0) \
|
|
||||||
_ ## type ## Type = uiRegisterType(#type, uiWindowsControlType(), sizeof (type)); \
|
|
||||||
return _ ## type ## Type; \
|
|
||||||
} \
|
|
||||||
static void _ ## type ## CommitDestroy(uiControl *c) \
|
|
||||||
{ \
|
|
||||||
type *hthis = type(c); \
|
|
||||||
onDestroy; \
|
|
||||||
delete uiWindowsControl(c)->genericHandle; \
|
|
||||||
delete hthis->handle; \
|
|
||||||
} \
|
|
||||||
static uintptr_t _ ## type ## Handle(uiControl *c) \
|
|
||||||
{ \
|
|
||||||
return (uintptr_t) (uiWindowsControl(c)->genericHandle); \
|
|
||||||
} \
|
|
||||||
static void _ ## type ## ContainerUpdateState(uiControl *c) \
|
|
||||||
{ \
|
|
||||||
/* do nothing */ \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define uiWindowsDefineControl(type, typefn, handle) \
|
|
||||||
uiWindowsDefineControlWithOnDestroy(type, typefn, handle, (void) hthis;)
|
|
||||||
|
|
||||||
#define uiWindowsFinishNewControl(variable, type, handle) \
|
|
||||||
uiControl(variable)->CommitDestroy = _ ## type ## CommitDestroy; \
|
|
||||||
uiControl(variable)->Handle = _ ## type ## Handle; \
|
|
||||||
uiControl(variable)->ContainerUpdateState = _ ## type ## ContainerUpdateState; \
|
|
||||||
uiWindowsControl(variable)->genericHandle = new gcroot<System::Windows::UIElement ^>(); \
|
|
||||||
*(uiWindowsControl(variable)->genericHandle) = *(variable->handle); \
|
|
||||||
uiWindowsFinishControl(uiControl(variable));
|
|
||||||
|
|
||||||
// This is a function used to set up a control.
|
|
||||||
// Don't call it directly; use uiWindowsFinishNewControl() instead.
|
|
||||||
_UI_EXTERN void uiWindowsFinishControl(uiControl *c);
|
|
||||||
|
|
||||||
// TODO document
|
|
||||||
_UI_EXTERN char *uiWindowsCLRStringToText(gcroot<System::String ^> str);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,28 +0,0 @@
|
||||||
// 25 november 2015
|
|
||||||
#include <vcclr.h>
|
|
||||||
#include "../ui.h"
|
|
||||||
#include "ui_winforms.hpp"
|
|
||||||
#include "../common/uipriv.h"
|
|
||||||
#include "unmanaged.h"
|
|
||||||
|
|
||||||
#using <System.dll>
|
|
||||||
#using <System.Windows.Forms.dll>
|
|
||||||
using namespace System;
|
|
||||||
using namespace System::Windows::Forms;
|
|
||||||
|
|
||||||
// text.cpp
|
|
||||||
extern String ^fromUTF8(const char *);
|
|
||||||
|
|
||||||
// control.cpp
|
|
||||||
extern Control ^genericHandle(uiControl *c);
|
|
||||||
|
|
||||||
typedef gcroot<Label ^> *DUMMY;
|
|
||||||
static inline DUMMY mkdummy(String ^classname)
|
|
||||||
{
|
|
||||||
DUMMY t;
|
|
||||||
|
|
||||||
t = new gcroot<Label ^>();
|
|
||||||
*t = gcnew Label();
|
|
||||||
(*t)->Content = L"TODO " + classname + L" not implemented";
|
|
||||||
return t;
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
// 25 november 2015
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#else
|
|
||||||
#include "winapi.h"
|
|
||||||
#include "../ui.h"
|
|
||||||
#include "../common/uipriv.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// main.cpp
|
|
||||||
extern void initWinForms(void);
|
|
||||||
extern void uninitWinForms(void);
|
|
||||||
|
|
||||||
// alloc.c
|
|
||||||
extern int initAlloc(void);
|
|
||||||
extern void uninitAlloc(void);
|
|
||||||
|
|
||||||
// init.c
|
|
||||||
extern uiInitOptions options;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -1,17 +0,0 @@
|
||||||
// 6 april 2015
|
|
||||||
#include "unmanaged.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
void complain(const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
|
|
||||||
va_start(ap, fmt);
|
|
||||||
fprintf(stderr, "[libui] ");
|
|
||||||
vfprintf(stderr, fmt, ap);
|
|
||||||
fprintf(stderr, "\n");
|
|
||||||
va_end(ap);
|
|
||||||
DebugBreak();
|
|
||||||
abort(); // just in case
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
// 31 may 2015
|
|
||||||
#define UNICODE
|
|
||||||
#define _UNICODE
|
|
||||||
#define STRICT
|
|
||||||
#define STRICT_TYPED_ITEMIDS
|
|
||||||
// get Windows version right; right now Windows Vista
|
|
||||||
#define WINVER 0x0600 /* according to Microsoft's winnls.h */
|
|
||||||
#define _WIN32_WINNT 0x0600 /* according to Microsoft's sdkddkver.h */
|
|
||||||
#define _WIN32_WINDOWS 0x0600 /* according to Microsoft's pdh.h */
|
|
||||||
#define _WIN32_IE 0x0700 /* according to Microsoft's sdkddkver.h */
|
|
||||||
#define NTDDI_VERSION 0x06000000 /* according to Microsoft's sdkddkver.h */
|
|
||||||
#include <windows.h>
|
|
||||||
#include <stdarg.h>
|
|
|
@ -1,165 +0,0 @@
|
||||||
// 25 november 2015
|
|
||||||
#include "uipriv_winforms.hpp"
|
|
||||||
|
|
||||||
// TODO save alignment of children?
|
|
||||||
|
|
||||||
ref class libuiForm : public Form {
|
|
||||||
public:
|
|
||||||
uiWindow *w;
|
|
||||||
// void onClosing(Object ^sender, CancelEventArgs ^e);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct uiWindow {
|
|
||||||
uiWindowsControl c;
|
|
||||||
gcroot<libuiForm ^> *form;
|
|
||||||
|
|
||||||
uiControl *child;
|
|
||||||
int margined;
|
|
||||||
|
|
||||||
int (*onClosing)(uiWindow *, void *);
|
|
||||||
void *onClosingData;
|
|
||||||
// gcroot<CancelEventHandler ^> *onClosingDelegate;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void onDestroy(uiWindow *);
|
|
||||||
|
|
||||||
uiWindowsDefineControlWithOnDestroy(
|
|
||||||
uiWindow, // type name
|
|
||||||
uiWindowType, // type function
|
|
||||||
window, // handle
|
|
||||||
onDestroy(hthis); // on destroy
|
|
||||||
)
|
|
||||||
|
|
||||||
/*
|
|
||||||
void libuiWindow::onClosing(Object ^sender, CancelEventArgs ^e)
|
|
||||||
{
|
|
||||||
// TODO copy comments
|
|
||||||
if ((*(this->w->onClosing))(this->w, this->w->onClosingData))
|
|
||||||
uiControlDestroy(uiControl(this->w));
|
|
||||||
e->Cancel = true;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int defaultOnClosing(uiWindow *w, void *data)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void onDestroy(uiWindow *w)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
// first hide the window
|
|
||||||
(*(w->window))->Hide();
|
|
||||||
// take off the closing event; otherwise it will be recursed
|
|
||||||
(*(w->window))->Closing -= *(w->onClosingDelegate);
|
|
||||||
delete w->onClosingDelegate;
|
|
||||||
// then destroy the child
|
|
||||||
if (w->child != NULL) {
|
|
||||||
(*(w->border))->Child = nullptr;
|
|
||||||
uiControlSetParent(w->child, NULL);
|
|
||||||
uiControlDestroy(w->child);
|
|
||||||
}
|
|
||||||
// clean up remaining .net objects
|
|
||||||
delete w->border;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
static void windowCommitShow(uiControl *c)
|
|
||||||
{
|
|
||||||
uiWindow *w = uiWindow(c);
|
|
||||||
|
|
||||||
// TODO does this behave properly in re presentation?
|
|
||||||
(*(w->window))->Show();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void windowCommitHide(uiControl *c)
|
|
||||||
{
|
|
||||||
uiWindow *w = uiWindow(c);
|
|
||||||
|
|
||||||
(*(w->window))->Hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void windowContainerUpdateState(uiControl *c)
|
|
||||||
{
|
|
||||||
uiWindow *w = uiWindow(c);
|
|
||||||
|
|
||||||
if (w->child != NULL)
|
|
||||||
controlUpdateState(w->child);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *uiWindowTitle(uiWindow *w)
|
|
||||||
{
|
|
||||||
return uiWindowsCLRStringToText((*(w->window))->Text);
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiWindowSetTitle(uiWindow *w, const char *title)
|
|
||||||
{
|
|
||||||
(*(w->window))->Text = fromUTF8(title);
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiWindowOnClosing(uiWindow *w, int (*f)(uiWindow *, void *), void *data)
|
|
||||||
{
|
|
||||||
w->onClosing = f;
|
|
||||||
w->onClosingData = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiWindowSetChild(uiWindow *w, uiControl *child)
|
|
||||||
{
|
|
||||||
if (w->child != NULL) {
|
|
||||||
uiControlSetParent(w->child, NULL);
|
|
||||||
// (*(w->border))->Child = nullptr;
|
|
||||||
}
|
|
||||||
w->child = child;
|
|
||||||
if (w->child != NULL) {
|
|
||||||
// (*(w->border))->Child = genericHandle(w->child);
|
|
||||||
uiControlSetParent(w->child, uiControl(w));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int uiWindowMargined(uiWindow *w)
|
|
||||||
{
|
|
||||||
return w->margined;
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiWindowSetMargined(uiWindow *w, int margined)
|
|
||||||
{
|
|
||||||
w->margined = margined;
|
|
||||||
/* // TODO margin or padding?
|
|
||||||
if (w->margined)
|
|
||||||
(*(w->border))->Margin = Thickness(10, 10, 10, 10);
|
|
||||||
else
|
|
||||||
(*(w->border))->Margin = Thickness(0, 0, 0, 0);
|
|
||||||
*/}
|
|
||||||
|
|
||||||
uiWindow *uiNewWindow(const char *title, int width, int height, int hasMenubar)
|
|
||||||
{
|
|
||||||
uiWindow *w;
|
|
||||||
|
|
||||||
w = (uiWindow *) uiNewControl(uiWindowType());
|
|
||||||
|
|
||||||
w->form = new gcroot<libuiForm ^>();
|
|
||||||
*(w->form) = gcnew libuiForm();
|
|
||||||
(*(w->form))->w = w;
|
|
||||||
|
|
||||||
(*(w->window))->Text = fromUTF8(title);
|
|
||||||
// (*(w->window))->ClientSize = xxxxx(width, height);
|
|
||||||
|
|
||||||
// TODO background color?
|
|
||||||
|
|
||||||
/* w->border = new gcroot<Border ^>();
|
|
||||||
*(w->border) = gcnew Border();
|
|
||||||
(*(w->window))->Content = *(w->border);
|
|
||||||
|
|
||||||
w->onClosingDelegate = new gcroot<CancelEventHandler ^>();
|
|
||||||
*(w->onClosingDelegate) = gcnew CancelEventHandler(*(w->window),
|
|
||||||
&libuiWindow::onClosing);
|
|
||||||
(*(w->window))->Closing += *(w->onClosingDelegate);
|
|
||||||
*/ uiWindowOnClosing(w, defaultOnClosing, NULL);
|
|
||||||
|
|
||||||
uiWindowsFinishNewControl(w, uiWindow, window);
|
|
||||||
uiControl(w)->CommitShow = windowCommitShow;
|
|
||||||
uiControl(w)->CommitHide = windowCommitHide;
|
|
||||||
uiControl(w)->ContainerUpdateState = windowContainerUpdateState;
|
|
||||||
|
|
||||||
return w;
|
|
||||||
}
|
|
Loading…
Reference in New Issue