diff --git a/Core/CategoryManager.lua b/Core/CategoryManager.lua index 6554ccf..29f3aaf 100644 --- a/Core/CategoryManager.lua +++ b/Core/CategoryManager.lua @@ -1012,22 +1012,29 @@ function CategoryManager:EvaluateCategoryRules(categoryDef, itemData, bagID, slo local matchMode = categoryDef.matchMode or "any" - if matchMode == "all" then - -- All rules must match - for _, rule in ipairs(rules) do - if not self:EvaluateRule(rule, itemData, bagID, slotID, isOtherChar) then - return false - end + local hasRequired, hasOptional = false, false + local requiredAllPass, optionalAnyPass, optionalAllPass = true, false, true + + for _, rule in ipairs(rules) do + local pass = self:EvaluateRule(rule, itemData, bagID, slotID, isOtherChar) + if rule.required then + hasRequired = true + if not pass then requiredAllPass = false end + else + hasOptional = true + if pass then optionalAnyPass = true else optionalAllPass = false end end + end + + if matchMode == "all" then + if hasRequired and not requiredAllPass then return false end + if hasOptional and not optionalAllPass then return false end return true else - -- Any rule must match - for _, rule in ipairs(rules) do - if self:EvaluateRule(rule, itemData, bagID, slotID, isOtherChar) then - return true - end - end - return false + -- "any" mode: required rules must ALL pass; among optional rules at least one must pass + if hasRequired and not requiredAllPass then return false end + if hasOptional then return optionalAnyPass end + return hasRequired end end diff --git a/Guda.toc b/Guda.toc index f270475..a0be893 100644 --- a/Guda.toc +++ b/Guda.toc @@ -2,7 +2,7 @@ ## Title: Guda ## Notes: All-in-one bag and bank addon for World of Warcraft 1.12.1 (Turtle WoW) ## Author: Vati -## Version: 2.3.0 +## Version: 2.3.1 ## SavedVariables: Guda_DB ## SavedVariablesPerCharacter: Guda_CharDB ## OptionalDeps: pfUI diff --git a/Localization.lua b/Localization.lua index c208e51..6900309 100644 --- a/Localization.lua +++ b/Localization.lua @@ -207,6 +207,8 @@ L["Group:"] = "Group:" L["Mark:"] = "Mark:" L["Any rule"] = "Any rule" L["All rules"] = "All rules" +L["Required rule"] = "Required rule" +L["Required rule tooltip"] = "Pin a rule to mark it as required. In 'Any rule' mode, ALL required rules must match AND at least one non-required rule must match. Has no effect in 'All rules' mode." L["Edit Category (Built-in)"] = "Edit Category (Built-in)" L["Edit Category"] = "Edit Category" L["Rules (%d/%d):"] = "Rules (%d/%d):" @@ -544,6 +546,8 @@ if locale == "zhCN" then L["Mark:"] = "标记:" L["Any rule"] = "任一规则" L["All rules"] = "所有规则" + L["Required rule"] = "必需规则" + L["Required rule tooltip"] = "标记此规则为必需。在“任一规则”模式下,所有必需规则都必须匹配,且至少一条非必需规则也要匹配。“所有规则”模式下无效。" L["Edit Category (Built-in)"] = "编辑分类(内置)" L["Edit Category"] = "编辑分类" L["Rules (%d/%d):"] = "规则 (%d/%d):" @@ -801,6 +805,8 @@ elseif locale == "esES" then L["Mark:"] = "Marca:" L["Any rule"] = "Cualquier regla" L["All rules"] = "Todas las reglas" + L["Required rule"] = "Regla obligatoria" + L["Required rule tooltip"] = "Fija una regla para marcarla como obligatoria. En el modo 'Cualquier regla', TODAS las reglas obligatorias deben coincidir Y al menos una regla no obligatoria también. No tiene efecto en 'Todas las reglas'." L["Edit Category (Built-in)"] = "Editar categoría (integrada)" L["Edit Category"] = "Editar categoría" L["Rules (%d/%d):"] = "Reglas (%d/%d):" @@ -1053,6 +1059,8 @@ elseif locale == "ptBR" then L["Mark:"] = "Marca:" L["Any rule"] = "Qualquer regra" L["All rules"] = "Todas as regras" + L["Required rule"] = "Regra obrigatória" + L["Required rule tooltip"] = "Fixe uma regra para marcá-la como obrigatória. No modo 'Qualquer regra', TODAS as regras obrigatórias devem corresponder E pelo menos uma regra não obrigatória também. Sem efeito em 'Todas as regras'." L["Edit Category (Built-in)"] = "Editar categoria (integrada)" L["Edit Category"] = "Editar categoria" L["Rules (%d/%d):"] = "Regras (%d/%d):" @@ -1305,6 +1313,8 @@ elseif locale == "deDE" then L["Mark:"] = "Markierung:" L["Any rule"] = "Beliebige Regel" L["All rules"] = "Alle Regeln" + L["Required rule"] = "Erforderliche Regel" + L["Required rule tooltip"] = "Regel anheften, um sie als erforderlich zu markieren. Im Modus 'Beliebige Regel' müssen ALLE erforderlichen Regeln zutreffen UND mindestens eine nicht-erforderliche Regel. Im Modus 'Alle Regeln' ohne Wirkung." L["Edit Category (Built-in)"] = "Kategorie bearbeiten (integriert)" L["Edit Category"] = "Kategorie bearbeiten" L["Rules (%d/%d):"] = "Regeln (%d/%d):" @@ -1557,6 +1567,8 @@ elseif locale == "ruRU" then L["Mark:"] = "Метка:" L["Any rule"] = "Любое правило" L["All rules"] = "Все правила" + L["Required rule"] = "Обязательное правило" + L["Required rule tooltip"] = "Закрепите правило, чтобы сделать его обязательным. В режиме «Любое правило» ВСЕ обязательные правила должны совпасть И хотя бы одно необязательное правило. В режиме «Все правила» не влияет." L["Edit Category (Built-in)"] = "Изменить категорию (встроенная)" L["Edit Category"] = "Изменить категорию" L["Rules (%d/%d):"] = "Правила (%d/%d):" diff --git a/UI/SettingsPopup.lua b/UI/SettingsPopup.lua index ba46e04..9eaf738 100644 --- a/UI/SettingsPopup.lua +++ b/UI/SettingsPopup.lua @@ -2556,7 +2556,11 @@ function Guda_CategoryEditor_Open(categoryId) editorRules = {} if categoryDef.rules then for i, rule in ipairs(categoryDef.rules) do - table.insert(editorRules, { type = rule.type, value = rule.value }) + table.insert(editorRules, { + type = rule.type, + value = rule.value, + required = rule.required and true or false, + }) end end @@ -2627,6 +2631,11 @@ function Guda_CategoryEditor_SetMatchMode(mode) if anyRadio then anyRadio:SetChecked(mode == "any" and 1 or 0) end if allRadio then allRadio:SetChecked(mode == "all" and 1 or 0) end + + -- Re-render rule rows so pin buttons reflect new enabled state + if Guda_CategoryEditor_UpdateRulesDisplay then + Guda_CategoryEditor_UpdateRulesDisplay() + end end -- Get or create a rule row frame @@ -2644,11 +2653,38 @@ local function GetRuleRowFrame(index) row:SetWidth(310) row:SetPoint("TOPLEFT", container, "TOPLEFT", 0, -((index - 1) * RULE_ROW_HEIGHT)) + -- Required (pin) toggle button + local reqBtn = CreateFrame("Button", rowName .. "_ReqBtn", row) + reqBtn:SetWidth(18) + reqBtn:SetHeight(18) + reqBtn:SetPoint("LEFT", row, "LEFT", 0, 0) + local reqTex = reqBtn:CreateTexture(nil, "ARTWORK") + reqTex:SetAllPoints(reqBtn) + reqTex:SetTexture("Interface\\AddOns\\Guda\\Assets\\pin") + reqBtn.tex = reqTex + reqBtn.ruleIndex = index + reqBtn:SetScript("OnClick", function() + local idx = this.ruleIndex + if editorMatchMode == "all" then return end + if editorRules[idx] then + editorRules[idx].required = not editorRules[idx].required + Guda_CategoryEditor_UpdateRulesDisplay() + end + end) + reqBtn:SetScript("OnEnter", function() + GameTooltip:SetOwner(this, "ANCHOR_RIGHT") + GameTooltip:AddLine(Guda_L["Required rule"], 1, 0.82, 0) + GameTooltip:AddLine(Guda_L["Required rule tooltip"], 1, 1, 1, true) + GameTooltip:Show() + end) + reqBtn:SetScript("OnLeave", function() GameTooltip:Hide() end) + row.reqBtn = reqBtn + -- Rule type dropdown button local typeBtn = CreateFrame("Button", rowName .. "_TypeBtn", row, "UIPanelButtonTemplate") - typeBtn:SetWidth(120) + typeBtn:SetWidth(105) typeBtn:SetHeight(22) - typeBtn:SetPoint("LEFT", row, "LEFT", 0, 0) + typeBtn:SetPoint("LEFT", reqBtn, "RIGHT", 4, 0) typeBtn:SetText(Guda_L["Select Type"]) typeBtn.ruleIndex = index typeBtn:SetScript("OnClick", function() @@ -2849,6 +2885,23 @@ function Guda_CategoryEditor_UpdateRulesDisplay() row.valueBox.ruleIndex = ruleIndex row.valueBtn.ruleIndex = ruleIndex row.deleteBtn.ruleIndex = ruleIndex + if row.reqBtn then + row.reqBtn.ruleIndex = ruleIndex + if rule.required then + row.reqBtn.tex:SetVertexColor(1, 0.82, 0) + row.reqBtn.tex:SetDesaturated(nil) + else + row.reqBtn.tex:SetVertexColor(0.45, 0.45, 0.45) + row.reqBtn.tex:SetDesaturated(1) + end + if editorMatchMode == "all" then + row.reqBtn:Disable() + row.reqBtn.tex:SetAlpha(0.35) + else + row.reqBtn:Enable() + row.reqBtn.tex:SetAlpha(1) + end + end -- Set type button text local typeName = "Select Type" @@ -3137,7 +3190,11 @@ function Guda_CategoryEditor_Save() categoryDef.rules = {} for _, rule in ipairs(editorRules) do if rule.type and rule.type ~= "" then - table.insert(categoryDef.rules, { type = rule.type, value = rule.value }) + table.insert(categoryDef.rules, { + type = rule.type, + value = rule.value, + required = rule.required and true or nil, + }) end end