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