view Frames.lua @ 106:d3fbb5676a5e

Added tooltips to the item refill window headers. Now color coding the availibility of items at the item refill window. Added a hide help text option (which is off by default). Renamed all premade groups to a new naming pattern; ?Profession - Category - Detail?, e.g. ?Inscription - Glyphs by class - Death Knight?. To continue getting notified about updates to a selected premade group, you must re-add them. Repositioned elements of the item refill frame to fit better. No longer using colorsargs to remember the index of a queued move, but instead providing a reference to the move itself in the new ?rowData? property of each row. Added tooltips to the headers of the sort table. Merged missing and available columns together (showing available / missing) and sorting on available now sorts on percentage of how many of the missing items are available. Moving and available columns are now aligned to the right. Added an ?extra? config group which contains the additional (but completely optional) settings. Moved color codes adjustments, forget character, auto refill skip confirm and hide help info options to this group.
author Zerotorescue
date Wed, 12 Jan 2011 19:58:39 +0100
parents 8502f02bf543
children 67bd5057ecb7
line wrap: on
line source
local addon = select(2, ...);

local function ShowTooltip(self)
	-- If this function is called from a widget, self is the widget and self.frame the actual frame
	local this = self.frame or self;
	
	if not this.tooltipTitle then return; end
	
	GameTooltip:SetOwner(this, "ANCHOR_NONE");
	if this.tooltipLocation and this.tooltipLocation == "BOTTOM" then
		GameTooltip:SetPoint("TOP", this, "BOTTOM");
	else
		GameTooltip:SetPoint("BOTTOM", this, "TOP");
	end
	GameTooltip:SetText(this.tooltipTitle, 1, .82, 0, 1);
	
	if type(this.tooltip) == "string" then
		GameTooltip:AddLine(this.tooltip, 1, 1, 1, 1);
	end
	
	GameTooltip:Show();
end

local function HideTooltip()
	GameTooltip:Hide();
end

