ui/common/action.c

changeset 1092
0accf125a65f
parent 1066
afe02792303d
equal deleted inserted replaced
1091:1524b5dc4d4d 1092:0accf125a65f
47 action.name = ui_strdup(ctx, name); 47 action.name = ui_strdup(ctx, name);
48 action.callback = callback; 48 action.callback = callback;
49 action.userdata = userdata; 49 action.userdata = userdata;
50 action.accelerator = accelerator ? ui_strdup(ctx, accelerator) : NULL; 50 action.accelerator = accelerator ? ui_strdup(ctx, accelerator) : NULL;
51 action.accelerator_text = accelerator_text ? ui_strdup(ctx, accelerator_text) : NULL; 51 action.accelerator_text = accelerator_text ? ui_strdup(ctx, accelerator_text) : NULL;
52 action.ctx = ctx;
52 cxMapPut(ctx->actions, name, &action); 53 cxMapPut(ctx->actions, name, &action);
53 cxMapRehash(ctx->actions); 54 cxMapRehash(ctx->actions);
54 } 55 }
55 56
56 void uic_bind_action( 57 void uic_bind_action(
57 UiContext *ctx, 58 UiContext *ctx,
58 const char *action, 59 const char *action,
59 void *bind_obj, 60 void *bind_obj,
60 ui_action_binding_set_enabled_func set_enabled, 61 ui_enablefunc set_enabled)
61 ui_action_binding_set_accelerator_text_func set_accelerator_text)
62 { 62 {
63 if(!action) { 63 if(!action) {
64 return; 64 return;
65 } 65 }
66 66
67 UiActionBinding binding; 67 UiActionBinding binding;
68 binding.action = ui_strdup(ctx, action); 68 binding.action = ui_strdup(ctx, action);
69 binding.userdata = bind_obj; 69 binding.userdata = bind_obj;
70 binding.set_enabled = set_enabled; 70 binding.set_enabled = set_enabled;
71 binding.set_accelerator_text = set_accelerator_text;
72 cxListAdd(ctx->action_bindings, &binding); 71 cxListAdd(ctx->action_bindings, &binding);
73 } 72 }
73
74 UiAction* uic_resolve_action(UiContext *ctx, const char *action) {
75 UiAction *a = NULL;
76 if(ctx->actions) {
77 a = cxMapGet(ctx->actions, action);
78 }
79 // check if any sub-document defines this action
80 // sub-document actions have precedence, the most specific action will
81 // be returned
82 CxIterator i = cxListIterator(ctx->documents);
83 cx_foreach(void *, doc, i) {
84 UiContext *doc_ctx = ui_document_context(doc);
85 UiAction *sub_action = uic_resolve_action(doc_ctx, action);
86 if(sub_action) {
87 a = sub_action;
88 // if one sub-tree has an action, we don't care about other
89 // subtrees
90 break;
91 }
92 }
93
94 if(!a && ctx->parent) {
95 // check parents
96 a = uic_resolve_action_from_parents(ctx, action);
97 }
98
99 return a;
100 }
101
102 UiAction* uic_resolve_action_from_parents(UiContext *ctx, const char *action) {
103 UiContext *parent = ctx->parent;
104 if(parent == NULL) {
105 return NULL;
106 }
107 if(parent->actions) {
108 UiAction *a = cxMapGet(parent->actions, action);
109 if(a) {
110 return a;
111 }
112 }
113 return uic_resolve_action_from_parents(parent, action);
114 }
115
116
117
118 void ui_update_action_bindings(UiContext *ctx) {
119 CxIterator i = cxListIterator(ctx->action_bindings);
120 cx_foreach(UiActionBinding*, binding, i) {
121 UiAction *action = uic_resolve_action(ctx, binding->action);
122 if(binding->set_enabled) {
123 binding->set_enabled(binding->userdata, action != NULL);
124 }
125 }
126 }
127
128 void uic_action_callback(UiEvent *event, const char *action_name) {
129 UiContext *ctx = ui_global_context();
130 if(event->obj) {
131 ctx = event->obj->ctx;
132 }
133
134 UiAction *action = uic_resolve_action(ctx, action_name);
135 if(action) {
136 // override event document: for actions we know that the event is
137 // for a specific document
138 event->document = action->ctx->self_doc;
139 if(action->callback) {
140 action->callback(event, action->userdata);
141 }
142 }
143 }

mercurial