diff --git a/planet/Objects.ocd/HUD.ocd/MenuDeco2.ocd/DefCore.txt b/planet/Objects.ocd/HUD.ocd/MenuDeco2.ocd/DefCore.txt new file mode 100644 index 000000000..bca4674a5 --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/MenuDeco2.ocd/DefCore.txt @@ -0,0 +1,7 @@ +[DefCore] +id=GUI_MenuDeco2 +Version=8,0 +Category=C4D_StaticBack +Width=1 +Height=1 +HideInCreator=true diff --git a/planet/Objects.ocd/HUD.ocd/MenuDeco2.ocd/Graphics.png b/planet/Objects.ocd/HUD.ocd/MenuDeco2.ocd/Graphics.png new file mode 100644 index 000000000..99bc1a536 Binary files /dev/null and b/planet/Objects.ocd/HUD.ocd/MenuDeco2.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/HUD.ocd/MenuDeco2.ocd/Script.c b/planet/Objects.ocd/HUD.ocd/MenuDeco2.ocd/Script.c new file mode 100644 index 000000000..cec639e7a --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/MenuDeco2.ocd/Script.c @@ -0,0 +1,100 @@ +/*-- Menu-Deco --*/ + +//func FrameDecorationBackClr() { return RGBa(25, 25, 25, 128); } +func FrameDecorationBorderTop() { return 0; } +func FrameDecorationBorderLeft() { return 0; } +func FrameDecorationBorderRight() { return 0; } +func FrameDecorationBorderBottom() { return 0; } + +func Definition(def) +{ + var corner_size = 2; + var border_size = 2; + var border_length = 28; + + var offs = corner_size/2; + var offs = corner_size/2; + + SetProperty("ActMap", { + FrameDecoTopLeft = { + Prototype = Action, + Name = "FrameDecoTopLeft", + X = 0, + Y = 0, + Wdt = corner_size, + Hgt = corner_size, + OffX = -offs, + OffY = -offs, + }, + FrameDecoTopRight = { + Prototype = Action, + Name = "FrameDecoTopRight", + X = border_length + corner_size, + Y = 0, + Wdt = corner_size, + Hgt = corner_size, + OffX = 0, + OffY = -offs, + }, + FrameDecoBottomRight = { + Prototype = Action, + Name = "FrameDecoBottomRight", + X = border_length + corner_size, + Y = border_length + corner_size, + Wdt = corner_size, + Hgt = corner_size, + OffX = 0, + OffY = 0, + }, + FrameDecoBottomLeft = { + Prototype = Action, + Name = "FrameDecoBottomLeft", + X = 0, + Y = border_length + corner_size, + Wdt = corner_size, + Hgt = corner_size, + OffX = -offs, + OffY = 0, + }, + FrameDecoTop = { + Prototype = Action, + Name = "FrameDecoTop", + X = corner_size, + Y = 0, + Wdt = border_length, + Hgt = border_size, + OffX = 0, + OffY = -offs, + }, + FrameDecoRight = { + Prototype = Action, + Name = "FrameDecoRight", + X = corner_size + border_length, + Y = corner_size, + Wdt = border_size, + Hgt = border_length, + OffX = 0, + OffY = 0, + }, + FrameDecoBottom = { + Prototype = Action, + Name = "FrameDecoBottom", + X = corner_size, + Y = border_length + corner_size, + Wdt = border_length, + Hgt = border_size, + OffX = +offs, + OffY = 0, + }, + FrameDecoLeft = { + Prototype = Action, + Name = "FrameDecoLeft", + X = 0, + Y = corner_size, + Wdt = border_size, + Hgt = border_length, + OffX = -offs, + OffY = 0, + } + }); +} diff --git a/planet/Objects.ocd/HUD.ocd/ObjectInteractionMenu.ocd/OIM_NewStyle.ocd/DefCore.txt b/planet/Objects.ocd/HUD.ocd/ObjectInteractionMenu.ocd/OIM_NewStyle.ocd/DefCore.txt new file mode 100644 index 000000000..7ee896b38 --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/ObjectInteractionMenu.ocd/OIM_NewStyle.ocd/DefCore.txt @@ -0,0 +1,5 @@ +[DefCore] +id=GUI_OIM_NewStyle +Version=8,0 +Category=C4D_StaticBack +HideInCreator=true diff --git a/planet/Objects.ocd/HUD.ocd/ObjectInteractionMenu.ocd/OIM_NewStyle.ocd/Script.c b/planet/Objects.ocd/HUD.ocd/ObjectInteractionMenu.ocd/OIM_NewStyle.ocd/Script.c new file mode 100644 index 000000000..eb261c17d --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/ObjectInteractionMenu.ocd/OIM_NewStyle.ocd/Script.c @@ -0,0 +1,736 @@ +/** + This defines a menu style for the interaction menu. + + The style definition is given to the interaction menu object upon creation when + CreateFor() + is called. See Library_ClonkControl, ObjectControl() if you want to provide a + different, custom style. + + The object interaction menu will need the following functions in the style definition + to work properly: + + Init(object menu) + menu: The interaction menu object (GUI_ObjectInteractionMenu) + Does not expect any return value but can be used to manipulate the menu object in any + way desired before the GUI is actually opened. In here, it is used to apply the + settings. + + CreateRootMenu(object menu, object center_column_menu, proplist description_box) + menu: The interaction menu object (GUI_ObjectInteractionMenu) + center_column_menu: A dummy object, target for the center column + description_box: A proplist, containing initial information for the description box + Properties are: + .target: A dummy object, target for the surrounding box + .symbol_target: A dummy object, target for the symbol box + .desc_target: A dummy object, target for the description box + The function is called when the menu is first opened, but also during it being open + but whenever a total reset of the menu is required. + The return value has to be a proplist containing the overarching structure of the + interaction menu. As is obvious from the parameters, the menu is expected to have two + submenus: one called .center_column and one called .description_box (again with two submenus: + .symbol_part and .desc_part). Though the actual placement of the elements is arbitrary (i.e. + center_column does not have to be centered). The center column holds the 'move all' buttons. + + CreateMainMenu(object menu, int slot, object target, object obj_for) + menu: The interaction menu object (GUI_ObjectInteractionMenu) + slot: Either 0 or 1. 0: the left-hand menu, 1: the right-hand menu + target: A dummy object, target for the main menu + obj_for: The object this menu is opened for (which infos are displayed) + This is to assemble the menu for a currently selected object. There are always two 'main' menus + open, one at the left, one at the right. The displayed object is changed with the sidebar. The + menu must not necessarily contain visual elements (but either the main menu, the part menu or the + root menu should). The menu will be filled with entries generated from CreateMainMenuItem(). The + assembled proplist must be returned. + + CreateMainMenuItem(object menu, int slot, object target, proplist menu_entry, object cursor, int i) + menu: The interaction menu object (GUI_ObjectInteractionMenu) + slot: Either 0 or 1. 0: the left-hand menu, 1: the right-hand menu + target: A dummy object, target for the main menu + menu_entry: A proplist with various attributes, as defined in the object interaction menu + cursor: The player's current cursor (clonk) + i: An ascending number + The function should assemble and return a unified subelement for the main menu. The content is often + up to the specific object whose entries are displayed. Some properties of menu_entry are irrelevant + for the visuals, some are not (see Object Interaction Menu for a full list of possible entries). + Subentries (like inventory objects) can be included in menu_entry.entries or added later or change + dynamically (like inventory!). + + CreateSideBar(object menu, int slot, object target) + menu: The interaction menu object (GUI_ObjectInteractionMenu) + slot: Either 0 or 1. 0: the left-hand menu, 1: the right-hand menu + target: A dummy object, target for the menu + Assemble a sidebar element which is shown next to the main item and contains a list of all other + object that could be displayed in the main menu (because they are available to the clonk). The + menu will be filled with entries generated from CreateSideBarItem(). The assembled proplist + must be returned. + + CreateSideBarItem(object menu, int slot, object target, bool selected, bool crossed_out, bool cursor) + menu: The interaction menu object (GUI_ObjectInteractionMenu) + slot: Either 0 or 1. 0: the left-hand menu, 1: the right-hand menu + target: Object shown in this entry + selected: True if the object is currently selected for the main menu + crossed_out: True if the object should be unavailable for selection (usually because it is shown + in the other main menu) + cursor: The player's current cursor (clonk) + The function should assemble and return a unified subelement for the sidebar. The visuals can be + freely defined. Tabs are a good choice but not the only one. + + CreatePartMenu(object menu, int slot, object target, proplist sidebar, proplist main) + menu: The interaction menu object (GUI_ObjectInteractionMenu) + slot: Either 0 or 1. 0: the left-hand menu, 1: the right-hand menu + target: The object displayed in the 'main' menu + sidebar: The complete proplist for the sidebar + main: The complete proplist for the main menu + The function is mainly expected to assemble to sidebar and the main object into one + larger menu that does not need to have any visual elements. The finished proplist must + be returned. + + + The object interaction menu offers this callback in return: + + ReopenWithSetting(string setting, any value) + Closes the menu and reopens it wit a specific property (setting) set to a specific + value. The property is even available in the Init() function. +*/ + +// Coordinates in em + +local SideBarSize = 40; +local CenterColumnWidth = 50; + +local ExtraData_Settings_Transparency = "InteractionMenu_NewStyle_Transp"; +local ExtraData_Settings_HideText = "InteractionMenu_NewStyle_THidden"; +local ExtraData_Settings_Saturation = "InteractionMenu_NewStyle_Saturat"; + +/* Callbacks from the menu that should be handled by the style */ + +public func ToggleSettings(object menu) // Open/Close additional settings +{ + var value = true; + if (menu.SettingsOpen != nil) + value = !menu.SettingsOpen; + + menu->ReopenWithSetting("SettingsOpen", value); +} + +public func ToggleBackground(object menu) // Change transparency of background +{ + var owner = menu->GetOwner(); + if (owner == NO_OWNER) + return; // NO_OWNER opened a menu? + + // Settings are: + // 0 = Semi-transparent background, opaque entries (Default) + // 1 = Very transparent background, semi-transparent entries (maximum transparency) + // 2 = Non-transparent backgrounds (minimum transparency) + var value = 1; + if (menu.BackgroundTransparency != nil) + { + value = menu.BackgroundTransparency + 1; + if (value > 2) + value = 0; + } + + SetPlrExtraData(owner, ExtraData_Settings_Transparency, value); + menu->ReopenWithSetting("BackgroundTransparency", value); +} + +public func ToggleText(object menu) // Hide text captions +{ + var owner = menu->GetOwner(); + if (owner == NO_OWNER) + return; // NO_OWNER opened a menu? + + // Settings are: + // 0 = Captions are there (Default) + // 1 = Captions are hidden + var value = 1; + if (menu.TextHidden != nil) + { + value = menu.TextHidden + 1; + if (value > 1) + value = 0; + } + + SetPlrExtraData(owner, ExtraData_Settings_HideText, value); + menu->ReopenWithSetting("TextHidden", value); +} + +public func ToggleSaturation(object menu) // Desaturate the menu +{ + var owner = menu->GetOwner(); + if (owner == NO_OWNER) + return; // NO_OWNER opened a menu? + + // Settings are: + // 0 = With color (Default) + // 1 = Without color + var value = 1; + if (menu.Saturation != nil) + { + value = menu.Saturation + 1; + if (value > 1) + value = 0; + } + + SetPlrExtraData(owner, ExtraData_Settings_Saturation, value); + menu->ReopenWithSetting("Saturation", value); +} + +/* Everything called by Object Interation Menu */ + +// Initialization of the menu +public func Init(object menu) +{ + var owner = menu->GetOwner(); + if (owner == NO_OWNER) + return; // NO_OWNER opened a menu? + + // Set background transparency setting + if (menu.BackgroundTransparency == nil) + { + if (GetPlrExtraData(owner, ExtraData_Settings_Transparency) != nil) + menu.BackgroundTransparency = GetPlrExtraData(owner, ExtraData_Settings_Transparency); + else + menu.BackgroundTransparency = 0; + } + + // Set caption display setting + if (menu.TextHidden == nil) + { + if (GetPlrExtraData(owner, ExtraData_Settings_HideText) != nil) + menu.TextHidden = GetPlrExtraData(owner, ExtraData_Settings_HideText); + else + menu.TextHidden = 0; + } + + // Set saturation setting + if (menu.Saturation == nil) + { + if (GetPlrExtraData(owner, ExtraData_Settings_Saturation) != nil) + menu.Saturation = GetPlrExtraData(owner, ExtraData_Settings_Saturation); + else + menu.Saturation = 0; + } +} + +// Root menu is the overall surrounding structure of the menu +// Parameters are: Interaction Menu Object, Dummy Object for center column, Dummy Object for description box +public func CreateRootMenu(object menu, object center_column_menu, proplist description_box) +{ + var owner = menu->GetOwner(); + if (owner == NO_OWNER) + return; // NO_OWNER opened a menu? + + // Assemble button row (Close, Settings, Background change, Hide text) + var buttons_height = 40; + if (menu.SettingsOpen) + buttons_height = 100; + + var close_button = + { + Tooltip = "$TooltipClose$", + Priority = 0x0fffff, + Left = "0%", Top = "0%+0em", + Right = "100%", Bottom = "0%+2em", + Symbol = Icon_Cancel, + BackgroundColor = {Std = nil, Hover = 0x50ffff00}, + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + OnClick = GuiAction_Call(menu, "Close") + }; + + var settings_button = + { + Tooltip = "$TooltipSettings$", + Priority = 0x0ffffe, + Left = "0%", Top = "0%+2em", + Right = "100%", Bottom = "0%+4em", + Symbol = Icon_Settings, + BackgroundColor = {Std = nil, Hover = 0x50ffff00}, + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + OnClick = GuiAction_Call(this, "ToggleSettings", menu) + }; + if (menu.SettingsOpen) + settings_button.Tooltip = "$TooltipSettingsClose$"; + + var background_change = + { + Tooltip = "$TooltipBackground$", + Priority = 0x0ffffd, + Left = "0%", Top = "0%+4em", + Right = "100%", Bottom = "0%+6em", + Symbol = Icon_ChangeBackground, + BackgroundColor = {Std = nil, Hover = 0x50ffff00}, + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + OnClick = GuiAction_Call(this, "ToggleBackground", menu) + }; + + var hide_text = + { + Tooltip = "$TooltipHideText$", + Priority = 0x0ffffd, + Left = "0%", Top = "0%+6em", + Right = "100%", Bottom = "0%+8em", + Symbol = Icon_HideText, + BackgroundColor = {Std = nil, Hover = 0x50ffff00}, + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + OnClick = GuiAction_Call(this, "ToggleText", menu) + }; + if (menu.TextHidden == 1) + { + hide_text.Tooltip = "$TooltipShowText$"; + hide_text.GraphicsName = "Show"; + } + + var saturation = + { + Tooltip = "$TooltipWithoutSaturation$", + Priority = 0x0ffffc, + Left = "0%", Top = "0%+8em", + Right = "100%", Bottom = "0%+10em", + Symbol = Icon_ChangeColor, + GraphicsName = "Grey", + BackgroundColor = {Std = nil, Hover = 0x50ffff00}, + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + OnClick = GuiAction_Call(this, "ToggleSaturation", menu) + }; + if (menu.Saturation == 1) + { + saturation.Tooltip = "$TooltipWithSaturation$"; + saturation.GraphicsName = nil; + } + + // For the description box + var background_color = RGBa(25,25,25, 200); + if (menu.BackgroundTransparency == 1) + background_color = RGBa(25,25,25, 100); + if (menu.BackgroundTransparency == 2) + background_color = RGBa(25,25,25, 255); + + // Assemble the menu + var root_menu = + { + Target = menu, + // Open just below the inventory bar, -20 to counter the standard margin + Top = ToEmString(GUI_Controller_InventoryBar_IconMarginScreenTop * 2 + GUI_Controller_InventoryBar_IconSize + GUI_Controller_InventoryBar_IconSize/2 - 20), + Style = GUI_NoCrop, + // Mostly transparent but shows the 'transfer all' buttons + center_column = + { + // -10 because the button bar takes up 2em on the right side + Left = Format("50%% %s", ToEmString(-CenterColumnWidth / 2 - 10)), + Right = Format("50%% %s", ToEmString(CenterColumnWidth / 2 - 10)), + Top = "1.5em", + Bottom = "4.5em", + Style = GUI_VerticalLayout, + move_all_left = + { + Target = center_column_menu, + ID = 10 + 0, + Right = ToEmString(CenterColumnWidth), Bottom = "1.5em", + Margin = ["0.1em"], + Style = GUI_TextHCenter | GUI_TextVCenter, + Symbol = Icon_MoveItems, GraphicsName = "Left", + Tooltip = "$TooltipTransferAllLeft$", + BackgroundColor ={Std = nil, Hover = 0x50ffff00}, + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + OnClick = GuiAction_Call(menu, "OnMoveAllToClicked", 0) + }, + move_all_right = + { + Target = center_column_menu, + ID = 10 + 1, + Right = ToEmString(CenterColumnWidth), Bottom = "1.5em", + Margin = ["0.1em"], + Style = GUI_TextHCenter | GUI_TextVCenter, + Symbol = Icon_MoveItems, + Tooltip = "$TooltipTransferAllRight$", + BackgroundColor ={Std = nil, Hover = 0x50ffff00}, + OnMouseIn = GuiAction_SetTag("Hover"), + OnMouseOut = GuiAction_SetTag("Std"), + OnClick = GuiAction_Call(menu, "OnMoveAllToClicked", 1) + } + }, + // Show descriptive texts when hovering stuff + description_box = + { + Top = "100%-5em", + Right = "100% - 2em", + Margin = [ToEmString(SideBarSize), "0em"], + Decoration = GUI_MenuDeco2, + BackgroundColor = background_color, + symbol_part = + { + Right = "5em", + Symbol = nil, + Margin = "0.2em", + ID = 1, + Target = description_box.symbol_target + }, + desc_part = + { + Left = "5em", + Margin = "0.2em", + ID = 1, + Target = description_box.target, + real_contents = // nested one more time so it can dynamically be replaced without messing up the layout + { + ID = 1, + Target = description_box.desc_target + } + } + }, + // Buttons bar at the top right + buttons = + { + ID = 10 + 2, + Left = "100%-2em", + Top = "0%+0em", + Right = "100%", + Bottom = ToEmString(buttons_height), + Decoration = GUI_MenuDecoInventoryHeader + } + }; + + GuiAddSubwindow(close_button, root_menu.buttons); + GuiAddSubwindow(settings_button, root_menu.buttons); + if (menu.SettingsOpen) + { + GuiAddSubwindow(background_change, root_menu.buttons); + GuiAddSubwindow(hide_text, root_menu.buttons); + GuiAddSubwindow(saturation, root_menu.buttons); + } + + return root_menu; +} + +// Assemble the main menu and the sidebar into a surrounding structure +// There are always two part menus open +// Parameters are: Interaction Menu Object, Slot of the current sidebar (either 0 or 1, left/right), Menu target (probably the same as the first parameter but can change), the sidebar menu, the main menu +public func CreatePartMenu(object menu, int slot, object target, proplist sidebar, proplist main) +{ + // Stretch from left border to center column + var part_menu = + { + Left = "0%", Right = Format("50%% %s", ToEmString(-CenterColumnWidth / 2 - 10)), + sidebar = sidebar, main = main, + Target = target, + ID = 1, + Style = GUI_NoCrop + }; + + // Right part menu will stretch from center column to the button bar + if (slot == 1) + { + part_menu.Left = Format("50%% %s", ToEmString(CenterColumnWidth / 2 - 10)); + part_menu.Right = "100%-2em"; + } + + return part_menu; +} + +// Main menu is the big information menu for a single inspected object +// So there are always two 'main' menus open +// Parameters are: Interaction Menu Object, Slot of the current main menu (either 0 or 1, left/right), Dummy menu target, Object whose settings are displayed +public func CreateMainMenu(object menu, int slot, object target, object obj_for) +{ + var background_color = RGBa(25,25,25, 200); + if (menu.BackgroundTransparency == 1) + background_color = RGBa(25,25,25, 100); + if (menu.BackgroundTransparency == 2) + background_color = RGBa(25,25,25, 255); + + var big_menu = + { + Target = target, + Priority = 5, + Right = Format("100%% %s", ToEmString(-SideBarSize)), + Bottom = "100% - 5.5em", + Decoration = GUI_MenuDeco2, + BackgroundColor = background_color, + container = + { + Priority = 7, + Top = "1em", + Style = GUI_VerticalLayout, + Margin = ["0.1em"], + }, + headline = + { + Priority = 7, + Bottom = "1em", + Text = obj_for->GetName(), + Style = GUI_TextHCenter | GUI_TextVCenter, + }, + }; + + if (slot == 0) + { + big_menu.Left = ToEmString(SideBarSize); + big_menu.Right = "100%"; + } + + return big_menu; +} + +// Create a single information menu (row) in the main menu +// Parameters are: Interaction Menu Object, Slot of the current main menu (either 0 or 1, left/right), Object whose settings are displayed, the menu information, the player's cursor, an ascending integer +// This function should create a GUI target (like MenuStyle_Grid) +// menu can have the following properties: +// flag: Marking special entries (currently only contents), if not set should be set to InteractionMenu_Custom +// title: The entry's caption +// entries: An array of proplists with subentries ({ symbol, text, unique_index, custom }) +// entries_callback: A callback the interaction menu will ask for subentries (subentries is most likely empty if given) +// callback: A callback if the entry is clicked +// callback_hover: A callback if the entry is hovered over +// callback_target: Target object for the callback +// Anything that goes into scripted GUIs anyway (see documentation) +// Most of these entries are of no concern to this function and can be ignored +public func CreateMainMenuItem(object menu, int slot, object target, proplist menu_entry, object cursor, int i) +{ + // Create a basic layout object + menu_entry.menu_object = CreateObject(MenuStyle_Grid); + + // Special display settings for contents entries + if (menu_entry.flag == InteractionMenu_Contents) + { + menu_entry.menu_object->SetTightGridLayout(); + } + + // Settings + menu_entry.menu_object.Top = "+1em"; + menu_entry.menu_object.Priority = 7; + menu_entry.menu_object->SetPermanent(); + menu_entry.menu_object->SetFitChildren(); + menu_entry.menu_object->SetMouseOverCallback(menu, "OnMenuEntryHover"); + + // Handle subentries + for (var e = 0; e < GetLength(menu_entry.entries); ++e) + { + var entry = menu_entry.entries[e]; + entry.unique_index = ++menu_entry.entry_index_count; + // This also allows the interaction-menu user to supply a custom entry with custom layout f.e. + var added_entry = menu_entry.menu_object->AddItem(entry.symbol, entry.text, entry.unique_index, menu, "OnMenuEntrySelected", { slot = slot, index = i }, entry["custom"]); + } + + // Assemble the entry + var all = + { + Priority = menu_entry.Priority ?? i, + Style = GUI_FitChildren, + // Caption + title_bar = + { + Priority = (menu_entry.Priority ?? i) - 2, + Style = GUI_TextVCenter | GUI_TextHCenter, + Bottom = "+1em", + Text = menu_entry.title, + // Visual separation at the top + hline = {Bottom = "0.05em", BackgroundColor = RGB(100, 100, 100)}, + }, + hline = {Top = "1em", Bottom = "1.05em", BackgroundColor = RGB(100, 100, 100), Priority = (menu_entry.Priority ?? i) - 1}, + Margin = [nil, nil, nil, "0.25em"], + // The content of this entry + real_menu = menu_entry.menu_object, + spacer = {Left = "0em", Right = "0em", Bottom = "3em"} // guarantees a minimum height + }; + + // Background color according to transparency setting + var background_color = nil; + + // Background color is defined + if (menu_entry.BackgroundColor) + { + if (menu.BackgroundTransparency == 0) + background_color = SetRGBaValue(menu_entry.BackgroundColor, Min(200, GetRGBaValue(menu_entry.BackgroundColor, RGBA_ALPHA)), RGBA_ALPHA); + if (menu.BackgroundTransparency == 1) + background_color = SetRGBaValue(menu_entry.BackgroundColor, Min(100, GetRGBaValue(menu_entry.BackgroundColor, RGBA_ALPHA)), RGBA_ALPHA); + if (menu.BackgroundTransparency == 2) + background_color = menu_entry.BackgroundColor; + } + // Menu decoration is defined + else if (menu_entry.Decoration) + { + background_color = menu_entry.Decoration->FrameDecorationBackClr(); + if (menu.BackgroundTransparency == 0) + background_color = SetRGBaValue(menu_entry.Decoration->FrameDecorationBackClr(), Min(200, GetRGBaValue(menu_entry.Decoration->FrameDecorationBackClr(), RGBA_ALPHA)), RGBA_ALPHA); + if (menu.BackgroundTransparency == 1) + background_color = SetRGBaValue(menu_entry.Decoration->FrameDecorationBackClr(), Min(100, GetRGBaValue(menu_entry.Decoration->FrameDecorationBackClr(), RGBA_ALPHA)), RGBA_ALPHA); + //if (menu.BackgroundTransparency == 2) + // No change required + } + + // Menu color saturation + if (background_color) + { + if (menu.Saturation == 1) + { + var alpha = GetRGBaValue(background_color, RGBA_ALPHA); + var val = RGB2HSL(background_color); + // Desaturate + if (GetRGBaValue(val, RGBA_GREEN) > 10) + val = SetRGBaValue(val, 10, RGBA_GREEN); + // Increase light + if (GetRGBaValue(val, RGBA_BLUE) < 50) + val = SetRGBaValue(val, 50, RGBA_BLUE); + val = HSL2RGB(val); + // Restore alpha + val = SetRGBaValue(val, alpha, RGBA_ALPHA); + background_color = val; + } + } + + //menu_entry.menu_object.BackgroundColor = background_color; + all.BackgroundColor = background_color; + + // Hide captions? + if (menu.TextHidden) + { + all.title_bar.Text = nil; + all.title_bar.Bottom = "0.05em"; + all.title_bar.hline.Bottom = nil; + all.real_menu.Top = "0.05em"; + all.spacer.Bottom = "2.05em"; + all.hline = nil; + } + + return all; +} + +// The sidebar shows all available objects to display as tabs +// There are always two sidebars open (one left, one right) +// Parameters are: Interaction Menu Object, Slot of the current sidebar (either 0 or 1, left/right), Menu target (probably the same as the first parameter but can change) +public func CreateSideBar(object menu, int slot, object target) +{ + // Entries will be inserted in the next step + var sidebar = + { + Priority = 10, + Right = ToEmString(SideBarSize), + Style = GUI_VerticalLayout, + Target = target, + ID = 2 + }; + + if (slot == 1) + { + sidebar.Left = Format("100%% %s", ToEmString(-SideBarSize)); + sidebar.Right = "100%"; + } + + return sidebar; +} + +// Create a single sidebar item (/entry) +// Parameters are: Interaction Menu Object, Slot of the current sidebar (either 0 or 1, left/right), Object shown in the entry, is the entry selected, is the entry selected on the other side, is the entry the player's cursor +public func CreateSideBarItem(object menu, int slot, object target, bool selected, bool crossed_out, bool cursor) +{ + // For sorting: the vertical layout will sort by priority + var priority = 10000 - target.Plane; + // The cursor should always be at the top + if (cursor) + priority = 1; + + var background_symbol = ""; + var highlight_symbol = "Highlight"; + if (selected) + { + background_symbol = "Selected"; + highlight_symbol = "Selected"; + } + + if (slot == 1) + { + background_symbol = "Right"; + highlight_symbol = "RightHighlight"; + if (selected) + { + background_symbol = "RightSelected"; + highlight_symbol = "RightSelected"; + } + } + + var deactivation_symbol = nil; + if (crossed_out) + deactivation_symbol = Icon_Cancel; + + // Coordinates for the little picture & name + var left = "2.25em"; + var right = "4em"; + var top = "0%"; + var bottom = "1.75em"; + var text_margin = [nil, nil, "0.25em", nil]; + var text_style = GUI_TextRight | GUI_TextTop | GUI_FitChildren; + + if (slot == 1) + { + left = "0%"; + right = "1.5em"; + var text_margin = ["0.25em", nil, nil, nil]; + var text_style = GUI_TextLeft | GUI_TextTop | GUI_FitChildren; + } + + var entry = + { + // The object is added as the target of the entry, so it can easily be identified later. + // For example, to apply show the grey haze to indicate that it cannot be clicked. + Target = target, + Right = ToEmString(SideBarSize), Bottom = "2.75em", + Priority = priority, + Style = GUI_FitChildren, + OnMouseIn = GuiAction_SetTag("OnHover"), + OnMouseOut = GuiAction_SetTag("Std"), + OnClick = GuiAction_Call(menu, "OnSidebarEntrySelected", {slot = slot, obj = target}), + Priority = 1, + obj_background = { + Top = top, + Left = left, + Right = right, + Bottom = bottom, + Symbol = Icon_Menu_Tab, + GraphicsName = { Std = background_symbol, OnHover = highlight_symbol }, + Priority = 2 + }, + obj_symbol = { + Top = top, + Left = left, + Right = right, + Bottom = bottom, + Symbol = target, + Priority = 3 + }, + obj_symbol_deactivated = { + Target = target, + ID = 1 + slot, + Top = top, + Left = left, + Right = right, + Bottom = bottom, + Symbol = deactivation_symbol, + Priority = 4 + }, + obj_name = { + Style = text_style, + Top = "1.75em", + Bottom = "2.75em", + Margin = text_margin, + Text = target->GetName(), + Priority = 5 + } + }; + + // Hide object's name if the option is selected + if (menu.TextHidden) + { + entry.obj_name = nil; + entry.Bottom = "1.75em"; + } + + return entry; +} \ No newline at end of file diff --git a/planet/Objects.ocd/HUD.ocd/ObjectInteractionMenu.ocd/OIM_NewStyle.ocd/StringTblDE.txt b/planet/Objects.ocd/HUD.ocd/ObjectInteractionMenu.ocd/OIM_NewStyle.ocd/StringTblDE.txt new file mode 100644 index 000000000..59dfefd09 --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/ObjectInteractionMenu.ocd/OIM_NewStyle.ocd/StringTblDE.txt @@ -0,0 +1,15 @@ +TooltipClose=Schließen + +TooltipSettings=Einstellungen öffnen +TooltipSettingsClose=Einstellungen schließen + +TooltipBackground=Hintergrundtransparenz umstellen + +TooltipHideText=Überschriften verbergen +TooltipShowText=Überschriften anzeigen + +TooltipWithSaturation=Menüfarben anzeigen +TooltipWithoutSaturation=Menüfarben ausblenden + +TooltipTransferAllLeft=Gesamtes Inventar nach links schieben. +TooltipTransferAllRight=Gesamtes Inventar nach rechts schieben. \ No newline at end of file diff --git a/planet/Objects.ocd/HUD.ocd/ObjectInteractionMenu.ocd/OIM_NewStyle.ocd/StringTblUS.txt b/planet/Objects.ocd/HUD.ocd/ObjectInteractionMenu.ocd/OIM_NewStyle.ocd/StringTblUS.txt new file mode 100644 index 000000000..35b63f114 --- /dev/null +++ b/planet/Objects.ocd/HUD.ocd/ObjectInteractionMenu.ocd/OIM_NewStyle.ocd/StringTblUS.txt @@ -0,0 +1,15 @@ +TooltipClose=Close + +TooltipSettings=Open settings +TooltipSettingsClose=Close settings + +TooltipBackground=Toggle background transparency + +TooltipHideText=Hide captions +TooltipShowText=Show captions + +TooltipWithSaturation=Show menu colors +TooltipWithoutSaturation=Hide menu colors + +TooltipTransferAllLeft=Transfer inventory to the left. +TooltipTransferAllRight=Transfer inventory to the right. \ No newline at end of file diff --git a/planet/Objects.ocd/HUD.ocd/ObjectInteractionMenu.ocd/Script.c b/planet/Objects.ocd/HUD.ocd/ObjectInteractionMenu.ocd/Script.c index 640a46f1c..eb6d12768 100644 --- a/planet/Objects.ocd/HUD.ocd/ObjectInteractionMenu.ocd/Script.c +++ b/planet/Objects.ocd/HUD.ocd/ObjectInteractionMenu.ocd/Script.c @@ -8,8 +8,6 @@ local Name = "$Name$"; local Description = "$Description$"; -static const InteractionMenu_SideBarSize = 40; // in tenth-em - static const InteractionMenu_Contents = 2; static const InteractionMenu_Custom = 4; @@ -111,7 +109,7 @@ func Destruction() } // used as a static function -func CreateFor(object cursor) +func CreateFor(object cursor, id style_def, array settings) { var obj = CreateObject(GUI_ObjectInteractionMenu, AbsX(0), AbsY(0), cursor->GetOwner()); obj.Visibility = VIS_Owner; @@ -129,16 +127,42 @@ func CreateFor(object cursor) { obj.minimized = false; } - - obj->Init(cursor); + if (settings != nil) + { + obj.Settings = settings; + for (var setting in settings) + obj[setting[0]] = setting[1]; + } + obj->Init(cursor, style_def); cursor->SetMenu(obj); return obj; } +// Reopen the menu with a certain settings value set (arbitrarily defined) +// All previous settings will be kept +public func ReopenWithSetting(string setting_name, value) +{ + var last_cursor = this.cursor; + var settings = []; + if (this.Settings != nil) + var settings = this.Settings[:]; + var i; + for (i = 0; i < GetLength(settings); i++) + if (settings[i][0] == setting_name) + break; + settings[i] = [setting_name, value]; + var style_def = this.style_def; + RemoveObject(); + GUI_ObjectInteractionMenu->CreateFor(last_cursor, style_def, settings); +} -func Init(object cursor) + +public func Init(object cursor, id style_def) { this.cursor = cursor; + this.style_def = style_def; + this.style_def->Init(this); + //this.Uncollapsed = uncollapsed; var checking_effect = AddEffect("IntCheckObjects", cursor, 1, 10, this); // Notify the Clonk. This can be used to create custom entries in the objects list via helper objects. For example the "Your Environment" tab. // Note that the cursor is NOT informed when the menu is closed again. Helper objects can be attached to the livetime of this menu by, f.e., effects. @@ -290,28 +314,13 @@ func OpenMenuForObject(object obj, int slot, bool forced) current_menus[slot].menu_object = main.Target; // Now, the sidebar. var sidebar = CreateSideBar(slot); - - var sidebar_size_em = ToEmString(InteractionMenu_SideBarSize); - var part_menu = - { - Left = "0%", Right = "50%-3em", - Bottom = "100%-7em", - sidebar = sidebar, main = main, - Target = current_menus[slot].menu_object, - ID = 1 - }; - - if (slot == 1) - { - part_menu.Left = "50%-1em"; - part_menu.Right = "100%-2em"; - } - + + var part_menu = this.style_def->CreatePartMenu(this, slot, current_menus[slot].menu_object, sidebar, main); + if (this.minimized) { part_menu.Bottom = nil; // maximum height } - // need to open a completely new menu? if (!current_main_menu_id) @@ -325,91 +334,9 @@ func OpenMenuForObject(object obj, int slot, bool forced) if (!current_center_column_target) current_center_column_target = CreateDummy(); - var root_menu = - { - _one_part = part_menu, - Target = this, - Decoration = GUI_MenuDeco, - BackgroundColor = RGB(0, 0, 0), - minimize_button = - { - Bottom = "100%", - Top = "100% - 2em", - Left = "100% - 2em", - Tooltip = "$Minimize$", - Symbol = Icon_Arrow, - GraphicsName = "Down", - BackgroundColor = {Std = nil, OnHover = 0x50ffff00}, - OnMouseIn = GuiAction_SetTag("OnHover"), - OnMouseOut = GuiAction_SetTag("Std"), - OnClick = GuiAction_Call(this, "OnToggleMinimizeClicked") - }, - center_column = - { - Left = "50%-3em", - Right = "50%-1em", - Top = "1.75em", - Bottom = "100%-7em", - Style = GUI_VerticalLayout, - move_all_left = - { - Target = current_center_column_target, - ID = 10 + 0, - Right = "2em", Bottom = "3em", - Style = GUI_TextHCenter | GUI_TextVCenter, - Symbol = Icon_MoveItems, GraphicsName = "Left", - Tooltip = "", - BackgroundColor ={Std = 0, Hover = 0x50ffff00}, - OnMouseIn = GuiAction_SetTag("Hover"), - OnMouseOut = GuiAction_SetTag("Std"), - OnClick = GuiAction_Call(this, "OnMoveAllToClicked", 0) - }, - move_all_right = - { - Target = current_center_column_target, - ID = 10 + 1, - Right = "2em", Bottom = "3em", - Style = GUI_TextHCenter | GUI_TextVCenter, - Symbol = Icon_MoveItems, - Tooltip = "", - BackgroundColor ={Std = 0, Hover = 0x50ffff00}, - OnMouseIn = GuiAction_SetTag("Hover"), - OnMouseOut = GuiAction_SetTag("Std"), - OnClick = GuiAction_Call(this, "OnMoveAllToClicked", 1) - } - }, - description_box = - { - Top = "100%-5em", - Right = "100% - 2em", - Margin = [sidebar_size_em, "0em"], - BackgroundColor = RGB(25, 25, 25), - symbol_part = - { - Right = "5em", - Symbol = nil, - Margin = "0.5em", - ID = 1, - Target = current_description_box.symbol_target - }, - desc_part = - { - Left = "5em", - Margin = "0.5em", - ID = 1, - Target = current_description_box.target, - real_contents = // nested one more time so it can dynamically be replaced without messing up the layout - { - ID = 1, - Target = current_description_box.desc_target - } - } - } - }; - - // Allow the menu to be closed with a clickable button. - GuiAddCloseButton(root_menu, this, "Close"); - + var root_menu = this.style_def->CreateRootMenu(this, current_center_column_target, current_description_box); + root_menu._one_part = part_menu; + // Special setup for a minimized menu. if (this.minimized) { @@ -553,22 +480,9 @@ public func OnMoveAllToClicked(int menu_id) func CreateSideBar(int slot) { var other_menu = current_menus[1 - slot]; - - var em_size = ToEmString(InteractionMenu_SideBarSize); - var sidebar = - { - Priority = 10, - Right = em_size, - Style = GUI_VerticalLayout, - Target = current_menus[slot].menu_object, - ID = 2 - }; - if (slot == 1) - { - sidebar.Left = Format("100%% %s", ToEmString(-InteractionMenu_SideBarSize)); - sidebar.Right = "100%"; - } - + + var sidebar = this.style_def->CreateSideBar(this, slot, current_menus[slot].menu_object); + // Now show the current_objects list as entries. // If there is a forced-open menu, also add it to bottom of sidebar.. var sidebar_items = nil; @@ -579,43 +493,11 @@ func CreateSideBar(int slot) } else sidebar_items = current_objects; - + for (var obj in sidebar_items) { - var background_color = nil; - var symbol = {Std = SidebarIconStandard(), OnHover = SidebarIconOnHover()}; - // figure out whether the object is already selected - // if so, highlight the entry - if (current_menus[slot].target == obj) - { - background_color = RGBa(255, 255, 0, 10); - symbol = SidebarIconSelected(); - } - var priority = 10000 - obj.Plane; - // Cross-out the entry? - var deactivation_symbol = nil; - if (other_menu && other_menu.target == obj) - deactivation_symbol = Icon_Cancel; - // Always show Clonk at top. - if (obj == cursor) priority = 1; - var entry = - { - // The object is added as the target of the entry, so it can easily be identified later. - // For example, to apply show the grey haze to indicate that it cannot be clicked. - Target = obj, - Right = em_size, Bottom = em_size, - Symbol = symbol, - Priority = priority, - Style = GUI_TextBottom | GUI_TextHCenter, - BackgroundColor = background_color, - OnMouseIn = GuiAction_SetTag("OnHover"), - OnMouseOut = GuiAction_SetTag("Std"), - OnClick = GuiAction_Call(this, "OnSidebarEntrySelected", {slot = slot, obj = obj}), - Text = obj->GetName(), - obj_symbol = {Symbol = obj, Margin = "0.25em", Priority = 1}, - obj_symbol_deactivated = {Symbol = deactivation_symbol, Margin = "0.5em", Priority = 2, Target = obj, ID = 1 + slot} - }; - + var entry = this.style_def->CreateSideBarItem(this, slot, obj, current_menus[slot].target == obj, other_menu && other_menu.target == obj, obj == cursor); + GuiAddSubwindow(entry, sidebar); } return sidebar; @@ -648,37 +530,13 @@ func OnSidebarEntrySelected(data, int player, int ID, int subwindowID, object ta */ func CreateMainMenu(object obj, int slot) { - var big_menu = - { - Target = CreateDummy(), - Priority = 5, - Right = Format("100%% %s", ToEmString(-InteractionMenu_SideBarSize)), - container = - { - Top = "1em", - Style = GUI_VerticalLayout, - BackgroundColor = RGB(25, 25, 25), - }, - headline = - { - Bottom = "1em", - Text = obj->GetName(), - Style = GUI_TextHCenter | GUI_TextVCenter, - BackgroundColor = 0xff000000 - } - - }; + var big_menu = this.style_def->CreateMainMenu(this, slot, CreateDummy(), obj); + var container = big_menu.container; - - if (slot == 0) - { - big_menu.Left = ToEmString(InteractionMenu_SideBarSize); - big_menu.Right = "100%"; - } - + // Do virtually nothing if the building/object is not ready to be interacted with. This can be caused by several things. var error_message = obj->~RejectInteractionMenu(cursor); - + if (error_message) { if (GetType(error_message) != C4V_String) @@ -688,7 +546,7 @@ func CreateMainMenu(object obj, int slot) current_menus[slot].menus = []; return big_menu; } - + var menus = obj->~GetInteractionMenus(cursor) ?? []; // get all interaction info from the object and put it into a menu // contents first @@ -702,86 +560,44 @@ func CreateMainMenu(object obj, int slot) entries_callback = nil, callback = "OnContentsSelection", callback_target = this, - decoration = GUI_MenuDecoInventoryHeader, + BackgroundColor = RGB(0, 50, 0), Priority = 10 }; PushBack(menus, info); } - + current_menus[slot].menus = menus; - + // now generate the actual menus from the information-list for (var i = 0; i < GetLength(menus); ++i) { var menu = menus[i]; + + // Everything not flagged is a custom entry if (!menu.flag) { menu.flag = InteractionMenu_Custom; } + // If a callback is given, try to get entries if (menu.entries_callback) { - var call_from = menu.entries_callback_target ?? obj; + var call_from = menu.entries_callback_target ?? obj; menu.entries = call_from->Call(menu.entries_callback, cursor, menu.entries_callback_parameter); } + // Empty entries should not be there if (menu.entries == nil) { FatalError(Format("An interaction menu did not return valid entries. %s -> %v() (object %v)", obj->GetName(), menu.entries_callback, obj)); continue; } - menu.menu_object = CreateObject(MenuStyle_Grid); - if (menu.flag == InteractionMenu_Contents) - { - menu.menu_object->SetTightGridLayout(); - } - - menu.menu_object.Top = "+1em"; - menu.menu_object.Priority = 2; - menu.menu_object->SetPermanent(); - menu.menu_object->SetFitChildren(); - menu.menu_object->SetMouseOverCallback(this, "OnMenuEntryHover"); - for (var e = 0; e < GetLength(menu.entries); ++e) - { - var entry = menu.entries[e]; - entry.unique_index = ++menu.entry_index_count; - // This also allows the interaction-menu user to supply a custom entry with custom layout f.e. - var added_entry = menu.menu_object->AddItem(entry.symbol, entry.text, entry.unique_index, this, "OnMenuEntrySelected", { slot = slot, index = i }, entry["custom"]); - // Remember the menu entry's ID (e.g. for passing it to an update effect after the menu has been opened). - entry.ID = added_entry.ID; - } - - var all = - { - Priority = menu.Priority ?? i, - Style = GUI_FitChildren, - title_bar = - { - Priority = 1, - Style = GUI_TextVCenter | GUI_TextHCenter, - Bottom = "+1em", - Text = menu.title, - BackgroundColor = 0xa0000000, - //Decoration = menu.decoration - hline = {Bottom = "0.05em", BackgroundColor = RGB(100, 100, 100)} - }, - Margin = [nil, nil, nil, "0.25em"], - real_menu = menu.menu_object, - spacer = {Left = "0em", Right = "0em", Bottom = "3em"} // guarantees a minimum height - }; - if (menu.flag == InteractionMenu_Contents) - { - all.BackgroundColor = RGB(0, 50, 0); - } - else if (menu.BackgroundColor) - { - all.BackgroundColor = menu.BackgroundColor; - } - else if (menu.decoration) - { - menu.menu_object.BackgroundColor = menu.decoration->FrameDecorationBackClr(); - } + + var all = this.style_def->CreateMainMenuItem(this, slot, obj, menu, cursor, i); + if (!all) + continue; + GuiAddSubwindow(all, container); } - + // add refreshing effects for all of the contents menus for (var i = 0; i < GetLength(menus); ++i) { @@ -789,7 +605,7 @@ func CreateMainMenu(object obj, int slot) continue; AddEffect("IntRefreshContentsMenu", this, 1, 1, this, nil, obj, slot, i); } - + return big_menu; } @@ -824,7 +640,7 @@ func OnMenuEntryHover(proplist menu_info, int entry_index, int player) if (!info.menu.callback_target || !info.menu.callback_hover) { var text = Format("%s:|%s", info.entry.symbol->GetName(), info.entry.symbol.Description); - + // For contents menus, we can sometimes present additional information about objects. if (info.menu.flag == InteractionMenu_Contents) { @@ -860,7 +676,7 @@ func OnMenuEntryHover(proplist menu_info, int entry_index, int player) text = Format("%s||%s", text, additional); } } - + GuiUpdateText(text, current_main_menu_id, 1, current_description_box.desc_target); } else @@ -873,25 +689,25 @@ func OnMenuEntrySelected(proplist menu_info, int entry_index, int player) { var info = GetEntryInformation(menu_info, entry_index); if (!info.entry) return; - + var callback_target; if (!(callback_target = info.menu.callback_target)) return; if (!info.menu.callback) return; // The menu can actually decide to handle user interaction itself and not provide a callback. - callback_target->Call(info.menu.callback, info.entry.symbol, info.entry.extra_data, cursor); - - // todo: trigger refresh for special value of callback result? + var result = callback_target->Call(info.menu.callback, info.entry.symbol, info.entry.extra_data, cursor); + + // todo: trigger refresh for special value of result? } private func OnContentsSelection(symbol, extra_data) { - if (!current_menus[extra_data.slot]) return; + if (!extra_data || !current_menus[extra_data.slot]) return; var target = current_menus[extra_data.slot].target; if (!target) return; // no target to swap to? if (!current_menus[1 - extra_data.slot]) return; var other_target = current_menus[1 - extra_data.slot].target; if (!other_target) return; - + // Only if the object wants to be interacted with (hostility etc.) if (other_target->~RejectInteractionMenu(cursor)) return; @@ -901,10 +717,10 @@ private func OnContentsSelection(symbol, extra_data) cursor->~PlaySoundDoubt(true, nil, cursor->GetOwner()); return; } - + var transfer_only_one = GetPlayerControlState(GetOwner(), CON_ModifierMenu1) == 0; // Transfer ONE object of the stack? var to_transfer = nil; - + if (transfer_only_one) { for (var possible in extra_data.objects) @@ -918,7 +734,7 @@ private func OnContentsSelection(symbol, extra_data) { to_transfer = extra_data.objects; } - + var successful_transfers = TransferObjectsFromTo(to_transfer, target, other_target); // Did we at least transfer one item? @@ -1023,7 +839,7 @@ func FxIntRefreshContentsMenuTimer(object target, effect, int time) { var symbol = obj; var extra_data = {slot = effect.slot, menu_index = effect.menu_index, objects = []}; - + // check if already exists (and then stack!) var found = false; // Never stack containers with (different) contents, though. @@ -1064,6 +880,8 @@ func FxIntRefreshContentsMenuTimer(object target, effect, int time) // This object has a custom symbol (because it's a container)? Then the normal text would not be displayed. if (inv.custom != nil) { + if (inv.custom.top == nil) + inv.custom.top = {}; inv.custom.top.Text = inv.text; inv.custom.top.Style = inv.custom.top.Style | GUI_TextRight | GUI_TextBottom; } @@ -1076,27 +894,26 @@ func FxIntRefreshContentsMenuTimer(object target, effect, int time) if (!found) { PushBack(extra_data.objects, obj); - - // Do we need a custom entry when the object has contents? - var custom = nil; + + // Use a default grid-menu entry as the base. + var custom = MenuStyle_Grid->MakeEntryProplist(symbol, nil); + custom.BackgroundColor = {Std = 0, OnHover = RGB(0, 100, 0)}; if (is_container) { - // Use a default grid-menu entry as the base. - custom = MenuStyle_Grid->MakeEntryProplist(symbol, nil); - // Pack it into a larger frame to allow for another button below. + // Pack the custom entry into a larger frame to allow for another button below. // The priority offset makes sure that double-height items are at the front. custom = {Right = custom.Right, Bottom = "4em", top = custom, Priority = -10000 + obj->GetValue()}; // Then add a little container-symbol (that can be clicked). custom.bottom = { Top = "2em", - BackgroundColor = {Std = 0, Selected = RGBa(255, 100, 100, 100)}, + BackgroundColor = {Std = 0, Selected = RGB(0, 100, 0)}, OnMouseIn = GuiAction_SetTag("Selected"), OnMouseOut = GuiAction_SetTag("Std"), OnClick = GuiAction_Call(this, "OnExtraSlotClicked", {slot = effect.slot, objects = extra_data.objects, ID = obj->GetID()}), container = { - Symbol = Chest, + Symbol = Icon_ExtraSlot, Priority = 1 } }; @@ -1136,15 +953,10 @@ func FxIntRefreshContentsMenuTimer(object target, effect, int time) var overlay = obj->~GetInventoryIconOverlay(); if (overlay != nil) { - if (!custom) - { - custom = MenuStyle_Grid->MakeEntryProplist(symbol, nil); - custom.Priority = obj->GetValue(); - custom.top = {}; - } - custom.top._overlay = overlay; + custom.Priority = obj->GetValue(); + custom.top = { _overlay = overlay }; } - + // Add to menu! var text = nil; if (object_amount > 1) @@ -1159,36 +971,50 @@ func FxIntRefreshContentsMenuTimer(object target, effect, int time) }); } } - + // Add a contents counter on top. var contents_count_bar = { - BackgroundColor = RGBa(0, 0, 0, 100), - Priority = -1, + // Too low a value (-5000 doesn't work) and the bar will be at the bottom when + // an extra slot item is in the container and the HUD breaks + Priority = -10000, Bottom = "1em", - text = + Style = GUI_NoCrop, + text = { - Priority = 2, - Style = GUI_TextRight | GUI_TextVCenter + Priority = 3, + Style = GUI_TextRight | GUI_TextVCenter, + Bottom = "1em" } }; - + if (effect.obj.MaxContentsCount) { var count = effect.obj->ContentsCount(); var max = effect.obj.MaxContentsCount; contents_count_bar.text.Text = Format("%3d / %3d", count, max); - contents_count_bar.bar = + contents_count_bar.Bottom = "0.5em"; + contents_count_bar.bar = + { + Priority = 2, + BackgroundColor = RGB(0, 100, 0), + Right = ToPercentString(1000 * count / max, 10), + Bottom = "50%" + }; + contents_count_bar.background = { Priority = 1, - BackgroundColor = RGBa(0, 255, 0, 50), - Right = ToPercentString(1000 * count / max, 10) - }; + BackgroundColor = RGBa(0, 0, 0, 100), + Bottom = "50%" + }; } - else contents_count_bar.text.Text = Format("%3d", effect.obj->ContentsCount()); - + else + { + contents_count_bar.text.Text = Format("%3d", effect.obj->ContentsCount()); + } + PushBack(inventory, {symbol = nil, text = nil, custom = contents_count_bar}); - + // Check if nothing changed. If so, we don't need to update. if (GetLength(inventory) == GetLength(effect.last_inventory)) { @@ -1203,7 +1029,7 @@ func FxIntRefreshContentsMenuTimer(object target, effect, int time) if (same) return FX_OK; } - + effect.last_inventory = inventory[:]; DoMenuRefresh(effect.slot, effect.menu_index, inventory); return FX_OK; diff --git a/planet/Objects.ocd/Icons.ocd/Menu.ocd/ChangeBackground.ocd/DefCore.txt b/planet/Objects.ocd/Icons.ocd/Menu.ocd/ChangeBackground.ocd/DefCore.txt new file mode 100644 index 000000000..b2d5ccccb --- /dev/null +++ b/planet/Objects.ocd/Icons.ocd/Menu.ocd/ChangeBackground.ocd/DefCore.txt @@ -0,0 +1,8 @@ +[DefCore] +id=Icon_ChangeBackground +Version=8,0 +Category=C4D_StaticBack +Width=128 +Height=128 +Offset=-64,-64 +HideInCreator=true diff --git a/planet/Objects.ocd/Icons.ocd/Menu.ocd/ChangeBackground.ocd/Graphics.png b/planet/Objects.ocd/Icons.ocd/Menu.ocd/ChangeBackground.ocd/Graphics.png new file mode 100644 index 000000000..ef635f523 Binary files /dev/null and b/planet/Objects.ocd/Icons.ocd/Menu.ocd/ChangeBackground.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Icons.ocd/Menu.ocd/ChangeColor.ocd/DefCore.txt b/planet/Objects.ocd/Icons.ocd/Menu.ocd/ChangeColor.ocd/DefCore.txt new file mode 100644 index 000000000..fb4784a43 --- /dev/null +++ b/planet/Objects.ocd/Icons.ocd/Menu.ocd/ChangeColor.ocd/DefCore.txt @@ -0,0 +1,8 @@ +[DefCore] +id=Icon_ChangeColor +Version=8,0 +Category=C4D_StaticBack +Width=128 +Height=128 +Offset=-64,-64 +HideInCreator=true diff --git a/planet/Objects.ocd/Icons.ocd/Menu.ocd/ChangeColor.ocd/Graphics.png b/planet/Objects.ocd/Icons.ocd/Menu.ocd/ChangeColor.ocd/Graphics.png new file mode 100644 index 000000000..dc8a74bf3 Binary files /dev/null and b/planet/Objects.ocd/Icons.ocd/Menu.ocd/ChangeColor.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Icons.ocd/Menu.ocd/ChangeColor.ocd/GraphicsGrey.png b/planet/Objects.ocd/Icons.ocd/Menu.ocd/ChangeColor.ocd/GraphicsGrey.png new file mode 100644 index 000000000..ed8113793 Binary files /dev/null and b/planet/Objects.ocd/Icons.ocd/Menu.ocd/ChangeColor.ocd/GraphicsGrey.png differ diff --git a/planet/Objects.ocd/Icons.ocd/Menu.ocd/ExtraSlot.ocd/DefCore.txt b/planet/Objects.ocd/Icons.ocd/Menu.ocd/ExtraSlot.ocd/DefCore.txt new file mode 100644 index 000000000..9a9c4a97d --- /dev/null +++ b/planet/Objects.ocd/Icons.ocd/Menu.ocd/ExtraSlot.ocd/DefCore.txt @@ -0,0 +1,8 @@ +[DefCore] +id=Icon_ExtraSlot +Version=8,0 +Category=C4D_StaticBack +Width=128 +Height=128 +Offset=-64,-64 +HideInCreator=true diff --git a/planet/Objects.ocd/Icons.ocd/Menu.ocd/ExtraSlot.ocd/Graphics.png b/planet/Objects.ocd/Icons.ocd/Menu.ocd/ExtraSlot.ocd/Graphics.png new file mode 100644 index 000000000..8e24790b1 Binary files /dev/null and b/planet/Objects.ocd/Icons.ocd/Menu.ocd/ExtraSlot.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Icons.ocd/Menu.ocd/HideText.ocd/DefCore.txt b/planet/Objects.ocd/Icons.ocd/Menu.ocd/HideText.ocd/DefCore.txt new file mode 100644 index 000000000..32e734658 --- /dev/null +++ b/planet/Objects.ocd/Icons.ocd/Menu.ocd/HideText.ocd/DefCore.txt @@ -0,0 +1,8 @@ +[DefCore] +id=Icon_HideText +Version=8,0 +Category=C4D_StaticBack +Width=128 +Height=128 +Offset=-64,-64 +HideInCreator=true diff --git a/planet/Objects.ocd/Icons.ocd/Menu.ocd/HideText.ocd/Graphics.png b/planet/Objects.ocd/Icons.ocd/Menu.ocd/HideText.ocd/Graphics.png new file mode 100644 index 000000000..1639409df Binary files /dev/null and b/planet/Objects.ocd/Icons.ocd/Menu.ocd/HideText.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Icons.ocd/Menu.ocd/HideText.ocd/GraphicsShow.png b/planet/Objects.ocd/Icons.ocd/Menu.ocd/HideText.ocd/GraphicsShow.png new file mode 100644 index 000000000..ff46ad851 Binary files /dev/null and b/planet/Objects.ocd/Icons.ocd/Menu.ocd/HideText.ocd/GraphicsShow.png differ diff --git a/planet/Objects.ocd/Icons.ocd/Menu.ocd/Settings.ocd/DefCore.txt b/planet/Objects.ocd/Icons.ocd/Menu.ocd/Settings.ocd/DefCore.txt new file mode 100644 index 000000000..6a2e0ad82 --- /dev/null +++ b/planet/Objects.ocd/Icons.ocd/Menu.ocd/Settings.ocd/DefCore.txt @@ -0,0 +1,8 @@ +[DefCore] +id=Icon_Settings +Version=8,0 +Category=C4D_StaticBack +Width=128 +Height=128 +Offset=-64,-64 +HideInCreator=true diff --git a/planet/Objects.ocd/Icons.ocd/Menu.ocd/Settings.ocd/Graphics.png b/planet/Objects.ocd/Icons.ocd/Menu.ocd/Settings.ocd/Graphics.png new file mode 100644 index 000000000..7be0a4b72 Binary files /dev/null and b/planet/Objects.ocd/Icons.ocd/Menu.ocd/Settings.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Icons.ocd/Menu.ocd/Tab.ocd/DefCore.txt b/planet/Objects.ocd/Icons.ocd/Menu.ocd/Tab.ocd/DefCore.txt new file mode 100644 index 000000000..25211c3c5 --- /dev/null +++ b/planet/Objects.ocd/Icons.ocd/Menu.ocd/Tab.ocd/DefCore.txt @@ -0,0 +1,8 @@ +[DefCore] +id=Icon_Menu_Tab +Version=8,0 +Category=C4D_StaticBack +Width=128 +Height=128 +Offset=-64,-64 +HideInCreator=true diff --git a/planet/Objects.ocd/Icons.ocd/Menu.ocd/Tab.ocd/Graphics.png b/planet/Objects.ocd/Icons.ocd/Menu.ocd/Tab.ocd/Graphics.png new file mode 100644 index 000000000..99daf941b Binary files /dev/null and b/planet/Objects.ocd/Icons.ocd/Menu.ocd/Tab.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Icons.ocd/Menu.ocd/Tab.ocd/GraphicsHighlight.png b/planet/Objects.ocd/Icons.ocd/Menu.ocd/Tab.ocd/GraphicsHighlight.png new file mode 100644 index 000000000..07629348e Binary files /dev/null and b/planet/Objects.ocd/Icons.ocd/Menu.ocd/Tab.ocd/GraphicsHighlight.png differ diff --git a/planet/Objects.ocd/Icons.ocd/Menu.ocd/Tab.ocd/GraphicsRight.png b/planet/Objects.ocd/Icons.ocd/Menu.ocd/Tab.ocd/GraphicsRight.png new file mode 100644 index 000000000..3eac7c2d4 Binary files /dev/null and b/planet/Objects.ocd/Icons.ocd/Menu.ocd/Tab.ocd/GraphicsRight.png differ diff --git a/planet/Objects.ocd/Icons.ocd/Menu.ocd/Tab.ocd/GraphicsRightHighlight.png b/planet/Objects.ocd/Icons.ocd/Menu.ocd/Tab.ocd/GraphicsRightHighlight.png new file mode 100644 index 000000000..21115e555 Binary files /dev/null and b/planet/Objects.ocd/Icons.ocd/Menu.ocd/Tab.ocd/GraphicsRightHighlight.png differ diff --git a/planet/Objects.ocd/Icons.ocd/Menu.ocd/Tab.ocd/GraphicsRightSelected.png b/planet/Objects.ocd/Icons.ocd/Menu.ocd/Tab.ocd/GraphicsRightSelected.png new file mode 100644 index 000000000..6d3592807 Binary files /dev/null and b/planet/Objects.ocd/Icons.ocd/Menu.ocd/Tab.ocd/GraphicsRightSelected.png differ diff --git a/planet/Objects.ocd/Icons.ocd/Menu.ocd/Tab.ocd/GraphicsSelected.png b/planet/Objects.ocd/Icons.ocd/Menu.ocd/Tab.ocd/GraphicsSelected.png new file mode 100644 index 000000000..682d6ef35 Binary files /dev/null and b/planet/Objects.ocd/Icons.ocd/Menu.ocd/Tab.ocd/GraphicsSelected.png differ diff --git a/planet/Objects.ocd/Icons.ocd/MoveItems.ocd/Graphics.png b/planet/Objects.ocd/Icons.ocd/MoveItems.ocd/Graphics.png index 458280b77..e9a1cac63 100644 Binary files a/planet/Objects.ocd/Icons.ocd/MoveItems.ocd/Graphics.png and b/planet/Objects.ocd/Icons.ocd/MoveItems.ocd/Graphics.png differ diff --git a/planet/Objects.ocd/Icons.ocd/MoveItems.ocd/GraphicsLeft.png b/planet/Objects.ocd/Icons.ocd/MoveItems.ocd/GraphicsLeft.png index 64b7d8b32..8b612c3db 100644 Binary files a/planet/Objects.ocd/Icons.ocd/MoveItems.ocd/GraphicsLeft.png and b/planet/Objects.ocd/Icons.ocd/MoveItems.ocd/GraphicsLeft.png differ diff --git a/planet/Objects.ocd/Libraries.ocd/ClonkControl.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/ClonkControl.ocd/Script.c index f8d6b41b9..d6c52f371 100644 --- a/planet/Objects.ocd/Libraries.ocd/ClonkControl.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/ClonkControl.ocd/Script.c @@ -153,7 +153,7 @@ public func ObjectControl(int plr, int ctrl, int x, int y, int strength, bool re } // Open contents menu. CancelUse(); - GUI_ObjectInteractionMenu->CreateFor(this); + GUI_ObjectInteractionMenu->CreateFor(this, GUI_OIM_NewStyle); // the interaction menu calls SetMenu(this) in the clonk // so after this call menu = the created menu if(GetMenu())