function addon:CreateMoverFrame(onAccept, onCancel)
	local frameWidth = 400;
	
	-- Main window
		local frame = CreateFrame("Frame", "InventoriumItemMover", UIParent);
		-- Hide by default
		frame:Hide();
		-- Center the frame (will be adjusted later)
		frame:SetPoint("CENTER", UIParent, "CENTER", 0, 0);
		-- Put in front of other windows
		frame:SetFrameStrata("FULLSCREEN_DIALOG");
		frame:SetToplevel(true);
		-- Give it a size
		frame:SetWidth(frameWidth);
		frame:SetHeight(175);
		-- Background
		frame:SetBackdrop({
			bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
			edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
			edgeSize = 20,
			insets = {
				left = 5,
				right = 5,
				top = 5,
				bottom = 5,
			},
		});
		frame:SetBackdropColor(0, 0, 0, .8);
		-- Mouse functions
		frame:EnableMouse();
		frame:SetMovable(true);
		frame:SetResizable(true);
		frame:SetMinResize(300, 175);
		-- Set event handlers
		frame:SetScript("OnMouseUp", function(this) this:StopMovingOrSizing(); end);
		frame:SetScript("OnShow", function(this)
			if not tContains(StaticPopup_DisplayedFrames, this) then
				-- We wish to display our box at a similar position as the default interface's static popups, so we literally copied the code for these popups
				local lastFrame = StaticPopup_DisplayedFrames[#StaticPopup_DisplayedFrames];
				if lastFrame then
					this:SetPoint("TOP", lastFrame, "BOTTOM", 0, 0);
				else
					this:SetPoint("TOP", UIParent, "TOP", 0, -135);
				end
				
				-- Position other static popups below this
				tinsert(StaticPopup_DisplayedFrames, this);
			end
			
			this:AdjustScrollTableRows();
			
			PlaySound("OrcExploration");
		end);
	
	-- Title (AceGUI frame-widget-title used as example)
		local titleBackground = frame:CreateTexture(nil, "OVERLAY");
		titleBackground:SetTexture("Interface\\DialogFrame\\UI-DialogBox-Header");
		titleBackground:SetTexCoord(0.31, 0.67, 0, 0.63);
		titleBackground:SetPoint("TOP", 0, 12);
		titleBackground:SetWidth(150);
		titleBackground:SetHeight(40);

		local titleBackgroundLeft = frame:CreateTexture(nil, "OVERLAY");
		titleBackgroundLeft:SetTexture("Interface\\DialogFrame\\UI-DialogBox-Header");
		titleBackgroundLeft:SetTexCoord(0.21, 0.31, 0, 0.63);
		titleBackgroundLeft:SetPoint("RIGHT", titleBackground, "LEFT");
		titleBackgroundLeft:SetWidth(30);
		titleBackgroundLeft:SetHeight(40);

		local titleBackgroundRight = frame:CreateTexture(nil, "OVERLAY");
		titleBackgroundRight:SetTexture("Interface\\DialogFrame\\UI-DialogBox-Header");
		titleBackgroundRight:SetTexCoord(0.67, 0.77, 0, 0.63);
		titleBackgroundRight:SetPoint("LEFT", titleBackground, "RIGHT");
		titleBackgroundRight:SetWidth(30);
		titleBackgroundRight:SetHeight(40);

		local frmTitle = CreateFrame("Frame", nil, frame);
		frmTitle:EnableMouse(true);
		frmTitle:SetScript("OnMouseDown", function(this) this:GetParent():StartMoving(); end);
		frmTitle:SetScript("OnMouseUp", function(this) this:GetParent():StopMovingOrSizing(); end);
		frmTitle:SetAllPoints(titleBackground);

		local lblTitle = frmTitle:CreateFontString(nil, "OVERLAY", "GameFontNormal");
		lblTitle:SetPoint("TOP", titleBackground, "TOP", 0, -14);
		lblTitle:SetText("Inventorium Bank Refill");
	
	-- Resizer (vertical only)
		local frmResizer = CreateFrame("Frame", nil, frame);
		frmResizer:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", 0, -10);
		frmResizer:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", 0, -10);
		frmResizer:SetHeight(20);
		frmResizer:EnableMouse();
		frmResizer:SetScript("OnMouseDown", function(this) this:GetParent():StartSizing("BOTTOM"); end);
		frmResizer:SetScript("OnMouseUp", function(this) this:GetParent():StopMovingOrSizing(); end);
	
	-- Description
		local lblDescription = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal");
		lblDescription:SetPoint("TOPLEFT", frame, "TOPLEFT", 15, -27);
		lblDescription:SetWidth(frameWidth - 15 - 15); -- 10 margin left & 10 margin right
		lblDescription:SetJustifyH("LEFT");
		lblDescription:SetJustifyV("TOP");
		lblDescription:SetText("The items listed below can be refilled from this location, do you wish to move them to your bags?");
		
		frame.lblDescription = lblDescription;
	
	-- Buttons
		-- Move (proceed)
			local btnMove = CreateFrame("Button", "$parentProceed", frame, "UIPanelButtonTemplate");
			btnMove:SetHeight(21);
			btnMove:SetWidth(125);
			btnMove:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", 15, 11);
			btnMove:SetText("Move Items");
			btnMove:SetScript("OnClick", onAccept);
			btnMove:SetScript("OnEnter", ShowTooltip);
			btnMove:SetScript("OnLeave", HideTooltip);
			btnMove.tooltipTitle = (not addon.db.profile.defaults.hideHelp and "Move Items");
			btnMove.tooltip = (not addon.db.profile.defaults.hideHelp and "Start moving these items from the bank.");
			
			frame.btnMove = btnMove;
			
		-- Cancel
			local btnCancel = CreateFrame("Button", "$parentCancel", frame, "UIPanelButtonTemplate");
			btnCancel:SetHeight(21);
			btnCancel:SetWidth(125);
			btnCancel:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -15, 11);
			btnCancel:SetText("Cancel");
			btnCancel:SetScript("OnClick", onCancel);
			btnCancel:SetScript("OnEnter", ShowTooltip);
			btnCancel:SetScript("OnLeave", HideTooltip);
			btnCancel.tooltipTitle = (not addon.db.profile.defaults.hideHelp and "Cancel");
			btnCancel.tooltip = (not addon.db.profile.defaults.hideHelp and "Do not move anything and close the window.");
			
			frame.btnCancel = btnCancel;
		
	-- Because the scrolling table code-behind will change this element's height, we can't rely on that. Make a dummy frame which we can measure
		local frmMeasureDummy = CreateFrame("Frame", nil, frame);
		frmMeasureDummy:SetPoint("TOP", frame.lblDescription, "BOTTOM", 0, -18);
		frmMeasureDummy:SetPoint("LEFT", frame, "LEFT", 15, 0);
		frmMeasureDummy:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -15, 35);
		
		frame.frmMeasureDummy = frmMeasureDummy;
		
	-- Scrolling table with a list of items to be moved
		local scrollTableWidth = ( frame.frmMeasureDummy:GetWidth() - 30 ); -- adjust width by the scrollbar size
		local headers = {
			{
				["name"] = "Item",
				["width"] = (scrollTableWidth * .60),
				["defaultsort"] = "asc",
				["comparesort"] = function(this, aRow, bRow, column)
					local aName, _, aRarity = GetItemInfo(this:GetRow(aRow).rowData.id);
					local bName, _, bRarity = GetItemInfo(this:GetRow(bRow).rowData.id);
					local template = "%d%s";
					aName = template:format((10 - (aRarity or 10)), (aName or ""):lower());
					bName = template:format((10 - (bRarity or 10)), (bName or ""):lower());
					
					if this.cols[column].sort == "dsc" then
						return aName > bName;
					else
						return aName < bName;
					end
				end,
				["sort"] = "asc", -- when the data is set, use this column so sort the default data
				["tooltipTitle"] = (not addon.db.profile.defaults.hideHelp and "Item"),
				["tooltip"] = (not addon.db.profile.defaults.hideHelp and "Click to sort the list by item quality then item name."),
			},
			{
				["name"] = "Moving",
				["width"] = (scrollTableWidth * .15),
				["align"] = "RIGHT",
				["defaultsort"] = "dsc",
				["sortnext"] = 1,
				["tooltipTitle"] = (not addon.db.profile.defaults.hideHelp and "Moving"),
				["tooltip"] = (not addon.db.profile.defaults.hideHelp and "Click to sort the list by the amount of movable items."),
			},
			{
				["name"] = "Available",
				["width"] = (scrollTableWidth * .25),
				["align"] = "RIGHT",
				["defaultsort"] = "dsc",
				["sortnext"] = 1,
				["comparesort"] = function(this, aRow, bRow, column)
					local aAvailablePercent = (this:GetRow(aRow).rowData.available / this:GetRow(aRow).rowData.missing);
					local bAvailablePercent = (this:GetRow(bRow).rowData.available / this:GetRow(bRow).rowData.missing);
					
					if this.cols[column].sort == "dsc" then
						return aAvailablePercent > bAvailablePercent;
					else
						return aAvailablePercent < bAvailablePercent;
					end
				end,
				["tooltipTitle"] = (not addon.db.profile.defaults.hideHelp and "Item"),
				["tooltip"] = (not addon.db.profile.defaults.hideHelp and "Click to sort the list by the availibility percentage."),
			},
		};
		
		local ScrollingTable = LibStub("ScrollingTable");
		local table = ScrollingTable:CreateST(headers, 3, 15, nil, frame);
		-- When moving over a row, provide a tooltip for the item
		table:RegisterEvents({
			["OnEnter"] = function(rowFrame, cellFrame, data, cols, row, realrow, column, scrollingTable, ...)
				if row and realrow then
					-- Data row
					
					if data[realrow] and data[realrow].rowData and data[realrow].rowData.id then
						GameTooltip:SetOwner(rowFrame, "ANCHOR_NONE");
						GameTooltip:SetPoint("TOPLEFT", rowFrame, "BOTTOMLEFT");
						GameTooltip:SetHyperlink(("item:%d"):format(data[realrow].rowData.id));
						GameTooltip:Show();
					end
				else
					-- Header row
					
					if cols[column].tooltipTitle and type(cols[column].tooltipTitle) == "string" then
						cellFrame.tooltipTitle = cols[column].tooltipTitle;
						if cols[column].tooltip then
							cellFrame.tooltip = cols[column].tooltip; -- Optional
						else
							cellFrame.tooltip = nil;
						end
						
						ShowTooltip(cellFrame);
					end
				end
			end,
			["OnLeave"] = function(rowFrame, cellFrame, data, cols, row, realrow, column, scrollingTable, ...)
				HideTooltip();
			end,
		});
		
		frame.scrollTable = table;
		table.frame:SetPoint("TOP", frame.lblDescription, "BOTTOM", 0, -18);
		table.frame:SetPoint("LEFT", frame, "LEFT", 15, 0);
		table.frame:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -15, 35);
		
	-- Change the amount of displayed rows based on the size of the frame
		frame.AdjustScrollTableRows = function(this)
			local newRows = math.floor(( this.frmMeasureDummy:GetHeight() - 5 ) / 15);
			newRows = (newRows < 3 and 3) or newRows;
			
			this.scrollTable:SetDisplayRows(newRows, 15);
		end;
		frame:SetScript("OnSizeChanged", frame.AdjustScrollTableRows);
end

function addon:SetMoverFrameData(data)
	InventoriumItemMover.scrollTable:SetData(data);
	
	InventoriumItemMover:Show();
end