enUS Localization Update Announcement / localization-update-announcement (push) Canceled after 0s
490 lines
18 KiB
Lua
490 lines
18 KiB
Lua
-- Bagshui Inventory Prototype: Groups
|
|
|
|
Bagshui:AddComponent(function()
|
|
local Inventory = Bagshui.prototypes.Inventory
|
|
local InventoryUi = Bagshui.prototypes.InventoryUi
|
|
|
|
--#region Groups
|
|
|
|
--- Trigger Edit Mode colors and tooltips.
|
|
--- This is part of the Inventory class instead of a local function like the other
|
|
--- group script functions so that it's available to call from Inventory:ItemSlotAndGroupMouseOverCheck().
|
|
---@param group table Group UI frame.
|
|
function Inventory:Group_OnEnter(group)
|
|
local this = group or _G.this
|
|
local ui = this.bagshuiData.ui
|
|
local inventory = ui.inventory
|
|
|
|
-- It feels weird to have colors flashing under the cursor and tooltips appearing when menus are open.
|
|
-- (The IsMouseEnabled() check is just a safeguard.)
|
|
if inventory.menus:IsMenuOpen() or not this:IsMouseEnabled() then
|
|
return
|
|
end
|
|
|
|
-- Actual mouseover status tracking, since MouseIsOver() returns true even
|
|
-- when other frames are in front of this one.
|
|
this.bagshuiData.mouseIsOver = true
|
|
|
|
-- Update colors and borders for mouseover.
|
|
ui:SetGroupColors(this, false)
|
|
|
|
-- Show tooltip in Edit Mode when the user hasn't picked up an object.
|
|
if inventory.editMode and not inventory:EditModeCursorHasItem() then
|
|
local groupId = this.bagshuiData.groupId
|
|
local groupName = string.len(inventory.groups[groupId].name or "") > 0 and inventory.groups[groupId].name
|
|
or L.UnnamedGroup
|
|
|
|
-- Prepare tooltips.
|
|
_G.GameTooltip:SetOwner(this, "ANCHOR_" .. BsUtil.FlipAnchorPoint(inventory.settings.windowAnchorXPoint))
|
|
|
|
-- Format the group name.
|
|
_G.GameTooltip:AddLine(Bagshui:FormatTooltipLine(groupName, string.format(L.Symbol_Colon, L.Group), true))
|
|
|
|
-- Group is hidden.
|
|
if inventory.groups[groupId] and inventory.groups[groupId].hide then
|
|
_G.GameTooltip:AddLine(GRAY_FONT_COLOR_CODE .. "«" .. L.Hidden .. "»" .. FONT_COLOR_CODE_CLOSE)
|
|
end
|
|
|
|
-- Build bulleted category list.
|
|
_G.GameTooltip:AddLine(string.format(L.Symbol_Colon, L.Categories), nil, nil, nil, true) -- "Categories:"
|
|
local categoryList = inventory.groups[groupId] and inventory.groups[groupId].categories
|
|
if type(categoryList) == "table" and table.getn(categoryList) > 0 then
|
|
-- Need to smash them all into one line to circumvent the 30 line tooltip limit.
|
|
local categories = ""
|
|
BsCategories:SortIdList(categoryList)
|
|
for _, categoryId in ipairs(categoryList) do
|
|
if BsCategories.list[categoryId] then
|
|
categories = categories
|
|
.. GRAY_FONT_COLOR_CODE
|
|
.. "• "
|
|
.. FONT_COLOR_CODE_CLOSE
|
|
.. HIGHLIGHT_FONT_COLOR_CODE
|
|
.. (BsCategories:GetName(categoryId) or tostring(categoryId))
|
|
.. FONT_COLOR_CODE_CLOSE
|
|
.. BS_NEWLINE
|
|
end
|
|
end
|
|
_G.GameTooltip:AddLine(BsUtil.Trim(categories), nil, nil, nil, true)
|
|
else
|
|
-- No categories assigned.
|
|
_G.GameTooltip:AddLine(GRAY_FONT_COLOR_CODE .. L.NoneAssigned .. FONT_COLOR_CODE_CLOSE, nil, nil, nil, true)
|
|
end
|
|
|
|
-- Put instructions in Bagshui info tooltip.
|
|
Bagshui:SetInfoTooltipPosition(this, true, true)
|
|
inventory:AddBagshuiInfoTooltipLine(L.Click, string.format(L.Symbol_Colon, string.format(L.Prefix_Move, L.Group)))
|
|
inventory:AddBagshuiInfoTooltipLine(
|
|
L.RightClick,
|
|
string.format(L.Symbol_Colon, string.format(L.Suffix_Menu, L.Group))
|
|
)
|
|
|
|
_G.GameTooltip:Show()
|
|
Bagshui:ShowInfoTooltip()
|
|
end
|
|
end
|
|
|
|
--- Reset colors, hide tooltips.
|
|
local function Group_OnLeave()
|
|
local this = _G.this
|
|
local ui = this.bagshuiData.ui
|
|
|
|
this.bagshuiData.mouseIsOver = false
|
|
Bagshui:HideTooltips()
|
|
if not this:IsMouseEnabled() then
|
|
return
|
|
end
|
|
ui:SetGroupColors(this, false)
|
|
end
|
|
|
|
--- Edit Mode interactions for groups.
|
|
local function Group_OnClick()
|
|
local this = _G.this
|
|
local ui = this.bagshuiData.ui
|
|
local inventory = ui.inventory
|
|
|
|
-- This isn't really necessary because group interactivity is disabled outside Edit Mode, but let's have a safeguard.
|
|
if not inventory.editMode then
|
|
return
|
|
end
|
|
|
|
-- Left/Right click.
|
|
if _G.arg1 == "LeftButton" or inventory:EditModeCursorHasItem() then
|
|
-- When a menu is open, just close it and don't do anything else.
|
|
-- Without this, you can accidentally pick up a group when trying to close a menu.
|
|
if inventory.menus:IsMenuOpen() then
|
|
Bagshui:CloseMenus()
|
|
this:GetScript("OnEnter")()
|
|
-- Tooltips and highlighting may need to reappear.
|
|
inventory:ItemSlotAndGroupMouseOverCheck()
|
|
return
|
|
end
|
|
|
|
-- Something is on the cursor, so let's take it off.
|
|
if inventory:EditModeCursorHasItem() then
|
|
if inventory.editState.cursorItemType == BS_INVENTORY_OBJECT_TYPE.GROUP then
|
|
inventory:AssignGroupToLayout(
|
|
inventory.editState.cursorItem,
|
|
BS_INVENTORY_OBJECT_TYPE.GROUP,
|
|
BS_INVENTORY_LAYOUT_DIRECTION.COLUMN,
|
|
this.bagshuiData.rowNum,
|
|
this.bagshuiData.columnNum
|
|
)
|
|
elseif inventory.editState.cursorItemType == BS_INVENTORY_OBJECT_TYPE.CATEGORY then
|
|
inventory:AssignCategoryToGroup(inventory.editState.cursorItem, this.bagshuiData.groupId)
|
|
elseif inventory.editState.cursorItemType == BS_INVENTORY_OBJECT_TYPE.ITEM then
|
|
inventory:ShowItemCategoryAssignmentMenuForGroup(inventory.editState.cursorItem, this)
|
|
else
|
|
-- Failsafe
|
|
inventory:ClearEditModeCursor()
|
|
end
|
|
_G.PlaySound("INTERFACESOUND_CURSORDROPOBJECT")
|
|
else
|
|
-- Nothing on the cursor - pick up the group.
|
|
-- _G.PlaySound is handled by PickUpGroup().
|
|
this:GetScript("OnLeave")()
|
|
inventory:EditModePickUpGroup(this.bagshuiData.groupId)
|
|
ui:SetGroupColors(this, false)
|
|
end
|
|
elseif _G.arg1 == "RightButton" then
|
|
inventory.menus:OpenMenu("Group", this, nil, "cursor")
|
|
end
|
|
end
|
|
|
|
--- Highlight group when the mouse button is pressed to indicate that it will be dragged.
|
|
local function Group_OnMouseDown()
|
|
if not _G.this:IsEnabled() then
|
|
return
|
|
end
|
|
_G.this.bagshuiData.ui:SetGroupColors(_G.this, true)
|
|
end
|
|
|
|
--- Remove group highlight.
|
|
local function Group_OnMouseUp()
|
|
_G.this.bagshuiData.ui:SetGroupColors(_G.this, false)
|
|
end
|
|
|
|
--- Pick up the group.
|
|
local function Group_OnDragStart()
|
|
_G.this:Click()
|
|
end
|
|
|
|
---Create a new group frame that holds item slot buttons.
|
|
---@param groupNum number? When provided, only create the group if it doesn't exist.
|
|
function InventoryUi:CreateGroup(groupNum)
|
|
local ui = self
|
|
|
|
-- Declare reusable group creation function.
|
|
if not ui.CreateGroupIfNotExists then
|
|
-- Wrapper function.
|
|
local function Group_OnEnter()
|
|
ui.inventory:Group_OnEnter()
|
|
end
|
|
|
|
function ui.CreateGroupIfNotExists(elementNum)
|
|
-- Group frame is actually a button so it can have an OnClick event.
|
|
ui.frames.groups[elementNum] =
|
|
_G.CreateFrame("Button", ui:CreateElementName("Group" .. elementNum), ui.frames.main)
|
|
local group = ui.frames.groups[elementNum]
|
|
group.bagshuiData = {
|
|
type = BS_INVENTORY_OBJECT_TYPE.GROUP,
|
|
text = nil,
|
|
mouseIsOver = false,
|
|
groupId = nil,
|
|
rowNum = nil,
|
|
ColumNum = nil,
|
|
ui = ui,
|
|
}
|
|
|
|
-- It feels better when the group is a little bigger than the visual would indicate.
|
|
group:SetHitRectInsets(2, 2, 2, 2)
|
|
|
|
-- Set default appearance.
|
|
ui:SetFrameBackdrop(group)
|
|
|
|
-- Add label text in top left corner.
|
|
-- This has to be in a frame so the full label can be revealed on mouseover.
|
|
group.bagshuiData.labelFrame, group.bagshuiData.text = ui:CreateLabel(group, ui.frames.main)
|
|
|
|
-- Add hidden indicator.
|
|
group.bagshuiData.hidden = group:CreateTexture(nil, "OVERLAY")
|
|
group.bagshuiData.hidden:SetTexture(BsUtil.GetFullTexturePath("Icons\\Mask"))
|
|
group.bagshuiData.hidden:SetHeight(10)
|
|
group.bagshuiData.hidden:SetWidth(10)
|
|
-- Adjust position based on border inset.
|
|
local backdrop = group:GetBackdrop()
|
|
local inset = ((backdrop.insets and backdrop.insets.top) or 0) + 1
|
|
group.bagshuiData.hidden:SetPoint("TOPRIGHT", group, "TOPRIGHT", -inset, 2 - inset)
|
|
-- Will be displayed by `Inventory:SetGroupColors()` when appropriate.
|
|
group.bagshuiData.hidden:Hide()
|
|
|
|
-- Add group behaviors
|
|
group:RegisterForClicks("LeftButtonUp", "RightButtonUp")
|
|
group:RegisterForDrag("LeftButton")
|
|
group:SetScript("OnEnter", Group_OnEnter)
|
|
group:SetScript("OnLeave", Group_OnLeave)
|
|
group:SetScript("OnClick", Group_OnClick)
|
|
group:SetScript("OnMouseDown", Group_OnMouseDown)
|
|
group:SetScript("OnMouseUp", Group_OnMouseUp)
|
|
group:SetScript("OnDragStart", Group_OnDragStart)
|
|
end
|
|
end
|
|
|
|
-- Perform group creation.
|
|
ui:CreateIfNotExists(groupNum, ui.frames.groups, ui.CreateGroupIfNotExists)
|
|
|
|
-- Create a corresponding group move target.
|
|
-- We'll need at least `<number of groups> + 2` to complete
|
|
-- the layout, but UpdateWindow() will take care of that.
|
|
ui:CreateGroupMoveTarget(groupNum)
|
|
end
|
|
|
|
--- Set the colors of a group / group move target.
|
|
---@param uiGroup table Group or group move target frame (type will be determined via `uiGroup.bagshuiData.type`).
|
|
---@param mouseDown boolean? Control whether the extra highlighting to indicate mouse button press should be applied.
|
|
function InventoryUi:SetGroupColors(uiGroup, mouseDown)
|
|
local inventory = self.inventory
|
|
|
|
-- Default values.
|
|
|
|
local backdropOpacity = 0.1
|
|
local backdropColor = BS_COLOR.WHITE
|
|
local borderOpacity = 0.5
|
|
local borderColor = BS_COLOR.GRAY
|
|
local textOpacity = 0.5 -- This will be the base opacity in Edit Mode.
|
|
local textColor = BS_COLOR.WHITE
|
|
|
|
-- Track whether this Group has been picked up.
|
|
local groupIsOnCursor = false
|
|
local highlightThisGroup = false
|
|
|
|
-- These are only applicable to groups, not group move targets.
|
|
if uiGroup.bagshuiData.type == BS_INVENTORY_OBJECT_TYPE.GROUP then
|
|
local groupId = uiGroup.bagshuiData.groupId
|
|
|
|
-- Group color priority:
|
|
-- 1. Per-group setting.
|
|
-- 2. Skin colors, if groupUseSkinColors is enabled and applicable for the setting.
|
|
-- 3. Default colors.
|
|
|
|
backdropColor = inventory.groups[groupId] and inventory.groups[groupId].background
|
|
or inventory.settings.groupUseSkinColors and BsSkin.skinBackgroundColor
|
|
or inventory.settings.groupBackgroundDefault
|
|
backdropOpacity = backdropColor[4]
|
|
|
|
borderColor = inventory.groups[groupId] and inventory.groups[groupId].border
|
|
or inventory.settings.groupUseSkinColors and BsSkin.skinBorderColor
|
|
or inventory.settings.groupBorderDefault
|
|
borderOpacity = borderColor[4]
|
|
|
|
-- Outline the group in yellow if it's on the cursor or highlighting is requested.
|
|
groupIsOnCursor = inventory.editState.cursorItem == groupId
|
|
highlightThisGroup = inventory.editModeGroupHighlight == groupId
|
|
|
|
textColor = inventory.groups[groupId] and inventory.groups[groupId].label or inventory.settings.groupLabelDefault
|
|
|
|
-- Use configured label opacity outside Edit Mode.
|
|
if not inventory.editMode then
|
|
textOpacity = textColor[4]
|
|
end
|
|
|
|
-- Display hidden indicator in Edit Mode.
|
|
if inventory.editMode and inventory.groups[groupId].hide then
|
|
uiGroup.bagshuiData.hidden:Show()
|
|
uiGroup.bagshuiData.hidden:SetAlpha(uiGroup.bagshuiData.mouseIsOver and 0.8 or 0.5)
|
|
else
|
|
uiGroup.bagshuiData.hidden:Hide()
|
|
end
|
|
end
|
|
|
|
-- Highlight the group.
|
|
if
|
|
-- In Edit Mode when the cursor has an item and one of the following is true:
|
|
-- - This is a group move target.
|
|
-- - This group is on the cursor.
|
|
-- - There is another group on the cursor and this group mis moused over.
|
|
(
|
|
inventory:EditModeCursorHasItem()
|
|
and (
|
|
uiGroup.bagshuiData.type == BS_INVENTORY_OBJECT_TYPE.GROUP_MOVE_TARGET
|
|
or groupIsOnCursor
|
|
or (inventory.editState.cursorItemType == BS_INVENTORY_OBJECT_TYPE.GROUP and uiGroup.bagshuiData.mouseIsOver)
|
|
)
|
|
)
|
|
-- When this group is being targeted in Edit Mode via self.editModeGroupHighlight.
|
|
or highlightThisGroup
|
|
then
|
|
borderOpacity = (groupIsOnCursor or highlightThisGroup) and 0.8 or 0.6
|
|
borderColor = BS_COLOR.YELLOW
|
|
textOpacity = 0.8
|
|
textColor = BS_COLOR.YELLOW
|
|
end
|
|
|
|
-- Apply mouse button down/mouseover opacity changes.
|
|
if mouseDown then
|
|
backdropOpacity = math.max(backdropOpacity, 0.3)
|
|
borderOpacity = math.max(borderOpacity, 1)
|
|
textOpacity = 1
|
|
elseif uiGroup.bagshuiData.mouseIsOver then
|
|
backdropOpacity = math.max(backdropOpacity, 0.2)
|
|
borderOpacity = math.max(borderOpacity, 0.9)
|
|
textOpacity = 0.9
|
|
end
|
|
|
|
-- Apply special backdrop color for highlighted group.
|
|
if highlightThisGroup or groupIsOnCursor then
|
|
backdropColor = BS_COLOR.YELLOW
|
|
backdropOpacity = 0.25
|
|
end
|
|
|
|
-- Set colors.
|
|
uiGroup:SetBackdropColor(backdropColor[1], backdropColor[2], backdropColor[3], backdropOpacity)
|
|
uiGroup:SetBackdropBorderColor(borderColor[1], borderColor[2], borderColor[3], borderOpacity)
|
|
if uiGroup.bagshuiData.text then
|
|
uiGroup.bagshuiData.text:SetTextColor(textColor[1], textColor[2], textColor[3], textOpacity)
|
|
end
|
|
end
|
|
|
|
--- Control whether a group has interactivity enabled. Used when entering/exiting Edit Mode.
|
|
---@param uiGroup table Group frame.
|
|
---@param enabled boolean Whether the group should receive mouse events.
|
|
function InventoryUi:SetGroupInteractivityEnabled(uiGroup, enabled)
|
|
uiGroup:EnableMouse(enabled)
|
|
end
|
|
|
|
--#endregion Groups
|
|
|
|
--#region Groups Move Targets
|
|
|
|
--- Trigger color changes and tooltips.
|
|
local function GroupMoveTarget_OnEnter()
|
|
local this = _G.this
|
|
local ui = this.bagshuiData.ui
|
|
local inventory = ui.inventory
|
|
|
|
-- It feels weird to have colors flashing under the cursor and tooltips appearing when menus are open.
|
|
if inventory.menus:IsMenuOpen() then
|
|
return
|
|
end
|
|
|
|
this.bagshuiData.mouseIsOver = true
|
|
ui:SetGroupColors(this, false)
|
|
|
|
-- Don't show tooltip if there's an item held on the Edit Mode cursor.
|
|
if inventory:EditModeCursorHasItem() then
|
|
return
|
|
end
|
|
|
|
-- Place tooltip in bottom right of the screen.
|
|
_G.GameTooltip_SetDefaultAnchor(_G.GameTooltip, this)
|
|
_G.GameTooltip:ClearLines()
|
|
_G.GameTooltip:SetText(string.format(L.Prefix_New, L.Group)) -- "Add Group"
|
|
_G.GameTooltip:Show()
|
|
end
|
|
|
|
--- Hide tooltips and reset colors.
|
|
local function GroupMoveTarget_OnLeave()
|
|
local this = _G.this
|
|
local ui = this.bagshuiData.ui
|
|
|
|
this.bagshuiData.mouseIsOver = false
|
|
ui:SetGroupColors(this, false)
|
|
Bagshui:HideTooltips()
|
|
end
|
|
|
|
--- Create a new group and move the object on the cursor into it if applicable.
|
|
local function GroupMoveTarget_OnClick()
|
|
local this = _G.this
|
|
local inventory = this.bagshuiData.ui.inventory
|
|
|
|
this.bagshuiData.ui.inventory:AssignGroupToLayout(
|
|
inventory.editState.cursorItem,
|
|
inventory.editState.cursorItemType,
|
|
this.bagshuiData.insert,
|
|
this.bagshuiData.rowNum,
|
|
this.bagshuiData.columnNum
|
|
)
|
|
end
|
|
|
|
--- Highlight.
|
|
local function GroupMoveTarget_OnMouseDown()
|
|
_G.this.bagshuiData.ui:SetGroupColors(_G.this, true)
|
|
end
|
|
|
|
--- Un-highlight.
|
|
local function GroupMoveTarget_OnMouseUp()
|
|
_G.this.bagshuiData.ui:SetGroupColors(_G.this, false)
|
|
end
|
|
|
|
---Create a new UI group move target button.
|
|
---@param groupMoveTargetNum number? When provided, only create the group move target if it doesn't exist.
|
|
function InventoryUi:CreateGroupMoveTarget(groupMoveTargetNum)
|
|
local ui = self
|
|
local inventory = self.inventory
|
|
|
|
-- Declare reusable group move target creation function.
|
|
if not ui.CreateGroupMoveTargetIfNotExists then
|
|
function ui.CreateGroupMoveTargetIfNotExists(elementNum)
|
|
ui.frames.groupMoveTargets[elementNum] =
|
|
_G.CreateFrame("Frame", ui:CreateElementName("GroupMoveTarget" .. elementNum), ui.frames.main)
|
|
|
|
local button = _G.CreateFrame(
|
|
"Button",
|
|
ui:CreateElementName("GroupMoveTarget" .. elementNum),
|
|
ui.frames.groupMoveTargets[elementNum]
|
|
)
|
|
|
|
-- Share Bagshui table between outer frame and actual button
|
|
ui.frames.groupMoveTargets[elementNum].bagshuiData = {
|
|
type = BS_INVENTORY_OBJECT_TYPE.GROUP_MOVE_TARGET,
|
|
button = button,
|
|
mouseIsOver = false,
|
|
insert = nil,
|
|
rowNum = nil,
|
|
columnNum = nil,
|
|
ui = ui,
|
|
}
|
|
button.bagshuiData = ui.frames.groupMoveTargets[elementNum].bagshuiData
|
|
|
|
button:EnableMouse(true)
|
|
button:SetHitRectInsets(-4, -4, -4, -4)
|
|
|
|
ui:SetFrameBackdrop(
|
|
button,
|
|
"SOLID", -- borderStyle
|
|
nil, -- bgFile
|
|
nil, -- edgeFile
|
|
nil, -- tileSize
|
|
nil, -- edgeSize
|
|
0 -- insets
|
|
)
|
|
|
|
local text = button:CreateFontString(nil, nil, "GameFontNormal")
|
|
button.bagshuiData.text = text
|
|
text:SetJustifyH("CENTER")
|
|
text:SetJustifyV("MIDDLE")
|
|
text:SetPoint("TOPLEFT", button, -10, 10)
|
|
text:SetPoint("BOTTOMRIGHT", button, 10, -12)
|
|
text:SetShadowColor(0, 0, 0, 0)
|
|
text:SetShadowOffset(0, 0)
|
|
text:SetFont(text:GetFont(), 13, "THICKOUTLINE, MONOCHROME")
|
|
text:SetText("+")
|
|
|
|
-- Set initial colors.
|
|
ui:SetGroupColors(button, false)
|
|
|
|
-- Assign behaviors.
|
|
button:SetScript("OnEnter", GroupMoveTarget_OnEnter)
|
|
button:SetScript("OnLeave", GroupMoveTarget_OnLeave)
|
|
button:SetScript("OnClick", GroupMoveTarget_OnClick)
|
|
button:SetScript("OnMouseDown", GroupMoveTarget_OnMouseDown)
|
|
button:SetScript("OnMouseUp", GroupMoveTarget_OnMouseUp)
|
|
end
|
|
end
|
|
|
|
-- Perform group move target creation.
|
|
ui:CreateIfNotExists(groupMoveTargetNum, ui.frames.groupMoveTargets, ui.CreateGroupMoveTargetIfNotExists)
|
|
end
|
|
|
|
--#endregion Group Move Targets
|
|
end)
|