ui/cocoa/MainWindow.m

changeset 571
f6e92de49959
parent 570
a2df724b4cb9
child 677
04bcb1930fbf
equal deleted inserted replaced
570:a2df724b4cb9 571:f6e92de49959
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 }

mercurial