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())