summaryrefslogtreecommitdiff
path: root/src/ui/util.c
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-09-21 14:09:29 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-09-21 14:09:29 +0300
commit2ed9d1bbd3b92b8d39a368963c3fd5d0fbcdc974 (patch)
tree2221cdb8f6337830ed8ffed81b8b76368fa167db /src/ui/util.c
parentcb7795c12a40b2c8f749d9848276f58199819799 (diff)
Disabling items in native menus
Added the special prefix `///` to mark items disabled.
Diffstat (limited to 'src/ui/util.c')
-rw-r--r--src/ui/util.c152
1 files changed, 105 insertions, 47 deletions
diff --git a/src/ui/util.c b/src/ui/util.c
index a5b1cfb3..6d518282 100644
--- a/src/ui/util.c
+++ b/src/ui/util.c
@@ -709,6 +709,7 @@ void makeMenuItems_Widget(iWidget *menu, const iMenuItem *items, size_t n) {
709 } 709 }
710 else { 710 else {
711 iBool isInfo = iFalse; 711 iBool isInfo = iFalse;
712 iBool isDisabled = iFalse;
712 if (startsWith_CStr(labelText, ">>>")) { 713 if (startsWith_CStr(labelText, ">>>")) {
713 labelText += 3; 714 labelText += 3;
714 if (!horizGroup) { 715 if (!horizGroup) {
@@ -722,6 +723,10 @@ void makeMenuItems_Widget(iWidget *menu, const iMenuItem *items, size_t n) {
722 labelText += 3; 723 labelText += 3;
723 isInfo = iTrue; 724 isInfo = iTrue;
724 } 725 }
726 if (startsWith_CStr(labelText, "///")) {
727 labelText += 3;
728 isDisabled = iTrue;
729 }
725 iLabelWidget *label = addChildFlags_Widget( 730 iLabelWidget *label = addChildFlags_Widget(
726 horizGroup ? horizGroup : menu, 731 horizGroup ? horizGroup : menu,
727 iClob(newKeyMods_LabelWidget(labelText, item->key, item->kmods, item->command)), 732 iClob(newKeyMods_LabelWidget(labelText, item->key, item->kmods, item->command)),
@@ -730,6 +735,7 @@ void makeMenuItems_Widget(iWidget *menu, const iMenuItem *items, size_t n) {
730 setWrap_LabelWidget(label, isInfo); 735 setWrap_LabelWidget(label, isInfo);
731 haveIcons |= checkIcon_LabelWidget(label); 736 haveIcons |= checkIcon_LabelWidget(label);
732 updateSize_LabelWidget(label); /* drawKey was set */ 737 updateSize_LabelWidget(label); /* drawKey was set */
738 setFlags_Widget(as_Widget(label), disabled_WidgetFlag, isDisabled);
733 if (isInfo) { 739 if (isInfo) {
734 setFlags_Widget(as_Widget(label), fixedHeight_WidgetFlag, iTrue); /* wrap changes height */ 740 setFlags_Widget(as_Widget(label), fixedHeight_WidgetFlag, iTrue); /* wrap changes height */
735 setTextColor_LabelWidget(label, uiTextAction_ColorId); 741 setTextColor_LabelWidget(label, uiTextAction_ColorId);
@@ -784,10 +790,10 @@ static iArray *deepCopyMenuItems_(iWidget *menu, const iMenuItem *items, size_t
784 } 790 }
785#endif 791#endif
786 pushBack_Array(array, &(iMenuItem){ 792 pushBack_Array(array, &(iMenuItem){
787 item->label ? strdup(item->label) : NULL, 793 item->label ? iDupStr(item->label) : NULL,
788 item->key, 794 item->key,
789 item->kmods, 795 item->kmods,
790 itemCommand ? strdup(itemCommand) : NULL /* NOTE: Only works with string commands. */ 796 itemCommand ? iDupStr(itemCommand) : NULL /* NOTE: Only works with string commands. */
791 }); 797 });
792 } 798 }
793 deinit_String(&cmd); 799 deinit_String(&cmd);
@@ -883,45 +889,78 @@ iMenuItem *findNativeMenuItem_Widget(iWidget *menu, const char *commandSuffix) {
883 return NULL; 889 return NULL;
884} 890}
885 891
886void setSelected_NativeMenuItem(iMenuItem *item, iBool isSelected) { 892void setPrefix_NativeMenuItem(iMenuItem *item, const char *prefix, iBool set) {
887 if (!item->label) { 893 if (!item->label) {
888 return; 894 return;
889 } 895 }
890 const iBool hasPrefix = startsWith_CStr(item->label, "###"); 896 const iBool hasPrefix = startsWith_CStr(item->label, prefix);
891 if (hasPrefix && !isSelected) { 897 if (hasPrefix && !set) {
892 char *label = strdup(item->label + 3); 898 char *label = iDupStr(item->label + 3);
893 free((char *) item->label); 899 free((char *) item->label);
894 item->label = label; 900 item->label = label;
895 } 901 }
896 else if (!hasPrefix && isSelected) { 902 else if (!hasPrefix && set) {
897 char *label = malloc(strlen(item->label) + 4); 903 char *label = malloc(strlen(item->label) + 4);
898 memcpy(label, "###", 3); 904 memcpy(label, prefix, 3);
899 strcpy(label + 3, item->label); 905 strcpy(label + 3, item->label);
900 free((char *) item->label); 906 free((char *) item->label);
901 item->label = label; 907 item->label = label;
902 } 908 }
903} 909}
904 910
905void updateMenuItemLabel_Widget(iWidget *menu, const char *command, const char *newLabel) { 911void setSelected_NativeMenuItem(iMenuItem *item, iBool isSelected) {
906 if (~flags_Widget(menu) & nativeMenu_WidgetFlag) { 912 if (item) {
907 iLabelWidget *menuItem = findMenuItem_Widget(menu, command); 913 setPrefix_NativeMenuItem(item, "///", iFalse);
908 if (menuItem) { 914 setPrefix_NativeMenuItem(item, "###", isSelected);
909 setTextCStr_LabelWidget(menuItem, newLabel);
910 checkIcon_LabelWidget(menuItem);
911 }
912 } 915 }
913 else { 916}
917
918void setDisabled_NativeMenuItem(iMenuItem *item, iBool isDisabled) {
919 if (item) {
920 setPrefix_NativeMenuItem(item, "###", iFalse);
921 setPrefix_NativeMenuItem(item, "///", isDisabled);
922 }
923}
924
925void setLabel_NativeMenuItem(iMenuItem *item, const char *label) {
926 free((char *) item->label);
927 item->label = iDupStr(label);
928}
929
930void setMenuItemLabel_Widget(iWidget *menu, const char *command, const char *newLabel) {
931 if (flags_Widget(menu) & nativeMenu_WidgetFlag) {
914 iArray *items = userData_Object(menu); 932 iArray *items = userData_Object(menu);
915 iAssert(items); 933 iAssert(items);
916 iForEach(Array, i, items) { 934 iForEach(Array, i, items) {
917 iMenuItem *item = i.value; 935 iMenuItem *item = i.value;
918 if (item->command && !iCmpStr(item->command, command)) { 936 if (item->command && !iCmpStr(item->command, command)) {
919 free((void *) item->label); 937 setLabel_NativeMenuItem(item, newLabel);
920 item->label = strdup(newLabel);
921 break; 938 break;
922 } 939 }
923 } 940 }
924 } 941 }
942 else {
943 iLabelWidget *menuItem = findMenuItem_Widget(menu, command);
944 if (menuItem) {
945 setTextCStr_LabelWidget(menuItem, newLabel);
946 checkIcon_LabelWidget(menuItem);
947 }
948 }
949}
950
951void setMenuItemLabelByIndex_Widget(iWidget *menu, size_t index, const char *newLabel) {
952 if (flags_Widget(menu) & nativeMenu_WidgetFlag) {
953 iArray *items = userData_Object(menu);
954 iAssert(items);
955 iAssert(index < size_Array(items));
956 setLabel_NativeMenuItem(at_Array(items, index), newLabel);
957 }
958 else {
959 iLabelWidget *menuItem = child_Widget(menu, index);
960 iAssert(isInstance_Object(menuItem, &Class_LabelWidget));
961 setTextCStr_LabelWidget(menuItem, newLabel);
962 checkIcon_LabelWidget(menuItem);
963 }
925} 964}
926 965
927void unselectAllNativeMenuItems_Widget(iWidget *menu) { 966void unselectAllNativeMenuItems_Widget(iWidget *menu) {
@@ -953,8 +992,7 @@ void openMenuFlags_Widget(iWidget *d, iInt2 windowCoord, iBool postCommands) {
953 const iArray *items = userData_Object(d); 992 const iArray *items = userData_Object(d);
954 iAssert(flags_Widget(d) & nativeMenu_WidgetFlag); 993 iAssert(flags_Widget(d) & nativeMenu_WidgetFlag);
955 iAssert(items); 994 iAssert(items);
956 showPopupMenu_MacOS(d, windowCoord, //mouseCoord_Window(get_Window(), 0), 995 showPopupMenu_MacOS(d, windowCoord, constData_Array(items), size_Array(items));
957 constData_Array(items), size_Array(items));
958#else 996#else
959 const iRect rootRect = rect_Root(d->root); 997 const iRect rootRect = rect_Root(d->root);
960 const iInt2 rootSize = rootRect.size; 998 const iInt2 rootSize = rootRect.size;
@@ -1085,9 +1123,14 @@ iLabelWidget *findMenuItem_Widget(iWidget *menu, const char *command) {
1085} 1123}
1086 1124
1087void setMenuItemDisabled_Widget(iWidget *menu, const char *command, iBool disable) { 1125void setMenuItemDisabled_Widget(iWidget *menu, const char *command, iBool disable) {
1088 iLabelWidget *item = findMenuItem_Widget(menu, command); 1126 if (flags_Widget(menu) & nativeMenu_WidgetFlag) {
1089 if (item) { 1127 setDisabled_NativeMenuItem(findNativeMenuItem_Widget(menu, command), disable);
1090 setFlags_Widget(as_Widget(item), disabled_WidgetFlag, disable); 1128 }
1129 else {
1130 iLabelWidget *item = findMenuItem_Widget(menu, command);
1131 if (item) {
1132 setFlags_Widget(as_Widget(item), disabled_WidgetFlag, disable);
1133 }
1091 } 1134 }
1092} 1135}
1093 1136
@@ -1120,6 +1163,10 @@ const iString *removeMenuItemLabelPrefixes_String(const iString *d) {
1120 remove_Block(&str->chars, 0, 3); 1163 remove_Block(&str->chars, 0, 3);
1121 continue; 1164 continue;
1122 } 1165 }
1166 if (startsWith_String(str, "///")) {
1167 remove_Block(&str->chars, 0, 3);
1168 continue;
1169 }
1123 if (startsWith_String(str, "```")) { 1170 if (startsWith_String(str, "```")) {
1124 remove_Block(&str->chars, 0, 3); 1171 remove_Block(&str->chars, 0, 3);
1125 continue; 1172 continue;
@@ -2823,10 +2870,17 @@ static const iMenuItem languages[] = {
2823static iBool translationHandler_(iWidget *dlg, const char *cmd) { 2870static iBool translationHandler_(iWidget *dlg, const char *cmd) {
2824 iUnused(dlg); 2871 iUnused(dlg);
2825 if (equal_Command(cmd, "xlt.lang")) { 2872 if (equal_Command(cmd, "xlt.lang")) {
2826 iLabelWidget *menuItem = pointer_Command(cmd); 2873 const iMenuItem *langItem = &languages[languageIndex_CStr(cstr_Rangecc(range_Command(cmd, "id")))];
2827 iWidget *button = parent_Widget(parent_Widget(menuItem)); 2874 iWidget *widget = pointer_Command(cmd);
2828 iAssert(isInstance_Object(button, &Class_LabelWidget)); 2875 iLabelWidget *drop;
2829 updateText_LabelWidget((iLabelWidget *) button, text_LabelWidget(menuItem)); 2876 if (flags_Widget(widget) & nativeMenu_WidgetFlag) {
2877 drop = (iLabelWidget *) parent_Widget(widget);
2878 }
2879 else {
2880 drop = (iLabelWidget *) parent_Widget(parent_Widget(widget));
2881 }
2882 iAssert(isInstance_Object(drop, &Class_LabelWidget));
2883 updateDropdownSelection_LabelWidget(drop, langItem->command);
2830 return iTrue; 2884 return iTrue;
2831 } 2885 }
2832 return iFalse; 2886 return iFalse;
@@ -2880,25 +2934,25 @@ iWidget *makeTranslation_Widget(iWidget *parent) {
2880 addChild_Widget(dlg, iClob(page = makeTwoColumns_Widget(&headings, &values))); 2934 addChild_Widget(dlg, iClob(page = makeTwoColumns_Widget(&headings, &values)));
2881 setId_Widget(page, "xlt.langs"); 2935 setId_Widget(page, "xlt.langs");
2882 iLabelWidget *fromLang, *toLang; 2936 iLabelWidget *fromLang, *toLang;
2937 const size_t numLangs = iElemCount(languages) - 1;
2938 const char *widestLabel = languages[findWidestLabel_MenuItem(languages, numLangs)].label;
2883 /* Source language. */ { 2939 /* Source language. */ {
2884 addChild_Widget(headings, iClob(makeHeading_Widget("${dlg.translate.from}"))); 2940 addChild_Widget(headings, iClob(makeHeading_Widget("${dlg.translate.from}")));
2885 setId_Widget( 2941 setId_Widget(addChildFlags_Widget(values,
2886 addChildFlags_Widget(values, 2942 iClob(fromLang = makeMenuButton_LabelWidget(
2887 iClob(fromLang = makeMenuButton_LabelWidget( 2943 widestLabel, languages, numLangs)),
2888 "${lang.pt}", languages, iElemCount(languages) - 1)), 2944 alignLeft_WidgetFlag),
2889 alignLeft_WidgetFlag), 2945 "xlt.from");
2890 "xlt.from");
2891 setBackgroundColor_Widget(findChild_Widget(as_Widget(fromLang), "menu"), 2946 setBackgroundColor_Widget(findChild_Widget(as_Widget(fromLang), "menu"),
2892 uiBackgroundMenu_ColorId); 2947 uiBackgroundMenu_ColorId);
2893 } 2948 }
2894 /* Target language. */ { 2949 /* Target language. */ {
2895 addChild_Widget(headings, iClob(makeHeading_Widget("${dlg.translate.to}"))); 2950 addChild_Widget(headings, iClob(makeHeading_Widget("${dlg.translate.to}")));
2896 setId_Widget( 2951 setId_Widget(addChildFlags_Widget(values,
2897 addChildFlags_Widget(values, 2952 iClob(toLang = makeMenuButton_LabelWidget(
2898 iClob(toLang = makeMenuButton_LabelWidget( 2953 widestLabel, languages, numLangs)),
2899 "${lang.pt}", languages, iElemCount(languages) - 1)), 2954 alignLeft_WidgetFlag),
2900 alignLeft_WidgetFlag), 2955 "xlt.to");
2901 "xlt.to");
2902 setBackgroundColor_Widget(findChild_Widget(as_Widget(toLang), "menu"), 2956 setBackgroundColor_Widget(findChild_Widget(as_Widget(toLang), "menu"),
2903 uiBackgroundMenu_ColorId); 2957 uiBackgroundMenu_ColorId);
2904 } 2958 }
@@ -2908,14 +2962,18 @@ iWidget *makeTranslation_Widget(iWidget *parent) {
2908 arrange_Widget(dlg); 2962 arrange_Widget(dlg);
2909 } 2963 }
2910 /* Update choices. */ 2964 /* Update choices. */
2911 updateText_LabelWidget( 2965 updateDropdownSelection_LabelWidget(findChild_Widget(dlg, "xlt.from"),
2912 findChild_Widget(dlg, "xlt.from"), 2966 languages[prefs_App()->langFrom].command);
2913 text_LabelWidget(child_Widget(findChild_Widget(findChild_Widget(dlg, "xlt.from"), "menu"), 2967 updateDropdownSelection_LabelWidget(findChild_Widget(dlg, "xlt.to"),
2914 prefs_App()->langFrom))); 2968 languages[prefs_App()->langTo].command);
2915 updateText_LabelWidget( 2969// updateText_LabelWidget(
2916 findChild_Widget(dlg, "xlt.to"), 2970// findChild_Widget(dlg, "xlt.from"),
2917 text_LabelWidget(child_Widget(findChild_Widget(findChild_Widget(dlg, "xlt.to"), "menu"), 2971// text_LabelWidget(child_Widget(findChild_Widget(findChild_Widget(dlg, "xlt.from"), "menu"),
2918 prefs_App()->langTo))); 2972// prefs_App()->langFrom)));
2973// updateText_LabelWidget(
2974// findChild_Widget(dlg, "xlt.to"),
2975// text_LabelWidget(child_Widget(findChild_Widget(findChild_Widget(dlg, "xlt.to"), "menu"),
2976// prefs_App()->langTo)));
2919 setCommandHandler_Widget(dlg, translationHandler_); 2977 setCommandHandler_Widget(dlg, translationHandler_);
2920 setupSheetTransition_Mobile(dlg, iTrue); 2978 setupSheetTransition_Mobile(dlg, iTrue);
2921 return dlg; 2979 return dlg;