diff options
Diffstat (limited to 'src/ui/util.c')
-rw-r--r-- | src/ui/util.c | 122 |
1 files changed, 121 insertions, 1 deletions
diff --git a/src/ui/util.c b/src/ui/util.c index 38977b96..0baf541d 100644 --- a/src/ui/util.c +++ b/src/ui/util.c | |||
@@ -44,6 +44,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | |||
44 | # include "../ios.h" | 44 | # include "../ios.h" |
45 | #endif | 45 | #endif |
46 | 46 | ||
47 | #if defined (iPlatformAppleDesktop) | ||
48 | # include "macos.h" | ||
49 | #endif | ||
50 | |||
47 | #include <the_Foundation/math.h> | 51 | #include <the_Foundation/math.h> |
48 | #include <the_Foundation/path.h> | 52 | #include <the_Foundation/path.h> |
49 | #include <SDL_timer.h> | 53 | #include <SDL_timer.h> |
@@ -749,10 +753,65 @@ void makeMenuItems_Widget(iWidget *menu, const iMenuItem *items, size_t n) { | |||
749 | } | 753 | } |
750 | } | 754 | } |
751 | } | 755 | } |
752 | }} | 756 | } |
757 | } | ||
758 | |||
759 | static iArray *deepCopyMenuItems_(iWidget *menu, const iMenuItem *items, size_t n) { | ||
760 | iArray *array = new_Array(sizeof(iMenuItem)); | ||
761 | iString cmd; | ||
762 | init_String(&cmd); | ||
763 | for (size_t i = 0; i < n; i++) { | ||
764 | const iMenuItem *item = &items[i]; | ||
765 | const char *itemCommand = item->command; | ||
766 | #if 0 | ||
767 | if (itemCommand) { | ||
768 | /* Make it appear the command is coming from the right widget. */ | ||
769 | setCStr_String(&cmd, itemCommand); | ||
770 | if (!hasLabel_Command(itemCommand, "ptr")) { | ||
771 | size_t firstSpace = indexOf_String(&cmd, ' '); | ||
772 | iBlock ptr; | ||
773 | init_Block(&ptr, 0); | ||
774 | printf_Block(&ptr, " ptr:%p", menu); | ||
775 | if (firstSpace != iInvalidPos) { | ||
776 | insertData_Block(&cmd.chars, firstSpace, data_Block(&ptr), size_Block(&ptr)); | ||
777 | } | ||
778 | else { | ||
779 | append_Block(&cmd.chars, &ptr); | ||
780 | } | ||
781 | deinit_Block(&ptr); | ||
782 | } | ||
783 | itemCommand = cstr_String(&cmd); | ||
784 | } | ||
785 | #endif | ||
786 | pushBack_Array(array, &(iMenuItem){ | ||
787 | item->label ? strdup(item->label) : NULL, | ||
788 | item->key, | ||
789 | item->kmods, | ||
790 | itemCommand ? strdup(itemCommand) : NULL /* NOTE: Only works with string commands. */ | ||
791 | }); | ||
792 | } | ||
793 | deinit_String(&cmd); | ||
794 | return array; | ||
795 | } | ||
796 | |||
797 | static void deleteMenuItems_(iArray *items) { | ||
798 | iForEach(Array, i, items) { | ||
799 | iMenuItem *item = i.value; | ||
800 | free((void *) item->label); | ||
801 | free((void *) item->command); | ||
802 | } | ||
803 | delete_Array(items); | ||
804 | } | ||
753 | 805 | ||
754 | iWidget *makeMenu_Widget(iWidget *parent, const iMenuItem *items, size_t n) { | 806 | iWidget *makeMenu_Widget(iWidget *parent, const iMenuItem *items, size_t n) { |
755 | iWidget *menu = new_Widget(); | 807 | iWidget *menu = new_Widget(); |
808 | #if defined (iHaveNativeMenus) | ||
809 | setFlags_Widget(menu, hidden_WidgetFlag | nativeMenu_WidgetFlag, iTrue); | ||
810 | setUserData_Object(menu, deepCopyMenuItems_(menu, items, n)); | ||
811 | addChild_Widget(parent, menu); | ||
812 | iRelease(menu); /* owned by parent now */ | ||
813 | #else | ||
814 | /* Non-native custom popup menu. This may still be displayed inside a separate window. */ | ||
756 | setDrawBufferEnabled_Widget(menu, iTrue); | 815 | setDrawBufferEnabled_Widget(menu, iTrue); |
757 | setBackgroundColor_Widget(menu, uiBackgroundMenu_ColorId); | 816 | setBackgroundColor_Widget(menu, uiBackgroundMenu_ColorId); |
758 | if (deviceType_App() != desktop_AppDeviceType) { | 817 | if (deviceType_App() != desktop_AppDeviceType) { |
@@ -777,6 +836,7 @@ iWidget *makeMenu_Widget(iWidget *parent, const iMenuItem *items, size_t n) { | |||
777 | iWidget *cancel = addAction_Widget(menu, SDLK_ESCAPE, 0, "cancel"); | 836 | iWidget *cancel = addAction_Widget(menu, SDLK_ESCAPE, 0, "cancel"); |
778 | setId_Widget(cancel, "menu.cancel"); | 837 | setId_Widget(cancel, "menu.cancel"); |
779 | setFlags_Widget(cancel, disabled_WidgetFlag, iTrue); | 838 | setFlags_Widget(cancel, disabled_WidgetFlag, iTrue); |
839 | #endif | ||
780 | return menu; | 840 | return menu; |
781 | } | 841 | } |
782 | 842 | ||
@@ -812,11 +872,52 @@ static void updateMenuItemFonts_Widget_(iWidget *d) { | |||
812 | } | 872 | } |
813 | } | 873 | } |
814 | 874 | ||
875 | void updateMenuItemLabel_Widget(iWidget *menu, const char *command, const char *newLabel) { | ||
876 | if (~flags_Widget(menu) & nativeMenu_WidgetFlag) { | ||
877 | iLabelWidget *menuItem = findMenuItem_Widget(menu, command); | ||
878 | if (menuItem) { | ||
879 | setTextCStr_LabelWidget(menuItem, newLabel); | ||
880 | checkIcon_LabelWidget(menuItem); | ||
881 | } | ||
882 | } | ||
883 | else { | ||
884 | iArray *items = userData_Object(menu); | ||
885 | iAssert(items); | ||
886 | iForEach(Array, i, items) { | ||
887 | iMenuItem *item = i.value; | ||
888 | if (item->command && !iCmpStr(item->command, command)) { | ||
889 | free((void *) item->label); | ||
890 | item->label = strdup(newLabel); | ||
891 | break; | ||
892 | } | ||
893 | } | ||
894 | } | ||
895 | } | ||
896 | |||
815 | iLocalDef iBool isUsingMenuPopupWindows_(void) { | 897 | iLocalDef iBool isUsingMenuPopupWindows_(void) { |
816 | return deviceType_App() == desktop_AppDeviceType; | 898 | return deviceType_App() == desktop_AppDeviceType; |
817 | } | 899 | } |
818 | 900 | ||
901 | void releaseNativeMenu_Widget(iWidget *d) { | ||
902 | #if defined (iHaveNativeMenus) | ||
903 | iArray *items = userData_Object(d); | ||
904 | iAssert(flags_Widget(d) & nativeMenu_WidgetFlag); | ||
905 | iAssert(items); | ||
906 | deleteMenuItems_(items); | ||
907 | setUserData_Object(d, NULL); | ||
908 | #else | ||
909 | iUnused(d); | ||
910 | #endif | ||
911 | } | ||
912 | |||
819 | void openMenuFlags_Widget(iWidget *d, iInt2 windowCoord, iBool postCommands) { | 913 | void openMenuFlags_Widget(iWidget *d, iInt2 windowCoord, iBool postCommands) { |
914 | #if defined (iHaveNativeMenus) | ||
915 | const iArray *items = userData_Object(d); | ||
916 | iAssert(flags_Widget(d) & nativeMenu_WidgetFlag); | ||
917 | iAssert(items); | ||
918 | showPopupMenu_MacOS(d, mouseCoord_Window(get_Window(), 0), | ||
919 | constData_Array(items), size_Array(items)); | ||
920 | #else | ||
820 | const iRect rootRect = rect_Root(d->root); | 921 | const iRect rootRect = rect_Root(d->root); |
821 | const iInt2 rootSize = rootRect.size; | 922 | const iInt2 rootSize = rootRect.size; |
822 | const iBool isPortraitPhone = (deviceType_App() == phone_AppDeviceType && isPortrait_App()); | 923 | const iBool isPortraitPhone = (deviceType_App() == phone_AppDeviceType && isPortrait_App()); |
@@ -904,9 +1005,13 @@ void openMenuFlags_Widget(iWidget *d, iInt2 windowCoord, iBool postCommands) { | |||
904 | postCommand_Widget(d, "menu.opened"); | 1005 | postCommand_Widget(d, "menu.opened"); |
905 | } | 1006 | } |
906 | setupMenuTransition_Mobile(d, iTrue); | 1007 | setupMenuTransition_Mobile(d, iTrue); |
1008 | #endif | ||
907 | } | 1009 | } |
908 | 1010 | ||
909 | void closeMenu_Widget(iWidget *d) { | 1011 | void closeMenu_Widget(iWidget *d) { |
1012 | if (flags_Widget(d) & nativeMenu_WidgetFlag) { | ||
1013 | return; /* Handled natively. */ | ||
1014 | } | ||
910 | if (d == NULL || flags_Widget(d) & hidden_WidgetFlag) { | 1015 | if (d == NULL || flags_Widget(d) & hidden_WidgetFlag) { |
911 | return; /* Already closed. */ | 1016 | return; /* Already closed. */ |
912 | } | 1017 | } |
@@ -1780,6 +1885,21 @@ size_t findWidestLabel_MenuItem(const iMenuItem *items, size_t num) { | |||
1780 | return widestPos; | 1885 | return widestPos; |
1781 | } | 1886 | } |
1782 | 1887 | ||
1888 | iChar removeIconPrefix_String(iString *d) { | ||
1889 | if (isEmpty_String(d)) { | ||
1890 | return 0; | ||
1891 | } | ||
1892 | iStringConstIterator iter; | ||
1893 | init_StringConstIterator(&iter, d); | ||
1894 | iChar icon = iter.value; | ||
1895 | next_StringConstIterator(&iter); | ||
1896 | if (iter.value == ' ' && icon >= 0x100) { | ||
1897 | remove_Block(&d->chars, 0, iter.next - constBegin_String(d)); | ||
1898 | return icon; | ||
1899 | } | ||
1900 | return 0; | ||
1901 | } | ||
1902 | |||
1783 | iWidget *makeDialog_Widget(const char *id, | 1903 | iWidget *makeDialog_Widget(const char *id, |
1784 | const iMenuItem *itemsNullTerminated, | 1904 | const iMenuItem *itemsNullTerminated, |
1785 | const iMenuItem *actions, size_t numActions) { | 1905 | const iMenuItem *actions, size_t numActions) { |