1. #1

    Help With moving Vehicle UI above Panel.

    Hello, and thanks for looking at this.

    I was using the Jostle Lib but it keeps moving my unit frames every time I load a screen so I'm trying to do this without the lib.

    What I would like to happen is when I'm not in a vehicle my bar to show below the MainMenuBar and when I'm in a vehicle to just hide my bar.

    Here is the current code I'm using to hide and show:
    Code:
    	-- Hide Panels When in a Vehicle or Pet Battle
    	------------------------------------------------------------------------
    	cDataMainPanel:RegisterEvent("ADDON_LOADED")
    	cDataMainPanel:RegisterEvent("ONUPDATE")
    	cDataMainPanel:RegisterEvent("ONLOAD")
    	cDataMainPanel:RegisterEvent("UNIT_ENTERING_VEHICLE")
    	cDataMainPanel:RegisterEvent("UNIT_ENTERED_VEHICLE")
    	cDataMainPanel:RegisterEvent("UNIT_EXITING_VEHICLE")
    	cDataMainPanel:RegisterEvent("UNIT_EXITED_VEHICLE")
    	cDataMainPanel:RegisterEvent("PET_BATTLE_OPENING_DONE")
    	cDataMainPanel:RegisterEvent("PET_BATTLE_CLOSE")
    	cDataMainPanel:RegisterEvent("PLAYER_ENTERING_WORLD")
    	
    	cDataMainPanel:SetScript("OnEvent", function(self, event, ...)
    		if event == "UNIT_EXITED_VEHICLE" or event == "PET_BATTLE_CLOSE" or event == "PLAYER_ENTERING_WORLD" then	
    			if not InCombatLockdown() then
    				local cPanelFunction = function() end
    				MainMenuBar:ClearAllPoints() 
    				MainMenuBar:SetPoint("BOTTOM",cDataMainPanel,"TOP",0,-4) 
    				MainMenuBar.ClearAllPoints = cPanelFunction 
    				MainMenuBar.SetPoint = cPanelFunction
    				
    				OverrideActionBar:ClearAllPoints() 
    				OverrideActionBar:SetPoint("BOTTOM",cDataMainPanel,"TOP",0,8) 
    				OverrideActionBar.ClearAllPoints = cPanelFunction 
    				OverrideActionBar.SetPoint = cPanelFunction
    			end
    			self:Show()
    		elseif event == "UNIT_ENTERED_VEHICLE" or event == "PET_BATTLE_OPENING_DONE" then
    			if not InCombatLockdown() then
    				self:Hide()
    			end
    		end
    	end)

    So this is what it looks like when not in a vehicle


    But when I get in a vehicle it looks like this:


    I cannot seem to get it to reset to its default location.
    Any help here would be Great...

    and Thanks Again
    Coke

  2. #2
    I'm trying to understand exactly what you want. You initially stated you wanted your data bar to hide in a vehicle, but your bar is correctly hidden in the second screenshot. However, I don't understand what you mean by "I cannot seem to get it to reset to its default location.". Do you want your bar to show somewhere else? Do you want that vehicle bar to move down to cover the empty space left by your hidden bar? Using OverrideActionBar:SetPoint("BOTTOM",UIParent) will slide the vehicle bar down to the bottom of the screen.
    Originally Posted by Zarhym (Blue Tracker)
    this thread is a waste of internet

  3. #3
    Quote Originally Posted by Kanegasi View Post
    Do you want your bar to show somewhere else?
    Yes

    Quote Originally Posted by Kanegasi View Post
    Do you want that vehicle bar to move down to cover the empty space left by your hidden bar?
    Yes

    Quote Originally Posted by Kanegasi View Post
    Using OverrideActionBar:SetPoint("BOTTOM",UIParent) will slide the vehicle bar down to the bottom of the screen.
    I tried this with no success.

    I've tried several variables of the last quote.

    1st:
    Code:
    		elseif event == "UNIT_ENTERED_VEHICLE" or event == "PET_BATTLE_OPENING_DONE" then
    			if not InCombatLockdown() then
    				self:Hide()
    				local cPanelHide = function() end
    				OverrideActionBar:ClearAllPoints() 
    				OverrideActionBar:SetPoint("BOTTOM",UIParent)
    				OverrideActionBar.ClearAllPoints = cPanelHide 
    				OverrideActionBar.SetPoint = cPanelHide
    			end
    		end
    Nothing

    2nd:
    Code:
    		elseif event == "UNIT_ENTERED_VEHICLE" or event == "PET_BATTLE_OPENING_DONE" then
    			if not InCombatLockdown() then
    				self:Hide()
    				if UnitInVehicle("player") == true then
    					OverrideActionBar:ClearAllPoints() 
    					OverrideActionBar:SetPoint("BOTTOM",UIParent)
    				end
    			end
    		end
    Nothing

    3rd: Outside the SetScript for OnEvent
    Code:
    	if UnitInVehicle("player")  then
    		OverrideActionBar:ClearAllPoints() 
    		OverrideActionBar:SetPoint("BOTTOM",UIParent)
    	end
    Nothing

    4th: Also outside the SetScript for OnEvent
    Code:
    	if UnitInVehicle("player") then
    		return OverrideActionBar:SetPoint("BOTTOM",UIParent)
    	end
    So I'm not sure where to go from here.

    Maybe you seeing the full cData.lua would help so HERE it is. (Also HERE is the GitHub for the Addon)

    Again Thanks for any help on this. I guess I'm being picky on how it looks but to me seeing the Vehicle bar that high off the bottom looks odd to me.

    Coke

  4. #4
    So no one has any idea why it will not let me move the OverrideActionBar?

  5. #5
    Deleted
    Maybe you shouldn't replace OverrideActionBar.ClearAllPoints and OverrideActionBar.SetPoint with an empty function on PLAYER_ENTERING_WORLD, right after using the original methods to place the frame where you don't want it to be. :thinking:

    If you want to have the empty function there to prevent external sources from moving the frame, you can still call the real method, if you do something like:
    Code:
    OverrideActionBar.RealClearAllPoints = OverrideActionBar.ClearAllPoints
    , then use that. Or you can just call any other frame's methods like this:
    Code:
    UIParent.ClearAllPoints(OverrideActionBar)
    although that looks confusing and bad like that, since in that case UIParent is an object used as a namespace, so it'd be better to do this instead:
    Code:
    local F_ClearAllPoints = UIParent.ClearAllPoints
    F_ClearAllPoints(OverrideActionBar)
    Fun fact: it's faster to call frame methods that are localized like this, kinda like when you localize global variables. It's just not worth the hassle, unless you need to call the same frame methods thousands of times a frame for some peculiar reason.

    Also,this doesn't make an iota of sense:
    Code:
    if event == "UNIT_EXITED_VEHICLE" or event == "PET_BATTLE_CLOSE" or event == "PLAYER_ENTERING_WORLD" then	
    	if not InCombatLockdown() then
    		local cPanelFunction = function() end
    		MainMenuBar:ClearAllPoints() 
    		MainMenuBar:SetPoint("BOTTOM",cDataMainPanel,"TOP",0,-4) 
    		MainMenuBar.ClearAllPoints = cPanelFunction 
    		MainMenuBar.SetPoint = cPanelFunction
    		
    		OverrideActionBar:ClearAllPoints() 
    		OverrideActionBar:SetPoint("BOTTOM",cDataMainPanel,"TOP",0,8) -- Why even place it there?
    		OverrideActionBar.ClearAllPoints = cPanelFunction 
    		OverrideActionBar.SetPoint = cPanelFunction
    	end
    	self:Show()
    ...
    You are moving 2 frames, then replacing their ClearAllPoints and SetPoint methods so that they will not be moved by anything ever again. This is something that only needs to be run once, because after the first time the methods will just call the empty function anyway. If is done when you login, you don't even need to worry about combat. There's no combat lockdown on the first frame, because otherwise your unit frames couldn't be positioned if you login or reload during combat. Even if you initialize the AddOn later when you do have to care about combat, you can just do something like:

    Code:
    if not InCombatLockdown() then
    	-- do stuff
    else
    	self:RegisterEvent("PLAYER_REGEN_ENABLED")
    end
    then do the stuff on PLAYER_REGEN_ENABLED and unregister the event.

    Another part where you're needlessly checking for combat is here:
    Code:
    elseif event == "UNIT_ENTERED_VEHICLE" or event == "PET_BATTLE_OPENING_DONE" then
    	if not InCombatLockdown() then
    		self:Hide()
    	end
    end
    cDataMainPanel isn't a secure frame, so you can hide it whenever you want.

  6. #6
    So Would something like this be the correct method?
    Code:
    	cDataMainPanel:SetScript("OnEvent", function(self, event, ...)
    		if event == "UNIT_EXITED_VEHICLE" or event == "PET_BATTLE_CLOSE" or event == "PLAYER_ENTERING_WORLD" then
    			local F_ClearAllPoints = UIParent.ClearAllPoints
    			F_ClearAllPoints(_G["MainMenuBar"])
    			F_ClearAllPoints(_G["OverrideActionBar"])
    			F_ClearAllPoints(_G["ExtraActionButton1"])
    	
    			_G["MainMenuBar"]:SetPoint("BOTTOM",cDataMainPanel,"TOP",0,-4);			
    			_G["OverrideActionBar"]:SetPoint("BOTTOM",cDataMainPanel,"TOP",0,8); 				
    			_G["ExtraActionButton1"]:SetPoint("CENTER", MainMenuBar, "TOP", 0, 100);
    			
    			self:Show()
    	
    		else
    			self:Hide()
    		end
    	end)
    - - - Updated - - -

    Ok so I was looking around and I figured it out.

    First I Created 2 new functions:

    #1
    Code:
    function cData:ShowPanel()
    
    	F_ClearAllPoints(_G["MainMenuBar"])
    	F_ClearAllPoints(_G["OverrideActionBar"])
    	F_ClearAllPoints(_G["ExtraActionButton1"])
    
    	_G["MainMenuBar"]:SetPoint("BOTTOM",cDataMainPanel,"TOP",0,-4);			
    	_G["OverrideActionBar"]:SetPoint("BOTTOM",cDataMainPanel,"TOP",0,8); 				
    	_G["ExtraActionButton1"]:SetPoint("CENTER", MainMenuBar, "TOP", 0, 100);
    	
    	cDataMainPanel:Show()
    end
    #2
    Code:
    function cData:HidePanel()
    
    	F_ClearAllPoints(_G["MainMenuBar"])
    	F_ClearAllPoints(_G["OverrideActionBar"])
    	
    	_G["MainMenuBar"]:SetPoint("BOTTOM",UIParent);			
    	_G["OverrideActionBar"]:SetPoint("BOTTOM",UIParent);
    	
    	cDataMainPanel:Hide()
    
    end
    Also added at the top of the lua file:
    Code:
    local F_ClearAllPoints = UIParent.ClearAllPoints
    So it would be called threw out the addon.

    Then I added both functions to the OnEnable() like so:
    Code:
    	self:ShowPanel();
    	self:RegisterEvent("UNIT_EXITED_VEHICLE", "ShowPanel");
    	self:RegisterEvent("PET_BATTLE_CLOSE", "ShowPanel");
    	self:RegisterEvent("PLAYER_ENTERING_WORLD", "ShowPanel");
    	self:HidePanel();
    	self:RegisterEvent("UNIT_ENTERED_VEHICLE", "HidePanel");
    	self:RegisterEvent("PET_BATTLE_OPENING_DONE", "HidePanel");
    And low and behold it works perfect (so Far :P)

    Thanks for the help.

    Coke

  7. #7
    Deleted
    Good that you got it working, but I get the feeling that I didn't communicate the point I was trying to get through quite well enough.

    I see you're now only using the different way to call ClearAllPoints, but not SetPoint. If you're still replacing both with an empty function, the SetPoint method should be doing nothing. If you're not replacing them with an empty function, then you should be able to directly call the ClearAllPoints method normally.

    I merely explained 2 ways (renaming the method and calling the method directly as a function with the frame as the first argument) to use frame methods on frames that have their original methods replaced with empty functions.

  8. #8
    Quote Originally Posted by Kalolt View Post
    Good that you got it working, but I get the feeling that I didn't communicate the point I was trying to get through quite well enough.

    I see you're now only using the different way to call ClearAllPoints, but not SetPoint. If you're still replacing both with an empty function, the SetPoint method should be doing nothing. If you're not replacing them with an empty function, then you should be able to directly call the ClearAllPoints method normally.

    I merely explained 2 ways (renaming the method and calling the method directly as a function with the frame as the first argument) to use frame methods on frames that have their original methods replaced with empty functions.
    I'm not the greatest code writer and have never went to school for any of this so by what you are saying I'm guessing that the following is what should work best?

    Code:
    function cData:ShowPanel()
    
    	_G["MainMenuBar"]:SetPoint("BOTTOM",cDataMainPanel,"TOP",0,-4);			
    	_G["OverrideActionBar"]:SetPoint("BOTTOM",cDataMainPanel,"TOP",0,8); 				
    	_G["ExtraActionButton1"]:SetPoint("CENTER", MainMenuBar, "TOP", 0, 100);
    	
    	cDataMainPanel:Show()
    end
    
    function cData:HidePanel()
    
    	F_ClearAllPoints(_G["MainMenuBar"])
    	F_ClearAllPoints(_G["OverrideActionBar"])
    	
    	cDataMainPanel:Hide()
    
    end
    Coke

  9. #9
    Deleted
    No. This was in your original code, and it replaces the original ClearAllPoints and SetPoint frame methods with an empty function:

    Code:
    -- This replaces the frame methods with an empty function (following method calls will do nothing).
    local cPanelHide = function() end -- This declares an empty function. It does nothing when called.
    OverrideActionBar.ClearAllPoints = cPanelHide -- This replaces OverrideActionBar's ClearAllPoints with the empty function.
    OverrideActionBar.SetPoint = cPanelHide -- This replaces OverrideActionBar's SetPoint with the empty function.
    If you do that, then every time you try to call these methods, it calls the empty function instead. In other words, if that code has ever been ran, then this does nothing:

    Code:
    -- This does nothing, if the frame methods have been replaced with an empty function, because these method calls just call the empty cPanelHide-function.
    OverrideActionBar:ClearAllPoints() 
    OverrideActionBar:SetPoint("BOTTOM",UIParent)
    Basically, you could say that Lua doesn't have true objects like actual object oriented programmin languages do. Lua just has tables, which can be used as arrays, namespaces, and pseudo-objects. Table references can be localized, but the table itself is always global and persistent, which means that if you do something like "OverrideActionBar.ClearAllPoints = cPanelHide" in any scope, it will permanently change the value of the OverrideActionBar-table at key "ClearAllPoints". The way method calls work in Lua is this:

    Code:
    -- These 2 lines of code do exactly the same thing.
    table:method(arg)
    table.method(table, arg)
    So in a way real methods don't exist in Lua. It's just that when you use : instead of . to index a function you're calling, it will pass a reference to the table itself as the first argument. This means that:
    Code:
    local cPanelHide = function() end
    OverrideActionBar.ClearAllPoints = cPanelHide -- OverrideActionBar's ClearAllPoints-method has now been replaced with a reference to the cPanelHide-function, which does nothing
    -- These 2 lines of code do exactly the same thing.
    OverrideActionBar:ClearAllPoints()
    cPanelHide(OverrideActionBar)
    So just to be clear, if you never do this:

    Code:
    local cPanelHide = function() end
    OverrideActionBar.ClearAllPoints = cPanelHide 
    OverrideActionBar.SetPoint = cPanelHide
    then you should forget about the whole F_ClearAllPoints thing, and just call the methods normally like:

    Code:
    MainMenuBar:ClearAllPoints()

  10. #10
    Still kind of lost with a lot of that but the code you are referring "local cPanelHide = function() end" to was provided by Treeston.

    So just to make sure is this the correct way to make it work...
    Code:
    function cData:ShowPanel()
    
    	-- Move the MainMenuBar.
    	_G["MainMenuBar"]:ClearAllPoints();
    	_G["MainMenuBar"]:SetPoint("BOTTOM",cDataMainPanel,"TOP",0,-4);	
    	
    	-- Move the OverrideActionBar.
    	_G["OverrideActionBar"]:ClearAllPoints();
    	_G["OverrideActionBar"]:SetPoint("BOTTOM",cDataMainPanel,"TOP",0,8); 
    
    	-- Move the ExtraActionButton.
    	_G["ExtraActionButton1"]:ClearAllPoints();
    	_G["ExtraActionButton1"]:SetPoint("CENTER", MainMenuBar, "TOP", 0, 100);
    	
    	cDataMainPanel:Show();
    end
    
    function cData:HidePanel()
    
    	-- Reset all the stuff moved when the panel is shown.
    	_G["MainMenuBar"]:ClearAllPoints();
    	_G["OverrideActionBar"]:ClearAllPoints();
    	_G["ExtraActionButton1"]:ClearAllPoints();
    	
    	cDataMainPanel:Hide();
    
    end
    Thanks
    Coke

  11. #11
    Deleted
    Technically that seems reasonable, except for this part:
    Code:
    -- Reset all the stuff moved when the panel is shown.
    _G["MainMenuBar"]:ClearAllPoints();
    _G["OverrideActionBar"]:ClearAllPoints();
    _G["ExtraActionButton1"]:ClearAllPoints();
    When you call ClearAllPoints, it doesn't reset the position of the frame or anything like that. It just leaves it wherever it is, and removes all anchors it has to other frames. There's practically no reason to ever call ClearAllPoints, unless it's followed by SetPoint as it is in the ShowPanel function. In other words, that part can be removed.

    Also, this is more of a stylistic thing, but I don't really see any reason to refer to global variables through the _G table in this situation. It's usually used when the name of the variable is resolved in run-time, for example:
    Code:
    for i = 1, 12 do
        local button = _G[format("ActionButton%d", i)]
        ...
    end
    When you just have a predetermined static variable name, there's really no reason to use _G["MainMenuBar"] instead of just MainMenuBar.

  12. #12
    Quote Originally Posted by Kalolt View Post
    Technically that seems reasonable, except for this part:
    Code:
    -- Reset all the stuff moved when the panel is shown.
    _G["MainMenuBar"]:ClearAllPoints();
    _G["OverrideActionBar"]:ClearAllPoints();
    _G["ExtraActionButton1"]:ClearAllPoints();
    When you call ClearAllPoints, it doesn't reset the position of the frame or anything like that. It just leaves it wherever it is, and removes all anchors it has to other frames. There's practically no reason to ever call ClearAllPoints, unless it's followed by SetPoint as it is in the ShowPanel function. In other words, that part can be removed.

    Also, this is more of a stylistic thing, but I don't really see any reason to refer to global variables through the _G table in this situation. It's usually used when the name of the variable is resolved in run-time, for example:
    Code:
    for i = 1, 12 do
        local button = _G[format("ActionButton%d", i)]
        ...
    end
    When you just have a predetermined static variable name, there's really no reason to use _G["MainMenuBar"] instead of just MainMenuBar.
    So should I complete remove the hide function and then just do this?
    Code:
    	self:RegisterEvent("PLAYER_GAINS_VEHICLE_DATA", cDataMainPanel:Hide());
    	self:RegisterEvent("UNIT_ENTERED_VEHICLE", cDataMainPanel:Hide()); 
    	self:RegisterEvent("PET_BATTLE_OPENING_DONE", cDataMainPanel:Hide())
    - - - Updated - - -

    Quote Originally Posted by Kalolt View Post
    Technically that seems reasonable, except for this part:
    Code:
    -- Reset all the stuff moved when the panel is shown.
    _G["MainMenuBar"]:ClearAllPoints();
    _G["OverrideActionBar"]:ClearAllPoints();
    _G["ExtraActionButton1"]:ClearAllPoints();
    When you call ClearAllPoints, it doesn't reset the position of the frame or anything like that. It just leaves it wherever it is, and removes all anchors it has to other frames. There's practically no reason to ever call ClearAllPoints, unless it's followed by SetPoint as it is in the ShowPanel function. In other words, that part can be removed.

    Also, this is more of a stylistic thing, but I don't really see any reason to refer to global variables through the _G table in this situation. It's usually used when the name of the variable is resolved in run-time, for example:
    Code:
    for i = 1, 12 do
        local button = _G[format("ActionButton%d", i)]
        ...
    end
    When you just have a predetermined static variable name, there's really no reason to use _G["MainMenuBar"] instead of just MainMenuBar.
    So should I complete remove the hide function and then just do this?
    Code:
    	self:RegisterEvent("PLAYER_GAINS_VEHICLE_DATA", cDataMainPanel:Hide());
    	self:RegisterEvent("UNIT_ENTERED_VEHICLE", cDataMainPanel:Hide()); 
    	self:RegisterEvent("PET_BATTLE_OPENING_DONE", cDataMainPanel:Hide())

    [EDIT] nvm it wont work thorows an error so I just delete all the clearallpoints and am running with just the Hide()

    Thanks

    - - - Updated - - -

    Quote Originally Posted by Kalolt View Post
    Technically that seems reasonable, except for this part:
    Code:
    -- Reset all the stuff moved when the panel is shown.
    _G["MainMenuBar"]:ClearAllPoints();
    _G["OverrideActionBar"]:ClearAllPoints();
    _G["ExtraActionButton1"]:ClearAllPoints();
    When you call ClearAllPoints, it doesn't reset the position of the frame or anything like that. It just leaves it wherever it is, and removes all anchors it has to other frames. There's practically no reason to ever call ClearAllPoints, unless it's followed by SetPoint as it is in the ShowPanel function. In other words, that part can be removed.

    Also, this is more of a stylistic thing, but I don't really see any reason to refer to global variables through the _G table in this situation. It's usually used when the name of the variable is resolved in run-time, for example:
    Code:
    for i = 1, 12 do
        local button = _G[format("ActionButton%d", i)]
        ...
    end
    When you just have a predetermined static variable name, there's really no reason to use _G["MainMenuBar"] instead of just MainMenuBar.
    So should I complete remove the hide function and then just do this?
    Code:
    	self:RegisterEvent("PLAYER_GAINS_VEHICLE_DATA", cDataMainPanel:Hide());
    	self:RegisterEvent("UNIT_ENTERED_VEHICLE", cDataMainPanel:Hide()); 
    	self:RegisterEvent("PET_BATTLE_OPENING_DONE", cDataMainPanel:Hide())

    [EDIT] nvm it wont work thorows an error so I just delete all the clearallpoints and am running with just the Hide()

    Thanks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •