Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding a priority list system for mouse cursor icons. #4587

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion code/_helpers/cmp.dm
Original file line number Diff line number Diff line change
Expand Up @@ -154,4 +154,7 @@
if(a == prerequisite)
return -1 // goes after
return cmp_skill_asc(a, GET_DECL(b.prerequisites[1]))
return cmp_name_or_type_asc(a, b)
return cmp_name_or_type_asc(a, b)

/proc/cmp_priority_list(list/A, list/B)
return A["priority"] - B["priority"]
5 changes: 1 addition & 4 deletions code/_helpers/visual_filters.dm
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@
/atom/movable
var/list/filter_data // For handling persistent filters

/proc/cmp_filter_data_priority(list/A, list/B)
return A["priority"] - B["priority"]

// Defining this for future proofing and ease of searching for erroneous usage.
/image/proc/add_filter(filter_name, priority, list/params)
filters += filter(arglist(params))
Expand Down Expand Up @@ -35,7 +32,7 @@

/atom/movable/proc/update_filters()
filters = null
filter_data = sortTim(filter_data, /proc/cmp_filter_data_priority, TRUE)
filter_data = sortTim(filter_data, /proc/cmp_priority_list, TRUE)
for(var/f in filter_data)
var/list/data = filter_data[f]
var/list/arguments = data.Copy()
Expand Down
67 changes: 67 additions & 0 deletions code/modules/client/mouse_pointer/_mouse_pointer.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Adds pointer entries to clients to allow for multiple sources wanting to modify the cursor at once.
* - add_mouse_pointer(pointer_type, pointer_priority, icon_index) will add or replace a pointer of the specified /decl/mouse_pointer type.
* - remove_mouse_pointer(pointer_type) will clear that entry.
* - Updates are handled automatically by adding/removing, other procs should not be used without a good reason.
*/

/client
VAR_PRIVATE/list/_mouse_pointers

/client/proc/clear_mouse_pointers()
if(LAZYLEN(_mouse_pointers))
LAZYCLEARLIST(_mouse_pointers)
update_mouse_pointer()
return TRUE
return FALSE

/client/proc/set_mouse_pointer_icon(new_cursor)
if(isnull(new_cursor))
new_cursor = initial(mouse_pointer_icon)
if(mouse_pointer_icon != new_cursor)
mouse_pointer_icon = new_cursor
return TRUE
return FALSE

/client/proc/add_mouse_pointer(pointer_type, pointer_priority = 1, icon_index = 1)

// Is an identical pointer already being tracked?
var/decl/mouse_pointer/pointer_decl = ispath(pointer_type) ? GET_DECL(pointer_type) : pointer_type
if(!isnum(icon_index) || icon_index < 1 || icon_index > length(pointer_decl.icons))
CRASH("Invalid icon_index passed to add_mouse_pointer() for [pointer_type].")

var/pointer_icon = pointer_decl.icons[icon_index]
var/list/comparing = _mouse_pointers?[pointer_type]
if(islist(comparing) && comparing["icon"] == pointer_icon && comparing["priority"] == pointer_priority)
return FALSE

// Update our list entry. If we have multiple pointers, sort by priority.
var/need_update = !(pointer_type in _mouse_pointers)
LAZYSET(_mouse_pointers, pointer_type, list("icon" = pointer_icon, "priority" = pointer_priority))
if(LAZYLEN(_mouse_pointers) > 1)
_mouse_pointers = sortTim(_mouse_pointers, /proc/cmp_priority_list, TRUE)
need_update = TRUE

// Refresh if needed.
if(need_update)
update_mouse_pointer()

/client/proc/remove_mouse_pointer(pointer_type)
if(!_mouse_pointers?[pointer_type])
return FALSE
var/current_pointer = _mouse_pointers[1]
LAZYREMOVE(_mouse_pointers, pointer_type)
if(pointer_type == current_pointer)
update_mouse_pointer()
return TRUE

