--- @type StdUi local StdUi = LibStub and LibStub('StdUi', true); if not StdUi then return end local module, version = 'EditBox', 9; if not StdUi:UpgradeNeeded(module, version) then return end; local pairs = pairs; local strlen = strlen; ---------------------------------------------------- --- SimpleEditBox ---------------------------------------------------- local SimpleEditBoxMethods = { SetFontSize = function(self, newSize) self:SetFont(self:GetFont(), newSize, self.stdUi.config.font.effect); end }; local SimpleEditBoxEvents = { OnEscapePressed = function (self) self:ClearFocus(); end } --- @return EditBox function StdUi:SimpleEditBox(parent, width, height, text) --- @type EditBox local editBox = CreateFrame('EditBox', nil, parent); editBox.stdUi = self; self:InitWidget(editBox); editBox:SetTextInsets(3, 3, 3, 3); editBox:SetFontObject(ChatFontNormal); editBox:SetAutoFocus(false); for k, v in pairs(SimpleEditBoxMethods) do editBox[k] = v; end for k, v in pairs(SimpleEditBoxEvents) do editBox:SetScript(k, v); end if text then editBox:SetText(text); end self:HookDisabledBackdrop(editBox); self:HookHoverBorder(editBox); self:ApplyBackdrop(editBox); self:SetObjSize(editBox, width, height); return editBox; end ---------------------------------------------------- --- ApplyPlaceholder ---------------------------------------------------- local ApplyPlaceholderOnTextChanged = function(self) if strlen(self:GetText()) > 0 then self.placeholder.icon:Hide(); self.placeholder.label:Hide(); else self.placeholder.icon:Show(); self.placeholder.label:Show(); end end function StdUi:ApplyPlaceholder(widget, placeholderText, icon, iconColor) widget.placeholder = {}; local label = self:Label(widget, placeholderText); self:SetTextColor(label, 'disabled'); widget.placeholder.label = label; if icon then local texture = self:Texture(widget, 14, 14, icon); local c = iconColor or self.config.font.color.disabled; texture:SetVertexColor(c.r, c.g, c.b, c.a); self:GlueLeft(texture, widget, 5, 0, true); self:GlueRight(label, texture, 2, 0); widget.placeholder.icon = texture; else self:GlueLeft(label, widget, 2, 0, true); end widget:HookScript('OnTextChanged', ApplyPlaceholderOnTextChanged); end ---------------------------------------------------- --- SearchEditBox ---------------------------------------------------- local SearchEditBoxOnTextChanged = function(self) if self.OnValueChanged then self:OnValueChanged(self:GetText()); end end function StdUi:SearchEditBox(parent, width, height, placeholderText) local editBox = self:SimpleEditBox(parent, width, height, ''); editBox:SetScript('OnTextChanged', SearchEditBoxOnTextChanged); self:ApplyPlaceholder(editBox, placeholderText, [[Interface\Common\UI-Searchbox-Icon]]); return editBox; end ---------------------------------------------------- --- SearchEditBox ---------------------------------------------------- local EditBoxMethods = { GetValue = function(self) return self.value; end, SetValue = function(self, value) self.value = value; self:SetText(value); self:Validate(); self.button:Hide(); end, IsValid = function(self) return self.isValid; end, Validate = function(self) self.isValidated = true; self.isValid = self.validator(self); if self.isValid then if self.button then self.button:Hide(); end if self.OnValueChanged and tostring(self.lastValue) ~= tostring(self.value) then self:OnValueChanged(self.value); self.lastValue = self.value; end end self.isValidated = false; end; } local EditBoxButtonOnClick = function(self) self.editBox:Validate(self.editBox); end local EditBoxEvents = { OnEnterPressed = function(self) self:Validate(); end, OnTextChanged = function(self, isUserInput) local value = StdUi.Util.stripColors(self:GetText()); if tostring(value) ~= tostring(self.value) then if not self.isValidated and self.button and isUserInput then self.button:Show(); end else self.button:Hide(); end end } --- @return EditBox function StdUi:EditBox(parent, width, height, text, validator) validator = validator or StdUi.Util.editBoxValidator; local editBox = self:SimpleEditBox(parent, width, height, text); editBox.validator = validator; local button = self:Button(editBox, 40, height - 4, OKAY); button:SetPoint('RIGHT', -2, 0); button:Hide(); button.editBox = editBox; editBox.button = button; for k, v in pairs(EditBoxMethods) do editBox[k] = v; end button:SetScript('OnClick', EditBoxButtonOnClick); for k, v in pairs(EditBoxEvents) do editBox:SetScript(k, v); end return editBox; end ---------------------------------------------------- --- SearchEditBox ---------------------------------------------------- local NumericBoxMethods = { SetMaxValue = function(self, value) self.maxValue = value; self:Validate(); end; SetMinValue = function(self, value) self.minValue = value; self:Validate(); end; SetMinMaxValue = function(self, min, max) self.minValue = min; self.maxValue = max; self:Validate(); end } function StdUi:NumericBox(parent, width, height, text, validator) validator = validator or self.Util.numericBoxValidator; local editBox = self:EditBox(parent, width, height, text, validator); editBox:SetNumeric(true); for k, v in pairs(NumericBoxMethods) do editBox[k] = v; end return editBox; end ---------------------------------------------------- --- MoneyBox ---------------------------------------------------- local MoneyBoxMethods = { SetValue = function(self, value) self.value = value; local formatted = self.stdUi.Util.formatMoney(value); self:SetText(formatted); self:Validate(); self.button:Hide(); end; }; function StdUi:MoneyBox(parent, width, height, text, validator, excludeCopper) if excludeCopper then validator = validator or self.Util.moneyBoxValidatorExC; else validator = validator or self.Util.moneyBoxValidator; end local editBox = self:EditBox(parent, width, height, text, validator); editBox.stdUi = self; editBox:SetMaxLetters(20); for k, v in pairs(MoneyBoxMethods) do editBox[k] = v; end return editBox; end ---------------------------------------------------- --- MultiLineBox ---------------------------------------------------- local MultiLineBoxMethods = { SetValue = function(self, value) self.editBox:SetText(value); if self.OnValueChanged then self:OnValueChanged(value); end end, GetValue = function(self) return self.editBox:GetText(); end, SetFont = function(self, font, size, flags) self.editBox:SetFont(font, size, flags); end, Enable = function(self) self.editBox:Enable(); end, Disable = function(self) self.editBox:Disable(); end, SetFocus = function(self) self.editBox:SetFocus(); end, ClearFocus = function(self) self.editBox:ClearFocus(); end, HasFocus = function(self) return self.editBox:HasFocus(); end }; local MultiLineBoxOnCursorChanged = function(self, _, y, _, cursorHeight) local sf, newY = self.scrollFrame, -y; local offset = sf:GetVerticalScroll(); if newY < offset then sf:SetVerticalScroll(newY); else newY = newY + cursorHeight - sf:GetHeight() + 6; --text insets if newY > offset then sf:SetVerticalScroll(math.ceil(newY)); end end end local MultiLineBoxOnTextChanged = function(self) if self.panel.OnValueChanged then self.panel.OnValueChanged(self.panel, self:GetText()); end end local MultiLineBoxScrollOnMouseDown = function(self, button) self.scrollChild:SetFocus(); end local MultiLineBoxScrollOnVerticalScroll = function(self, offset) self.scrollChild:SetHitRectInsets(0, 0, offset, self.scrollChild:GetHeight() - offset - self:GetHeight()); end function StdUi:MultiLineBox(parent, width, height, text) local editBox = CreateFrame('EditBox'); local widget = self:ScrollFrame(parent, width, height, editBox); editBox.stdUi = self; local scrollFrame = widget.scrollFrame; scrollFrame.editBox = editBox; widget.editBox = editBox; editBox.panel = widget; self:ApplyBackdrop(widget, 'button'); self:HookHoverBorder(scrollFrame); self:HookHoverBorder(editBox); editBox:SetWidth(scrollFrame:GetWidth()); self:GlueAcross(scrollFrame, widget, 2, -2, -widget.scrollBarWidth - 2, 3); --editBox:SetHeight(scrollFrame:GetHeight()); editBox:SetTextInsets(3, 3, 3, 3); editBox:SetFontObject(ChatFontNormal); editBox:SetAutoFocus(false); editBox:SetScript('OnEscapePressed', editBox.ClearFocus); editBox:SetMultiLine(true); editBox:EnableMouse(true); editBox:SetAutoFocus(false); editBox:SetCountInvisibleLetters(false); editBox:SetAllPoints(); editBox.scrollFrame = scrollFrame; editBox.panel = widget; for k, v in pairs(MultiLineBoxMethods) do widget[k] = v; end if text then editBox:SetText(text); end editBox:SetScript('OnCursorChanged', MultiLineBoxOnCursorChanged) editBox:SetScript('OnTextChanged', MultiLineBoxOnTextChanged); scrollFrame:HookScript('OnMouseDown', MultiLineBoxScrollOnMouseDown); scrollFrame:HookScript('OnVerticalScroll', MultiLineBoxScrollOnVerticalScroll); widget.SetText = widget.SetValue; widget.GetText = widget.GetValue; return widget; end StdUi:RegisterModule(module, version);