diff --git a/code/modules/wiremod/components/abstract/module.dm b/code/modules/wiremod/components/abstract/module.dm
index d7d7676006c..91b9db308ac 100644
--- a/code/modules/wiremod/components/abstract/module.dm
+++ b/code/modules/wiremod/components/abstract/module.dm
@@ -17,13 +17,17 @@
var/port_limit = 10
+ ui_buttons = list(
+ "edit" = "action"
+ )
+
/obj/item/integrated_circuit/module
var/obj/item/circuit_component/module/attached_module
/obj/item/integrated_circuit/module/ui_host(mob/user)
- . = ..()
- if(. == src)
- return attached_module
+ if(attached_module)
+ return attached_module.ui_host()
+ return ..()
/obj/item/integrated_circuit/module/set_display_name(new_name)
. = ..()
@@ -296,6 +300,9 @@
#undef WITHIN_RANGE
+/obj/item/circuit_component/module/ui_perform_action(mob/user, action)
+ interact(user)
+
/obj/item/circuit_component/module/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
diff --git a/code/modules/wiremod/components/list/list_literal.dm b/code/modules/wiremod/components/list/list_literal.dm
index 70647c75819..01db810ac1d 100644
--- a/code/modules/wiremod/components/list/list_literal.dm
+++ b/code/modules/wiremod/components/list/list_literal.dm
@@ -20,6 +20,11 @@
var/min_size = 1
var/max_size = 20
+ ui_buttons = list(
+ "plus" = "increase",
+ "minus" = "decrease"
+ )
+
/obj/item/circuit_component/list_literal/save_data_to_list(list/component_data)
. = ..()
component_data["length"] = length
@@ -60,16 +65,12 @@
return ..()
// Increases list length
-/obj/item/circuit_component/list_literal/attack_self(mob/user, list/modifiers)
- . = ..()
- set_list_size(min(length + 1, max_size))
- balloon_alert(user, "new size is now [length]")
-
-// Decreases list length
-/obj/item/circuit_component/list_literal/attack_self_secondary(mob/user, list/modifiers)
- . = ..()
- set_list_size(max(length - 1, min_size))
- balloon_alert(user, "new size is now [length]")
+/obj/item/circuit_component/list_literal/ui_perform_action(mob/user, action)
+ switch(action)
+ if("increase")
+ set_list_size(min(length + 1, max_size))
+ if("decrease")
+ set_list_size(max(length - 1, min_size))
/obj/item/circuit_component/list_literal/input_received(datum/port/input/port)
diff --git a/code/modules/wiremod/core/component.dm b/code/modules/wiremod/core/component.dm
index 0368b29722b..d2c8fef5f7a 100644
--- a/code/modules/wiremod/core/component.dm
+++ b/code/modules/wiremod/core/component.dm
@@ -51,6 +51,9 @@
// Defines which shells support this component. Only used as an informational guide, does not restrict placing these components in circuits.
var/required_shells = null
+ /// The UI buttons of this circuit component. An assoc list that has this format: "button_icon" = "action_name"
+ var/ui_buttons = null
+
/// Called when the option ports should be set up
/obj/item/circuit_component/proc/populate_options()
return
@@ -295,6 +298,16 @@
if(length(input_ports))
. += create_ui_notice("Power Usage Per Input: [power_usage_per_input]", "orange", "bolt")
+/**
+ * Called when a special button is pressed on this component in the UI.
+ *
+ * Arguments:
+ * * user - Interacting mob
+ * * action - A string for which action is being performed. No parameters passed because it's only a button press.
+ */
+/obj/item/circuit_component/proc/ui_perform_action(mob/user, action)
+ return
+
/**
* Creates a UI notice entry to be used in get_ui_notices()
*
@@ -309,6 +322,11 @@
"color" = color,
))
+/obj/item/circuit_component/ui_host(mob/user)
+ if(parent)
+ return parent.ui_host()
+ return ..()
+
/**
* Creates a table UI notice entry to be used in get_ui_notices()
*
diff --git a/code/modules/wiremod/core/integrated_circuit.dm b/code/modules/wiremod/core/integrated_circuit.dm
index de5cb466220..9315db39c51 100644
--- a/code/modules/wiremod/core/integrated_circuit.dm
+++ b/code/modules/wiremod/core/integrated_circuit.dm
@@ -316,6 +316,7 @@ GLOBAL_LIST_EMPTY_TYPED(integrated_circuits, /obj/item/integrated_circuit)
component_data["y"] = component.rel_y
component_data["removable"] = component.removable
component_data["color"] = component.ui_color
+ component_data["ui_buttons"] = component.ui_buttons
.["components"] += list(component_data)
.["variables"] = list()
@@ -380,7 +381,7 @@ GLOBAL_LIST_EMPTY_TYPED(integrated_circuits, /obj/item/integrated_circuit)
#define WITHIN_RANGE(id, table) (id >= 1 && id <= length(table))
-/obj/item/integrated_circuit/ui_act(action, list/params)
+/obj/item/integrated_circuit/ui_act(action, list/params, datum/tgui/ui)
. = ..()
if(.)
return
@@ -464,6 +465,7 @@ GLOBAL_LIST_EMPTY_TYPED(integrated_circuits, /obj/item/integrated_circuit)
if(port.datatype != PORT_TYPE_ATOM && port.datatype != PORT_TYPE_ANY)
return
var/obj/item/multitool/circuit/marker = usr.get_active_held_item()
+ // Let's admins upload marked datums to an entity port.
if(!istype(marker))
var/client/user = usr.client
if(!check_rights_for(user, R_VAREDIT))
@@ -573,6 +575,15 @@ GLOBAL_LIST_EMPTY_TYPED(integrated_circuits, /obj/item/integrated_circuit)
if("move_screen")
screen_x = text2num(params["screen_x"])
screen_y = text2num(params["screen_y"])
+ if("perform_action")
+ var/component_id = text2num(params["component_id"])
+ if(!WITHIN_RANGE(component_id, attached_components))
+ return
+ var/obj/item/circuit_component/component = attached_components[component_id]
+ component.ui_perform_action(ui.user, params["action_name"])
+
+
+#undef WITHIN_RANGE
/obj/item/integrated_circuit/proc/clear_setter_or_getter(datum/source)
SIGNAL_HANDLER
@@ -586,8 +597,6 @@ GLOBAL_LIST_EMPTY_TYPED(integrated_circuits, /obj/item/integrated_circuit)
usb_cable.balloon_alert(user, "circuit needs to be in a compatible shell")
return COMSIG_CANCEL_USB_CABLE_ATTACK
-#undef WITHIN_RANGE
-
/// Sets the display name that appears on the shell.
/obj/item/integrated_circuit/proc/set_display_name(new_name)
display_name = new_name
diff --git a/tgui/packages/tgui/interfaces/IntegratedCircuit/ObjectComponent.js b/tgui/packages/tgui/interfaces/IntegratedCircuit/ObjectComponent.js
index 3a721c572f3..ca9d78a4184 100644
--- a/tgui/packages/tgui/interfaces/IntegratedCircuit/ObjectComponent.js
+++ b/tgui/packages/tgui/interfaces/IntegratedCircuit/ObjectComponent.js
@@ -96,6 +96,7 @@ export class ObjectComponent extends Component {
index,
color = 'blue',
removable,
+ ui_buttons,
locations,
onPortUpdated,
onPortLoaded,
@@ -140,6 +141,19 @@ export class ObjectComponent extends Component {
{name}
+ {!!ui_buttons && Object.keys(ui_buttons).map(icon => (
+
+
+ ))}