WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   Lua/XML Help (https://www.wowinterface.com/forums/forumdisplay.php?f=16)
-   -   Resize frame (https://www.wowinterface.com/forums/showthread.php?t=48862)

Resike 01-24-14 05:12 AM

Resize frame
 
I would like to resize a frame with the mouse, just like the chat frame resizing, however i don't want anything fancy i just want to increase and decrase the scale of the frame based on the mouse's position. Here is my code so far:

Lua Code:
  1. local function LeftButtonOnUpdate(frame, elapsed)
  2.     --frame.x = math.floor(frame:GetLeft() + (frame:GetWidth() - UIParent:GetWidth()) / 2 + 0.5)
  3.     --frame.y = math.floor(frame:GetTop() - (frame:GetHeight() + UIParent:GetHeight()) / 2 + 0.5)
  4.     FRAMETORESIZE:SetScale(FRAMETORESIZE:GetScale() * 1.001)
  5. end
  6.  
  7. local function SizeOnMouseDown(frame, button)
  8.     if button == "LeftButton" then
  9.         frame.x, frame.y = GetCursorPosition()
  10.         frame:SetScript("OnUpdate", LeftButtonOnUpdate)
  11.     end
  12. end
  13.  
  14. local function SizeOnMouseUp(frame, button)
  15.     if button == "LeftButton" then
  16.         frame:SetScript("OnUpdate", nil)
  17.     end
  18. end
  19.  
  20. function ResizeStart(frame)
  21.     frame:SetScript("OnMouseDown", SizeOnMouseDown)
  22.     frame:SetScript("OnMouseUp", SizeOnMouseUp)
  23. end

Choonstertwo 01-24-14 06:13 AM

Try this:
lua Code:
  1. local frame = CreateFrame("Frame", "MyAddOn_MainFrame", UIParent)
  2.  
  3. -- Set up the main frame here
  4.  
  5. local resizeButton = CreateFrame("Button", nil, frame)
  6. resizeButton:SetSize(16, 16)
  7. resizeButton:SetPoint("BOTTOMRIGHT")
  8. resizeButton:SetNormalTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Up")
  9. resizeButton:SetHighlightTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Highlight")
  10. resizeButton:SetPushedTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Down")
  11.  
  12. resizeButton:SetScript("OnMouseDown", function(self, button)
  13.     frame:StartSizing("BOTTOMRIGHT")
  14.     frame:SetUserPlaced(true)
  15. end)
  16.  
  17. resizeButton:SetScript("OnMouseUp", function(self, button)
  18.     frame:StopMovingOrSizing()
  19. end)

This should create a resize button in the bottom right corner of your main frame that looks like the chat frame resize button.

You can add a check for the left mouse button in the OnMouseUp/Down scripts like you have in your code if you want.

Resike 01-24-14 06:18 AM

Yes but i would like to scale the frame not resize it, (Just noticed i might messed up the thread's topic, sorry for that.)

Choonstertwo 01-24-14 08:58 AM

I'm not really sure how to help you. Is there a particular reason you're scaling the frame instead of just resizing it?

Duugu 01-24-14 09:05 AM

Quote:

Is there a particular reason you're scaling the frame instead of just resizing it
Obviously :)

Scaling affects all child objects, sizing does not.

Choonstertwo 01-24-14 09:08 AM

Quote:

Originally Posted by Duugu (Post 290094)
Obviously :)

Scaling affects all child objects, sizing does not.

That makes sense. I don't think I've ever seen a drag-scaled frame before.

Vrul 01-24-14 10:02 AM

Quote:

Originally Posted by Duugu (Post 290094)
Scaling affects all child objects, sizing does not.

If you anchor everything just the right way that shouldn't matter. Now there would be an exception if you wanted font sizes to also change but that could be handled with an OnSizeChanged script or in the OnMouseUp script.

Duugu 01-24-14 10:58 AM

left button at frame background and draging = drag frame
left button at resize button and draging = resize frame
right button at resize button and draging = rescale frame

Rescaling is affected by horizontal mouse movement only. Someone has to implement the y axis. :)

It's not perfect but it's working.

Nevertheles I do agree with Vrul. Scaling a fame is never the best way to do anything size-related. In best case it just adds an extra level of complexity to your code. In worst case all your visible objects are a total mess. :)

[e] Didn't tested what would happen to child object of my test frame. And I'm seriously afraid of finding it out. ;D

