Thread Tools Display Modes
01-24-14, 05:12 AM   #1
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
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

Last edited by Resike : 01-24-14 at 05:17 AM.
  Reply With Quote
01-24-14, 06:13 AM   #2
Choonstertwo
A Chromatic Dragonspawn
 
Choonstertwo's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2011
Posts: 194
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.
  Reply With Quote
01-24-14, 06:18 AM   #3
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
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.)

Last edited by Resike : 01-24-14 at 06:20 AM.
  Reply With Quote
01-24-14, 08:58 AM   #4
Choonstertwo
A Chromatic Dragonspawn
 
Choonstertwo's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2011
Posts: 194
I'm not really sure how to help you. Is there a particular reason you're scaling the frame instead of just resizing it?
  Reply With Quote
01-24-14, 09:05 AM   #5
Duugu
Premium Member
 
Duugu's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 851
Is there a particular reason you're scaling the frame instead of just resizing it
Obviously

Scaling affects all child objects, sizing does not.
  Reply With Quote
01-24-14, 09:08 AM   #6
Choonstertwo
A Chromatic Dragonspawn
 
Choonstertwo's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2011
Posts: 194
Originally Posted by Duugu View Post
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.
  Reply With Quote
01-24-14, 10:02 AM   #7
Vrul
A Scalebane Royal Guard
 
Vrul's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2007
Posts: 404
Originally Posted by Duugu View Post
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.
  Reply With Quote
01-24-14, 10:58 AM   #8
Duugu
Premium Member
 
Duugu's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 851
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)

Last edited by Duugu : 01-24-14 at 11:21 AM.
  Reply With Quote
01-24-14, 01:39 PM   #9
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
F@ck me i can't convert it to TOPLEFT anchored resize, but beside that it's works thanks.
  Reply With Quote
01-24-14, 02:55 PM   #10
Duugu
Premium Member
 
Duugu's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 851
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)
  Reply With Quote
01-24-14, 05:43 PM   #11
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
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.

Last edited by Resike : 01-25-14 at 04:49 AM.
  Reply With Quote
01-25-14, 08:44 AM   #12
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Ninjaed this from Peggle:

https://github.com/Resike/Resize
  Reply With Quote
01-25-14, 10:01 AM   #13
Duugu
Premium Member
 
Duugu's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 851
Originally Posted by Resike View Post
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

Last edited by Duugu : 01-25-14 at 10:07 AM.
  Reply With Quote
01-25-14, 10:35 AM   #14
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
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.

Last edited by Resike : 01-25-14 at 10:37 AM.
  Reply With Quote
01-25-14, 10:47 AM   #15
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
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.

Last edited by Resike : 01-25-14 at 06:11 PM.
  Reply With Quote
01-25-14, 01:28 PM   #16
Duugu
Premium Member
 
Duugu's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 851
Nice one. I'll definitly bookmark this for later use.

Originally Posted by Resike View Post
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)

Last edited by Duugu : 01-25-14 at 01:32 PM.
  Reply With Quote
01-25-14, 02:06 PM   #17
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
Featured
Join Date: Oct 2006
Posts: 10,860
Peggle does not have a license which allows you to "reverse engineer" and "ninja" its code.
©2000, 2008 PopCap Games, Inc. All rights reserved.
__________________
"You'd be surprised how many people violate this simple principle every day of their lives and try to fit square pegs into round holes, ignoring the clear reality that Things Are As They Are." -Benjamin Hoff, The Tao of Pooh

  Reply With Quote
01-25-14, 02:24 PM   #18
Duugu
Premium Member
 
Duugu's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 851
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?
  Reply With Quote
01-25-14, 02:46 PM   #19
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Originally Posted by Seerah View Post
Peggle does not have a license which allows you to "reverse engineer" and "ninja" its code.
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.

Last edited by Resike : 01-25-14 at 03:00 PM.
  Reply With Quote
01-25-14, 02:55 PM   #20
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Originally Posted by Duugu View Post
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.
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Resize frame

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off