UNIXworkcode

1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright 2025 Olaf Wintermann. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include "text.h" 30 31 static W32WidgetClass textarea_widget_class = { 32 .eventproc = ui_textarea_eventproc, 33 .enable = w32_widget_default_enable, 34 .show = w32_widget_default_show, 35 .get_preferred_size = ui_textarea_get_preferred_size, 36 .destroy = w32_widget_default_destroy 37 }; 38 39 UIWIDGET ui_textarea_create(UiObject *obj, UiTextAreaArgs *args) { 40 HINSTANCE hInstance = GetModuleHandle(NULL); 41 UiContainerPrivate *container = ui_obj_container(obj); 42 HWND parent = ui_container_get_parent(container); 43 UiLayout layout = UI_ARGS2LAYOUT(args); 44 45 int width = args->width >= 0 ? args->width : 100; 46 int height = args->height >= 0 ? args->height : 100; 47 48 HWND hwnd = CreateWindowEx( 49 0, 50 "EDIT", 51 "", 52 WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL, 53 0, 0, width, height, 54 parent, 55 (HMENU)0, 56 hInstance, 57 NULL); 58 ui_win32_set_ui_font(hwnd); 59 60 W32Widget *widget = w32_widget_create(&textarea_widget_class, hwnd, sizeof(UiTextArea)); 61 ui_container_add(container, widget, &layout); 62 63 UiTextArea *textarea = (UiTextArea*)widget; 64 textarea->width = width; 65 textarea->widget.var = uic_widget_var(obj->ctx, obj->ctx, args->value, args->varname, UI_VAR_TEXT); 66 textarea->widget.callback = args->onchange; 67 textarea->widget.callbackdata = args->onchangedata; 68 69 if (textarea->widget.var) { 70 UiText *t = textarea->widget.var->value; 71 72 if (t->value.ptr) { 73 // TODO: set textarea string 74 } 75 t->obj = widget; 76 t->save = ui_textarea_save; 77 t->destroy = ui_textarea_destroy; 78 t->restore = ui_textarea_restore; 79 t->get = ui_textarea_get; 80 t->set = ui_textarea_set; 81 t->getsubstr = ui_textarea_getsubstr; 82 t->insert = ui_textarea_insert; 83 t->setposition = ui_textarea_setposition; 84 t->position = ui_textarea_position; 85 t->setselection = ui_textarea_setselection; 86 t->selection = ui_textarea_selection; 87 t->length = ui_textarea_length; 88 t->remove = ui_textarea_remove; 89 } 90 91 return widget; 92 } 93 94 W32Size ui_textarea_get_preferred_size(W32Widget *widget) { 95 W32Size size; 96 UiTextArea *textarea = (UiTextArea*)widget; 97 size.width = textarea->width; 98 size.height = textarea->height; 99 return size; 100 } 101 102 int ui_textarea_eventproc(W32Widget *widget, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { 103 return 0; 104 } 105 106 void ui_textarea_save(UiText *text) { 107 108 } 109 110 void ui_textarea_destroy(UiText *text) { 111 112 } 113 114 void ui_textarea_restore(UiText *text) { 115 116 } 117 118 void ui_textarea_set(UiText *text, const char *str) { 119 120 } 121 122 char* ui_textarea_get(UiText *text) { 123 return NULL; 124 } 125 126 char* ui_textarea_getsubstr(UiText *text, int begin, int end) { 127 return NULL; 128 } 129 130 void ui_textarea_insert(UiText *text, int pos, char *str) { 131 132 } 133 134 void ui_textarea_setposition(UiText *text, int pos) { 135 136 } 137 138 int ui_textarea_position(UiText *text) { 139 return 0; 140 } 141 142 void ui_textarea_setselection(UiText *text, int begin, int end) { 143 144 } 145 146 void ui_textarea_selection(UiText *text, int *begin, int *end) { 147 148 } 149 150 int ui_textarea_length(UiText *text) { 151 return 0; 152 } 153 154 void ui_textarea_remove(UiText *text, int begin, int end) { 155 156 } 157 158 /* ----------------------------- TextField ----------------------------- */ 159 160 static W32WidgetClass textfield_widget_class = { 161 .eventproc = ui_textfield_eventproc, 162 .enable = w32_widget_default_enable, 163 .show = w32_widget_default_show, 164 .get_preferred_size = ui_textfield_get_preferred_size, 165 .destroy = w32_widget_default_destroy 166 }; 167 168 UIWIDGET ui_textfield_create(UiObject *obj, UiTextFieldArgs *args) { 169 HINSTANCE hInstance = GetModuleHandle(NULL); 170 UiContainerPrivate *container = ui_obj_container(obj); 171 HWND parent = ui_container_get_parent(container); 172 UiLayout layout = UI_ARGS2LAYOUT(args); 173 174 int width = args->width >= 0 ? args->width : 100; 175 176 HWND hwnd = CreateWindowEx( 177 WS_EX_CLIENTEDGE, 178 "EDIT", 179 "", 180 WS_VISIBLE | WS_CHILD | ES_LEFT | ES_AUTOHSCROLL, 181 0, 0, width, 25, 182 parent, 183 (HMENU)0, 184 hInstance, 185 NULL); 186 ui_win32_set_ui_font(hwnd); 187 188 W32Widget *widget = w32_widget_create(&textfield_widget_class, hwnd, sizeof(UiTextField)); 189 ui_container_add(container, widget, &layout); 190 191 UiTextField *textfield = (UiTextField*)widget; 192 textfield->width = width; 193 textfield->widget.var = uic_widget_var(obj->ctx, obj->ctx, args->value, args->varname, UI_VAR_STRING); 194 textfield->widget.callback = args->onchange; 195 textfield->widget.callbackdata = args->onchangedata; 196 197 if (textfield->widget.var) { 198 UiString *s = textfield->widget.var->value; 199 200 if (s->value.ptr) { 201 // TODO: set textfield string 202 } 203 s->obj = widget; 204 s->get = ui_textfield_get; 205 s->set = ui_textfield_set; 206 } 207 208 return widget; 209 } 210 211 W32Size ui_textfield_get_preferred_size(W32Widget *widget) { 212 UiTextField *textfield = (UiTextField *)widget; 213 return (W32Size){ .width = textfield->width, .height = 32}; 214 } 215 216 int ui_textfield_eventproc(W32Widget *widget, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { 217 return 0; 218 } 219 220 char* ui_textfield_get(UiString *s) { 221 UiTextField *textfield = s->obj; 222 223 if (s->value.free) { 224 s->value.free(s->value.ptr); 225 } 226 227 int len = GetWindowTextLength(textfield->widget.widget.hwnd); 228 s->value.ptr = calloc(len+1, 1); 229 GetWindowText(textfield->widget.widget.hwnd, s->value.ptr, len+1); 230 231 return s->value.ptr; 232 } 233 234 void ui_textfield_set(UiString *s, const char *value) { 235 UiTextField *textfield = s->obj; 236 if (s->value.free) { 237 s->value.free(s->value.ptr); 238 } 239 s->value.ptr = NULL; 240 SetWindowText(textfield->widget.widget.hwnd, value); 241 } 242