| 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 } |