| 73 |
73 |
| 74 - (MainWindowController*)initWithWindow:(UiObject*)obj window:(NSWindow*)window { |
74 - (MainWindowController*)initWithWindow:(UiObject*)obj window:(NSWindow*)window { |
| 75 self = [super initWithWindow:window]; |
75 self = [super initWithWindow:window]; |
| 76 _uiobj = obj; |
76 _uiobj = obj; |
| 77 |
77 |
| |
78 self.checkItemStates = [[NSMutableDictionary alloc] init]; |
| |
79 self.radioItems = [[NSMutableDictionary alloc] init]; |
| |
80 |
| 78 // bind all stateful menu items (checkbox, radiobuttons, lists) |
81 // bind all stateful menu items (checkbox, radiobuttons, lists) |
| 79 self.checkItemStates = [[NSMutableDictionary alloc] init]; |
|
| 80 NSArray *menuBindItems = ui_get_binding_items(); // returns all items that require binding |
82 NSArray *menuBindItems = ui_get_binding_items(); // returns all items that require binding |
| 81 for(MenuItem *item in menuBindItems) { |
83 for(MenuItem *item in menuBindItems) { |
| 82 if(item.checkItem) { |
84 if(item.checkItem || item.radioItem) { |
| 83 // simple check item (ui_menu_toggleitem_create) |
85 // simple check item (ui_menu_toggleitem_create) |
| 84 UiVar *var = uic_widget_var(obj->ctx, obj->ctx, NULL, item.checkItem->varname, UI_VAR_INTEGER); |
86 UiVar *var = uic_widget_var(obj->ctx, obj->ctx, NULL, item.checkItem ? item.checkItem->varname : item.radioItem->varname, UI_VAR_INTEGER); |
| 85 // create the state object for this item/window |
87 // create the state object for this item/window |
| 86 MenuCheckItem *state = [[MenuCheckItem alloc] init]; |
88 MenuItemState *state = [[MenuItemState alloc] init]; |
| 87 state.mainWindow = self; |
89 state.mainWindow = self; |
| 88 state.var = var; |
90 state.var = var; |
| 89 if(var) { |
91 if(var) { |
| 90 // bind toggle item |
|
| 91 UiInteger *i = var->value; |
92 UiInteger *i = var->value; |
| 92 state.state = (int)i->value; |
93 if(item.checkItem) { |
| 93 i->obj = (__bridge void*)state; |
94 // bind toggle item |
| 94 i->get = ui_menu_check_item_get; |
95 state.state = (int)i->value; |
| 95 i->set = ui_menu_check_item_set; |
96 i->obj = (__bridge void*)state; |
| |
97 i->get = ui_menu_check_item_get; |
| |
98 i->set = ui_menu_check_item_set; |
| |
99 } else { |
| |
100 // bind radio item |
| |
101 NSMutableArray *rgroup = nil; |
| |
102 if(i->obj) { |
| |
103 rgroup = (__bridge NSMutableArray*)i->obj; |
| |
104 } else { |
| |
105 // create a new rgroup array and register it in the window |
| |
106 rgroup = [[NSMutableArray alloc] init]; |
| |
107 NSString *varname = [[NSString alloc] initWithUTF8String:item.radioItem->varname]; |
| |
108 [_radioItems setObject:rgroup forKey:varname]; |
| |
109 i->obj = (__bridge void*)rgroup; |
| |
110 } |
| |
111 i->get = ui_menu_radio_item_get; |
| |
112 i->set = ui_menu_radio_item_set; |
| |
113 [rgroup addObject:state]; // add this item state to the radio group |
| |
114 // i->value can contain a non-zero value, which means a specific radiobutton |
| |
115 // should be pre-selected |
| |
116 if(i->value == rgroup.count) { |
| |
117 state.state = NSControlStateValueOn; |
| |
118 } |
| |
119 } |
| 96 } else { |
120 } else { |
| 97 state.state = 0; |
121 state.state = 0; |
| 98 } |
122 } |
| 99 [_checkItemStates setObject:state forKey:item.itemId]; |
123 [_checkItemStates setObject:state forKey:item.itemId]; |
| 100 } else if(item.radioItem) { |
|
| 101 // bind radio item |
|
| 102 |
|
| 103 } |
124 } |
| 104 } |
125 } |
| 105 |
126 |
| 106 return self; |
127 return self; |
| 107 } |
128 } |
| 122 NSMenuItem *menuItem = sender; |
143 NSMenuItem *menuItem = sender; |
| 123 MenuItem *item = objc_getAssociatedObject(sender, "menuitem"); |
144 MenuItem *item = objc_getAssociatedObject(sender, "menuitem"); |
| 124 if(!item || !item.checkItem) { |
145 if(!item || !item.checkItem) { |
| 125 return; |
146 return; |
| 126 } |
147 } |
| 127 UiMenuCheckItem *it = item.checkItem; |
148 |
| 128 |
149 MenuItemState *state = [_checkItemStates objectForKey:item.itemId]; |
| 129 MenuCheckItem *state = [_checkItemStates objectForKey:item.itemId]; |
|
| 130 state.state = state.state == NSControlStateValueOff ? NSControlStateValueOn : NSControlStateValueOff; |
150 state.state = state.state == NSControlStateValueOff ? NSControlStateValueOn : NSControlStateValueOff; |
| 131 menuItem.state = state.state; |
151 menuItem.state = state.state; |
| 132 |
152 |
| |
153 UiMenuCheckItem *it = item.checkItem; |
| 133 if(it->callback) { |
154 if(it->callback) { |
| 134 UiEvent event; |
155 UiEvent event; |
| 135 event.obj = _uiobj; |
156 event.obj = _uiobj; |
| 136 event.window = event.obj->window; |
157 event.window = event.obj->window; |
| 137 event.document = event.obj->ctx->document; |
158 event.document = event.obj->ctx->document; |
| 139 event.intval = state.state; |
160 event.intval = state.state; |
| 140 it->callback(&event, it->userdata); |
161 it->callback(&event, it->userdata); |
| 141 } |
162 } |
| 142 } |
163 } |
| 143 |
164 |
| |
165 - (void)menuRadioItemAction:(id)sender { |
| |
166 NSMenuItem *menuItem = sender; |
| |
167 MenuItem *item = objc_getAssociatedObject(sender, "menuitem"); |
| |
168 if(!item || !item.radioItem) { |
| |
169 return; |
| |
170 } |
| |
171 |
| |
172 UiMenuRadioItem *it = item.radioItem; |
| |
173 if(!it->varname) { |
| |
174 return; |
| |
175 } |
| |
176 |
| |
177 MenuItemState *state = [_checkItemStates objectForKey:item.itemId]; // current state of this menu item |
| |
178 |
| |
179 NSString *varname = [[NSString alloc] initWithUTF8String:it->varname]; |
| |
180 NSArray *radioGroup = [_radioItems objectForKey:varname]; |
| |
181 if(!radioGroup) { |
| |
182 return; |
| |
183 } |
| |
184 int index = 1; |
| |
185 int value = 0; |
| |
186 for(MenuItemState *g in radioGroup) { |
| |
187 if(g == state) { |
| |
188 menuItem.state = NSControlStateValueOn; |
| |
189 g.state = NSControlStateValueOn; |
| |
190 value = index; |
| |
191 } else { |
| |
192 menuItem.state = NSControlStateValueOff; |
| |
193 g.state = NSControlStateValueOff; |
| |
194 } |
| |
195 } |
| |
196 |
| |
197 if(it->callback) { |
| |
198 UiEvent event; |
| |
199 event.obj = _uiobj; |
| |
200 event.window = event.obj->window; |
| |
201 event.document = event.obj->ctx->document; |
| |
202 event.eventdata = state.var ? state.var->value : NULL; |
| |
203 event.intval = value; |
| |
204 it->callback(&event, it->userdata); |
| |
205 } |
| |
206 } |
| |
207 |
| |
208 |
| 144 - (BOOL) validateMenuItem:(NSMenuItem *) menuItem { |
209 - (BOOL) validateMenuItem:(NSMenuItem *) menuItem { |
| 145 MenuItem *item = objc_getAssociatedObject(menuItem, "menuitem"); |
210 MenuItem *item = objc_getAssociatedObject(menuItem, "menuitem"); |
| 146 if(item) { |
211 if(item) { |
| 147 MenuCheckItem *state = [_checkItemStates objectForKey:item.itemId]; |
212 MenuItemState *state = [_checkItemStates objectForKey:item.itemId]; |
| 148 if(state) { |
213 if(state) { |
| 149 menuItem.state = state.state; |
214 menuItem.state = state.state; |
| 150 } else { |
215 } else { |
| 151 menuItem.state = NSControlStateValueOff; |
216 menuItem.state = NSControlStateValueOff; |
| 152 } |
217 } |
| 155 return YES; |
220 return YES; |
| 156 } |
221 } |
| 157 |
222 |
| 158 @end |
223 @end |
| 159 |
224 |
| 160 @implementation MenuCheckItem |
225 @implementation MenuItemState |
| 161 |
226 |
| 162 @end |
227 @end |
| 163 |
228 |
| 164 int64_t ui_menu_check_item_get(UiInteger *i) { |
229 int64_t ui_menu_check_item_get(UiInteger *i) { |
| 165 MenuCheckItem *state = (__bridge MenuCheckItem*)i->obj; |
230 MenuItemState *state = (__bridge MenuItemState*)i->obj; |
| 166 i->value = state.state; |
231 i->value = state.state; |
| 167 return i->value; |
232 return i->value; |
| 168 } |
233 } |
| 169 |
234 |
| 170 void ui_menu_check_item_set(UiInteger *i, int64_t value) { |
235 void ui_menu_check_item_set(UiInteger *i, int64_t value) { |
| 171 MenuCheckItem *state = (__bridge MenuCheckItem*)i->obj; |
236 MenuItemState *state = (__bridge MenuItemState*)i->obj; |
| 172 i->value = value; |
237 i->value = value; |
| 173 state.state = (int)value; |
238 state.state = (int)value; |
| 174 } |
239 } |
| |
240 |
| |
241 int64_t ui_menu_radio_item_get(UiInteger *i) { |
| |
242 NSArray *rgroup = (__bridge NSArray*)i->obj; |
| |
243 i->value = 0; |
| |
244 int index = 1; |
| |
245 for(MenuItemState *state in rgroup) { |
| |
246 if(state.state == NSControlStateValueOn) { |
| |
247 i->value = index; |
| |
248 break; |
| |
249 } |
| |
250 index++; |
| |
251 } |
| |
252 return i->value; |
| |
253 } |
| |
254 |
| |
255 void ui_menu_radio_item_set(UiInteger *i, int64_t value) { |
| |
256 NSArray *rgroup = (__bridge NSArray*)i->obj; |
| |
257 i->value = 0; |
| |
258 int index = 1; |
| |
259 for(MenuItemState *state in rgroup) { |
| |
260 state.state = value == index; |
| |
261 index++; |
| |
262 } |
| |
263 } |