Mercurial > dwindows
comparison ios/dw.m @ 2807:975df4680ff7
iOS: Need to trigger window menu rebuilds if a menu item changes.
Currently if code changes the checked or enabled state of a menu item it
triggers a repopulation of all menus on all windows. We may be able to
reduce this by attempting to detect which window the menu item is a
descendant of and only repopulate that menu... however this will do for now.
author | bsmith@81767d24-ef19-dc11-ae90-00e081727c95 |
---|---|
date | Wed, 20 Jul 2022 19:22:06 +0000 |
parents | deefe6f5d716 |
children | 9c9b680f7772 |
comparison
equal
deleted
inserted
replaced
2806:d7b6e19e44d2 | 2807:975df4680ff7 |
---|---|
713 { | 713 { |
714 UIMenu *menu; | 714 UIMenu *menu; |
715 NSMutableArray *children; | 715 NSMutableArray *children; |
716 NSString *title; | 716 NSString *title; |
717 unsigned long tag; | 717 unsigned long tag; |
718 UIWindow *window; | |
718 } | 719 } |
719 -(id)initWithTag:(unsigned long)newtag; | 720 -(id)initWithTag:(unsigned long)newtag; |
720 -(void)setTitle:(NSString *)input; | 721 -(void)setTitle:(NSString *)input; |
721 -(UIMenu *)menu; | 722 -(UIMenu *)menu; |
722 -(unsigned long)tag; | 723 -(unsigned long)tag; |
811 -(void)layoutSubviews; | 812 -(void)layoutSubviews; |
812 -(void)setMenu:(DWMenu *)input; | 813 -(void)setMenu:(DWMenu *)input; |
813 -(void)setPopupMenu:(DWMenu *)input; | 814 -(void)setPopupMenu:(DWMenu *)input; |
814 -(DWMenu *)menu; | 815 -(DWMenu *)menu; |
815 -(DWMenu *)popupMenu; | 816 -(DWMenu *)popupMenu; |
817 -(void)updateMenu; | |
816 -(void *)userdata; | 818 -(void *)userdata; |
817 -(void)setUserdata:(void *)input; | 819 -(void)setUserdata:(void *)input; |
818 @end | 820 @end |
819 | 821 |
820 @implementation DWWindow | 822 @implementation DWWindow |
832 -(int)shown { return shown; } | 834 -(int)shown { return shown; } |
833 -(void)setShown:(int)val { shown = val; } | 835 -(void)setShown:(int)val { shown = val; } |
834 -(void)layoutSubviews { } | 836 -(void)layoutSubviews { } |
835 -(void)setMenu:(DWMenu *)input { [windowmenu release]; windowmenu = input; [windowmenu retain]; } | 837 -(void)setMenu:(DWMenu *)input { [windowmenu release]; windowmenu = input; [windowmenu retain]; } |
836 -(void)setPopupMenu:(DWMenu *)input { [popupmenu release]; popupmenu = input; [popupmenu retain]; } | 838 -(void)setPopupMenu:(DWMenu *)input { [popupmenu release]; popupmenu = input; [popupmenu retain]; } |
839 -(void)updateMenu | |
840 { | |
841 if(windowmenu) | |
842 { | |
843 NSArray *array = [[[self rootViewController] view] subviews]; | |
844 UINavigationBar *nav = nil; | |
845 | |
846 for(id obj in array) | |
847 { | |
848 if([obj isMemberOfClass:[UINavigationBar class]]) | |
849 nav = obj; | |
850 } | |
851 if(nav) | |
852 { | |
853 UINavigationItem *item = [[nav items] firstObject]; | |
854 | |
855 if (@available(iOS 14.0, *)) { | |
856 if(item && item.rightBarButtonItem && item.rightBarButtonItem.menu) | |
857 [item.rightBarButtonItem setMenu:[windowmenu menu]]; | |
858 } | |
859 } | |
860 } | |
861 } | |
837 -(DWMenu *)menu { return windowmenu; } | 862 -(DWMenu *)menu { return windowmenu; } |
838 -(DWMenu *)popupMenu { return popupmenu; } | 863 -(DWMenu *)popupMenu { return popupmenu; } |
839 -(void)closeWindow:(id)sender | 864 -(void)closeWindow:(id)sender |
840 { | 865 { |
841 if(_dw_event_handler(self, nil, _DW_EVENT_DELETE) < 1) | 866 if(_dw_event_handler(self, nil, _DW_EVENT_DELETE) < 1) |
1843 if(@available(iOS 14.0, *)) | 1868 if(@available(iOS 14.0, *)) |
1844 menu = [UIMenu menuWithChildren:menuchildren]; | 1869 menu = [UIMenu menuWithChildren:menuchildren]; |
1845 else | 1870 else |
1846 menu = [UIMenu menuWithTitle:@"" children:menuchildren]; | 1871 menu = [UIMenu menuWithTitle:@"" children:menuchildren]; |
1847 } | 1872 } |
1873 [menu retain]; | |
1848 if(oldmenu) | 1874 if(oldmenu) |
1849 [oldmenu release]; | 1875 [oldmenu release]; |
1850 return menu; | 1876 return menu; |
1851 } | 1877 } |
1852 -(void)addItem:(id)item | 1878 -(void)addItem:(id)item |
1868 return child; | 1894 return child; |
1869 } | 1895 } |
1870 } | 1896 } |
1871 return nil; | 1897 return nil; |
1872 } | 1898 } |
1873 -(void)dealloc { [super dealloc]; } | 1899 -(void)dealloc |
1900 { | |
1901 if(menu) | |
1902 [menu release]; | |
1903 [super dealloc]; | |
1904 } | |
1874 @end | 1905 @end |
1875 | 1906 |
1876 @implementation DWImage | 1907 @implementation DWImage |
1877 -(id)initWithSize:(CGSize)size | 1908 -(id)initWithSize:(CGSize)size |
1878 { | 1909 { |
8591 nstr = [NSString stringWithUTF8String:newtitle]; | 8622 nstr = [NSString stringWithUTF8String:newtitle]; |
8592 free(newtitle); | 8623 free(newtitle); |
8593 | 8624 |
8594 item = [DWMenuItem actionWithTitle:nstr image:nil identifier:nil | 8625 item = [DWMenuItem actionWithTitle:nstr image:nil identifier:nil |
8595 handler:^(__kindof UIAction * _Nonnull action) { | 8626 handler:^(__kindof UIAction * _Nonnull action) { |
8627 if(check) | |
8628 { | |
8629 UIMenuElementState state = [item state] == UIMenuElementStateOn ? UIMenuElementStateOff : UIMenuElementStateOn; | |
8630 [item setState:state]; | |
8631 } | |
8596 [DWObj menuHandler:item]; | 8632 [DWObj menuHandler:item]; |
8633 if(check) | |
8634 { | |
8635 for(id obj in _dw_toplevel_windows) | |
8636 [obj updateMenu]; | |
8637 } | |
8597 }]; | 8638 }]; |
8598 /* Don't set the tag if the ID is 0 or -1 */ | 8639 /* Don't set the tag if the ID is 0 or -1 */ |
8599 if(itemid != DW_MENU_AUTO && itemid != DW_MENU_POPUP) | 8640 if(itemid != DW_MENU_AUTO && itemid != DW_MENU_POPUP) |
8600 [item setTag:itemid]; | 8641 [item setTag:itemid]; |
8601 [menu addItem:item]; | 8642 [menu addItem:item]; |
8633 id menu = menux; | 8674 id menu = menux; |
8634 DWMenuItem *menuitem = [menu childWithTag:itemid]; | 8675 DWMenuItem *menuitem = [menu childWithTag:itemid]; |
8635 | 8676 |
8636 if(menuitem != nil) | 8677 if(menuitem != nil) |
8637 { | 8678 { |
8638 if(check) | 8679 UIMenuElementState newstate = check ? UIMenuElementStateOn : UIMenuElementStateOff; |
8639 [menuitem setState:UIMenuElementStateOn]; | 8680 |
8640 else | 8681 /* Only force the menus to repopulate if something changed */ |
8641 [menuitem setState:UIMenuElementStateOff]; | 8682 if(newstate != [menuitem state]) |
8683 { | |
8684 [menuitem setState:newstate]; | |
8685 for(id obj in _dw_toplevel_windows) | |
8686 [obj updateMenu]; | |
8687 } | |
8642 } | 8688 } |
8643 } | 8689 } |
8644 | 8690 |
8645 /* | 8691 /* |
8646 * Deletes the menu item specified. | 8692 * Deletes the menu item specified. |
8676 id menu = menux; | 8722 id menu = menux; |
8677 DWMenuItem *menuitem = [menu childWithTag:itemid]; | 8723 DWMenuItem *menuitem = [menu childWithTag:itemid]; |
8678 | 8724 |
8679 if(menuitem != nil) | 8725 if(menuitem != nil) |
8680 { | 8726 { |
8727 UIMenuElementState oldstate = [menuitem state]; | |
8728 BOOL oldenabled = [menuitem enabled]; | |
8729 | |
8681 if(state & DW_MIS_CHECKED) | 8730 if(state & DW_MIS_CHECKED) |
8682 { | |
8683 [menuitem setState:UIMenuElementStateOn]; | 8731 [menuitem setState:UIMenuElementStateOn]; |
8684 } | |
8685 else if(state & DW_MIS_UNCHECKED) | 8732 else if(state & DW_MIS_UNCHECKED) |
8686 { | |
8687 [menuitem setState:UIMenuElementStateOff]; | 8733 [menuitem setState:UIMenuElementStateOff]; |
8688 } | |
8689 if(state & DW_MIS_ENABLED) | 8734 if(state & DW_MIS_ENABLED) |
8690 { | |
8691 [menuitem setEnabled:YES]; | 8735 [menuitem setEnabled:YES]; |
8692 } | |
8693 else if(state & DW_MIS_DISABLED) | 8736 else if(state & DW_MIS_DISABLED) |
8694 { | |
8695 [menuitem setEnabled:NO]; | 8737 [menuitem setEnabled:NO]; |
8738 | |
8739 /* Only force the menus to repopulate if something changed */ | |
8740 if(oldstate != [menuitem state] || oldenabled != [menuitem enabled]) | |
8741 { | |
8742 for(id obj in _dw_toplevel_windows) | |
8743 [obj updateMenu]; | |
8696 } | 8744 } |
8697 } | 8745 } |
8698 } | 8746 } |
8699 | 8747 |
8700 /* Gets the notebook page from associated ID */ | 8748 /* Gets the notebook page from associated ID */ |
9195 [mle setTextAlignment:(style & mask)]; | 9243 [mle setTextAlignment:(style & mask)]; |
9196 } | 9244 } |
9197 else if([object isMemberOfClass:[DWMenuItem class]]) | 9245 else if([object isMemberOfClass:[DWMenuItem class]]) |
9198 { | 9246 { |
9199 DWMenuItem *menuitem = object; | 9247 DWMenuItem *menuitem = object; |
9248 UIMenuElementState oldstate = [menuitem state]; | |
9249 BOOL oldenabled = [menuitem enabled]; | |
9200 | 9250 |
9201 if(mask & (DW_MIS_CHECKED | DW_MIS_UNCHECKED)) | 9251 if(mask & (DW_MIS_CHECKED | DW_MIS_UNCHECKED)) |
9202 { | 9252 { |
9203 if(style & DW_MIS_CHECKED) | 9253 if(style & DW_MIS_CHECKED) |
9204 [menuitem setState:UIMenuElementStateOn]; | 9254 [menuitem setState:UIMenuElementStateOn]; |
9209 { | 9259 { |
9210 if(style & DW_MIS_ENABLED) | 9260 if(style & DW_MIS_ENABLED) |
9211 [menuitem setEnabled:YES]; | 9261 [menuitem setEnabled:YES]; |
9212 else if(style & DW_MIS_DISABLED) | 9262 else if(style & DW_MIS_DISABLED) |
9213 [menuitem setEnabled:NO]; | 9263 [menuitem setEnabled:NO]; |
9264 } | |
9265 /* Only force the menus to repopulate if something changed */ | |
9266 if(oldstate != [menuitem state] || oldenabled != [menuitem enabled]) | |
9267 { | |
9268 for(id obj in _dw_toplevel_windows) | |
9269 [obj updateMenu]; | |
9214 } | 9270 } |
9215 } | 9271 } |
9216 DW_FUNCTION_RETURN_NOTHING; | 9272 DW_FUNCTION_RETURN_NOTHING; |
9217 } | 9273 } |
9218 | 9274 |