diff -r dbde25a5bc53 -r c03c338a7dcf ui/gtk/text.c --- a/ui/gtk/text.c Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/gtk/text.c Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 Olaf Wintermann. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -32,8 +32,7 @@ #include "text.h" #include "container.h" -#include "../common/context.h" -#include "../common/document.h" + static void selection_handler( GtkTextBuffer *buf, @@ -57,7 +56,7 @@ } } -UIWIDGET ui_textarea(UiObject *obj, UiText *value) { +UIWIDGET ui_textarea_var(UiObject *obj, UiVar *var) { GtkWidget *text_area = gtk_text_view_new(); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text_area), GTK_WRAP_WORD_CHAR); g_signal_connect( @@ -65,17 +64,17 @@ "realize", G_CALLBACK(ui_textarea_realize_event), NULL); - g_signal_connect( - text_area, - "selection-clear-event", - G_CALLBACK(selection_handler), - NULL); + + UiTextArea *uitext = malloc(sizeof(UiTextArea)); + uitext->ctx = obj->ctx; + uitext->var = var; + uitext->last_selection_state = 0; - UiTextArea *uitext = ucx_mempool_malloc( - obj->ctx->mempool, - sizeof(UiTextArea)); - uitext->ctx = obj->ctx; - uitext->last_selection_state = 0; + g_signal_connect( + text_area, + "destroy", + G_CALLBACK(ui_textarea_destroy), + uitext); GtkWidget *scroll_area = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy( @@ -98,6 +97,7 @@ ct->add(ct, scroll_area, TRUE); // bind value + UiText *value = var->value; if(value) { GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_area)); @@ -126,12 +126,12 @@ buf, "insert-text", G_CALLBACK(ui_textbuf_insert), - value); + var); g_signal_connect( buf, "delete-range", G_CALLBACK(ui_textbuf_delete), - value); + var); g_signal_connect( buf, @@ -143,11 +143,25 @@ return scroll_area; } +void ui_textarea_destroy(GtkWidget *object, UiTextArea *textarea) { + ui_destroy_boundvar(textarea->ctx, textarea->var); + free(textarea); +} + +UIWIDGET ui_textarea(UiObject *obj, UiText *value) { + UiVar *var = NULL; + if(value) { + var = malloc(sizeof(UiVar)); + var->value = value; + var->type = UI_VAR_SPECIAL; + } + return ui_textarea_var(obj, var); +} + UIWIDGET ui_textarea_nv(UiObject *obj, char *varname) { - UiVar *var = uic_connect_var(obj->ctx, varname, UI_VAR_TEXT); + UiVar *var = uic_create_var(obj->ctx, varname, UI_VAR_TEXT); if(var) { - UiText *value = var->value; - return ui_textarea(obj, value); + return ui_textarea_var(obj, var); } else { // TODO: error } @@ -168,11 +182,11 @@ } void ui_textarea_set(UiText *text, char *str) { + gtk_text_buffer_set_text((GtkTextBuffer*)text->obj, str, -1); if(text->value) { g_free(text->value); } text->value = NULL; - gtk_text_buffer_set_text((GtkTextBuffer*)text->obj, str, -1); } char* ui_textarea_getsubstr(UiText *text, int begin, int end) { @@ -242,24 +256,7 @@ gtk_widget_grab_focus(widget); } -void ui_text_set(UiText *text, char *str) { - if(text->set) { - text->set(text, str); - } else { - if(text->value) { - g_free(text->value); - } - text->value = g_strdup(str); - } -} -char* ui_text_get(UiText *text) { - if(text->get) { - return text->get(text); - } else { - return text->value; - } -} // undo manager functions @@ -271,7 +268,11 @@ int length, void *data) { - UiText *value = data; + UiVar *var = data; + UiText *value = var->value; + if(!value->undomgr) { + value->undomgr = ui_create_undomgr(); + } UiUndoMgr *mgr = value->undomgr; if(!mgr->event) { return; @@ -332,7 +333,11 @@ GtkTextIter *end, void *data) { - UiText *value = data; + UiVar *var = data; + UiText *value = var->value; + if(!value->undomgr) { + value->undomgr = ui_create_undomgr(); + } UiUndoMgr *mgr = value->undomgr; if(!mgr->event) { return; @@ -474,8 +479,19 @@ } -static UIWIDGET create_textfield(UiObject *obj, int width, UiBool frameless, UiBool password, UiString *value) { +static UIWIDGET create_textfield_var(UiObject *obj, int width, UiBool frameless, UiBool password, UiVar *var) { GtkWidget *textfield = gtk_entry_new(); + + UiTextField *uitext = malloc(sizeof(UiTextField)); + uitext->ctx = obj->ctx; + uitext->var = var; + + g_signal_connect( + textfield, + "destroy", + G_CALLBACK(ui_textfield_destroy), + uitext); + if(width > 0) { gtk_entry_set_width_chars(GTK_ENTRY(textfield), width); } @@ -490,11 +506,12 @@ UiContainer *ct = uic_get_current_container(obj); ct->add(ct, textfield, FALSE); - if(value) { + if(var) { + UiString *value = var->value; if(value->value) { gtk_entry_set_text(GTK_ENTRY(textfield), value->value); g_free(value->value); - // TODO: free value + value->value = NULL; } value->get = ui_textfield_get; @@ -507,16 +524,30 @@ } static UIWIDGET create_textfield_nv(UiObject *obj, int width, UiBool frameless, UiBool password, char *varname) { - UiVar *var = uic_connect_var(obj->ctx, varname, UI_VAR_STRING); + UiVar *var = uic_create_var(obj->ctx, varname, UI_VAR_STRING); if(var) { - UiString *value = var->value; - return create_textfield(obj, width, frameless, password, value); + return create_textfield_var(obj, width, frameless, password, var); } else { // TODO: error } return NULL; } +static UIWIDGET create_textfield(UiObject *obj, int width, UiBool frameless, UiBool password, UiString *value) { + UiVar *var = NULL; + if(value) { + var = malloc(sizeof(UiVar)); + var->value = value; + var->type = UI_VAR_SPECIAL; + } + return create_textfield_var(obj, width, frameless, password, var); +} + +void ui_textfield_destroy(GtkWidget *object, UiTextField *textfield) { + ui_destroy_boundvar(textfield->ctx, textfield->var); + free(textfield); +} + UIWIDGET ui_textfield(UiObject *obj, UiString *value) { return create_textfield(obj, 0, FALSE, FALSE, value); }