Lua Code:
  1. tObj = CreateFrame("Frame", "testframe", UIParent)
  2.     tObj:SetPoint("CENTER", UIParent, "CENTER")
  3.     tObj:SetHeight(100)
  4.     tObj:SetWidth(100)
  5.     tObj:SetBackdrop({bgFile="Interface\\Tooltips\\UI-Tooltip-Background", edgeFile="Interface\\Tooltips\\UI-Tooltip-Border", tile = false, tileSize = 1, edgeSize = 10, insets = { left = 0, right = 0, top = 0, bottom = 0 }})
  6.     tObj:SetBackdropColor(0, 0, 0, 0.75)
  7.     tObj:EnableMouse(true)
  8.     tObj:SetMovable(true)
  9.     tObj:SetResizable(true)
  10.     tObj:SetScript("OnDragStart", function(self)
  11.         self.isMoving = true
  12.         self:StartMoving()
  13.     end)
  14.     tObj:SetScript("OnDragStop", function(self)
  15.         self.isMoving = false
  16.         self:StopMovingOrSizing()
  17.         self.x = self:GetLeft()
  18.         self.y = (self:GetTop() - self:GetHeight())
  19.         self:ClearAllPoints()
  20.         self:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", self.x, self.y)
  21.     end)
  22.     tObj:SetScript("OnUpdate", function(self)
  23.         if self.isMoving == true then
  24.             self.x = self:GetLeft()
  25.             self.y = (self:GetTop() - self:GetHeight())
  26.             self:ClearAllPoints()
  27.             self:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", self.x, self.y)
  28.         end
  29.     end)
  30.     tObj:SetClampedToScreen(true)
  31.     tObj:RegisterForDrag("LeftButton")
  32.     tObj:SetScale(1)
  33.     tObj.x = tObj:GetLeft()
  34.     tObj.y = (tObj:GetTop() - tObj:GetHeight())
  35.     tObj:Show()
  36.  
  37.     local resizeButton = CreateFrame("Button", "resButton", tObj)
  38.     resizeButton:SetSize(16, 16)
  39.     resizeButton:SetPoint("BOTTOMRIGHT")
  40.     resizeButton:SetNormalTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Up")
  41.     resizeButton:SetHighlightTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Highlight")
  42.     resizeButton:SetPushedTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Down")
  43.     resizeButton:SetScript("OnMouseDown", function(self, button)
  44.         if button == "LeftButton" then
  45.             self.isSizing = true
  46.             self:GetParent():StartSizing("BOTTOMRIGHT")
  47.             self:GetParent():SetUserPlaced(true)
  48.         elseif button == "RightButton" then
  49.             self.isScaling = true
  50.         end
  51.     end)
  52.     resizeButton:SetScript("OnMouseUp", function(self, button)
  53.         if button == "LeftButton" then
  54.             self.isSizing = false
  55.             self:GetParent():StopMovingOrSizing()
  56.         elseif button == "RightButton" then
  57.             self.isScaling = false
  58.         end
  59.     end)
  60.     resizeButton:SetScript("OnUpdate", function(self, button)
  61.         if self.isScaling == true then
  62.             local cx, cy = GetCursorPosition()
  63.             cx = cx / self:GetEffectiveScale() - self:GetParent():GetLeft()
  64.             cy = self:GetParent():GetHeight() - (cy / self:GetEffectiveScale() - self:GetParent():GetBottom() )
  65.  
  66.             local tNewScale = cx / self:GetParent():GetWidth()
  67.             local tx, ty = self:GetParent().x / tNewScale, self:GetParent().y / tNewScale
  68.            
  69.             self:GetParent():ClearAllPoints()
  70.             self:GetParent():SetScale(self:GetParent():GetScale() * tNewScale)
  71.             self:GetParent():SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", tx, ty)
  72.             self:GetParent().x, self:GetParent().y = tx, ty
  73.         end
  74.     end)

Resike 01-24-14 01:39 PM

F@ck me i can't convert it to TOPLEFT anchored resize, but beside that it's works thanks.

Duugu 01-24-14 02:55 PM

Using bottomleft is the easiest way to do it. Bottomleft is equal to 0/0 and topleft is 0/1.
If you need it to be anchored to topleft you'll have to calculate new y coordinates accordingly to topleft. (eg. subtact the y value of the cursor coordinates from UIParents height to get a value relative to topleft)

Resike 01-24-14 05:43 PM

Goddamns frames always jump on y axis.

