pub kind: NoteType,
pub created: DateTimeWithTimeZone,
+ extract_title: bool,
title_start: i32,
title_end: i32,
content_id: 0,
kind: NoteType::PlainTextNote,
created: Default::default(),
+ extract_title: false,
title_start: -1,
title_end: -1,
});
}
+ /// Event before the text is changed: detect if the change affects the title
#[action]
- pub fn note_text_changed(&mut self, event: &ActionEvent) {
+ pub fn note_text_change(&mut self, event: &ActionEvent) {
if event.set {
+ self.extract_title = false;
return;
}
- let mut content = "".to_string();
// check if any text in the title range has changed
let pos = match &event.event_type {
EventType::TextInsert(t) => {
- content = self.text.get();
- content.insert_str(t.pos as usize, t.text.as_str());
t.pos
},
EventType::TextDelete(t) => {
- content = self.text.get();
- let range = t.begin as usize..t.end as usize;
- content.replace_range(range, "");
t.begin
},
_ => {
if self.title_end != -1 && pos > self.title_end + 1 {
//return; // this text edit can not change the title
}
+ self.extract_title = true;
+ }
+
- // TODO: we don't need the full text
- self.update_title(content.as_str(), true);
+ #[action]
+ pub fn note_text_changed(&mut self, event: &ActionEvent) {
+ if !event.set && self.extract_title {
+ self.update_title(self.text.get().as_str(), true);
+ }
+ self.extract_title = false;
}
}
obj.textarea(|b|{
b.fill(true);
b.varname("note_text");
- b.action("note_text_changed");
+ b.onchange_action("note_text_change");
+ b.ontextchanged_action("note_text_changed");
});
});
});
pub set: bool
}
+#[repr(i32)]
+enum UiEventType {
+ Null = 0,
+ Pointer,
+ String,
+ IntegerValue,
+ StringValue,
+ TextValue,
+ DoubleValue,
+ RangeValue,
+ TextChanged,
+ ListSelection,
+ ListElm,
+ DND,
+ SubList,
+ FileList
+}
+
pub enum EventType<'a> {
Null,
Pointer,
let event_type = unsafe { ui_event_get_eventdatatype(e) };
let ptr = unsafe { ui_event_get_eventdata(e) };
match event_type {
- 3 => {
+ UiEventType::String => {
+ EventTypeData::String(ptr.cast())
+ },
+ UiEventType::IntegerValue => {
let i: *mut ffi::UiInteger = ptr.cast();
EventTypeData::IntegerValue( UiInteger { ptr: i } )
}
- 4 => {
+ UiEventType::StringValue => {
let s: *mut ffi::UiString = ptr.cast();
EventTypeData::StringValue( UiString { ptr: s } )
}
- 5 => {
+ UiEventType::TextValue => {
let t: *mut ffi::UiText = ptr.cast();
EventTypeData::TextValue( UiText::from_ptr(t) )
}
- 6 => {
+ UiEventType::DoubleValue => {
let d: *mut ffi::UiDouble = ptr.cast();
EventTypeData::DoubleValue( UiDouble { ptr: d } )
}
- 7 => {
+ UiEventType::RangeValue => {
let d: *mut ffi::UiRange = ptr.cast();
EventTypeData::RangeValue( UiRange { ptr: d } )
}
- 8 => {
+ UiEventType::TextChanged => {
let d: *mut ffi::UiTextChangeEventData = ptr.cast();
let text_change_type = unsafe { ui_text_change_event_get_type(d) };
match text_change_type {
_ => EventTypeData::Null
}
},
- 9 => {
+ UiEventType::ListSelection => {
EventTypeData::ListSelection( ListSelection::from_ptr(ptr.cast()) )
}
- 10 => {
+ UiEventType::ListElm => {
// list elm
EventTypeData::Null
}
- 11 => {
+ UiEventType::DND => {
// dnd
EventTypeData::Null
}
- 12 => {
+ UiEventType::SubList => {
EventTypeData::SubList(SubListEvent::from_ptr(ptr.cast()))
}
- 13 => {
+ UiEventType::FileList => {
// filelist
EventTypeData::Null
}
fn ui_event_get_windowdata(event: *const UiEvent) -> *const c_void;
fn ui_event_get_document(event: *const UiEvent) -> *const c_void;
fn ui_event_get_eventdata(event: *const UiEvent) -> *mut c_void;
- fn ui_event_get_eventdatatype(event: *const UiEvent) -> i32;
+ fn ui_event_get_eventdatatype(event: *const UiEvent) -> UiEventType;
fn ui_event_get_int(event: *const UiEvent) -> i32;
fn ui_event_get_set(event: *const UiEvent) -> i32;
self
}
- pub fn action(&mut self, action: &str) -> &mut Self {
+ pub fn onchange_action(&mut self, action: &str) -> &mut Self {
+ let cstr = CString::new(action).unwrap();
+ unsafe {
+ ui_textarea_args_set_onchange_action(self.args, cstr.as_ptr());
+ }
+ self
+ }
+
+ pub fn ontextchanged<F>(&mut self, f: F) -> &mut Self
+ where F: FnMut(&mut event::Event<T>) + 'static {
+ let wrapper = Box::new(EventWrapper { callback: Box::new(f) });
+ let ptr = self.obj.ctx.reg_box(wrapper);
+ unsafe {
+ ui_textarea_args_set_ontextchanged(self.args, Some(event::event_wrapper::<T>));
+ ui_textarea_args_set_ontextchangeddata(self.args, ptr as *mut c_void);
+ }
+ self
+ }
+
+ pub fn ontextchanged_action(&mut self, action: &str) -> &mut Self {
let cstr = CString::new(action).unwrap();
unsafe {
- ui_textarea_args_set_action(self.args, cstr.as_ptr());
+ ui_textarea_args_set_ontextchanged_action(self.args, cstr.as_ptr());
}
self
}
fn ui_textarea_args_set_style_class(args: *mut UiTextAreaArgs, classname: *const c_char);
fn ui_textarea_args_set_onchange(args: *mut UiTextAreaArgs, callback: UiCallback);
fn ui_textarea_args_set_onchangedata(args: *mut UiTextAreaArgs, data: *mut c_void);
- fn ui_textarea_args_set_action(args: *mut UiTextAreaArgs, action: *const c_char);
+ fn ui_textarea_args_set_onchange_action(args: *mut UiTextAreaArgs, action: *const c_char);
+ fn ui_textarea_args_set_ontextchanged(args: *mut UiTextAreaArgs, callback: UiCallback);
+ fn ui_textarea_args_set_ontextchangeddata(args: *mut UiTextAreaArgs, data: *mut c_void);
+ fn ui_textarea_args_set_ontextchanged_action(args: *mut UiTextAreaArgs, action: *const c_char);
fn ui_textarea_args_set_varname(args: *mut UiTextAreaArgs, varname: *const c_char);
fn ui_textarea_args_set_value(args: *mut UiTextAreaArgs, ivalue: *mut UiText);
fn ui_textarea_args_set_states(args: *mut UiTextAreaArgs, states: *const c_int, numstates: c_int);
args->onchangedata = onchangedata;
}
-void ui_textarea_args_set_action(UiTextAreaArgs *args, const char *action) {
- args->action = strdup(action);
+void ui_textarea_args_set_onchange_action(UiTextAreaArgs *args, const char *action) {
+ args->onchange_action = strdup(action);
+}
+
+void ui_textarea_args_set_ontextchanged(UiTextAreaArgs *args, ui_callback callback) {
+ args->ontextchanged = callback;
+}
+
+void ui_textarea_args_set_ontextchangeddata(UiTextAreaArgs *args, void *onchangedata) {
+ args->ontextchangeddata = onchangedata;
+}
+
+void ui_textarea_args_set_ontextchanged_action(UiTextAreaArgs *args, const char *action) {
+ args->ontextchanged_action = strdup(action);
}
void ui_textarea_args_set_varname(UiTextAreaArgs *args, const char *varname) {
free((void*)args->name);
free((void*)args->style_class);
free((void*)args->varname);
- free((void*)args->action);
+ free((void*)args->onchange_action);
+ free((void*)args->ontextchanged_action);
free((void*)args->states);
free((void*)args->visibility_states);
free(args);
UIEXPORT void ui_textarea_args_set_style_class(UiTextAreaArgs *args, const char *classname);
UIEXPORT void ui_textarea_args_set_onchange(UiTextAreaArgs *args, ui_callback callback);
UIEXPORT void ui_textarea_args_set_onchangedata(UiTextAreaArgs *args, void *onchangedata);
-UIEXPORT void ui_textarea_args_set_action(UiTextAreaArgs *args, const char *action);
+UIEXPORT void ui_textarea_args_set_onchange_action(UiTextAreaArgs *args, const char *action);
+UIEXPORT void ui_textarea_args_set_ontextchanged(UiTextAreaArgs *args, ui_callback callback);
+UIEXPORT void ui_textarea_args_set_ontextchangeddata(UiTextAreaArgs *args, void *onchangedata);
+UIEXPORT void ui_textarea_args_set_ontextchanged_action(UiTextAreaArgs *args, const char *action);
UIEXPORT void ui_textarea_args_set_varname(UiTextAreaArgs *args, const char *varname);
UIEXPORT void ui_textarea_args_set_value(UiTextAreaArgs *args, UiText *value);
UIEXPORT void ui_textarea_args_set_states(UiTextAreaArgs *args, int *states, int numstates);
static GtkTextBuffer* create_textbuffer(UiTextArea *textarea) {
GtkTextBuffer *buf = gtk_text_buffer_new(NULL);
if(textarea) {
- /*
g_signal_connect(
buf,
"changed",
G_CALLBACK(ui_textbuf_changed),
textarea);
- */
g_signal_connect(
buf,
"insert-text",
- G_CALLBACK(ui_textbuf_changed_insert),
+ G_CALLBACK(ui_textbuf_change_insert),
textarea);
g_signal_connect(
buf,
"delete-range",
- G_CALLBACK(ui_textbuf_changed_delete),
+ G_CALLBACK(ui_textbuf_change_delete),
textarea);
} else {
fprintf(stderr, "Error: create_textbuffer: textarea == NULL\n");
uitext->last_selection_state = 0;
uitext->onchange = args->onchange;
uitext->onchangedata = args->onchangedata;
- uitext->action = args->action ? strdup(args->action) : NULL;
+ uitext->onchange_action = args->onchange_action ? strdup(args->onchange_action) : NULL;
+ uitext->ontextchanged = args->ontextchanged;
+ uitext->ontextchangeddata = args->ontextchangeddata;
+ uitext->ontextchanged_action = args->ontextchanged_action ? strdup(args->ontextchanged_action) : NULL;
g_object_set_data(G_OBJECT(text_area), "ui_textarea", uitext);
g_object_set_data(G_OBJECT(text_area), "ui_textarea_widget", text_area);
if(textarea->var) {
ui_destroy_boundvar(textarea->ctx, textarea->var);
}
- free(textarea->action);
+ free(textarea->onchange_action);
+ free(textarea->ontextchanged_action);
free(textarea);
}
}
-void ui_textbuf_changed_insert(
+static void textbuf_change_event(UiTextArea *textarea, UiTextChangeEventData *data) {
+ if(!ui_onchange_events_is_enabled()) {
+ return;
+ }
+
+ UiEvent e;
+ e.obj = textarea->obj;
+ e.window = e.obj->window;
+ e.document = textarea->ctx->document;
+ e.eventdata = data;
+ e.eventdatatype = UI_EVENT_DATA_TEXT_CHANGED;
+ e.intval = 0;
+ e.set = ui_get_setop();
+
+ if(textarea->onchange) {
+ textarea->onchange(&e, textarea->onchangedata);
+ }
+
+ if(textarea->onchange_action) {
+ uic_action_callback(&e, textarea->onchange_action);
+ }
+}
+
+void ui_textbuf_change_insert(
GtkTextBuffer *textbuffer,
GtkTextIter *location,
char *text,
event.end = event.begin + length;
event.text = text;
event.length = length;
- ui_textbuf_changed(textarea, &event);
+ textbuf_change_event(textarea, &event);
}
-void ui_textbuf_changed_delete(
+void ui_textbuf_change_delete(
GtkTextBuffer *self,
const GtkTextIter *start,
const GtkTextIter *end,
event.end = gtk_text_iter_get_offset(end);
event.text = NULL;
event.length = 0;
- ui_textbuf_changed(textarea, &event);
+ textbuf_change_event(textarea, &event);
}
-// void ui_textbuf_changed(GtkTextBuffer *textbuffer, UiTextArea *textarea)
-
-void ui_textbuf_changed(UiTextArea *textarea, UiTextChangeEventData *data) {
+void ui_textbuf_changed(GtkTextBuffer *textbuffer, UiTextArea *textarea) {
if(!ui_onchange_events_is_enabled()) {
return;
}
e.obj = textarea->obj;
e.window = e.obj->window;
e.document = textarea->ctx->document;
- e.eventdata = data;
- e.eventdatatype = UI_EVENT_DATA_TEXT_CHANGED;
+ e.eventdata = value;
+ e.eventdatatype = UI_EVENT_DATA_TEXT_VALUE;
e.intval = 0;
e.set = ui_get_setop();
- if(textarea->onchange) {
- textarea->onchange(&e, textarea->onchangedata);
+ if(textarea->ontextchanged) {
+ textarea->ontextchanged(&e, textarea->ontextchangeddata);
}
- if(value->observers) {
- ui_notify_evt(value->observers, &e);
+ if(textarea->ontextchanged_action) {
+ uic_action_callback(&e, textarea->ontextchanged_action);
}
- if(textarea->action) {
- uic_action_callback(&e, textarea->action);
+ if(value->observers) {
+ ui_notify_evt(value->observers, &e);
}
}
int last_selection_state;
ui_callback onchange;
void *onchangedata;
- char *action;
+ char *onchange_action;
+ ui_callback ontextchanged;
+ void *ontextchangeddata;
+ char *ontextchanged_action;
} UiTextArea;
typedef struct UiTextField {
void ui_textarea_realize_event(GtkWidget *widget, gpointer data);
//void ui_textbuf_changed(GtkTextBuffer *textbuffer, UiTextArea *textarea);
-void ui_textbuf_changed_insert(
+void ui_textbuf_change_insert(
GtkTextBuffer *textbuffer,
GtkTextIter *location,
char *text,
int length,
UiTextArea *textarea);
-void ui_textbuf_changed_delete(
+void ui_textbuf_change_delete(
GtkTextBuffer *self,
const GtkTextIter *start,
const GtkTextIter *end,
UiTextArea *textarea);
-void ui_textbuf_changed(UiTextArea *textarea, UiTextChangeEventData *data);
+
+void ui_textbuf_changed(GtkTextBuffer *textbuffer, UiTextArea *textarea);
void ui_textbuf_insert(
GtkTextBuffer *textbuffer,
#include "button.h"
#include "container.h"
#include "../common/context.h"
+#include "../common/action.h"
#include <cx/mempool.h>
#include <cx/linked_list.h>
eventdata->userdata = args->onclickdata;
eventdata->obj = obj;
eventdata->value = 0;
+ eventdata->action = args->action ? strdup(args->action) : NULL;
XtAddCallback(
button,
XmNactivateCallback,
XtAddCallback(
button,
XmNdestroyCallback,
- (XtCallbackProc)ui_destroy_data,
+ (XtCallbackProc)ui_destroy_event_data,
eventdata);
}
e.intval = event->value;
e.set = 0;
event->callback(&e, event->userdata);
+
+ if(event->action) {
+ uic_action_callback(&e, event->action);
+ }
}
UIWIDGET ui_togglebutton_create(UiObject* obj, UiToggleArgs *args) {
ui_set_widget_groups(obj->ctx, button, args->states);
- ui_bind_togglebutton(obj, button, args->varname, args->value, args->onchange, args->onchangedata, args->enable_state);
+ ui_bind_togglebutton(obj, button, args->varname, args->value, args->onchange, args->onchangedata, args->action, args->enable_state);
XmStringFree(label);
return button;
ui_set_widget_groups(obj->ctx, button, args->states);
- ui_bind_togglebutton(obj, button, args->varname, args->value, args->onchange, args->onchangedata, args->enable_state);
+ ui_bind_togglebutton(obj, button, args->varname, args->value, args->onchange, args->onchangedata, args->action, args->enable_state);
XmStringFree(label);
return button;
event->callback(&e, event->userdata);
}
+ if(event->action) {
+ uic_action_callback(&e, event->action);
+ }
+
if(event->var && event->var->value) {
UiInteger *v = event->var->value;
v->value = e.intval;
UiInteger *value,
ui_callback onchange,
void *onchangedata,
+ const char *action,
int enable_state)
{
UiVar* var = uic_widget_var(obj->ctx, obj->ctx, value, varname, UI_VAR_INTEGER);
event->obj = obj;
event->callback = onchange;
event->userdata = onchangedata;
+ event->action = action ? strdup(action) : NULL;
event->var = var;
event->observers = NULL;
event->value = enable_state;
XtAddCallback(
widget,
XmNdestroyCallback,
- (XtCallbackProc)ui_destroy_data,
+ (XtCallbackProc)ui_destroy_var_event_data,
event);
}
event->callback(&e, event->userdata);
}
+ if(event->action) {
+ uic_action_callback(&e, event->action);
+ }
+
if(value) {
ui_notify_evt(value->observers, &e);
}
}
-void ui_bind_radiobutton(UiObject *obj, Widget rbutton, UiInteger *value, const char *varname, ui_callback onchange, void *onchangedata, int enable_group) {
+void ui_bind_radiobutton(UiObject *obj, Widget rbutton, UiInteger *value, const char *varname, ui_callback onchange, void *onchangedata, const char *action, int enable_group) {
UiVar* var = uic_widget_var(obj->ctx, obj->ctx, value, varname, UI_VAR_INTEGER);
if(var) {
UiInteger *value = var->value;
event->obj = obj;
event->callback = onchange;
event->userdata = onchangedata;
+ event->action = action ? strdup(action) : NULL;
event->observers = NULL;
event->var = var;
event->value = enable_group;
event->obj = obj;
event->callback = args->onchange;
event->userdata = args->onchangedata;
+ event->action = args->action ? strdup(args->action) : NULL;
event->observers = NULL;
event->var = var;
event->value = args->enable_state;
UiInteger *value,
ui_callback onchange,
void *onchangedata,
+ const char *action,
int enable_state);
int64_t ui_togglebutton_get(UiInteger *i);
void ui_togglebutton_set(UiInteger *i, int64_t value);
-void ui_bind_radiobutton(UiObject *obj, Widget rbutton, UiInteger *value, const char *varname, ui_callback onchange, void *onchangedata, int enable_group);
+void ui_bind_radiobutton(UiObject *obj, Widget rbutton, UiInteger *value, const char *varname, ui_callback onchange, void *onchangedata, const char *action, int enable_group);
int64_t ui_radiobutton_get(UiInteger *i);
void ui_radiobutton_set(UiInteger *i, int64_t value);
XmStringFree(s);
}
- ui_bind_togglebutton(obj, checkbox, it->varname, NULL, it->callback, it->userdata, 0);
+ ui_bind_togglebutton(obj, checkbox, it->varname, NULL, it->callback, it->userdata, NULL, 0);
ui_set_widget_groups(obj->ctx, checkbox, it->states);
}
var);
}
+ if(args->onchange || args->action) {
+
+ }
+
return widget;
}
free(data);
}
+void ui_destroy_event_data(Widget w, UiEventData *data, XtPointer d) {
+ free(data->action);
+ free(data);
+}
+
+void ui_destroy_var_event_data(Widget w, UiVarEventData *data, XtPointer d) {
+ free(data->action);
+ free(data);
+}
+
void ui_set_widget_groups(UiContext *ctx, Widget widget, const int *groups) {
if(!groups) {
return;
void *userdata;
int value;
void *customdata;
+ char *action;
} UiEventData;
typedef struct UiEventDataExt {
UiObserver **observers;
ui_callback callback;
void *userdata;
+ char *action;
int value;
} UiVarEventData;
void ui_destroy_data(Widget w, XtPointer data, XtPointer d);
+void ui_destroy_event_data(Widget w, UiEventData *data, XtPointer d);
+
+void ui_destroy_var_event_data(Widget w, UiVarEventData *data, XtPointer d);
+
void ui_set_widget_groups(UiContext *ctx, Widget widget, const int *groups) ;
void ui_set_widget_ngroups(UiContext *ctx, Widget widget, const int *groups, size_t ngroups);
const char *varname;
ui_callback onchange;
void *onchangedata;
- const char *action;
+ const char *onchange_action;
+ ui_callback ontextchanged;
+ void *ontextchangeddata;
+ const char *ontextchanged_action;
const int *states;
const int *visibility_states;