ui/cocoa/button.m

changeset 112
c3f2f16fa4b8
parent 109
c3dfcb8f0be7
child 113
dde28a806552
--- a/ui/cocoa/button.m	Sat Oct 04 14:54:25 2025 +0200
+++ b/ui/cocoa/button.m	Sun Oct 19 21:20:08 2025 +0200
@@ -31,8 +31,12 @@
 #import "Container.h"
 #import <objc/runtime.h>
 
+#import <cx/buffer.h>
+#import <cx/json.h>
+
 UIWIDGET ui_button_create(UiObject* obj, UiButtonArgs *args) {
     NSButton *button = [[NSButton alloc] init];
+    button.translatesAutoresizingMaskIntoConstraints = NO;
     if(args->label) {
         NSString *label = [[NSString alloc] initWithUTF8String:args->label];
         button.title = label;
@@ -272,3 +276,187 @@
         index++;
     }
 }
+
+
+/* --------------------------- Link Button --------------------------- */
+
+@implementation UiLinkButtonData
+
+- (id)init:(UiObject*)obj textfield:(NSTextField*)textfield {
+    _obj = obj;
+    _textfield = textfield;
+    return self;
+}
+
+- (void)setLinkDataFromJson:(const char*)jsonStr {
+    CxJson json;
+    cxJsonInit(&json, NULL);
+    cxJsonFill(&json, jsonStr);
+    
+    CxJsonValue *value;
+    if(cxJsonNext(&json, &value) == CX_JSON_NO_ERROR) {
+        if(cxJsonIsObject(value)) {
+            CxJsonValue *label = cxJsonObjGet(value, "label");
+            CxJsonValue *uri = cxJsonObjGet(value, "uri");
+            CxJsonValue *visited = cxJsonObjGet(value, "visited");
+            if(label) {
+                char *str = cxJsonIsString(label) ? cxJsonAsString(label) : NULL;
+                if(str) {
+                    _label = [[NSString alloc]initWithUTF8String:str];
+                } else {
+                    _label = nil;
+                }
+            }
+            if(uri) {
+                char *str = cxJsonIsString(uri) ? cxJsonAsString(uri) : NULL;
+                if(str) {
+                    _uri = [[NSString alloc]initWithUTF8String:str];
+                } else {
+                    _uri = nil;
+                }
+            }
+            if(visited) {
+                _visited = cxJsonIsBool(visited) ? cxJsonAsBool(visited) : FALSE;
+            }
+        }
+        cxJsonValueFree(value);
+    }
+    cxJsonDestroy(&json);
+    
+    [self buildLink];
+}
+
+- (void)buildLink {
+    NSString *label = _label ? _label : @"";
+    
+    NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:label];
+    [attrString beginEditing];
+    if(_uri) {
+        [attrString addAttribute:NSLinkAttributeName value:_uri range:NSMakeRange(0, attrString.length)];
+    }
+    [attrString addAttribute:NSForegroundColorAttributeName value:[NSColor systemBlueColor] range:NSMakeRange(0, attrString.length)];
+    [attrString addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleSingle) range:NSMakeRange(0, attrString.length)];
+    [attrString endEditing];
+
+    [_textfield setAttributedStringValue:attrString];
+}
+
+@end
+
+static char* create_linkbutton_jsonvalue(const char *label, const char *uri, UiBool include_null, UiBool visited, UiBool set_visited) {
+    CxJsonValue *obj = cxJsonCreateObj(NULL);
+    if(label) {
+        cxJsonObjPutString(obj, CX_STR("label"), label);
+    } else if(include_null) {
+        cxJsonObjPutLiteral(obj, CX_STR("label"), CX_JSON_NULL);
+    }
+    
+    if(uri) {
+        cxJsonObjPutString(obj, CX_STR("uri"), uri);
+    } else if(include_null) {
+        cxJsonObjPutLiteral(obj, CX_STR("uri"), CX_JSON_NULL);
+    }
+    
+    if(set_visited) {
+        cxJsonObjPutLiteral(obj, CX_STR("visited"), visited ? CX_JSON_TRUE : CX_JSON_FALSE);
+    }
+    
+    CxJsonWriter writer = cxJsonWriterCompact();
+    CxBuffer buf;
+    cxBufferInit(&buf, NULL, 128, NULL, CX_BUFFER_AUTO_EXTEND);
+    cxJsonWrite(&buf, obj, (cx_write_func)cxBufferWrite, &writer);
+    cxJsonValueFree(obj);
+    cxBufferTerminate(&buf);
+    
+    return buf.space;
+}
+
+UIWIDGET ui_linkbutton_create(UiObject *obj, UiLinkButtonArgs *args) {
+    NSTextField *label = [[NSTextField alloc] init];
+    label.editable = NO;
+    label.bezeled = NO;
+    label.drawsBackground = NO;
+    label.allowsEditingTextAttributes = YES;
+    label.selectable = YES;
+    
+    UiLayout layout = UI_ARGS2LAYOUT(args);
+    ui_container_add(obj, label, &layout);
+    
+    UiLinkButtonData *data = [[UiLinkButtonData alloc]init:obj textfield:label];
+    objc_setAssociatedObject(label, "linkdata", data, OBJC_ASSOCIATION_RETAIN);
+    
+    UiVar *var = uic_widget_var(obj->ctx, obj->ctx, args->value, args->varname, UI_VAR_STRING);
+    if(var) {
+        UiString *s = var->value;
+        s->obj = (__bridge void*)data;
+        s->get = ui_linkbutton_get;
+        s->set = ui_linkbutton_set;
+        
+        if(s->value.ptr) {
+            [data setLinkDataFromJson:s->value.ptr];
+        }
+    }
+    
+    return (__bridge void*)label;
+}
+
+char* ui_linkbutton_get(UiString *s) {
+    return NULL; // TODO
+}
+
+void ui_linkbutton_set(UiString *s, const char *str) {
+    UiLinkButtonData *data = (__bridge UiLinkButtonData*)s->obj;
+    [data setLinkDataFromJson:str];
+}
+
+
+
+void ui_linkbutton_value_set(UiString *str, const char *label, const char *uri) {
+    char *value = create_linkbutton_jsonvalue(label, uri, TRUE, FALSE, TRUE);
+    ui_set(str, value);
+    free(value);
+}
+
+void ui_linkbutton_value_set_label(UiString *str, const char *label) {
+    char *value = create_linkbutton_jsonvalue(label, NULL, FALSE, FALSE, TRUE);
+    ui_set(str, value);
+    free(value);
+}
+
+void ui_linkbutton_value_set_uri(UiString *str, const char *uri) {
+    char *value = create_linkbutton_jsonvalue(NULL, uri, FALSE, FALSE, TRUE);
+    ui_set(str, value);
+    free(value);
+}
+
+void ui_linkbutton_value_set_visited(UiString *str, UiBool visited) {
+    char *value = create_linkbutton_jsonvalue(NULL, NULL, FALSE, visited, TRUE);
+    ui_set(str, value);
+    free(value);
+}
+
+// TODO
+
+void ui_linkbutton_set_label(UIWIDGET button, const char *label) {
+    
+}
+
+void ui_linkbutton_set_uri(UIWIDGET button, const char *label) {
+    
+}
+
+void ui_linkbutton_set_visited(UIWIDGET button, UiBool visited) {
+    
+}
+
+char* ui_linkbutton_get_label(UIWIDGET button) {
+    return NULL;
+}
+
+char* ui_linkbutton_get_uri(UIWIDGET button) {
+    return NULL;
+}
+
+UiBool ui_linkbutton_get_visited(UIWIDGET button) {
+    return FALSE;
+}

mercurial