I was trying to change:

self.y = (self:GetTop() - self:GetHeight())

To:

self.y = (UIParent:GetHeight() - self:GetTop())

But when i move the frame, then try to resize it it does a jump in the y axis.

Resike 01-25-14 08:44 AM

Ninjaed this from Peggle:

https://github.com/Resike/Resize

Duugu 01-25-14 10:01 AM

Quote:

Originally Posted by Resike (Post 290175)
Ninjaed this from Peggle:

https://github.com/Resike/Resize

From the Peggle addon? Is't it obfuscated?
Does it work if the overall UI scale is not set to default? (interface settings > UI scale)

Regarding the anchor point:
You can't just change bottomleft to topleft. The anchor point changes everything.
Lets assume UIParent has a size of 100x100. As you know in wow 0/0 is the lower left corner and 1/1 is the top right corner. Always. Regardless of where something is anchored or if we are talking about frames, cursor coordinates, textures or whatever.
Setpoint coordinates are relative to the anchor point.
A positive x means a shift to the right. Negative x is left.
Positive y shifts to the top (remember, in wow 0/0 is the bottom left corner and 0/1 is top left) and negative y shifts to the bottom.
Now let's see what happens:

setpoint("bottomleft", parent, "bottomleft", 20, 20) is something like:

Code:

0/100                100/100





        x


0/0                100/0

And setpoint("topleft", parent, "topleft", 100, 100) would be something like:


Code:

        x


0/100                100/100





 


0/0                100/0


Resike 01-25-14 10:35 AM

Yeah i reverse engineered most part of it.

It works properly with every UIScale because it's using a different method.

Also updated the code to scale every other child object:

Lua Code:
  1. local childrens = {t:GetChildren()}
  2.         for _, child in ipairs(childrens) do
  3.                 child:SetScale(n)
  4.         end

I'm aware of the anchoring issue i tried it like this:

self:GetParent():SetPoint("TOPLEFT", UIParent, "TOPLEFT", tx, - ty)

And was using:

self.y = (UIParent:GetHeight() - self:GetTop())

To get the y coordinates, which should be fine. But i also tried to multiple it with the UIParent:GetScale() any pretty much every other number on the universe, if the frame had 1 scale then it worked, but was faulty with every other scale level.

But still every time i moved the frame, then tried to resize it, it randomly jumped +/- y axis. Not sure why, probably some other scaling issue, since you can't just get the coords with simply the GetBottom/GetTop.

Resike 01-25-14 10:47 AM

If you call this after you created a frame, then the frame is gonna be scaleable, and it's gonna build up everything needed for it:

Lua Code:
  1. function PowaAurasOptions:ResizeFrame(frame)
  2.     local Width = frame:GetWidth()
  3.     local Height = frame:GetHeight()
  4.     local resizeframe = CreateFrame("Frame", nil, frame)
  5.     resizeframe:SetPoint("BottomRight", frame, "BottomRight", - 8, 7)
  6.     resizeframe:SetWidth(16)
  7.     resizeframe:SetHeight(16)
  8.     resizeframe:SetFrameLevel(frame:GetFrameLevel() + 7)
  9.     resizeframe:EnableMouse(true)
  10.     local resizetexture = resizeframe:CreateTexture(nil, "Artwork")
  11.     resizetexture:SetPoint("TopLeft", resizeframe, "TopLeft", 0, 0)
  12.     resizetexture:SetWidth(16)
  13.     resizetexture:SetHeight(16)
  14.     resizetexture:SetTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Up")
  15.     frame:SetMaxResize(Width * 1.5, Height * 1.5)
  16.     frame:SetMinResize(Width / 1.5, Height / 1.5)
  17.     frame:SetResizable(true)
  18.     resizeframe:SetScript("OnEnter", function(self)
  19.         resizetexture:SetTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Highlight")
  20.     end)
  21.     resizeframe:SetScript("OnLeave", function(self)
  22.         resizetexture:SetTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Up")
  23.     end)
  24.     resizeframe:SetScript("OnMouseDown", function(self, button)
  25.         if button == "RightButton" then
  26.             frame:SetWidth(Width)
  27.             frame:SetHeight(Height)
  28.         else
  29.             resizetexture:SetTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Down")
  30.             frame:StartSizing("Right")
  31.         end
  32.     end)
  33.     resizeframe:SetScript("OnMouseUp", function(self, button)
  34.         local x, y = GetCursorPosition()
  35.         local fx = self:GetLeft() * self:GetEffectiveScale()
  36.         local fy = self:GetBottom() * self:GetEffectiveScale()
  37.         if x >= fx and x <= (fx + self:GetWidth()) and y >= fy and y <= (fy + self:GetHeight()) then
  38.             resizetexture:SetTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Highlight")
  39.         else
  40.             resizetexture:SetTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Up")
  41.         end
  42.         frame:StopMovingOrSizing()
  43.     end)
  44.     local scrollframe = CreateFrame("ScrollFrame", nil, frame)
  45.     scrollframe:SetWidth(Width)
  46.     scrollframe:SetHeight(Height)
  47.     scrollframe:SetPoint("Topleft", frame, "Topleft", 0, 0)
  48.     frame:SetScript("OnSizeChanged", function(self)
  49.         local s = self:GetWidth() / Width
  50.         scrollframe:SetScale(s)
  51.         local childrens = {self:GetChildren()}
  52.         for _, child in ipairs(childrens) do
  53.             if child ~= resizeframe then
  54.                 child:SetScale(s)
  55.             end
  56.         end
  57.         self:SetHeight(Height * s)
  58.     end)
  59. end

