diff --git a/BlizzChatIntegration.lua b/BlizzChatIntegration.lua deleted file mode 100644 index a175441..0000000 --- a/BlizzChatIntegration.lua +++ /dev/null @@ -1,183 +0,0 @@ --- Author : Chrono --- Create Date : 3/30/2020 8:27:47 PM - -local ADDON_NAME, Import = ... - ---This is an invisible frame that is created to receive OnUpdate calls ---Attached to the WorldFrame so it receives events even when the UI is hidden -local Timer = CreateFrame("Frame","RPChatBubble-Timer",WorldFrame) -Timer:SetFrameStrata("TOOLTIP") -- higher strata is called last - ---Alias functions -Timer.Start = Timer.Show -Timer.Stop = function(self) - Timer:Hide() - Timer.elapsed = 0 -end - -Timer:Stop() - -local numBubbles = 0; -local messageToSender = {}; - -local MANAGED_CHANNELS = { - "CHAT_MSG_SAY", "CHAT_MSG_YELL", "CHAT_MSG_MONSTER_SAY", "CHAT_MSG_MONSTER_YELL" -}; - -local function getPadding(numSpaces) - local str = ">"; - for i=1,numSpaces,1 do - str = "-" .. str - end - return str -end - -local function printTable(t, depth) - local padding = getPadding(depth) - for key, value in pairs(t) do - if type(value) == "table" then - print(padding .. key .. " = (table):"); - printTable(value, depth + 1); - else - print(padding .. key .. " ("..type(value)..") = " .. tostring(value) ); - end - end -end - -local function getChatBubbleText(chatBubble) - for i = 1, chatBubble:GetNumRegions() do - local region = select(i, chatBubble:GetRegions()) - if region:GetObjectType() == "FontString" then - return region:GetText() - end - end -end - -local function getNamedPoint(chatBubble,pointName) - for i = 1, chatBubble:GetNumPoints() do - local point, relativeTo, relativePoint, xOfs, yOfs = chatBubble:GetPoint(i); - if point == pointName then - return relativeTo, relativePoint, xOfs, yOfs; - end - end -end - -local function skinBubble(chatBubble) - local message = getChatBubbleText(chatBubble); - local name = messageToSender[message] - - local NameText = CreateFrame("EditBox","BlizzBoxNameText",chatBubble); - NameText:SetFrameStrata("MEDIUM"); --This is the default but better to be explicit - --NameText:SetMultiLine(true); - NameText:SetAutoFocus(false); - --NameText:EnableMouse(false); - NameText:SetSize(700,11); - --NameText:SetPoint("CENTER"); - NameText:SetPoint("BOTTOMLEFT",chatBubble,"TOPLEFT",13,2); - NameText:SetFontObject("GameFontNormal"); - NameText:SetText(name); - --local tex = NameText:CreateTexture(nil,"ARTWORK"); - --tex:SetAllPoints() - --tex:SetTexture(255,255,255); - NameText.stringMeasure = NameText:CreateFontString(nil,"OVERLAY","GameFontNormal"); - NameText.stringMeasure:SetText(name); - - local NameBg = CreateFrame("Frame","BlizzBubbleNameBG",NameText); - NameBg:SetPoint("TOPLEFT",-1,14); - NameBg:SetPoint("BOTTOMLEFT",-1,-2); - NameBg:SetWidth(NameText.stringMeasure:GetStringWidth()); - NameBg:SetFrameStrata("BACKGROUND"); - - - local midTex = NameBg:CreateTexture("nameBoxBackgroundTex-middle","BACKGROUND"); - midTex:SetTexture("Interface/CHATFRAME/ChatFrameTab-BGMid.blp"); - midTex:SetPoint("TOPLEFT",8,0); - midTex:SetPoint("BOTTOMRIGHT",-7,0); - local leftTex = NameBg:CreateTexture("nameBoxBackgroundTex-left","BACKGROUND"); - leftTex:SetTexture("Interface/CHATFRAME/ChatFrameTab-BGLeft.blp"); - leftTex:SetPoint("TOPRIGHT",midTex,"TOPLEFT"); - leftTex:SetPoint("BOTTOMRIGHT",midTex,"BOTTOMLEFT"); - local rightTex = NameBg:CreateTexture("nameBoxBackgroundTex-right","BACKGROUND"); - rightTex:SetTexture("Interface/CHATFRAME/ChatFrameTab-BGRight.blp"); - rightTex:SetPoint("TOPLEFT",midTex,"TOPRIGHT"); - rightTex:SetPoint("BOTTOMLEFT",midTex,"BOTTOMRIGHT"); - - local relativeTo, relativePoint, xOfs, yOfs = getNamedPoint(chatBubble,"BOTTOMRIGHT"); - chatBubble.string = relativeTo; - chatBubble.defaultXOfs = xOfs; - chatBubble.fixWidth = function(self) - local nameWidth = NameText.stringMeasure:GetWidth(); - NameBg:SetWidth(nameWidth); - local stringWidth = self.string:GetStringWidth(); - local expectedWidth = stringWidth + 32; - local requiredWidthForName = nameWidth + 14 + 2 + 16; - local defaultXOfs = self.defaultXOfs; - local relativeTo, relativePoint, xOfs, yOfs = getNamedPoint(self,"BOTTOMRIGHT"); - local currHeight = self:GetHeight(); - if ( expectedWidth < requiredWidthForName ) then - local diff = requiredWidthForName - expectedWidth; - self:SetPoint("BOTTOMRIGHT",relativeTo,relativePoint,defaultXOfs+diff,yOfs); - else - self:SetPoint("BOTTOMRIGHT",relativeTo,relativePoint,defaultXOfs,yOfs); - end - end - chatBubble:fixWidth(); - - chatBubble.nameText = NameText; - chatBubble.SetName = function(self,text) - NameText:SetText(text) - NameText.stringMeasure:SetText(text); - self:fixWidth(); - end; - chatBubble.rpSkinned = true; - numBubbles = numBubbles + 1; -end - -local function checkBubbles(chatBubbles) - --chatBubbles is an indexed array of frames - for _, chatBubble in pairs(chatBubbles) do - if not chatBubble.rpSkinned then - skinBubble(chatBubble) - else - local message = getChatBubbleText(chatBubble) - chatBubble:SetName(messageToSender[message]) - end - end -end - -Timer:SetScript("OnUpdate", function(self, elapsed) - self.elapsed = self.elapsed + elapsed - -- 0.01 Seconds after the chat message happened... - if self.elapsed > 0.01 then - self:Stop(); - --This returns all chat bubbles created through default Blizz's UI. Custom chat bubbles aren't seen here - chatBubbles = C_ChatBubbles:GetAllChatBubbles() - checkBubbles(chatBubbles) - end -end) - -local function onChatMessage(_, event, message, sender, ...) - local name = GetColoredName(event, message, sender, ...); - messageToSender[message] = name; - --At the time of the chat event, the chat bubble hasn't been created yet. So we'll wait 0.01 seconds before looking for chat bubbles to skin. - Timer:Start(); - return false, message, sender, ... -end - -local function resetChatHandler(self) - for _, channel in pairs(MANAGED_CHANNELS) do - ChatFrame_RemoveMessageEventFilter(channel, onChatMessage) - ChatFrame_AddMessageEventFilter(channel, onChatMessage); - end -end - -local function onStart(self) - for _, channel in pairs(MANAGED_CHANNELS) do - ChatFrame_AddMessageEventFilter(channel, onChatMessage); - end -end - -Import.modules.BlizzChatIntegration = {}; -Import.modules.BlizzChatIntegration.name = "BlizzChatIntegration"; -Import.modules.BlizzChatIntegration.OnStart = onStart; -Import.modules.BlizzChatIntegration.ResetChatHandler = resetChatHandler \ No newline at end of file diff --git a/ChatBubblePool.lua b/ChatBubblePool.lua deleted file mode 100644 index e6ffcf6..0000000 --- a/ChatBubblePool.lua +++ /dev/null @@ -1,240 +0,0 @@ --- Author : Christopher Tse --- Create Date : 3/28/2020 1:37:28 PM - -local ADDON_NAME, Import = ...; - -local pool = {} - -Import.ChatBubblePool = {}; -local ChatBubblePool = Import.ChatBubblePool - -local function adjustChatBubbleWidth(chatBubble) - local editBox = chatBubble.editBox; - local strWidth = editBox.stringMeasure:GetStringWidth(); - local bg = editBox.background; - local padding = bg.padding; - local nameBox = chatBubble.nameBox - local nameBoxWidth = nameBox:GetFullWidth(); - local minWidth = 64; - if ( nameBoxWidth ~= nil) then - local nameBoxMargin = nameBox.margin.L + nameBox.margin.R; - minWidth = max(64, nameBoxWidth + nameBoxMargin); - end - local maxWidth = chatBubble:GetWidth() - if ( strWidth < minWidth ) then - bg:SetWidth(minWidth + padding) - elseif ( minWidth < strWidth and strWidth < maxWidth ) then - bg:SetWidth(strWidth + padding) - else - bg:SetWidth(maxWidth + padding ) - end -end - -local function adjustNameBoxWidth(chatBubble) - local nameBox = chatBubble.nameBox; - local nameBoxBg = nameBox.background; - local strWidth = nameBox.stringMeasure:GetStringWidth(); - local minWidth = 32; - local padding = nameBox.padding.L + nameBox.padding.R; - --The max width usually won't be reached because of the character limit on the name box - local maxWidth = chatBubble:GetWidth() - padding - nameBox.margin.L - if ( strWidth < minWidth ) then - nameBoxBg:SetWidth(minWidth + padding); - elseif ( minWidth < strWidth and strWidth < maxWidth ) then - nameBoxBg:SetWidth(strWidth + padding); - else - nameBoxBg:SetWidth(maxWidth + padding); - end -end - -local function pickNameColor(chatBubble) - local r, g, b = chatBubble:GetNameColor() - ColorPickerFrame:SetColorRGB(r,g,b); - ColorPickerFrame.hasOpacity = false; - ColorPickerFrame.func = function(self) chatBubble:SetNameColor(ColorPickerFrame:GetColorRGB()) end; - ColorPickerFrame.cancelFunc = function(self) chatBubble:SetNameColor(r,g,b) end; - ColorPickerFrame:Show(); -end - -local function closeBubble(chatBubble) - chatBubble:Hide(); - chatBubble:SetMessage(""); - chatBubble:SetName(""); - chatBubble.nameBox:SetAlpha(0.01) - chatBubble:ClearAllPoints(); - chatBubble:SetPoint("TOPLEFT",WorldFrame,"CENTER",-chatBubble.center.x,-chatBubble.center.y); - chatBubble.isAvailable = true; -end - -function ChatBubblePool.getChatBubble() - for index, chatBubble in ipairs(pool) do - if chatBubble.isAvailable then - chatBubble:Show() - chatBubble.isAvailable = false; - return chatBubble - end - end - - -- If we got here, there isn't any available chat bubble so create a new one - local frameName = "RPChatBubble" .. #pool - - local newChatBubble = CreateFrame("Frame",frameName,nil) - newChatBubble:SetWidth(300) - newChatBubble:SetHeight(300) - newChatBubble:SetMovable(true) - newChatBubble:SetFrameStrata("LOW") - newChatBubble.isAvailable = false - table.insert(pool, newChatBubble); - - --chatBubbleTail:EnableMouse(true) - --chatBubbleTail:SetMovable(true) - --chatBubbleTail:RegisterForDrag("LeftButton") - --chatBubbleTail:SetScript("OnDragStart", function(self) self:StartMoving() end) - --chatBubbleTail:SetScript("OnDragStop", function(self) self:StopMovingOrSizing() end) - - local editBox = CreateFrame("EditBox",frameName.."-EditBox",newChatBubble); - editBox:SetPoint("TOPLEFT",newChatBubble); - editBox:SetPoint("TOPRIGHT",newChatBubble); - editBox:SetMultiLine(true); - editBox:SetAutoFocus(false); - editBox:SetFontObject("ChatBubbleFont"); - editBox:SetScript("OnEnterPressed", function(self) self:ClearFocus() end); - editBox:SetScript("OnEscapePressed", function(self) self:ClearFocus() end); - --Apparently, the below code stops the user from being able to change the cursor location - --editBox:EnableMouse(true) - --editBox:SetScript("OnMouseDown", function(self) newChatBubble:StartMoving() end ) - --editBox:SetScript("OnMouseUp", function(self) newChatBubble:StopMovingOrSizing() end ) - - newChatBubble.editBox = editBox; - --This is a hack that centers the newChatBubble using the center of the editbox - newChatBubble.center = { x=editBox:GetWidth()/2, y=editBox:GetHeight()/2 }; - newChatBubble:SetPoint("TOPLEFT",WorldFrame,"CENTER",-newChatBubble.center.x,-newChatBubble.center.y); - - local chatBubbleBackground = CreateFrame("Frame",frameName.."Background",editBox); - chatBubbleBackground:SetBackdrop({ - bgFile="Interface\\Tooltips\\CHATBUBBLE-BACKGROUND.BLP", - edgeFile="Interface\\Tooltips\\CHATBUBBLE-BACKDROP.BLP", - tile=true, tileSize=16, edgeSize=16, - insets={left=16, right=16, top=16, bottom=16} - }) - chatBubbleBackground:EnableMouse(true) - chatBubbleBackground:SetPoint("TOPLEFT",editBox,"TOPLEFT",-16,16) - chatBubbleBackground:SetPoint("BOTTOMLEFT",editBox,"BOTTOMLEFT",-16,-16) - chatBubbleBackground.padding = 32; - chatBubbleBackground:SetWidth(64 + chatBubbleBackground.padding) - chatBubbleBackground:SetFrameStrata("BACKGROUND") - chatBubbleBackground:EnableMouse(true) - chatBubbleBackground:SetScript("OnMouseDown", function(self) newChatBubble:StartMoving() end ) - chatBubbleBackground:SetScript("OnMouseUp", function(self) newChatBubble:StopMovingOrSizing() end ) - editBox.background = chatBubbleBackground; - - --This part of the code makes the editbox and the background grow up to 300px as the text grows. - --We use an invisible FontString to measure the length of the text inside the edit box. - editBox.stringMeasure = editBox:CreateFontString(nil,"OVERLAY","ChatBubbleFont"); - editBox.stringMeasure:SetAlpha(0); - editBox:SetScript("OnTextChanged", function(self) - editBox.stringMeasure:SetText(self:GetText()); - adjustChatBubbleWidth(newChatBubble); - end) - - local closeButton = CreateFrame("Button",frameName.."-CloseButton",chatBubbleBackground,"UIPanelCloseButton") - closeButton:SetPoint("CENTER",chatBubbleBackground,"TOPRIGHT",-4,-4); - closeButton:SetScript("OnClick",function(self) closeBubble(newChatBubble) end); - closeButton:SetScript("OnEnter",function(self) closeButton:SetAlpha(1) end); - closeButton:SetScript("OnLeave",function(self) closeButton:SetAlpha(0.1) end); - closeButton:SetAlpha(0.1); - - local nameBoxFrame = CreateFrame("Frame",frameName.."-NameBoxFrame",newChatBubble) - nameBoxFrame:SetSize(250,18); - nameBoxFrame:SetPoint("BOTTOMLEFT",chatBubbleBackground,"TOPLEFT"); - - local nameBox = CreateFrame("EditBox",frameName.."-NameBox",nameBoxFrame); - nameBox:SetFontObject("GameFontNormal"); - nameBox:SetMaxLetters(25); - nameBox.margin = {L=10, R=0, T=4, D=4}; - nameBox.padding = {L=10, R=10}; - nameBox:SetPoint("TOPLEFT",nameBoxFrame,nameBox.margin.L,-nameBox.margin.T); - nameBox:SetPoint("BOTTOMRIGHT",nameBoxFrame,-nameBox.margin.R,nameBox.margin.D); - nameBox:SetAutoFocus(false); - nameBox:SetMultiLine(true); --It's not actually multiline, but this stops the name from scrolling off if the user selects too much of the text. - --The max letters should prevent the edit box from ever reaching more than one line - nameBox:SetScript("OnEnterPressed", function(self) self:ClearFocus() end); - nameBox:SetScript("OnTabPressed", function(self) editBox:SetFocus() end); - nameBox:SetAlpha(0); - nameBox:SetScript("OnEditFocusGained", function(self) self:SetAlpha(1) end); - nameBox:SetScript("OnEditFocusLost", function(self) if self:GetText() == "" then self:SetAlpha(0.01) end end); - newChatBubble.nameBox = nameBox; - - local nameBoxBackground = CreateFrame("Frame",frameName.."-NameBoxBackground",nameBox); - local paddingL = nameBox.padding.L; - nameBoxBackground:SetPoint("BOTTOMLEFT",nameBox,"BOTTOMLEFT",-paddingL,-nameBox.margin.D) - nameBoxBackground:SetPoint("TOPLEFT",nameBox,"TOPLEFT",-paddingL,nameBox.margin.T + 12); - nameBoxBackground:SetWidth(32); - nameBoxBackground:SetFrameStrata("BACKGROUND"); - nameBox.background = nameBoxBackground - - local nameBoxMouseCatcher = CreateFrame("Button",frameName.."-NameBoxMouseCatcher",nameBox); - nameBoxMouseCatcher:SetPoint("BOTTOMLEFT",nameBoxBackground); - nameBoxMouseCatcher:SetPoint("TOPRIGHT",nameBoxBackground); - nameBoxMouseCatcher:SetScript("OnEnter", function(self) if nameBox:GetText() == "" and not nameBox:HasFocus() then nameBox:SetAlpha(0.5) end end); - nameBoxMouseCatcher:SetScript("OnLeave", function(self) if nameBox:GetText() == "" and not nameBox:HasFocus() then nameBox:SetAlpha(0) end end); - nameBoxMouseCatcher:SetScript("OnClick", function(self) nameBox:SetFocus() end); - nameBoxMouseCatcher:SetScript("OnMouseDown", function(self) newChatBubble:StartMoving() end ) - nameBoxMouseCatcher:SetScript("OnMouseUp", function(self) newChatBubble:StopMovingOrSizing() end ) - - local nameBoxColorPicker = CreateFrame("Button",frameName.."-ColorPickerButton",newChatBubble); - nameBoxColorPicker:SetSize(16,16); - nameBoxColorPicker:SetFrameStrata("MEDIUM") -- Needs to be higher than the EditBox to override it - nameBox.colorPickerTex = nameBoxColorPicker:CreateTexture(frameName.."-ColorPickerButton-color","ARTWORK") - nameBox.colorPickerTex:SetPoint("TOPLEFT",2,-2); - nameBox.colorPickerTex:SetPoint("BOTTOMRIGHT",-2,2); - nameBox.colorPickerTex:SetColorTexture(nameBox:GetTextColor()); - local cpBorderTex = nameBoxColorPicker:CreateTexture(frameName.."-ColorPickerButton-border","BORDER"); - cpBorderTex:SetAllPoints(); - cpBorderTex:SetColorTexture(0.1,0.1,0.1); - nameBoxColorPicker:SetPoint("BOTTOMLEFT",nameBoxBackground,"BOTTOMRIGHT"); - nameBoxColorPicker:SetAlpha(0.01); - nameBoxColorPicker:EnableMouse(true); - nameBoxColorPicker:SetScript("OnEnter", function(self) if nameBox:GetText() ~= "" then self:SetAlpha(1); end; end); - nameBoxColorPicker:SetScript("OnLeave", function(self) self:SetAlpha(0.01) end); - nameBoxColorPicker:SetScript("OnClick", function(self) pickNameColor(newChatBubble) end); - - nameBox.stringMeasure = nameBox:CreateFontString(nil,"OVERLAY","GameFontNormal"); - --nameBox.stringMeasure:SetAlpha(0); - nameBox.GetFullWidth = function(self) return nameBoxBackground:GetWidth() end; - nameBox:SetScript("OnTextChanged", function(self) - nameBox.stringMeasure:SetText(self:GetText()); - adjustNameBoxWidth(newChatBubble) - adjustChatBubbleWidth(newChatBubble) - end); - - local midTex = nameBoxBackground:CreateTexture("nameBoxBackgroundTex-middle","BACKGROUND"); - midTex:SetTexture("Interface/CHATFRAME/ChatFrameTab-BGMid.blp"); - midTex:SetPoint("TOPLEFT",16,0); - midTex:SetPoint("BOTTOMRIGHT",-16,0); - local leftTex = nameBoxBackground:CreateTexture("nameBoxBackgroundTex-left","BACKGROUND"); - leftTex:SetTexture("Interface/CHATFRAME/ChatFrameTab-BGLeft.blp"); - leftTex:SetPoint("TOPRIGHT",midTex,"TOPLEFT"); - leftTex:SetPoint("BOTTOMRIGHT",midTex,"BOTTOMLEFT"); - local rightTex = nameBoxBackground:CreateTexture("nameBoxBackgroundTex-right","BACKGROUND"); - rightTex:SetTexture("Interface/CHATFRAME/ChatFrameTab-BGRight.blp"); - rightTex:SetPoint("TOPLEFT",midTex,"TOPRIGHT"); - rightTex:SetPoint("BOTTOMLEFT",midTex,"BOTTOMRIGHT"); - - local chatBubbleTail = CreateFrame("Frame",frameName.."-tail",chatBubbleBackground) - chatBubbleTail:SetBackdrop({ - bgFile="Interface\\Tooltips\\CHATBUBBLE-TAIL.BLP" - }) - chatBubbleTail:SetSize(16,16) - chatBubbleTail:SetPoint("TOPLEFT",chatBubbleBackground,"BOTTOMLEFT",8,3) - - --Functions for outside use - newChatBubble.GetName = nameBox.GetText; - newChatBubble.SetName = function(self,name) nameBox:SetText(name); if (name ~= "" ) then nameBox:SetAlpha(1); end; end; - newChatBubble.GetMessage = editBox.GetText; - newChatBubble.SetMessage = function(self,message) editBox:SetText(message) end; - newChatBubble.GetNameColor = function(self) return nameBox:GetTextColor() end; - newChatBubble.SetNameColor = function(self,r,g,b) nameBox:SetTextColor(r,g,b) nameBox.colorPickerTex:SetColorTexture(r,g,b) end; - - return newChatBubble -end \ No newline at end of file diff --git a/MainFrame.lua b/MainFrame.lua deleted file mode 100644 index 68547f9..0000000 --- a/MainFrame.lua +++ /dev/null @@ -1,33 +0,0 @@ --- Author : Christopher Tse --- Create Date : 3/28/2020 11:43:45 AM - -local ADDON_NAME, Import = ...; - -local mainFrame; -local ChatBubblePool = Import.ChatBubblePool - -function RPChatBubbles_createChatBubble() - return ChatBubblePool.getChatBubble() -end - -function RPChatBubbles_OnLoad(self, event,...) - self:SetClampedToScreen(true); - self:RegisterEvent("ADDON_LOADED"); -end - -function RPChatBubbles_OnEvent(self, event, ...) - if event == "ADDON_LOADED" and ... == ADDON_NAME then - self:RegisterForDrag("LeftButton"); - self:SetScript("OnDragStart", function(self) - self:StartMoving(); - end); - self:SetScript("OnDragStop", function(self) - self:StopMovingOrSizing(); - end); - for moduleName, moduleStructure in pairs(Import.modules) do - moduleStructure:OnStart(); - end - end -end - -Import.modules = {}; \ No newline at end of file diff --git a/MainFrame.xml b/MainFrame.xml deleted file mode 100644 index 45e7653..0000000 --- a/MainFrame.xml +++ /dev/null @@ -1,51 +0,0 @@ -<Ui xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.blizzard.com/wow/ui/"> - <Script file="MainFrame.lua" /> - <Script file="BlizzChatIntegration.lua" /> - <Script file="TotalRP3.lua" /> - <Frame name="MainFrame" parent="UIParent" toplevel="true" movable="true" enableMouse="true"> - <Size x="145" y="76" /> - <Anchors> - <Anchor point="CENTER" x="-28" y="29" /> - </Anchors> - <Backdrop bgFile="Interface\DialogFrame\UI-DialogBox-Background" edgeFile="Interface\DialogFrame\UI-DialogBox-Border" tile="true"> - <BackgroundInsets> - <AbsInset left="11" right="12" top="12" bottom="11" /> - </BackgroundInsets> - <TileSize> - <AbsValue val="32" /> - </TileSize> - <EdgeSize> - <AbsValue val="32" /> - </EdgeSize> - </Backdrop> - <Layers> - <Layer level="OVERLAY"> - <FontString inherits="GameFontNormal" text="RP Chat Bubbles"> - <Size x="112" y="20" /> - <Anchors> - <Anchor point="TOPLEFT" x="18" y="-14" /> - </Anchors> - </FontString> - </Layer> - </Layers> - <Frames> - <Button inherits="UIPanelButtonTemplate" text="Create"> - <Scripts> - <onClick function="RPChatBubbles_createChatBubble" /> - </Scripts> - <Size x="115" y="23" /> - <Anchors> - <Anchor point="TOPLEFT" x="15" y="-35" /> - </Anchors> - </Button> - </Frames> - <Scripts> - <OnLoad function="RPChatBubbles_OnLoad"> - - </OnLoad> - <OnEvent function="RPChatBubbles_OnEvent"> - - </OnEvent> - </Scripts> - </Frame> -</Ui> \ No newline at end of file diff --git a/RPChatBubbles/BlizzChatIntegration.lua b/RPChatBubbles/BlizzChatIntegration.lua new file mode 100644 index 0000000..a175441 --- /dev/null +++ b/RPChatBubbles/BlizzChatIntegration.lua @@ -0,0 +1,183 @@ +-- Author : Chrono +-- Create Date : 3/30/2020 8:27:47 PM + +local ADDON_NAME, Import = ... + +--This is an invisible frame that is created to receive OnUpdate calls +--Attached to the WorldFrame so it receives events even when the UI is hidden +local Timer = CreateFrame("Frame","RPChatBubble-Timer",WorldFrame) +Timer:SetFrameStrata("TOOLTIP") -- higher strata is called last + +--Alias functions +Timer.Start = Timer.Show +Timer.Stop = function(self) + Timer:Hide() + Timer.elapsed = 0 +end + +Timer:Stop() + +local numBubbles = 0; +local messageToSender = {}; + +local MANAGED_CHANNELS = { + "CHAT_MSG_SAY", "CHAT_MSG_YELL", "CHAT_MSG_MONSTER_SAY", "CHAT_MSG_MONSTER_YELL" +}; + +local function getPadding(numSpaces) + local str = ">"; + for i=1,numSpaces,1 do + str = "-" .. str + end + return str +end + +local function printTable(t, depth) + local padding = getPadding(depth) + for key, value in pairs(t) do + if type(value) == "table" then + print(padding .. key .. " = (table):"); + printTable(value, depth + 1); + else + print(padding .. key .. " ("..type(value)..") = " .. tostring(value) ); + end + end +end + +local function getChatBubbleText(chatBubble) + for i = 1, chatBubble:GetNumRegions() do + local region = select(i, chatBubble:GetRegions()) + if region:GetObjectType() == "FontString" then + return region:GetText() + end + end +end + +local function getNamedPoint(chatBubble,pointName) + for i = 1, chatBubble:GetNumPoints() do + local point, relativeTo, relativePoint, xOfs, yOfs = chatBubble:GetPoint(i); + if point == pointName then + return relativeTo, relativePoint, xOfs, yOfs; + end + end +end + +local function skinBubble(chatBubble) + local message = getChatBubbleText(chatBubble); + local name = messageToSender[message] + + local NameText = CreateFrame("EditBox","BlizzBoxNameText",chatBubble); + NameText:SetFrameStrata("MEDIUM"); --This is the default but better to be explicit + --NameText:SetMultiLine(true); + NameText:SetAutoFocus(false); + --NameText:EnableMouse(false); + NameText:SetSize(700,11); + --NameText:SetPoint("CENTER"); + NameText:SetPoint("BOTTOMLEFT",chatBubble,"TOPLEFT",13,2); + NameText:SetFontObject("GameFontNormal"); + NameText:SetText(name); + --local tex = NameText:CreateTexture(nil,"ARTWORK"); + --tex:SetAllPoints() + --tex:SetTexture(255,255,255); + NameText.stringMeasure = NameText:CreateFontString(nil,"OVERLAY","GameFontNormal"); + NameText.stringMeasure:SetText(name); + + local NameBg = CreateFrame("Frame","BlizzBubbleNameBG",NameText); + NameBg:SetPoint("TOPLEFT",-1,14); + NameBg:SetPoint("BOTTOMLEFT",-1,-2); + NameBg:SetWidth(NameText.stringMeasure:GetStringWidth()); + NameBg:SetFrameStrata("BACKGROUND"); + + + local midTex = NameBg:CreateTexture("nameBoxBackgroundTex-middle","BACKGROUND"); + midTex:SetTexture("Interface/CHATFRAME/ChatFrameTab-BGMid.blp"); + midTex:SetPoint("TOPLEFT",8,0); + midTex:SetPoint("BOTTOMRIGHT",-7,0); + local leftTex = NameBg:CreateTexture("nameBoxBackgroundTex-left","BACKGROUND"); + leftTex:SetTexture("Interface/CHATFRAME/ChatFrameTab-BGLeft.blp"); + leftTex:SetPoint("TOPRIGHT",midTex,"TOPLEFT"); + leftTex:SetPoint("BOTTOMRIGHT",midTex,"BOTTOMLEFT"); + local rightTex = NameBg:CreateTexture("nameBoxBackgroundTex-right","BACKGROUND"); + rightTex:SetTexture("Interface/CHATFRAME/ChatFrameTab-BGRight.blp"); + rightTex:SetPoint("TOPLEFT",midTex,"TOPRIGHT"); + rightTex:SetPoint("BOTTOMLEFT",midTex,"BOTTOMRIGHT"); + + local relativeTo, relativePoint, xOfs, yOfs = getNamedPoint(chatBubble,"BOTTOMRIGHT"); + chatBubble.string = relativeTo; + chatBubble.defaultXOfs = xOfs; + chatBubble.fixWidth = function(self) + local nameWidth = NameText.stringMeasure:GetWidth(); + NameBg:SetWidth(nameWidth); + local stringWidth = self.string:GetStringWidth(); + local expectedWidth = stringWidth + 32; + local requiredWidthForName = nameWidth + 14 + 2 + 16; + local defaultXOfs = self.defaultXOfs; + local relativeTo, relativePoint, xOfs, yOfs = getNamedPoint(self,"BOTTOMRIGHT"); + local currHeight = self:GetHeight(); + if ( expectedWidth < requiredWidthForName ) then + local diff = requiredWidthForName - expectedWidth; + self:SetPoint("BOTTOMRIGHT",relativeTo,relativePoint,defaultXOfs+diff,yOfs); + else + self:SetPoint("BOTTOMRIGHT",relativeTo,relativePoint,defaultXOfs,yOfs); + end + end + chatBubble:fixWidth(); + + chatBubble.nameText = NameText; + chatBubble.SetName = function(self,text) + NameText:SetText(text) + NameText.stringMeasure:SetText(text); + self:fixWidth(); + end; + chatBubble.rpSkinned = true; + numBubbles = numBubbles + 1; +end + +local function checkBubbles(chatBubbles) + --chatBubbles is an indexed array of frames + for _, chatBubble in pairs(chatBubbles) do + if not chatBubble.rpSkinned then + skinBubble(chatBubble) + else + local message = getChatBubbleText(chatBubble) + chatBubble:SetName(messageToSender[message]) + end + end +end + +Timer:SetScript("OnUpdate", function(self, elapsed) + self.elapsed = self.elapsed + elapsed + -- 0.01 Seconds after the chat message happened... + if self.elapsed > 0.01 then + self:Stop(); + --This returns all chat bubbles created through default Blizz's UI. Custom chat bubbles aren't seen here + chatBubbles = C_ChatBubbles:GetAllChatBubbles() + checkBubbles(chatBubbles) + end +end) + +local function onChatMessage(_, event, message, sender, ...) + local name = GetColoredName(event, message, sender, ...); + messageToSender[message] = name; + --At the time of the chat event, the chat bubble hasn't been created yet. So we'll wait 0.01 seconds before looking for chat bubbles to skin. + Timer:Start(); + return false, message, sender, ... +end + +local function resetChatHandler(self) + for _, channel in pairs(MANAGED_CHANNELS) do + ChatFrame_RemoveMessageEventFilter(channel, onChatMessage) + ChatFrame_AddMessageEventFilter(channel, onChatMessage); + end +end + +local function onStart(self) + for _, channel in pairs(MANAGED_CHANNELS) do + ChatFrame_AddMessageEventFilter(channel, onChatMessage); + end +end + +Import.modules.BlizzChatIntegration = {}; +Import.modules.BlizzChatIntegration.name = "BlizzChatIntegration"; +Import.modules.BlizzChatIntegration.OnStart = onStart; +Import.modules.BlizzChatIntegration.ResetChatHandler = resetChatHandler \ No newline at end of file diff --git a/RPChatBubbles/ChatBubblePool.lua b/RPChatBubbles/ChatBubblePool.lua new file mode 100644 index 0000000..e6ffcf6 --- /dev/null +++ b/RPChatBubbles/ChatBubblePool.lua @@ -0,0 +1,240 @@ +-- Author : Christopher Tse +-- Create Date : 3/28/2020 1:37:28 PM + +local ADDON_NAME, Import = ...; + +local pool = {} + +Import.ChatBubblePool = {}; +local ChatBubblePool = Import.ChatBubblePool + +local function adjustChatBubbleWidth(chatBubble) + local editBox = chatBubble.editBox; + local strWidth = editBox.stringMeasure:GetStringWidth(); + local bg = editBox.background; + local padding = bg.padding; + local nameBox = chatBubble.nameBox + local nameBoxWidth = nameBox:GetFullWidth(); + local minWidth = 64; + if ( nameBoxWidth ~= nil) then + local nameBoxMargin = nameBox.margin.L + nameBox.margin.R; + minWidth = max(64, nameBoxWidth + nameBoxMargin); + end + local maxWidth = chatBubble:GetWidth() + if ( strWidth < minWidth ) then + bg:SetWidth(minWidth + padding) + elseif ( minWidth < strWidth and strWidth < maxWidth ) then + bg:SetWidth(strWidth + padding) + else + bg:SetWidth(maxWidth + padding ) + end +end + +local function adjustNameBoxWidth(chatBubble) + local nameBox = chatBubble.nameBox; + local nameBoxBg = nameBox.background; + local strWidth = nameBox.stringMeasure:GetStringWidth(); + local minWidth = 32; + local padding = nameBox.padding.L + nameBox.padding.R; + --The max width usually won't be reached because of the character limit on the name box + local maxWidth = chatBubble:GetWidth() - padding - nameBox.margin.L + if ( strWidth < minWidth ) then + nameBoxBg:SetWidth(minWidth + padding); + elseif ( minWidth < strWidth and strWidth < maxWidth ) then + nameBoxBg:SetWidth(strWidth + padding); + else + nameBoxBg:SetWidth(maxWidth + padding); + end +end + +local function pickNameColor(chatBubble) + local r, g, b = chatBubble:GetNameColor() + ColorPickerFrame:SetColorRGB(r,g,b); + ColorPickerFrame.hasOpacity = false; + ColorPickerFrame.func = function(self) chatBubble:SetNameColor(ColorPickerFrame:GetColorRGB()) end; + ColorPickerFrame.cancelFunc = function(self) chatBubble:SetNameColor(r,g,b) end; + ColorPickerFrame:Show(); +end + +local function closeBubble(chatBubble) + chatBubble:Hide(); + chatBubble:SetMessage(""); + chatBubble:SetName(""); + chatBubble.nameBox:SetAlpha(0.01) + chatBubble:ClearAllPoints(); + chatBubble:SetPoint("TOPLEFT",WorldFrame,"CENTER",-chatBubble.center.x,-chatBubble.center.y); + chatBubble.isAvailable = true; +end + +function ChatBubblePool.getChatBubble() + for index, chatBubble in ipairs(pool) do + if chatBubble.isAvailable then + chatBubble:Show() + chatBubble.isAvailable = false; + return chatBubble + end + end + + -- If we got here, there isn't any available chat bubble so create a new one + local frameName = "RPChatBubble" .. #pool + + local newChatBubble = CreateFrame("Frame",frameName,nil) + newChatBubble:SetWidth(300) + newChatBubble:SetHeight(300) + newChatBubble:SetMovable(true) + newChatBubble:SetFrameStrata("LOW") + newChatBubble.isAvailable = false + table.insert(pool, newChatBubble); + + --chatBubbleTail:EnableMouse(true) + --chatBubbleTail:SetMovable(true) + --chatBubbleTail:RegisterForDrag("LeftButton") + --chatBubbleTail:SetScript("OnDragStart", function(self) self:StartMoving() end) + --chatBubbleTail:SetScript("OnDragStop", function(self) self:StopMovingOrSizing() end) + + local editBox = CreateFrame("EditBox",frameName.."-EditBox",newChatBubble); + editBox:SetPoint("TOPLEFT",newChatBubble); + editBox:SetPoint("TOPRIGHT",newChatBubble); + editBox:SetMultiLine(true); + editBox:SetAutoFocus(false); + editBox:SetFontObject("ChatBubbleFont"); + editBox:SetScript("OnEnterPressed", function(self) self:ClearFocus() end); + editBox:SetScript("OnEscapePressed", function(self) self:ClearFocus() end); + --Apparently, the below code stops the user from being able to change the cursor location + --editBox:EnableMouse(true) + --editBox:SetScript("OnMouseDown", function(self) newChatBubble:StartMoving() end ) + --editBox:SetScript("OnMouseUp", function(self) newChatBubble:StopMovingOrSizing() end ) + + newChatBubble.editBox = editBox; + --This is a hack that centers the newChatBubble using the center of the editbox + newChatBubble.center = { x=editBox:GetWidth()/2, y=editBox:GetHeight()/2 }; + newChatBubble:SetPoint("TOPLEFT",WorldFrame,"CENTER",-newChatBubble.center.x,-newChatBubble.center.y); + + local chatBubbleBackground = CreateFrame("Frame",frameName.."Background",editBox); + chatBubbleBackground:SetBackdrop({ + bgFile="Interface\\Tooltips\\CHATBUBBLE-BACKGROUND.BLP", + edgeFile="Interface\\Tooltips\\CHATBUBBLE-BACKDROP.BLP", + tile=true, tileSize=16, edgeSize=16, + insets={left=16, right=16, top=16, bottom=16} + }) + chatBubbleBackground:EnableMouse(true) + chatBubbleBackground:SetPoint("TOPLEFT",editBox,"TOPLEFT",-16,16) + chatBubbleBackground:SetPoint("BOTTOMLEFT",editBox,"BOTTOMLEFT",-16,-16) + chatBubbleBackground.padding = 32; + chatBubbleBackground:SetWidth(64 + chatBubbleBackground.padding) + chatBubbleBackground:SetFrameStrata("BACKGROUND") + chatBubbleBackground:EnableMouse(true) + chatBubbleBackground:SetScript("OnMouseDown", function(self) newChatBubble:StartMoving() end ) + chatBubbleBackground:SetScript("OnMouseUp", function(self) newChatBubble:StopMovingOrSizing() end ) + editBox.background = chatBubbleBackground; + + --This part of the code makes the editbox and the background grow up to 300px as the text grows. + --We use an invisible FontString to measure the length of the text inside the edit box. + editBox.stringMeasure = editBox:CreateFontString(nil,"OVERLAY","ChatBubbleFont"); + editBox.stringMeasure:SetAlpha(0); + editBox:SetScript("OnTextChanged", function(self) + editBox.stringMeasure:SetText(self:GetText()); + adjustChatBubbleWidth(newChatBubble); + end) + + local closeButton = CreateFrame("Button",frameName.."-CloseButton",chatBubbleBackground,"UIPanelCloseButton") + closeButton:SetPoint("CENTER",chatBubbleBackground,"TOPRIGHT",-4,-4); + closeButton:SetScript("OnClick",function(self) closeBubble(newChatBubble) end); + closeButton:SetScript("OnEnter",function(self) closeButton:SetAlpha(1) end); + closeButton:SetScript("OnLeave",function(self) closeButton:SetAlpha(0.1) end); + closeButton:SetAlpha(0.1); + + local nameBoxFrame = CreateFrame("Frame",frameName.."-NameBoxFrame",newChatBubble) + nameBoxFrame:SetSize(250,18); + nameBoxFrame:SetPoint("BOTTOMLEFT",chatBubbleBackground,"TOPLEFT"); + + local nameBox = CreateFrame("EditBox",frameName.."-NameBox",nameBoxFrame); + nameBox:SetFontObject("GameFontNormal"); + nameBox:SetMaxLetters(25); + nameBox.margin = {L=10, R=0, T=4, D=4}; + nameBox.padding = {L=10, R=10}; + nameBox:SetPoint("TOPLEFT",nameBoxFrame,nameBox.margin.L,-nameBox.margin.T); + nameBox:SetPoint("BOTTOMRIGHT",nameBoxFrame,-nameBox.margin.R,nameBox.margin.D); + nameBox:SetAutoFocus(false); + nameBox:SetMultiLine(true); --It's not actually multiline, but this stops the name from scrolling off if the user selects too much of the text. + --The max letters should prevent the edit box from ever reaching more than one line + nameBox:SetScript("OnEnterPressed", function(self) self:ClearFocus() end); + nameBox:SetScript("OnTabPressed", function(self) editBox:SetFocus() end); + nameBox:SetAlpha(0); + nameBox:SetScript("OnEditFocusGained", function(self) self:SetAlpha(1) end); + nameBox:SetScript("OnEditFocusLost", function(self) if self:GetText() == "" then self:SetAlpha(0.01) end end); + newChatBubble.nameBox = nameBox; + + local nameBoxBackground = CreateFrame("Frame",frameName.."-NameBoxBackground",nameBox); + local paddingL = nameBox.padding.L; + nameBoxBackground:SetPoint("BOTTOMLEFT",nameBox,"BOTTOMLEFT",-paddingL,-nameBox.margin.D) + nameBoxBackground:SetPoint("TOPLEFT",nameBox,"TOPLEFT",-paddingL,nameBox.margin.T + 12); + nameBoxBackground:SetWidth(32); + nameBoxBackground:SetFrameStrata("BACKGROUND"); + nameBox.background = nameBoxBackground + + local nameBoxMouseCatcher = CreateFrame("Button",frameName.."-NameBoxMouseCatcher",nameBox); + nameBoxMouseCatcher:SetPoint("BOTTOMLEFT",nameBoxBackground); + nameBoxMouseCatcher:SetPoint("TOPRIGHT",nameBoxBackground); + nameBoxMouseCatcher:SetScript("OnEnter", function(self) if nameBox:GetText() == "" and not nameBox:HasFocus() then nameBox:SetAlpha(0.5) end end); + nameBoxMouseCatcher:SetScript("OnLeave", function(self) if nameBox:GetText() == "" and not nameBox:HasFocus() then nameBox:SetAlpha(0) end end); + nameBoxMouseCatcher:SetScript("OnClick", function(self) nameBox:SetFocus() end); + nameBoxMouseCatcher:SetScript("OnMouseDown", function(self) newChatBubble:StartMoving() end ) + nameBoxMouseCatcher:SetScript("OnMouseUp", function(self) newChatBubble:StopMovingOrSizing() end ) + + local nameBoxColorPicker = CreateFrame("Button",frameName.."-ColorPickerButton",newChatBubble); + nameBoxColorPicker:SetSize(16,16); + nameBoxColorPicker:SetFrameStrata("MEDIUM") -- Needs to be higher than the EditBox to override it + nameBox.colorPickerTex = nameBoxColorPicker:CreateTexture(frameName.."-ColorPickerButton-color","ARTWORK") + nameBox.colorPickerTex:SetPoint("TOPLEFT",2,-2); + nameBox.colorPickerTex:SetPoint("BOTTOMRIGHT",-2,2); + nameBox.colorPickerTex:SetColorTexture(nameBox:GetTextColor()); + local cpBorderTex = nameBoxColorPicker:CreateTexture(frameName.."-ColorPickerButton-border","BORDER"); + cpBorderTex:SetAllPoints(); + cpBorderTex:SetColorTexture(0.1,0.1,0.1); + nameBoxColorPicker:SetPoint("BOTTOMLEFT",nameBoxBackground,"BOTTOMRIGHT"); + nameBoxColorPicker:SetAlpha(0.01); + nameBoxColorPicker:EnableMouse(true); + nameBoxColorPicker:SetScript("OnEnter", function(self) if nameBox:GetText() ~= "" then self:SetAlpha(1); end; end); + nameBoxColorPicker:SetScript("OnLeave", function(self) self:SetAlpha(0.01) end); + nameBoxColorPicker:SetScript("OnClick", function(self) pickNameColor(newChatBubble) end); + + nameBox.stringMeasure = nameBox:CreateFontString(nil,"OVERLAY","GameFontNormal"); + --nameBox.stringMeasure:SetAlpha(0); + nameBox.GetFullWidth = function(self) return nameBoxBackground:GetWidth() end; + nameBox:SetScript("OnTextChanged", function(self) + nameBox.stringMeasure:SetText(self:GetText()); + adjustNameBoxWidth(newChatBubble) + adjustChatBubbleWidth(newChatBubble) + end); + + local midTex = nameBoxBackground:CreateTexture("nameBoxBackgroundTex-middle","BACKGROUND"); + midTex:SetTexture("Interface/CHATFRAME/ChatFrameTab-BGMid.blp"); + midTex:SetPoint("TOPLEFT",16,0); + midTex:SetPoint("BOTTOMRIGHT",-16,0); + local leftTex = nameBoxBackground:CreateTexture("nameBoxBackgroundTex-left","BACKGROUND"); + leftTex:SetTexture("Interface/CHATFRAME/ChatFrameTab-BGLeft.blp"); + leftTex:SetPoint("TOPRIGHT",midTex,"TOPLEFT"); + leftTex:SetPoint("BOTTOMRIGHT",midTex,"BOTTOMLEFT"); + local rightTex = nameBoxBackground:CreateTexture("nameBoxBackgroundTex-right","BACKGROUND"); + rightTex:SetTexture("Interface/CHATFRAME/ChatFrameTab-BGRight.blp"); + rightTex:SetPoint("TOPLEFT",midTex,"TOPRIGHT"); + rightTex:SetPoint("BOTTOMLEFT",midTex,"BOTTOMRIGHT"); + + local chatBubbleTail = CreateFrame("Frame",frameName.."-tail",chatBubbleBackground) + chatBubbleTail:SetBackdrop({ + bgFile="Interface\\Tooltips\\CHATBUBBLE-TAIL.BLP" + }) + chatBubbleTail:SetSize(16,16) + chatBubbleTail:SetPoint("TOPLEFT",chatBubbleBackground,"BOTTOMLEFT",8,3) + + --Functions for outside use + newChatBubble.GetName = nameBox.GetText; + newChatBubble.SetName = function(self,name) nameBox:SetText(name); if (name ~= "" ) then nameBox:SetAlpha(1); end; end; + newChatBubble.GetMessage = editBox.GetText; + newChatBubble.SetMessage = function(self,message) editBox:SetText(message) end; + newChatBubble.GetNameColor = function(self) return nameBox:GetTextColor() end; + newChatBubble.SetNameColor = function(self,r,g,b) nameBox:SetTextColor(r,g,b) nameBox.colorPickerTex:SetColorTexture(r,g,b) end; + + return newChatBubble +end \ No newline at end of file diff --git a/RPChatBubbles/MainFrame.lua b/RPChatBubbles/MainFrame.lua new file mode 100644 index 0000000..68547f9 --- /dev/null +++ b/RPChatBubbles/MainFrame.lua @@ -0,0 +1,33 @@ +-- Author : Christopher Tse +-- Create Date : 3/28/2020 11:43:45 AM + +local ADDON_NAME, Import = ...; + +local mainFrame; +local ChatBubblePool = Import.ChatBubblePool + +function RPChatBubbles_createChatBubble() + return ChatBubblePool.getChatBubble() +end + +function RPChatBubbles_OnLoad(self, event,...) + self:SetClampedToScreen(true); + self:RegisterEvent("ADDON_LOADED"); +end + +function RPChatBubbles_OnEvent(self, event, ...) + if event == "ADDON_LOADED" and ... == ADDON_NAME then + self:RegisterForDrag("LeftButton"); + self:SetScript("OnDragStart", function(self) + self:StartMoving(); + end); + self:SetScript("OnDragStop", function(self) + self:StopMovingOrSizing(); + end); + for moduleName, moduleStructure in pairs(Import.modules) do + moduleStructure:OnStart(); + end + end +end + +Import.modules = {}; \ No newline at end of file diff --git a/RPChatBubbles/MainFrame.xml b/RPChatBubbles/MainFrame.xml new file mode 100644 index 0000000..45e7653 --- /dev/null +++ b/RPChatBubbles/MainFrame.xml @@ -0,0 +1,51 @@ +<Ui xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.blizzard.com/wow/ui/"> + <Script file="MainFrame.lua" /> + <Script file="BlizzChatIntegration.lua" /> + <Script file="TotalRP3.lua" /> + <Frame name="MainFrame" parent="UIParent" toplevel="true" movable="true" enableMouse="true"> + <Size x="145" y="76" /> + <Anchors> + <Anchor point="CENTER" x="-28" y="29" /> + </Anchors> + <Backdrop bgFile="Interface\DialogFrame\UI-DialogBox-Background" edgeFile="Interface\DialogFrame\UI-DialogBox-Border" tile="true"> + <BackgroundInsets> + <AbsInset left="11" right="12" top="12" bottom="11" /> + </BackgroundInsets> + <TileSize> + <AbsValue val="32" /> + </TileSize> + <EdgeSize> + <AbsValue val="32" /> + </EdgeSize> + </Backdrop> + <Layers> + <Layer level="OVERLAY"> + <FontString inherits="GameFontNormal" text="RP Chat Bubbles"> + <Size x="112" y="20" /> + <Anchors> + <Anchor point="TOPLEFT" x="18" y="-14" /> + </Anchors> + </FontString> + </Layer> + </Layers> + <Frames> + <Button inherits="UIPanelButtonTemplate" text="Create"> + <Scripts> + <onClick function="RPChatBubbles_createChatBubble" /> + </Scripts> + <Size x="115" y="23" /> + <Anchors> + <Anchor point="TOPLEFT" x="15" y="-35" /> + </Anchors> + </Button> + </Frames> + <Scripts> + <OnLoad function="RPChatBubbles_OnLoad"> + + </OnLoad> + <OnEvent function="RPChatBubbles_OnEvent"> + + </OnEvent> + </Scripts> + </Frame> +</Ui> \ No newline at end of file diff --git a/RPChatBubbles/RoleplayChatBubbles.toc b/RPChatBubbles/RoleplayChatBubbles.toc new file mode 100644 index 0000000..6d40004 --- /dev/null +++ b/RPChatBubbles/RoleplayChatBubbles.toc @@ -0,0 +1,8 @@ +## Title: RoleplayChatBubbles +## Version: 1.0 +## Author: Christopher Tse +## Interface: 80300 +## OptionalDeps: totalRP3 + +ChatBubblePool.lua +MainFrame.xml diff --git a/RPChatBubbles/TotalRP3.lua b/RPChatBubbles/TotalRP3.lua new file mode 100644 index 0000000..125fe11 --- /dev/null +++ b/RPChatBubbles/TotalRP3.lua @@ -0,0 +1,108 @@ +-- Author : Chrono +-- Create Date : 3/29/2020 4:39:46 PM + + +local _, Import = ...; + +local ellyb, loc, Color, ColorManager; +local NPC_TALK_PATTERNS; + + +local function makeBubbleForNPCChat(_, event, message, ...) + if event == "CHAT_MSG_EMOTE" then + local npcName = TRP3_API.chat.getNPCMessageName() + if npcName then + for talkType, talkChannel in pairs(NPC_TALK_PATTERNS) do + if message:find(talkType) then + local color; + local myMessage = message; + local normalColor = ColorManager.getChatColorForChannel(talkChannel); + local normalColorAsString = normalColor:GetColorCodeStartSequence(); + local nameColor; + + --Detect colour alterations + if myMessage:sub(1,2) == "|c" then + color = myMessage:sub(1,10); --Save this to prepend back later + myMessage = myMessage:sub(11); + end + + --If the name is in the default color scheme, remove it for titling emphasis + if npcName:sub(1,10) ~= normalColorAsString then + nameColor = Color.static.CreateFromHexa(npcName:sub(1,10)); + end + npcName = npcName:sub(11); + + local len = talkType:len(); + --Remove the "says:" from the beginning of the message. + if myMessage:sub(1, len) == talkType then + local actualMessage = myMessage:sub(len+1); + + --Remove leading spaces if any + if actualMessage:sub(1,1) == " " then + actualMessage = actualMessage:sub(2); + end + + actualMessage = color .. actualMessage; + local chatBubble = RPChatBubbles_createChatBubble() + print("NPC Talk Found! npcName="..npcName); + chatBubble:SetName(npcName); + chatBubble:SetMessage(actualMessage); + if nameColor then + chatBubble:SetNameColor(nameColor:GetRGBA()) + end + end + break; + end + end + end + end + return false, message, ... +end + +function initTRP3Vars(self) + ellyb = TRP3_API.Ellyb; + loc = TRP3_API.loc; + Color = ellyb.Color; + ColorManager = ellyb.ColorManager; + NPC_TALK_PATTERNS = { + [loc.NPC_TALK_SAY_PATTERN] = "MONSTER_SAY", + [loc.NPC_TALK_YELL_PATTERN] = "MONSTER_YELL", + [loc.NPC_TALK_WHISPER_PATTERN] = "MONSTER_WHISPER", + }; +end + +function TotalRP3_onStart(self) + if TRP3_API then + initTRP3Vars(); + for _, channel in pairs(POSSIBLE_CHANNELS) do + ChatFrame_RemoveMessageEventFilter(channel, makeBubbleForNPCChat); + ChatFrame_AddMessageEventFilter(channel, makeBubbleForNPCChat); + end + Import.modules.BlizzChatIntegration:ResetChatHandler() + end +end + +--Import.modules["TotalRP3"] = { +-- name="TotalRP3", +-- onStart = TotalRP3_onStart; +--} + +POSSIBLE_CHANNELS = { + "CHAT_MSG_SAY", "CHAT_MSG_YELL", "CHAT_MSG_EMOTE", "CHAT_MSG_TEXT_EMOTE", + "CHAT_MSG_PARTY", "CHAT_MSG_PARTY_LEADER", "CHAT_MSG_RAID", "CHAT_MSG_RAID_LEADER", + "CHAT_MSG_GUILD", "CHAT_MSG_OFFICER", "CHAT_MSG_WHISPER", "CHAT_MSG_WHISPER_INFORM" +}; + + +local MODULE_STRUCTURE = { + ["name"] = "Roleplay Chat Bubbles", + ["description"] = "Module for integrating TotalRP3's chatframe system with Roleplay Chat Bubbles.", + ["version"] = 1.000, + ["id"] = "rp_chatBubbles", + ["onStart"] = TotalRP3_onStart, + ["minVersion"] = 3, +}; + +if TRP3_API then + TRP3_API.module.registerModule(MODULE_STRUCTURE); +end diff --git a/TotalRP3.lua b/TotalRP3.lua deleted file mode 100644 index 125fe11..0000000 --- a/TotalRP3.lua +++ /dev/null @@ -1,108 +0,0 @@ --- Author : Chrono --- Create Date : 3/29/2020 4:39:46 PM - - -local _, Import = ...; - -local ellyb, loc, Color, ColorManager; -local NPC_TALK_PATTERNS; - - -local function makeBubbleForNPCChat(_, event, message, ...) - if event == "CHAT_MSG_EMOTE" then - local npcName = TRP3_API.chat.getNPCMessageName() - if npcName then - for talkType, talkChannel in pairs(NPC_TALK_PATTERNS) do - if message:find(talkType) then - local color; - local myMessage = message; - local normalColor = ColorManager.getChatColorForChannel(talkChannel); - local normalColorAsString = normalColor:GetColorCodeStartSequence(); - local nameColor; - - --Detect colour alterations - if myMessage:sub(1,2) == "|c" then - color = myMessage:sub(1,10); --Save this to prepend back later - myMessage = myMessage:sub(11); - end - - --If the name is in the default color scheme, remove it for titling emphasis - if npcName:sub(1,10) ~= normalColorAsString then - nameColor = Color.static.CreateFromHexa(npcName:sub(1,10)); - end - npcName = npcName:sub(11); - - local len = talkType:len(); - --Remove the "says:" from the beginning of the message. - if myMessage:sub(1, len) == talkType then - local actualMessage = myMessage:sub(len+1); - - --Remove leading spaces if any - if actualMessage:sub(1,1) == " " then - actualMessage = actualMessage:sub(2); - end - - actualMessage = color .. actualMessage; - local chatBubble = RPChatBubbles_createChatBubble() - print("NPC Talk Found! npcName="..npcName); - chatBubble:SetName(npcName); - chatBubble:SetMessage(actualMessage); - if nameColor then - chatBubble:SetNameColor(nameColor:GetRGBA()) - end - end - break; - end - end - end - end - return false, message, ... -end - -function initTRP3Vars(self) - ellyb = TRP3_API.Ellyb; - loc = TRP3_API.loc; - Color = ellyb.Color; - ColorManager = ellyb.ColorManager; - NPC_TALK_PATTERNS = { - [loc.NPC_TALK_SAY_PATTERN] = "MONSTER_SAY", - [loc.NPC_TALK_YELL_PATTERN] = "MONSTER_YELL", - [loc.NPC_TALK_WHISPER_PATTERN] = "MONSTER_WHISPER", - }; -end - -function TotalRP3_onStart(self) - if TRP3_API then - initTRP3Vars(); - for _, channel in pairs(POSSIBLE_CHANNELS) do - ChatFrame_RemoveMessageEventFilter(channel, makeBubbleForNPCChat); - ChatFrame_AddMessageEventFilter(channel, makeBubbleForNPCChat); - end - Import.modules.BlizzChatIntegration:ResetChatHandler() - end -end - ---Import.modules["TotalRP3"] = { --- name="TotalRP3", --- onStart = TotalRP3_onStart; ---} - -POSSIBLE_CHANNELS = { - "CHAT_MSG_SAY", "CHAT_MSG_YELL", "CHAT_MSG_EMOTE", "CHAT_MSG_TEXT_EMOTE", - "CHAT_MSG_PARTY", "CHAT_MSG_PARTY_LEADER", "CHAT_MSG_RAID", "CHAT_MSG_RAID_LEADER", - "CHAT_MSG_GUILD", "CHAT_MSG_OFFICER", "CHAT_MSG_WHISPER", "CHAT_MSG_WHISPER_INFORM" -}; - - -local MODULE_STRUCTURE = { - ["name"] = "Roleplay Chat Bubbles", - ["description"] = "Module for integrating TotalRP3's chatframe system with Roleplay Chat Bubbles.", - ["version"] = 1.000, - ["id"] = "rp_chatBubbles", - ["onStart"] = TotalRP3_onStart, - ["minVersion"] = 3, -}; - -if TRP3_API then - TRP3_API.module.registerModule(MODULE_STRUCTURE); -end