/client/proc/update_mouse_pointer()
if(!LAZYLEN(_mouse_pointers))
return set_mouse_pointer_icon()
var/list/pointer = _mouse_pointers[_mouse_pointers[1]]
if(!islist(pointer))
return set_mouse_pointer_icon()
var/set_pointer = pointer["icon"]
if(isicon(set_pointer))
return set_mouse_pointer_icon(set_pointer)
return set_mouse_pointer_icon()
31 changes: 31 additions & 0 deletions code/modules/client/mouse_pointer/mouse_pointer_definitions.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/decl/mouse_pointer
abstract_type = /decl/mouse_pointer
/// Icon to set on the client for this cursor.
var/list/icons

/decl/mouse_pointer/Initialize()
. = ..()
if(icons && !islist(icons))
icons = list(icons)

/decl/mouse_pointer/validate()
. = ..()
if(length(icons))
var/static/list/check_states = list(
"",
"over",
"drag",
"drop",
"all"
)
for(var/icon in icons)
for(var/check_state in check_states)
if(!check_state_in_icon(check_state, icon))
. += "missing state '[check_state]' from icon '[icon]'"
out-of-phaze marked this conversation as resolved.
Show resolved Hide resolved
else
. += "null or empty icon list"

// Subtypes for use in add_mouse_pointer() below.
out-of-phaze marked this conversation as resolved.
Show resolved Hide resolved
/decl/mouse_pointer/examine
uid = "pointer_examine"
icons = 'icons/effects/mouse_pointers/examine_pointer.dmi'
1 change: 1 addition & 0 deletions code/modules/mob/login.dm
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@

/mob/Login()

client.clear_mouse_pointers() // in case we are transferring mobs.
global.player_list |= src
update_Login_details()
world.update_status()
Expand Down
9 changes: 4 additions & 5 deletions code/modules/mob/mob.dm
Original file line number Diff line number Diff line change
Expand Up @@ -1135,11 +1135,10 @@
/mob/proc/update_mouse_pointer()
if(!client)
return

client.mouse_pointer_icon = initial(client.mouse_pointer_icon)

if(examine_cursor_icon && client.keys_held["Shift"])
client.mouse_pointer_icon = examine_cursor_icon
if(client.keys_held["Shift"])
client.add_mouse_pointer(/decl/mouse_pointer/examine)
else
client.remove_mouse_pointer(/decl/mouse_pointer/examine)

/mob/keybind_face_direction(direction)
facedir(direction)
Expand Down
3 changes: 0 additions & 3 deletions code/modules/mob/mob_defines.dm
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,6 @@
*/
var/obj/screen/zone_selector/zone_sel = null

/// Cursor icon used when holding shift over things.
var/examine_cursor_icon = 'icons/effects/mouse_pointers/examine_pointer.dmi'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for parity with the prior system we could specify an examine cursor decl on mob instead

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand what you mean by parity with the prior system. This var was never changed or used outside of being passed to the pointer.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mostly that it's a mob var that can be overridden


var/damageoverlaytemp = 0
var/obj/machinery/machine = null

Expand Down
Binary file modified icons/effects/mouse_pointers/examine_pointer.dmi
Binary file not shown.
2 changes: 2 additions & 0 deletions nebula.dme
Original file line number Diff line number Diff line change
Expand Up @@ -1870,6 +1870,8 @@
#include "code\modules\client\preferences_spawnpoints.dm"
#include "code\modules\client\preferences_storage.dm"
#include "code\modules\client\preferences_toggle.dm"
#include "code\modules\client\mouse_pointer\_mouse_pointer.dm"
#include "code\modules\client\mouse_pointer\mouse_pointer_definitions.dm"
#include "code\modules\client\preference_setup\_defines.dm"
#include "code\modules\client\preference_setup\preference_setup.dm"
#include "code\modules\client\preference_setup\antagonism\01_candidacy.dm"
Expand Down
Loading