There are still a few thing to do it with, like change the resize button's texture onmousedown and up.
Also ot exlude or only scale the scale button itself with lower frequency, to prevent it beeing unclickable. But its working properly.

Right click on the resize texture, reset the frame to the original size.

Duugu 01-25-14 01:28 PM

Nice one. I'll definitly bookmark this for later use. :)

Quote:

Originally Posted by Resike (Post 290179)
But still every time i moved the frame, then tried to resize it, it randomly jumped +/- y axis. Not sure why, probably some other scaling issue, since you can't just get the coords with simply the GetBottom/GetTop.

My guess is that's due to the way the moving stuff works. It re-anchors the frame all the time (to the nearest anchor point or whatever ... I don't know :)). If you anchor a frame to center/center and move it to the left then it will be re-anchored to left/left or something.

You can work around this annoying behavior with re-anchoring it to the desired anchor on OnDragStop.

Lua Code:
  1. frame:SetScript("OnDragStop", function(self)
  2.         self:StopMovingOrSizing()
  3.         self.x = self:GetLeft()
  4.         self.y = (self:GetTop() - self:GetHeight())
  5.         self:ClearAllPoints()
  6.         self:SetPoint("BOTTOMLEFT", self:GetParent(), "BOTTOMLEFT", self.x, self.y)
  7.     end)

Seerah 01-25-14 02:06 PM

Peggle does not have a license which allows you to "reverse engineer" and "ninja" its code. :mad:
Quote:

©2000, 2008 PopCap Games, Inc. All rights reserved.

Duugu 01-25-14 02:24 PM

OT:

I recently asked myself if Blizzard would allow me to use obfuscate code to implement a synchronized (realm or bg or something) high score table in http://www.wowinterface.com/download...doManager.html.
It wouldn't make any sense to create one without obfuscating code/data. I'm 100% sure that a clear text high score table would be 'hacked' immediately and be useless. :)

Do you think it's worth to ask for a permission to add obfuscate code?

Resike 01-25-14 02:46 PM

Quote:

Originally Posted by Seerah (Post 290186)
Peggle does not have a license which allows you to "reverse engineer" and "ninja" its code. :mad:

Well i hope they won't hang me to use a similar system to resize a damn frame. 99% of the code only contains Blizzard functions, i don't think checking how it's exactly works is a punishable sin.
If i could have found a similar solution for it which works properly i would use that.
I spent the last 3 days on this silly issue anyway.

Peggles system only rescales the main frame and resizes other frames to it, mine rescales the frame and all of it's childrens.

Resike 01-25-14 02:55 PM

Quote:

Originally Posted by Duugu (Post 290189)
OT:

I recently asked myself if Blizzard would allow me to use obfuscate code to implement a synchronized (realm or bg or something) high score table in http://www.wowinterface.com/download...doManager.html.
It wouldn't make any sense to create one without obfuscating code/data. I'm 100% sure that a clear text high score table would be 'hacked' immediately and be useless. :)

Do you think it's worth to ask for a permission to add obfuscate code?

They might be okay with that, however before any updates you would also have to show your clear code for them, which is the more problematic issue, not the actual permission for it.


All times are GMT -6. The time now is 04:32 PM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2004 - 2022 MMOUI