diff options
Diffstat (limited to 'Script.c')
| -rw-r--r-- | Script.c | 566 |
1 files changed, 309 insertions, 257 deletions
@@ -49,8 +49,8 @@ static const DT_Menu_KeepOpen_Keep = 0x1; static const DT_Menu_KeepOpen_Force = 0x2; static const DT_Menu_KeepOpen_Permanent = 0x2 << 1; static const DT_Menu_KeepOpen_Refresh = 0x2 << 1 << 1; -static const DT_Menu_KeepOpen_RefreshContinously = 0x2 << 1 << 1 << 1; -static const DT_Menu_KeepOpen_Refresh_Mask = 24; // DT_Menu_KeepOpen_Refresh | DT_Menu_KeepOpen_RefreshContinously +static const DT_Menu_KeepOpen_RefreshContinuously = 0x2 << 1 << 1 << 1; +static const DT_Menu_KeepOpen_Refresh_Mask = 24; // DT_Menu_KeepOpen_Refresh | DT_Menu_KeepOpen_RefreshContinuously */ static const DT_Menu_KeepOpen_Not = 0; @@ -58,8 +58,8 @@ static const DT_Menu_KeepOpen_Keep = 1; static const DT_Menu_KeepOpen_Force = 2; static const DT_Menu_KeepOpen_Permanent = 4; static const DT_Menu_KeepOpen_Refresh = 8; -static const DT_Menu_KeepOpen_RefreshContinously = 16; -static const DT_Menu_KeepOpen_Refresh_Mask = 24; // DT_Menu_KeepOpen_Refresh | DT_Menu_KeepOpen_RefreshContinously +static const DT_Menu_KeepOpen_RefreshContinuously = 16; +static const DT_Menu_KeepOpen_Refresh_Mask = 24; // DT_Menu_KeepOpen_Refresh | DT_Menu_KeepOpen_RefreshContinuously /* static const DT_Menu_Type_Setting = 0; @@ -212,6 +212,9 @@ static const Menu_AdaptorType_ID = 3; static const Menu_AdaptorType_Enum = 4; static const Menu_AdaptorType_BitField = 5; +static const Menu_Adaptor_Limits_Max = 0x7FFFFFFF; +static const Menu_Adaptor_Limits_Min = 0x80000000; + /* static const DT_Menu_Adaptor_Type = 0; static const DT_Menu_Adaptor_Variable = 0 + 1; @@ -222,7 +225,7 @@ static const DT_Menu_Adaptor_StepSize = 0 + 1 + 1 + 1 + 1 + 1; static const DT_Menu_Adaptor_LayoutVals = 0 + 1 + 1 + 1 + 1 + 1 + 1; static const DT_Menu_Adaptor_NoEmptyString = 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1; static const DT_Menu_Adaptor_EntryIndex = 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1; -static const DT_Menu_Adaptor_Bit = 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1; +static const DT_Menu_Adaptor_Mask = 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1; static const DT_Menu_Adaptor_WrapAround = 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1; static const DT_Menu_Adaptor_Args = 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1; static const DT_Menu_Adaptor_EnumSubmenu = 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1; @@ -239,7 +242,7 @@ static const DT_Menu_Adaptor_StepSize = 5; static const DT_Menu_Adaptor_LayoutVals = 6; static const DT_Menu_Adaptor_NoEmptyString = 7; static const DT_Menu_Adaptor_EntryIndex = 8; -static const DT_Menu_Adaptor_Bit = 9; +static const DT_Menu_Adaptor_Mask = 9; static const DT_Menu_Adaptor_WrapAround = 10; static const DT_Menu_Adaptor_Args = 11; static const DT_Menu_Adaptor_EnumSubmenu = 12; @@ -269,8 +272,6 @@ local entryCount; local currentSelection; local suspended; local closing; -local selectionOffset; -local selectionOverride; local msgBoardMode; local msgBoardEntry; local noSelectionCallbacks; @@ -293,6 +294,9 @@ func Create(array cSettings, array cEntries) createEntries = cEntries; currentSelection = -1; settings[DT_Menu_Settings_ConditionDisableMode] = settings[DT_Menu_Settings_ConditionDisableMode] || Menu_ConditionReact_Hide; + entryCount = 0; + + HandleEntries(createEntries, entryCount, entries); if(settings[DT_Menu_Settings_Parent]) settings[DT_Menu_Settings_Parent]->Suspend(); @@ -300,8 +304,7 @@ func Create(array cSettings, array cEntries) if(GetType(settings[DT_Menu_Settings_Size]) == C4V_Array) SetMenuSize(settings[DT_Menu_Settings_Size][0], settings[DT_Menu_Settings_Size][1], settings[DT_Menu_Settings_Object]); - entryCount = 0; - AddEntries(cEntries, entryCount); + AddEntries(entries); SelectEntry(settings[DT_Menu_Settings_Selection]); @@ -330,10 +333,7 @@ func ActivateEntry(int index, int action) SelectEntry(index); var entry = entries[index]; - if(entry[0] == DT_Menu_Type_Entry) - { - MenuItemCommand(entry[1][DT_Menu_Entry_Symbol], index, action); - } + MenuItemCommand(entry[DT_Menu_Entry_Symbol], index, action); } /*func FxMenuStart(object target, int effectNumber, int temp) @@ -362,8 +362,8 @@ func FxMenuTimer(object target, int effectNumber, int effectTime) if(msgBoardMode != 0 && !TestMessageBoard(GetOwner(settings[DT_Menu_Settings_Object]), true)) { var entry = entries[msgBoardEntry]; - var args = entry[1][DT_Menu_Entry_Args]; - var reaction = CallCallbacks(args[DT_Menu_Adaptor_Callbacks], Menu_CallbackType_InputAborted, [Menu_CallbackType_InputAborted, entry[1][DT_Menu_Entry_Symbol], settings[DT_Menu_Settings_Object], entry[DT_Menu_Entry_Args]]); + var args = entry[DT_Menu_Entry_Args]; + var reaction = CallCallbacks(args[DT_Menu_Adaptor_Callbacks], Menu_CallbackType_InputAborted, [Menu_CallbackType_InputAborted, entry[DT_Menu_Entry_Symbol], settings[DT_Menu_Settings_Object], entry[DT_Menu_Entry_Args]]); if(reaction != Menu_React_None) { React(reaction, msgBoardEntry); @@ -383,7 +383,7 @@ func FxMenuTimer(object target, int effectNumber, int effectTime) } } - if(settings[DT_Menu_Settings_KeepOpen] & DT_Menu_KeepOpen_RefreshContinously && !(effectTime % settings[DT_Menu_Settings_RefreshInterval])) + if(settings[DT_Menu_Settings_KeepOpen] & DT_Menu_KeepOpen_RefreshContinuously && !(effectTime % settings[DT_Menu_Settings_RefreshInterval])) { Refresh(currentSelection); } @@ -452,89 +452,104 @@ func Suspend(bool cont) } } -func AddEntries(array entries, &i) +func HandleEntries(array factoryEntries, int& i, array& ret) { - for(var entry in entries) + for(var entry in factoryEntries) { if(entry[0] == DT_Menu_Type_Entry) { - var condition = entry[1][DT_Menu_Entry_Condition], conditionRet; - var caption = entry[1][DT_Menu_Entry_Caption], noCommand = !entry[1][DT_Menu_Entry_Placeholder] || (entry[1][DT_Menu_Entry_Placeholder] != true && !entry[1][DT_Menu_Entry_Callbacks]); - if(condition) + ret[i++] = entry[1]; + } + else if(entry[0] == DT_Menu_Type_Factory) + { + for(var callback in entry[1][0]) { - if(noCommand || condition[1] == Menu_Condition_DenySelection || (condition[1] == Menu_Condition_Default && !settings[DT_Menu_Settings_ConditionAllowSelection])) - { - noCommand = true; - } - - conditionRet = CallA(condition[0], [entry[1][DT_Menu_Entry_Symbol], settings[DT_Menu_Settings_Object], entry[1][DT_Menu_Entry_Args]]) || settings[DT_Menu_Settings_ConditionDisableMode]; - if(conditionRet == Menu_ConditionReact_Hide) - { - continue; - } - else if(conditionRet == Menu_ConditionReact_GrayOut) - { - caption = Format("<c 808080>%s</c>", caption); - } - else if(GetType(conditionRet) == C4V_Array && conditionRet[0] == Menu_ConditionReact_CustomFormat) + var factoryResult = CallA(callback, [entry[1][1], i]); + if(GetType(factoryResult) == C4V_Array) { - caption = Format(conditionRet[1], caption); + var newEntries = []; + UncombineAndDistinguish(factoryResult, settings, newEntries); + HandleEntries(newEntries, i, ret); } - else + else if(factoryResult == Menu_React_Close) { - noCommand = false; + return Close(); } + } + } + } +} + +func AddEntries(array& entries) +{ + for(var i = 0; i < GetLength(entries); ++i) + { + var entry = entries[i]; + var condition = entry[DT_Menu_Entry_Condition], conditionRet; + var caption = entry[DT_Menu_Entry_Caption], noCommand = !entry[DT_Menu_Entry_Placeholder] || (entry[DT_Menu_Entry_Placeholder] != true && !entry[DT_Menu_Entry_Callbacks]); + if(condition) + { + if(noCommand || condition[1] == Menu_Condition_DenySelection || (condition[1] == Menu_Condition_Default && !settings[DT_Menu_Settings_ConditionAllowSelection])) + { + noCommand = true; } - var symbol = entry[1][DT_Menu_Entry_Symbol], symbolID = 0; - if(GetType(symbol) == C4V_Array) + conditionRet = CallA(condition[0], [entry[DT_Menu_Entry_Symbol], settings[DT_Menu_Settings_Object], entry[DT_Menu_Entry_Args]]) || settings[DT_Menu_Settings_ConditionDisableMode]; + if(conditionRet == Menu_ConditionReact_Hide) { - if(GetType(symbol[0]) == C4V_C4ID) - { - symbolID = symbol[0]; - if(symbol[1]) - { - entry[1][DT_Menu_Entry_Extra] |= C4MN_Add_ImgIndexed; - entry[1][DT_Menu_Entry_XPar1] = symbol[1]; - } - } - else if(GetType(symbol[0]) == C4V_C4Object) - { - entry[1][DT_Menu_Entry_Extra] |= C4MN_Add_ImgObject; - entry[1][DT_Menu_Entry_XPar1] = symbol[0]; - symbolID = GetID(symbol[0]); - } + continue; } - else + else if(conditionRet == Menu_ConditionReact_GrayOut) { - symbolID = symbol; + caption = Format("<c 808080>%s</c>", caption); } - entry[1][DT_Menu_Entry_Symbol] = symbolID; - - LocalN("entries")[i] = entry; - AddMenuItem(caption, !noCommand && "MenuItemCommand", symbolID, settings[DT_Menu_Settings_Object], entry[1][DT_Menu_Entry_Count], i++, entry[1][DT_Menu_Entry_InfoCaption], entry[1][DT_Menu_Entry_Extra], entry[1][DT_Menu_Entry_XPar1], entry[1][DT_Menu_Entry_XPar2]); - - if(GetType(symbol) == C4V_Array && GetType(symbol[0]) == C4V_C4Object && symbol[1]) + else if(GetType(conditionRet) == C4V_Array && conditionRet[0] == Menu_ConditionReact_CustomFormat) { - RemoveObject(symbol[0]); + caption = Format(conditionRet[1], caption); + } + else + { + noCommand = false; } } - else if(entry[0] == DT_Menu_Type_Factory) + + var symbol = entry[DT_Menu_Entry_Symbol], symbolID = 0, deleteSymbol = 0; + if(GetType(symbol) == C4V_Array) { - for(var callback in entry[1][0]) + if(GetType(symbol[0]) == C4V_C4ID) { - var factoryResult = CallA(callback, [entry[1][1], i]); - if(GetType(factoryResult) == C4V_Array) + symbolID = symbol[0]; + if(symbol[2]) { - var newEntries = []; - UncombineAndDistinguish(factoryResult, settings, newEntries); - AddEntries(newEntries, i); + symbol = [CreateSymbolDummy()->SetSymbol(symbolID, symbol[1])->SetColor(symbol[2]), true]; } - else if(factoryResult == Menu_React_Close) + else if(symbol[1]) { - return Close(); + entry[DT_Menu_Entry_Extra] |= C4MN_Add_ImgIndexed; + entry[DT_Menu_Entry_XPar1] = symbol[1]; } } + + if(GetType(symbol[0]) == C4V_C4Object) + { + entry[DT_Menu_Entry_Extra] |= C4MN_Add_ImgObject; + deleteSymbol = entry[DT_Menu_Entry_XPar1] = symbol[0]; + symbolID = GetID(symbol[0]); + } + } + else + { + symbolID = symbol; + } + entry[DT_Menu_Entry_Symbol] = symbolID; + + entries[i] = entry; + + AddMenuItem(caption, !noCommand && "MenuItemCommand", symbolID, settings[DT_Menu_Settings_Object], entry[DT_Menu_Entry_Count], i, entry[DT_Menu_Entry_InfoCaption], entry[DT_Menu_Entry_Extra], entry[DT_Menu_Entry_XPar1], entry[DT_Menu_Entry_XPar2]); + + if(deleteSymbol) + { + RemoveObject(deleteSymbol); } } } @@ -553,19 +568,22 @@ func React(reaction, int itemNumber, int refreshDelayed) { Refresh(itemNumber, refreshDelayed); } - else if(reaction == Menu_React_KeepOpen && (settings[DT_Menu_Settings_KeepOpen] == DT_Menu_KeepOpen_Not || settings[DT_Menu_Settings_KeepOpen] == DT_Menu_KeepOpen_Permanent)) - { -// Refresh(itemNumber, refreshDelayed); - } else if(GetType(reaction) == C4V_Array) { + var selection = currentSelection; if(reaction[0] == Menu_React_SelectionOffset) { - selectionOffset = reaction[1]; + selection += reaction[1]; + selection %= entryCount; } else if(reaction[0] == Menu_React_SelectionChange) { - selectionOverride = reaction[1] + 1; + selection = BoundBy(reaction[1], 0, entryCount - 1); + } + + if(selection != currentSelection) + { + SelectEntry(selection); } } } @@ -579,12 +597,12 @@ func CheckCondition(array entry) func MenuItemCommand(id ID, int itemNumber, int action) { var entry = entries[itemNumber]; - var condition = entry[1][DT_Menu_Entry_Condition]; + var condition = entry[DT_Menu_Entry_Condition]; action = action || Menu_CallbackType_Normal; var reaction; - if(CheckCondition(entry[1])) + if(CheckCondition(entry)) { - reaction = CallCallbacks(entry[1][DT_Menu_Entry_Callbacks], action, [action, ID, settings[DT_Menu_Settings_Object], entry[1][DT_Menu_Entry_Args]]); + reaction = CallCallbacks(entry[DT_Menu_Entry_Callbacks], action, [action, ID, settings[DT_Menu_Settings_Object], entry[DT_Menu_Entry_Args]]); } else { @@ -621,12 +639,9 @@ func MenuQueryCancel(int selection, object menuObject) { var entry = entries[selection]; var reaction; - if(entry[0] == DT_Menu_Type_Entry) + if(CheckCondition(entry)) { - if(CheckCondition(entry[1])) - { - reaction = CallCallbacks(entry[1][DT_Menu_Entry_Callbacks], Menu_CallbackType_Close, [Menu_CallbackType_Close, entry[1][DT_Menu_Entry_Symbol], settings[DT_Menu_Settings_Object], entry[1][DT_Menu_Entry_Args]]); - } + reaction = CallCallbacks(entry[DT_Menu_Entry_Callbacks], Menu_CallbackType_Close, [Menu_CallbackType_Close, entry[DT_Menu_Entry_Symbol], settings[DT_Menu_Settings_Object], entry[DT_Menu_Entry_Args]]); } React(reaction, selection, true); @@ -644,14 +659,28 @@ func OnMenuSelection(int selection, object menuObject) { var oldSelection = currentSelection; var entry = entries[currentSelection]; - if(!noSelectionCallbacks && entry[0] == DT_Menu_Type_Entry && CheckCondition(entry[1]) && currentSelection != -1) + var deselectReaction = Menu_React_None; + var selectReaction = Menu_React_None; + if(!noSelectionCallbacks && CheckCondition(entry) && currentSelection != -1) { - CallCallbacks(entry[1][DT_Menu_Entry_Callbacks], Menu_CallbackType_Deselection, [Menu_CallbackType_Deselection, entry[1][DT_Menu_Entry_Symbol], settings[DT_Menu_Settings_Object], entry[1][DT_Menu_Entry_Args], oldSelection, selection]); + deselectReaction = CallCallbacks(entry[DT_Menu_Entry_Callbacks], Menu_CallbackType_Deselection, [Menu_CallbackType_Deselection, entry[DT_Menu_Entry_Symbol], settings[DT_Menu_Settings_Object], entry[DT_Menu_Entry_Args], oldSelection, selection]); } + entry = entries[currentSelection = selection]; - if(!noSelectionCallbacks && entry[0] == DT_Menu_Type_Entry && CheckCondition(entry[1])) + + if(!noSelectionCallbacks && CheckCondition(entry)) + { + selectReaction = CallCallbacks(entry[DT_Menu_Entry_Callbacks], Menu_CallbackType_Selection, [Menu_CallbackType_Selection, entry[DT_Menu_Entry_Symbol], settings[DT_Menu_Settings_Object], entry[DT_Menu_Entry_Args], selection, oldSelection]); + } + + if(deselectReaction != Menu_React_None) + { + React(deselectReaction, currentSelection); + } + + if(selectReaction != Menu_React_None) { - CallCallbacks(entry[1][DT_Menu_Entry_Callbacks], Menu_CallbackType_Selection, [Menu_CallbackType_Selection, entry[1][DT_Menu_Entry_Symbol], settings[DT_Menu_Settings_Object], entry[1][DT_Menu_Entry_Args], selection, oldSelection]); + React(selectReaction, currentSelection); } } } @@ -677,11 +706,7 @@ func Refresh(int selection, bool delayed) CloseMenu(settings[DT_Menu_Settings_Object]); Create(settings, createEntries); - var newSelection = selection; - selectionOverride && (newSelection = selectionOverride-1); - SelectEntry(BoundBy(newSelection + selectionOffset, 0, entryCount-1)); - selectionOffset = 0; - selectionOverride = 0; + SelectEntry(BoundBy(selection, 0, entryCount - 1)); if(disabledCallbacks) { @@ -722,7 +747,7 @@ global func Menu_DontKeepOpen() { return Menu__KeepOpen(DT_Menu_KeepOpen_Not); } global func Menu_KeepOpen() { return Menu__KeepOpen(DT_Menu_KeepOpen_Keep); } global func Menu_ForceKeepOpen() { return Menu__KeepOpen(DT_Menu_KeepOpen_Force); } global func Menu_Refresh() { return Menu__KeepOpen(DT_Menu_KeepOpen_Refresh); } -global func Menu_RefreshContinously(int interval) { return Menu_Combined([Menu__KeepOpen(DT_Menu_KeepOpen_RefreshContinously), Menu_RefreshInterval(interval)]); } +global func Menu_RefreshContinuously(int interval) { return Menu_Combined([Menu__KeepOpen(DT_Menu_KeepOpen_RefreshContinuously), Menu_RefreshInterval(interval)]); } global func Menu_Permanent() { return Menu__KeepOpen(DT_Menu_KeepOpen_Permanent); } global func Menu_ConditionAllowSelection() { return Menu__Setting([DT_Menu_Settings_ConditionAllowSelection, true]);} @@ -748,7 +773,7 @@ global func Menu_Entry_XPar1(XPar1) { return [DT_Menu_Entry_XPar1, XPar1]; } global func Menu_Entry_XPar2(XPar2) { return [DT_Menu_Entry_XPar2, XPar2]; } global func Menu_Entry_Args(Args) { return [DT_Menu_Entry_Args, Args]; } global func Menu_Entry_Placeholder(bool Placeholder) { return [DT_Menu_Entry_Placeholder, Placeholder]; } -global func Menu_Entry_Symbol(symbol, extra) +global func Menu_Entry_Symbol(symbol, extra, int color) { if(GetType(symbol) == C4V_Array) { @@ -756,7 +781,7 @@ global func Menu_Entry_Symbol(symbol, extra) } else { - return [DT_Menu_Entry_Symbol, [symbol, extra]]; + return [DT_Menu_Entry_Symbol, [symbol, extra, color]]; } } global func Menu_Entry_Condition(callback, int allowDisabledSelection) { return [DT_Menu_Entry_Condition, [callback, allowDisabledSelection]]; } @@ -786,54 +811,22 @@ global func Menu_Entry_Object(object obj) return Menu_Combined([Menu_Entry_Symbol(obj), Menu_Entry_Caption(GetName(obj)), Menu_Entry_InfoCaption(GetDesc(obj))]); } -global func Menu_Entry(caption, array callback, id symbol, int count, string infoCaption, args, int extra, XPar1, XPar2) -{ - if(!caption) - { - caption = [Menu_Entry_Placeholder(false)]; - } - if(GetType(caption) == C4V_Array) // then caption is an array of named args - { - var namedArgs = []; - namedArgs[DT_Menu_Entry_Caption] = ""; - namedArgs[DT_Menu_Entry_Placeholder] = -1; - MN7I->NamedArgs(caption, namedArgs); - if(!namedArgs[DT_Menu_Entry_InfoCaption]) - { - namedArgs[DT_Menu_Entry_Extra] |= C4MN_Add_ForceNoDesc; - } - return [DT_Menu_Type_Entry, namedArgs]; - } - else // unnamed arguments for shorter code - { - var ret = [DT_Menu_Type_Entry, [caption || "", [Menu_Callback(callback)], symbol, count, infoCaption, extra, XPar1, XPar2, args]]; - ret[1][DT_Menu_Entry_Placeholder] = -1; - if(!infoCaption) - { - ret[1][DT_Menu_Entry_Extra] |= C4MN_Add_ForceNoDesc; - } - return ret; - } -} -global func Menu_AutoEntry(id_or_obj, array callbacks, int count) +global func Menu_Entry(array settings) { - var id, id_, obj; - if(GetType(id_or_obj) == C4V_C4ID) - { - id_ = id = id_or_obj; - } - else if(GetType(id_or_obj) == C4V_C4Object) + if(!settings) { - obj = id_or_obj; - id = GetID(obj); + settings = [Menu_Entry_Placeholder(false)]; } - else + + var namedArgs = []; + namedArgs[DT_Menu_Entry_Caption] = ""; + namedArgs[DT_Menu_Entry_Placeholder] = -1; + MN7I->NamedArgs(settings, namedArgs); + if(!namedArgs[DT_Menu_Entry_InfoCaption]) { - FatalError("Menu_AutoEntry: No ID or object given."); - return; + namedArgs[DT_Menu_Entry_Extra] |= C4MN_Add_ForceNoDesc; } - - return [DT_Menu_Type_Entry, [GetName(obj, id_), callbacks, id, count, GetDesc(obj, id_)]]; + return [DT_Menu_Type_Entry, namedArgs]; } global func Menu_SubMenu(array entrySettings, array menuEntry_Settings) @@ -849,25 +842,38 @@ global func Menu_Factory(array callbacks, args) return [DT_Menu_Type_Factory, [callbacks, args]]; } -global func Menu_Decline(array callbacks, string caption, string infoCaption, args) +global func Menu_Text(string text, bool allowSelection) +{ + return Menu_Entry([Menu_Entry_Caption(text), Menu_Entry_Placeholder(allowSelection)]); +} + +global func Menu_Blank(bool allowSelection) +{ + return Menu_Entry([Menu_Entry_Placeholder(allowSelection)]); +} + +func DeclineAcceptBack(string caption, symbol, string callback, array settings) +{ + var ret = Menu_Entry([Menu_Entry_Caption(caption), Menu_Combined(settings || [])]); + ret[1][DT_Menu_Entry_Args] = [ret[1][DT_Menu_Entry_Callbacks], ret[1][DT_Menu_Entry_Args]]; + ret[1][DT_Menu_Entry_Callbacks] = Menu_Entry_Callbacks([Menu_Callback(MN7I->MenuObjectCallback(callback), Menu_CallbackType_All)])[1]; + ExtraSymbol(ret[1][DT_Menu_Entry_Caption], ret[1][DT_Menu_Entry_Symbol], symbol); + return ret; +} + +global func Menu_Decline(array settings) { - caption || (caption = "$Decline$"); - caption = Format("{{MN7I:2}} %s", caption); - return Menu_Entry(caption, MN7I->MenuObjectCallback("DeclineAcceptCommand"), 0, 0, infoCaption, [callbacks, args]); + return MN7I->DeclineAcceptBack("$Decline$", [MN7I, 2], "DeclineAcceptCommand", settings); } -global func Menu_Accept(array callback, string caption, string infoCaption, args) +global func Menu_Accept(array settings) { - caption || (caption = "$Accept$"); - caption = Format("{{MN7I:1}} %s", caption); - return Menu_Entry(caption, MN7I->MenuObjectCallback("DeclineAcceptCommand"), 0, 0, infoCaption, [callback, args]); + return MN7I->DeclineAcceptBack("$Accept$", [MN7I, 1], "DeclineAcceptCommand", settings); } -global func Menu_Back(array callback, string caption, string infoCaption, args) +global func Menu_Back(array settings) { - caption || (caption = "$Back$"); - caption = Format("{{MN7I:5}} %s", caption); - return Menu_Entry(caption, MN7I->MenuObjectCallback("BackCommand"), 0, 0, infoCaption, [callback, args]); + return MN7I->DeclineAcceptBack("$Back$", [MN7I, 5], "BackCommand", settings); } global func Menu_Adaptor_Type(int Type) { return [DT_Menu_Adaptor_Type, Type]; } @@ -884,9 +890,17 @@ global func Menu_Adaptor_Enum(array enumVals, array layout, bool valuesAsSeparat MN7I->AdaptorLayout(layout, enumVals, valuesAsSeparateLists); return Menu_Combined([Menu_Adaptor_Type(Menu_AdaptorType_Enum), [DT_Menu_Adaptor_LayoutVals, [enumVals, layout]]]); } -global func Menu_Adaptor_BitField(array fieldVals, array layout, bool valuesAsSeparateLists) +global func Menu_Adaptor_BitField(array fieldVals, array layout, bool valuesAsSeparateLists, bool bitPositionAsValue) { MN7I->AdaptorLayout(layout, fieldVals, valuesAsSeparateLists); + if(bitPositionAsValue) + { + var valuePos = layout[Menu_Layout__ValuePos] - 1; + for(var i = 0; i < GetLength(fieldVals); ++i) + { + fieldVals[i][valuePos] = 1 << fieldVals[i][valuePos]; + } + } return Menu_Combined([Menu_Adaptor_Type(Menu_AdaptorType_BitField), [DT_Menu_Adaptor_LayoutVals, [fieldVals, layout]]]); } global func Menu_Adaptor_NoEmptyString() { return [DT_Menu_Adaptor_NoEmptyString, true]; } @@ -986,15 +1000,22 @@ func EnumValPos(array enumVals, array layout, val) return -1; } -func BooleanToggleCaption(bool val, string caption) +func BooleanToggleCaption(bool val, string& caption, &symbol) { val = !!val; - return Format("{{MN7I:%d}} <c %x>%s</c>", [2, 1][val], [RGB(128, 128, 128), RGB(255, 255, 255)][val], caption); + ExtraSymbol(caption, symbol, [MN7I, 2 - val, !val && RGB(128, 128, 128)]); } func InlineSymbol(string& caption, symbol) { - caption = Format("{{%i:%d}} %s", symbol[0], symbol[1], caption); + if(symbol[2]) + { + caption = Format("<c %x>{{%i:%d}}</c> %s", symbol[2], symbol[0], symbol[1], caption); + } + else + { + caption = Format("{{%i:%d}} %s", symbol[0], symbol[1], caption); + } } func ExtraSymbol(string& caption, &symbol, extraSymbol) @@ -1039,10 +1060,11 @@ func EnumEntrySettings(string& caption, &symbol, string& infoCaption, int index, func AdaptorFactory(args, int entryIndex) { + var origArgs = args; var entry = args[0]; var entrySettings = args[2]; args = args[1]; - var caption; + var caption = entry[DT_Menu_Entry_Caption]; var infoCaption = entry[DT_Menu_Entry_InfoCaption]; var symbol = entry[DT_Menu_Entry_Symbol]; var val = ScopedVar(args[DT_Menu_Adaptor_Variable]); @@ -1055,7 +1077,7 @@ func AdaptorFactory(args, int entryIndex) args[DT_Menu_Adaptor_Callbacks] = args[DT_Menu_Adaptor_Callbacks] || []; if(args[DT_Menu_Adaptor_Type] == Menu_AdaptorType_Boolean) { - caption = BooleanToggleCaption(val, entry[DT_Menu_Entry_Caption]); + BooleanToggleCaption(val, caption, symbol); } else if(args[DT_Menu_Adaptor_Type] == Menu_AdaptorType_String) { @@ -1077,17 +1099,17 @@ func AdaptorFactory(args, int entryIndex) min = true; } } - caption = Format("%s %s %s", ["{{MN7I:3}}", "<c 808080>{{MN7I:3}}</c>"][max], Format(entry[DT_Menu_Entry_Caption], val), ["{{MN7I:4}}", "<c 808080>{{MN7I:4}}</c>"][min]); + caption = Format("%s %s", Format(entry[DT_Menu_Entry_Caption], val), ["{{MN7I:4}}", "<c 808080>{{MN7I:4}}</c>"][min]); + ExtraSymbol(caption, symbol, [MN7I, 3, max && RGB(128, 128, 128)]); defaultMsgboardText = "$EnterNumber$"; } else if(args[DT_Menu_Adaptor_Type] == Menu_AdaptorType_ID) { - var text = ""; + caption = Format(entry[DT_Menu_Entry_Caption], val && GetName(0, val) || ""); if(val) { - text = Format("{{%i}} %s", val, GetName(0, val)); + ExtraSymbol(caption, symbol, val); } - caption = Format(entry[DT_Menu_Entry_Caption], text); defaultMsgboardText = "$EnterIDOrName$"; } else if(args[DT_Menu_Adaptor_Type] == Menu_AdaptorType_Enum) @@ -1112,77 +1134,12 @@ func AdaptorFactory(args, int entryIndex) { args[DT_Menu_Adaptor_MessageBoardText] = args[DT_Menu_Adaptor_MessageBoardText] || defaultMsgboardText; - var submenuCaption = args[DT_Menu_Adaptor_EnumSubmenuCaption]; - - if(submenuCaption && submenuCaption[0]) - { - submenuCaption = submenuCaption[0]; - } - else - { - submenuCaption = caption; - } - - retSubmenu = [ - Menu_KeepParentOnClose(), - Menu_Caption(submenuCaption), - Menu_DontKeepOpen(), - - Menu_Factory([MenuObjectCallback("AdaptorEnumSubmenuFactory")], [args, entry]) - ]; - - if(args[DT_Menu_Adaptor_EnumSubmenuSymbol]) - { - submenuSymbol = [args[DT_Menu_Adaptor_EnumSubmenuSymbol]]; - } - else if(!submenuSymbol && symbol && GetType(symbol[0]) == C4V_C4ID) - { - submenuSymbol = symbol; - } - - if(submenuSymbol && GetType(submenuSymbol[0]) == C4V_C4ID) - { - ArrayAppend(retSubmenu, Menu_Symbol(submenuSymbol[0])); - } + retSubmenu = [Menu_Factory([MenuObjectCallback("AdaptorEnumSubmenuFactory")], [args, entry])]; } } else if(args[DT_Menu_Adaptor_Type] == Menu_AdaptorType_BitField) { - args[DT_Menu_Adaptor_MessageBoardText] = args[DT_Menu_Adaptor_MessageBoardText] || defaultMsgboardText; - - var layoutVals = args[DT_Menu_Adaptor_LayoutVals]; - var layout = layoutVals[1]; - layoutVals = layoutVals[0]; - - var fieldValue = ScopedVar(args[DT_Menu_Adaptor_Variable]); - var ret = []; - - for(var val in layoutVals) - { - caption = entry[DT_Menu_Entry_Caption] || "%s"; - if(layout[Menu_Layout__CaptionPos]) - { - caption = Format(caption, val[layout[Menu_Layout__CaptionPos] - 1]); - } - caption = BooleanToggleCaption(fieldValue & (1 << val[layout[Menu_Layout__ValuePos] - 1]), caption); - - symbol = entry[DT_Menu_Entry_Symbol]; - if(layout[Menu_Layout_Symbol]) - { - ExtraSymbol(caption, symbol, val[layout[Menu_Layout_Symbol] - 1]); - } - - if(layout[Menu_Layout_InfoCaption]) - { - infoCaption = Format(infoCaption, val[layout[Menu_Layout_InfoCaption] - 1]); - } - - args[DT_Menu_Adaptor_Bit] = val[layout[Menu_Layout__ValuePos] - 1]; - - ArrayAppend(ret, Menu_Entry([Menu_Combined(entrySettings), Menu_Entry_Caption(caption), Menu_Entry_Callbacks([Menu_Callback(MenuObjectCallback("AdaptorCommand"), Menu_CallbackType_All)]), Menu_Entry_Symbol(symbol), Menu_Entry_InfoCaption(infoCaption), Menu_Entry_Args(args)])); - } - - return ret; + return AdaptorBitFieldItemsFactory(origArgs); } args[DT_Menu_Adaptor_MessageBoardText] = args[DT_Menu_Adaptor_MessageBoardText] || defaultMsgboardText; if(!retSubmenu) @@ -1203,9 +1160,40 @@ func AdaptorEnumSubmenuFactory(array args) var layout = layoutVals[1]; layoutVals = layoutVals[0]; - var ret = [Menu_Selection(EnumValPos(layoutVals, layout, ScopedVar(args[DT_Menu_Adaptor_Variable])))]; + var submenuCaption = args[DT_Menu_Adaptor_EnumSubmenuCaption]; + var submenuSymbol = []; + + var index = EnumValPos(layoutVals, layout, ScopedVar(args[DT_Menu_Adaptor_Variable])); + var symbol, infoCaption; + EnumEntrySettings(submenuCaption, symbol, infoCaption, index, args, entry); + + if(submenuCaption && submenuCaption[0]) + { + submenuCaption = submenuCaption[0]; + } + + var ret = [ + Menu_Selection(index), + Menu_KeepParentOnClose(), + Menu_DontKeepOpen(), + Menu_Caption(submenuCaption) + ]; + + if(args[DT_Menu_Adaptor_EnumSubmenuSymbol]) + { + submenuSymbol = [args[DT_Menu_Adaptor_EnumSubmenuSymbol]]; + } + else if(!submenuSymbol && symbol && GetType(symbol[0]) == C4V_C4ID) + { + submenuSymbol = symbol; + } - var caption, infoCaption, symbol; + if(submenuSymbol && GetType(submenuSymbol[0]) == C4V_C4ID) + { + ArrayAppend(ret, Menu_Symbol(submenuSymbol[0])); + } + + var caption; var submenuCaption = args[DT_Menu_Adaptor_EnumSubmenuCaption]; if(submenuCaption && submenuCaption[1]) @@ -1245,6 +1233,52 @@ func AdaptorEnumSubmenuItem(int action, id ID, object obj, args) return Menu_React_Back; } +func AdaptorBitFieldItemsFactory(args) +{ + var entry = args[0]; + var entrySettings = args[2]; + args = args[1]; + + var caption = entry[DT_Menu_Entry_Caption]; + var infoCaption = entry[DT_Menu_Entry_InfoCaption]; + var symbol = entry[DT_Menu_Entry_Symbol]; + var fieldValue = ScopedVar(args[DT_Menu_Adaptor_Variable]); + + var layoutVals = args[DT_Menu_Adaptor_LayoutVals]; + var layout = layoutVals[1]; + layoutVals = layoutVals[0]; + + var ret = []; + + for(var val in layoutVals) + { + var mask = val[layout[Menu_Layout__ValuePos] - 1]; + caption = entry[DT_Menu_Entry_Caption] || "%s"; + if(layout[Menu_Layout__CaptionPos]) + { + caption = Format(caption, val[layout[Menu_Layout__CaptionPos] - 1]); + } + + symbol = entry[DT_Menu_Entry_Symbol]; + BooleanToggleCaption((fieldValue & mask) == mask, caption, symbol); + if(layout[Menu_Layout_Symbol]) + { + ExtraSymbol(caption, symbol, val[layout[Menu_Layout_Symbol] - 1]); + } + + if(layout[Menu_Layout_InfoCaption]) + { + infoCaption = Format(infoCaption, val[layout[Menu_Layout_InfoCaption] - 1]); + } + + args[DT_Menu_Adaptor_Mask] = mask; + + ArrayAppend(ret, Menu_Entry([Menu_Combined(entrySettings), Menu_Entry_Caption(caption), Menu_Entry_Callbacks([Menu_Callback(MenuObjectCallback("AdaptorCommand"), Menu_CallbackType_All)]), Menu_Entry_Symbol(symbol), Menu_Entry_InfoCaption(infoCaption), Menu_Entry_Args(args)])); + } + + return ret; +} + func WrapOrBind(int val, array limits, bool wrap) { if(!limits) @@ -1283,7 +1317,7 @@ func WrapOrBind(int val, array limits, bool wrap) } } -func AdaptorCommand(int action, id ID, object obj, args) // TODO: Callback bei CallMessageBoard? +func AdaptorCommand(int action, id ID, object obj, args) { var callbackArgs = args[DT_Menu_Adaptor_Args]; var val = ScopedVar(args[DT_Menu_Adaptor_Variable]); @@ -1439,7 +1473,17 @@ func AdaptorCommand(int action, id ID, object obj, args) // TODO: Callback bei C { if(action & (Menu_CallbackType_Normal | Menu_CallbackType_Special2)) { - ScopedVar(args[DT_Menu_Adaptor_Variable]) = (val ^= (1 << args[DT_Menu_Adaptor_Bit])); + var mask = args[DT_Menu_Adaptor_Mask]; + if((val & mask) == mask) + { + val &= ~mask; + } + else + { + val |= mask; + } + + ScopedVar(args[DT_Menu_Adaptor_Variable]) = val; reaction = CallCallbacks(args[DT_Menu_Adaptor_Callbacks], Menu_CallbackType_ValueChanged, [Menu_CallbackType_ValueChanged, ID, obj, callbackArgs, val, oldVal]); if(reaction != Menu_React_None) { @@ -1458,7 +1502,7 @@ func AdaptorCommand(int action, id ID, object obj, args) // TODO: Callback bei C func InputCallback(string input, int plr) { var entry = entries[msgBoardEntry]; - var args = entry[1][DT_Menu_Entry_Args]; + var args = entry[DT_Menu_Entry_Args]; var callbackArgs = args[DT_Menu_Adaptor_Args]; var oldVal = ScopedVar(args[DT_Menu_Adaptor_Variable]); var val = input; @@ -1510,7 +1554,7 @@ func InputCallback(string input, int plr) msgBoardMode = 0; if(val != oldVal) { - var reaction = CallCallbacks(args[DT_Menu_Adaptor_Callbacks], Menu_CallbackType_ValueChanged, [Menu_CallbackType_ValueChanged, entry[1][DT_Menu_Entry_Symbol], settings[DT_Menu_Settings_Object], callbackArgs, val, oldVal]); + var reaction = CallCallbacks(args[DT_Menu_Adaptor_Callbacks], Menu_CallbackType_ValueChanged, [Menu_CallbackType_ValueChanged, entry[DT_Menu_Entry_Symbol], settings[DT_Menu_Settings_Object], callbackArgs, val, oldVal]); if(reaction != Menu_React_None) { return React(reaction, msgBoardEntry); @@ -1589,24 +1633,35 @@ func NamedArgs(array namedArgs, array& args) } } -func DeclineAcceptCommand(int action, id ID, object obj, args) +func DeclineAcceptBackCommand(int action, id ID, object obj, args, int defaultAction) { if(args[0]) { - var reaction = CallA(args[0], [action, ID, settings[DT_Menu_Settings_Object], args[1]]); - if(reaction != Menu_React_None) return reaction; + var reaction = CallCallbacks(args[0], action, [action, ID, obj, args[1]]); + if(reaction != Menu_React_None) + { + return reaction; + } + } + + if(action & Menu_CallbackType_Defaults) + { + return defaultAction; + } + else + { + return Menu_React_None; } - return Menu_React_Close; +} + +func DeclineAcceptCommand(int action, id ID, object obj, args) +{ + return DeclineAcceptBackCommand(action, ID, obj, args, Menu_React_Close); } func BackCommand(int action, id ID, object obj, args) { - if(args[0]) - { - var reaction = CallA(args[0], [action, ID, settings[DT_Menu_Settings_Object], args[1]]); - if(reaction != Menu_React_None) return reaction; - } - return Menu_React_Back; + return DeclineAcceptBackCommand(action, ID, obj, args, Menu_React_Back); } func MenuObjectCallback(string name) @@ -1640,11 +1695,8 @@ func GetObject() { return settings[DT_Menu_Settings_Object]; } -// TODO: Erstellungskontext in CreateNewMenu speichern, damit Callbacks ohne explizite Kontextangabe im "Erzeuger" aufgerufen werden können -// TODO: RefreshDelayed noch im gleichen Frame im Effekttimer, wenn möglich (also kein Umhergehüpfe); noch relevant? -// TODO: Created-Callback, Refresh-Callback, u.ä., Menu_Entry (optional) mit "benannten" Argumenten und Menu_AutoEntry dadurch ersetzen, Adapter-Factories (inline oder als SubMenu (optional side by side)), (Objekt-Selector mit Find_*-Filter als Ausgangsbasis (??)) -// TODO: Vordefiniertes Condition-Callback für Variablenvergleiche (mit ScopedVar() und Vergleichswert) -// TODO: SelectionMenu wie in ObjectsAppend mit SelectMark aber flexibler (vgl. SelectionMenu und Leitung trennen-Menü) -// TODO: Flexibles Side by Side Submenu wie bei Sensor base für Ziel hinzufügen -// TODO: Menüglobale (wird bei jeder Eintragsaktion aufgerufen; vor (wie ein Filter) oder nach Eintragcallback; optional nur wenn das Callback React_None zurückgibt; Callback-Reaction als Parameter) Callbacks (vorallem Close) -// TODO: List-Factory (wie Factory, nur dass ein Array mit Args übergeben werden _muss_, worüber im Menüsystem iteriert wird)(Erspart eine explizite Schleife) + +func CreateSymbolDummy() +{ + return CreateContents(DT_Menu_SymbolDummy); +} |
