int main(void) { uiInitOptions o; uiWindow *w; uiBox *b; uiButton *btn; memset(&o, 0, sizeof (uiInitOptions)); if (uiInit(&o) != NULL) abort(); w = uiNewWindow("Hello", 320, 240, 0); uiWindowSetMargined(w, 1); b = uiNewVerticalBox(); uiBoxSetPadded(b, 1); uiWindowSetChild(w, uiControl(b)); e = uiNewMultilineEntry(); uiMultilineEntrySetReadOnly(e, 1); btn = uiNewButton("Say Something"); uiButtonOnClicked(btn, saySomething, NULL); uiBoxAppend(b, uiControl(btn), 0); uiBoxAppend(b, uiControl(e), 1); uiTimer(1000, sayTime, NULL); uiWindowOnClosing(w, onClosing, NULL); uiControlShow(uiControl(w)); uiMain(); return 0; }
static void borderWindowOpen(uiButton *b, void *data) { uiWindow *w; uiArea *a; if (!borderAHInit) { borderAH.Draw = handlerDraw; borderAH.MouseEvent = handlerMouseEvent; borderAH.MouseCrossed = handlerMouseCrossed; borderAH.DragBroken = handlerDragBroken; borderAH.KeyEvent = handlerKeyEvent; borderAHInit = 1; } w = uiNewWindow("Border Resize Test", 300, 500, 0); uiWindowSetBorderless(w, 1); a = uiNewArea(&borderAH); // uiWindowSetChild(w, uiControl(a)); {uiBox *b; b=uiNewHorizontalBox(); uiBoxAppend(b,uiControl(a),1); uiWindowSetChild(w,uiControl(b));} //TODO why is this hack needed? GTK+ issue uiControlShow(uiControl(w)); }
static uiBox *half(uiMultilineEntry *(*mk)(void), const char *which) { uiBox *vbox, *hbox; uiMultilineEntry *me; uiButton *button; vbox = newVerticalBox(); me = (*mk)(); uiMultilineEntryOnChanged(me, meChanged, (void *) which); uiBoxAppend(vbox, uiControl(me), 1); hbox = newHorizontalBox(); uiBoxAppend(vbox, uiControl(hbox), 0); button = uiNewButton("Set"); uiButtonOnClicked(button, setClicked, me); uiBoxAppend(hbox, uiControl(button), 0); button = uiNewButton("Append"); uiButtonOnClicked(button, appendClicked, me); uiBoxAppend(hbox, uiControl(button), 0); return vbox; }
uiBox *makePage10(void) { uiBox *page10; uiBox *vbox; uiBox *hbox; page10 = newVerticalBox(); vbox = page10; hbox = newHorizontalBox(); uiBoxAppend(vbox, uiControl(hbox), 0); textString = uiNewEntry(); // TODO make it placeholder uiEntrySetText(textString, "Enter text here"); uiBoxAppend(hbox, uiControl(textString), 1); textFontButton = uiNewFontButton(); uiBoxAppend(hbox, uiControl(textFontButton), 1); hbox = newHorizontalBox(); uiBoxAppend(vbox, uiControl(hbox), 0); textApply = uiNewButton("Apply"); uiButtonOnClicked(textApply, onTextApply, NULL); uiBoxAppend(hbox, uiControl(textApply), 1); textWidth = uiNewEntry(); uiEntrySetText(textWidth, "-1"); uiBoxAppend(hbox, uiControl(textWidth), 1); addLeading = uiNewCheckbox("Add Leading"); uiCheckboxSetChecked(addLeading, 1); uiBoxAppend(hbox, uiControl(addLeading), 0); textAreaHandler.Draw = handlerDraw; textAreaHandler.MouseEvent = handlerMouseEvent; textAreaHandler.MouseCrossed = handlerMouseCrossed; textAreaHandler.DragBroken = handlerDragBroken; textAreaHandler.KeyEvent = handlerKeyEvent; textArea = uiNewArea(&textAreaHandler); uiBoxAppend(vbox, uiControl(textArea), 1); // dummy objects to test single-activation hbox = newHorizontalBox(); uiBoxAppend(vbox, uiControl(hbox), 0); uiBoxAppend(hbox, uiControl(uiNewFontButton()), 1); return page10; }
uiBox *makePage12(void) { uiBox *page12; uiBox *b; page12 = newHorizontalBox(); b = half(uiNewMultilineEntry, "wrap"); uiBoxAppend(page12, uiControl(b), 1); b = half(uiNewNonWrappingMultilineEntry, "no wrap"); uiBoxAppend(page12, uiControl(b), 1); return page12; }
uiSpinbox *uiNewSpinbox(int min, int max) { uiSpinbox *s; int temp; if (min >= max) { temp = min; min = max; max = temp; } uiWindowsNewControl(uiSpinbox, s); s->hwnd = uiWindowsMakeContainer(uiWindowsControl(s), onResize); s->edit = uiWindowsEnsureCreateControlHWND(WS_EX_CLIENTEDGE, L"edit", L"", // don't use ES_NUMBER; it doesn't allow typing in a leading - ES_AUTOHSCROLL | ES_LEFT | ES_NOHIDESEL | WS_TABSTOP, hInstance, NULL, TRUE); uiWindowsEnsureSetParentHWND(s->edit, s->hwnd); uiWindowsRegisterWM_COMMANDHandler(s->edit, onWM_COMMAND, uiControl(s)); uiSpinboxOnChanged(s, defaultOnChanged, NULL); recreateUpDown(s); s->inhibitChanged = TRUE; SendMessageW(s->updown, UDM_SETRANGE32, (WPARAM) min, (LPARAM) max); SendMessageW(s->updown, UDM_SETPOS32, 0, (LPARAM) min); s->inhibitChanged = FALSE; return s; }
void uiRadioButtonsAppend(uiRadioButtons *r, const char *text) { HWND hwnd; WCHAR *wtext; DWORD groupTabStop; // the first radio button gets both WS_GROUP and WS_TABSTOP // successive radio buttons get *neither* groupTabStop = 0; if (r->hwnds->size() == 0) groupTabStop = WS_GROUP | WS_TABSTOP; wtext = toUTF16(text); hwnd = uiWindowsEnsureCreateControlHWND(0, L"button", wtext, BS_RADIOBUTTON | groupTabStop, hInstance, NULL, TRUE); uiFree(wtext); uiWindowsEnsureSetParentHWND(hwnd, r->hwnd); uiWindowsRegisterWM_COMMANDHandler(hwnd, onWM_COMMAND, uiControl(r)); r->hwnds->push_back(hwnd); radiobuttonsArrangeChildren(r); uiWindowsControlMinimumSizeChanged(uiWindowsControl(r)); }
static uiControl *simpleGrid(void) { uiGrid *g; uiControl *t4; g = newGrid(); uiGridAppend(g, testControl("1", red), 0, 0, 1, 1, 0, uiAlignFill, 0, uiAlignFill); uiGridAppend(g, testControl("2", green), 1, 0, 1, 1, 0, uiAlignFill, 0, uiAlignFill); uiGridAppend(g, testControl("3", blue), 2, 0, 1, 1, 0, uiAlignFill, 0, uiAlignFill); t4 = testControl("4", green); uiGridAppend(g, t4, 0, 1, 1, 1, 0, uiAlignFill, 1, uiAlignFill); uiGridInsertAt(g, testControl("5", blue), t4, uiAtTrailing, 2, 1, 0, uiAlignFill, 0, uiAlignFill); uiGridAppend(g, testControl("6", yellow), -1, 0, 1, 2, 1, uiAlignFill, 0, uiAlignFill); return uiControl(g); }
static uiControl *spanningGrid(void) { uiGrid *g; g = newGrid(); uiGridAppend(g, testControl("0", blue), 0, 4, 4, 1, 1, uiAlignFill, 0, uiAlignFill); uiGridAppend(g, testControl("1", green), 4, 0, 1, 4, 0, uiAlignFill, 1, uiAlignFill); uiGridAppend(g, testControl("2", red), 3, 3, 1, 1, 1, uiAlignFill, 1, uiAlignFill); uiGridAppend(g, testControl("3", yellow), 0, 3, 2, 1, 0, uiAlignFill, 0, uiAlignFill); uiGridAppend(g, testControl("4", orange), 3, 0, 1, 2, 0, uiAlignFill, 0, uiAlignFill); uiGridAppend(g, testControl("5", purple), 1, 1, 1, 1, 0, uiAlignFill, 0, uiAlignFill); uiGridAppend(g, testControl("6", white), 0, 1, 1, 1, 0, uiAlignFill, 0, uiAlignFill); uiGridAppend(g, testControl("7", cyan), 1, 0, 1, 1, 0, uiAlignFill, 0, uiAlignFill); return uiControl(g); }
uiBox *makePage9(void) { uiBox *page9; uiTable *table; uiTableModel *model; uiTableColumnParams p; intmax_t i; page9 = newVerticalBox(); table = uiNewTable(); uiBoxAppend(page9, uiControl(table), 1); spec.NumRows = modelNumRows; spec.CellValue = modelCellValue; spec.SetCellValue = modelSetCellValue; model = uiNewTableModel(nColumns, coltypes, &spec, NULL); uiTableSetModel(table, model); for (i = 0; i < nColumns; i++) { p.Name = "Column"; p.Type = coltypes[i]; p.Mutable = i % 2 == 1; p.ValueColumn = i; uiTableAppendColumn(table, &p); } return page9; }
/* Cast a Janet into a uiControl structure. Returns a pointer to * the uiControl, or panics if cast fails. */ static uiControl *janet_getcontrol(const Janet *argv, int32_t n) { Janet x = argv[n]; if (!janet_checktype(x, JANET_ABSTRACT)) { janet_panicf("expected ui control, got %v", x); } UIControlWrapper *abst = janet_unwrap_abstract(x); const JanetAbstractType *at = janet_abstract_type(abst); if (at == &control_td || at == &window_td || at == &button_td || at == &box_td || at == &checkbox_td || at == &entry_td || at == &label_td || at == &tab_td || at == &group_td || at == &spinbox_td || at == &slider_td || at == &progress_bar_td || at == &separator_td || at == &combobox_td || at == &editable_combobox_td || at == &radio_buttons_td || at == &date_time_picker_td || at == &multiline_entry_td || at == &menu_item_td || at == &menu_td) { if (abst->flags & UI_FLAG_DESTROYED) { janet_panic("ui control already destoryed"); } return uiControl(abst->control); } janet_panicf("expected ui control, got %v", x); return NULL; }
static uiControl *testControl(const char *label, int color) { uiColorButton *b; b = uiNewColorButton(); uiColorButtonSetColor(b, colors[color].r, colors[color].g, colors[color].b, 1.0); return uiControl(b); }
void uiEditableComboboxDestroy(uiControl *cc) { uiEditableCombobox *c = uiEditableCombobox(cc); uiWindowsUnregisterWM_COMMANDHandler(c->hwnd); uiWindowsEnsureDestroyWindow(c->hwnd); uiFreeControl(uiControl(c)); }
void uiWindowsControlContinueMinimumSizeChanged(uiWindowsControl *c) { uiControl *parent; parent = uiControlParent(uiControl(c)); if (parent != NULL) uiWindowsControlMinimumSizeChanged(uiWindowsControl(parent)); }
static void uiImageBoxDestroy(uiControl *c) { uiImageBox *b = uiImageBox(c); uiImageBoxSetImage(b, NULL); uiWindowsEnsureDestroyWindow(b->hwnd); uiFreeControl(uiControl(b)); }
static void uiMultilineEntryDestroy(uiControl *c) { uiMultilineEntry *e = uiMultilineEntry(c); uiWindowsUnregisterWM_COMMANDHandler(e->hwnd); uiWindowsEnsureDestroyWindow(e->hwnd); uiFreeControl(uiControl(e)); }
static void openTestWindow(uiBox *(*mkf)(void)) { uiWindow *w; uiBox *b; uiCombobox *c; uiEditableCombobox *e; uiRadioButtons *r; w = uiNewWindow("Test", 100, 100, 0); uiWindowOnClosing(w, winClose, NULL); uiWindowSetMargined(w, 1); b = (*mkf)(); uiWindowSetChild(w, uiControl(b)); #define BA(x) uiBoxAppend(b, uiControl(x), 0) BA(uiNewButton("")); BA(uiNewCheckbox("")); BA(uiNewEntry()); BA(uiNewLabel("")); BA(uiNewSpinbox(0, 100)); BA(uiNewProgressBar()); BA(uiNewSlider(0, 100)); BA(uiNewHorizontalSeparator()); c = uiNewCombobox(); uiComboboxAppend(c, ""); BA(c); e = uiNewEditableCombobox(); uiEditableComboboxAppend(e, ""); BA(e); r = uiNewRadioButtons(); uiRadioButtonsAppend(r, ""); BA(r); BA(uiNewDateTimePicker()); BA(uiNewDatePicker()); BA(uiNewTimePicker()); BA(uiNewMultilineEntry()); // TODO nonscrolling and scrolling areas? BA(uiNewFontButton()); BA(uiNewColorButton()); BA(uiNewPasswordEntry()); BA(uiNewSearchEntry()); BA(uiNewVerticalSeparator()); uiControlShow(uiControl(w)); }
uiGroup *makePage7a(void) { uiGroup *group; uiBox *box, *box2; handler.ah.Draw = handlerDraw; handler.ah.MouseEvent = handlerMouseEvent; handler.ah.MouseCrossed = handlerMouseCrossed; handler.ah.DragBroken = handlerDragBroken; handler.ah.KeyEvent = handlerKeyEvent; group = newGroup("Arc Test"); box = newVerticalBox(); uiGroupSetChild(group, uiControl(box)); area = uiNewArea((uiAreaHandler *) (&handler)); uiBoxAppend(box, uiControl(area), 1); box2 = newHorizontalBox(); uiBoxAppend(box, uiControl(box2), 0); uiBoxAppend(box2, uiControl(uiNewLabel("Start Angle")), 0); startAngle = uiNewEntry(); uiEntryOnChanged(startAngle, entryChanged, NULL); uiBoxAppend(box2, uiControl(startAngle), 1); box2 = newHorizontalBox(); uiBoxAppend(box, uiControl(box2), 0); uiBoxAppend(box2, uiControl(uiNewLabel("Sweep")), 0); sweep = uiNewEntry(); uiEntryOnChanged(sweep, entryChanged, NULL); uiBoxAppend(box2, uiControl(sweep), 1); negative = uiNewCheckbox("Negative"); uiCheckboxOnToggled(negative, checkboxToggled, NULL); uiBoxAppend(box, uiControl(negative), 0); radians = uiNewCheckbox("Radians"); uiCheckboxOnToggled(radians, checkboxToggled, NULL); uiBoxAppend(box, uiControl(radians), 0); return group; }
static void uiColorButtonDestroy(uiControl *c) { uiColorButton *b = uiColorButton(c); uiWindowsUnregisterWM_COMMANDHandler(b->hwnd); uiWindowsUnregisterWM_NOTIFYHandler(b->hwnd); uiWindowsEnsureDestroyWindow(b->hwnd); uiFreeControl(uiControl(b)); }
static void showHide(uiButton *b, void *data) { uiControl *c = uiControl(data); if (uiControlVisible(c)) uiControlHide(c); else uiControlShow(c); }
int onShouldQuit(void *data) { printf("in onShouldQuit()\n"); if (uiMenuItemChecked(shouldQuitItem)) { uiControlDestroy(uiControl(data)); return 1; } return 0; }
static void uiSpinboxDestroy(uiControl *c) { uiSpinbox *s = uiSpinbox(c); uiWindowsUnregisterWM_COMMANDHandler(s->edit); uiWindowsEnsureDestroyWindow(s->updown); uiWindowsEnsureDestroyWindow(s->edit); uiWindowsEnsureDestroyWindow(s->hwnd); uiFreeControl(uiControl(s)); }
Window::Window(string title) : title{title}, mainLayout{uiNewHorizontalBox()}, histogram(handler, datapoints, color) { mainwin = uiNewWindow(title.c_str(), 640, 480, 0); uiWindowSetMargined(mainwin, 1); uiBoxSetPadded(mainLayout, 1); uiWindowSetChild(mainwin, uiControl(mainLayout)); typedef void (*callback_handlerdraw_t)(uiAreaHandler*, uiArea*, uiAreaDrawParams*); Callback<void(uiAreaHandler*, uiArea*, uiAreaDrawParams*)>::func = std::bind(&Window::handlerDraw, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); callback_handlerdraw_t handlerDrawFunction = static_cast<callback_handlerdraw_t>(Callback<void(uiAreaHandler*, uiArea*, uiAreaDrawParams*)>::callback); typedef void (*callback_handlermouseevent_t)(uiAreaHandler*, uiArea*, uiAreaMouseEvent*); Callback<void(uiAreaHandler*, uiArea*, uiAreaMouseEvent*)>::func = std::bind(&Window::handlerMouseEvent, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); callback_handlermouseevent_t handlerMouseeventFunction = static_cast<callback_handlermouseevent_t>(Callback<void(uiAreaHandler*, uiArea*, uiAreaMouseEvent*)>::callback); // only draw and mouseEvent are implemented for now // they are "filled" by the widgets handler.Draw = handlerDrawFunction; handler.MouseEvent = handlerMouseeventFunction; handler.MouseCrossed = [] (uiAreaHandler *ha, uiArea *a, int left) {}; handler.DragBroken = [] (uiAreaHandler *ah, uiArea *a) {}; handler.KeyEvent = [] (uiAreaHandler *ah, uiArea *a, uiAreaKeyEvent *e) {return 0;}; // reject all keys // todo: the data should be stored in the histogramm application, // not in the window // TODO: the datapoints and color are not passed correctly by reference! toolbox.attach(mainLayout); histogram.attachToolboxController(toolbox); histogram.attachHandlerController(this); histogram.attach(mainLayout); uiWindowOnClosing(mainwin, [](uiWindow *w, void *data) {uiControlDestroy(uiControl(w)); uiQuit(); return 0;}, NULL); typedef int (*callback_quitfunction_t)(void*); Callback<int(void*)>::func = std::bind(&Window::onQuit, this, std::placeholders::_1); callback_quitfunction_t quitFunction = static_cast<callback_quitfunction_t>(Callback<int(void*)>::callback); uiOnShouldQuit(quitFunction, NULL); }
static gboolean onClosing(GtkWidget *win, GdkEvent *e, gpointer data) { uiWindow *w = uiWindow(data); // manually destroy the window ourselves; don't let the delete-event handler do it if ((*(w->onClosing))(w, w->onClosingData)) uiControlDestroy(uiControl(w)); // don't continue to the default delete-event handler; we destroyed the window by now return TRUE; }
void enableAllWindowsExcept(uiWindow *which) { for (auto &w : windows) { if (w.first == which) continue; if (!uiControlEnabled(uiControl(w.first))) continue; EnableWindow(w.first->hwnd, TRUE); } }
static LRESULT CALLBACK windowWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { LONG_PTR ww; uiWindow *w; CREATESTRUCTW *cs = (CREATESTRUCTW *) lParam; WINDOWPOS *wp = (WINDOWPOS *) lParam; MINMAXINFO *mmi = (MINMAXINFO *) lParam; intmax_t width, height; LRESULT lResult; ww = GetWindowLongPtrW(hwnd, GWLP_USERDATA); if (ww == 0) { if (uMsg == WM_CREATE) SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LONG_PTR) (cs->lpCreateParams)); // fall through to DefWindowProc() anyway return DefWindowProcW(hwnd, uMsg, wParam, lParam); } w = uiWindow((void *) ww); if (handleParentMessages(hwnd, uMsg, wParam, lParam, &lResult) != FALSE) return lResult; switch (uMsg) { case WM_COMMAND: // not a menu if (lParam != 0) break; if (HIWORD(wParam) != 0) break; runMenuEvent(LOWORD(wParam), uiWindow(w)); return 0; case WM_WINDOWPOSCHANGED: if ((wp->flags & SWP_NOSIZE) != 0) break; windowRelayout(w); return 0; case WM_GETMINMAXINFO: // ensure the user cannot resize the window smaller than its minimum size lResult = DefWindowProcW(hwnd, uMsg, wParam, lParam); uiWindowsControlMinimumSize(uiWindowsControl(w), &width, &height); // width and height are in client coordinates; ptMinTrackSize is in window coordinates clientSizeToWindowSize(w->hwnd, &width, &height, w->hasMenubar); mmi->ptMinTrackSize.x = width; mmi->ptMinTrackSize.y = height; return lResult; case WM_PRINTCLIENT: // we do no special painting; just erase the background // don't worry about the return value; we let DefWindowProcW() handle this message SendMessageW(hwnd, WM_ERASEBKGND, wParam, lParam); return 0; case WM_CLOSE: if ((*(w->onClosing))(w, w->onClosingData)) uiControlDestroy(uiControl(w)); return 0; // we destroyed it already } return DefWindowProcW(hwnd, uMsg, wParam, lParam); }
static void uiGroupDestroy(uiControl *c) { uiGroup *g = uiGroup(c); if (g->child != NULL) { uiControlSetParent(g->child, NULL); uiControlDestroy(g->child); } uiWindowsEnsureDestroyWindow(g->hwnd); uiFreeControl(uiControl(g)); }
BOOL uiWindowsShouldStopSyncEnableState(uiWindowsControl *c, BOOL enabled) { int ce; ce = uiControlEnabled(uiControl(c)); // only stop if we're going from disabled back to enabled; don't stop under any other condition // (if we stop when going from enabled to disabled then enabled children of a disabled control won't get disabled at the OS level) if (!ce && enabled) return TRUE; return FALSE; }
static void uiRadioButtonsDestroy(uiControl *c) { uiRadioButtons *r = uiRadioButtons(c); for (const HWND &hwnd : *(r->hwnds)) { uiWindowsUnregisterWM_COMMANDHandler(hwnd); uiWindowsEnsureDestroyWindow(hwnd); } delete r->hwnds; uiWindowsEnsureDestroyWindow(r->hwnd); uiFreeControl(uiControl(r)); }
// TODO save and restore expands and aligns void uiWindowSetChild(uiWindow *w, uiControl *child) { if (w->child != NULL) { uiControlSetParent(w->child, NULL); uiUnixControlSetContainer(uiUnixControl(w->child), w->childHolderContainer, TRUE); } w->child = child; if (w->child != NULL) { uiControlSetParent(w->child, uiControl(w)); uiUnixControlSetContainer(uiUnixControl(w->child), w->childHolderContainer, FALSE); } }