view Frames.lua @ 144:12a8ea5af671

Added a ?remove? button to the crafting queue. When removing an item from the queue or when it is finished casting (when using the Inventorium queue processer), items are moved to the ?unqueuables? window. Fixed auction price checking. Now resetting filters before scanning the tradeskill recipes.
author Zerotorescue
date Wed, 19 Jan 2011 23:21:16 +0100
parents 5ed50feddeb0
children 6a52272a0e5a
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 or addon.db.profile.defaults.hideHelp 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()
	if InventoriumItemMover then
		return;
	end
	
	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);
		frame:SetScript("OnHide", function(this)
			StaticPopup_CollapseTable(this);
		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);
		
		frame.titleBackground = titleBackground;
		
		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);
		
		frame.lblTitle = lblTitle;
	
	-- 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");
		
		frame.lblDescription = lblDescription;
	
	-- Buttons
		-- Proceed
			local btnProceed = CreateFrame("Button", "$parentProceed", frame, "UIPanelButtonTemplate");
			btnProceed:SetHeight(21);
			btnProceed:SetWidth(125);
			btnProceed:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", 15, 11);
			btnProceed:SetScript("OnClick", function(this) this.OnClick(this); end);
			btnProceed:SetScript("OnEnter", ShowTooltip);
			btnProceed:SetScript("OnLeave", HideTooltip);
			
			frame.btnProceed = btnProceed;
			
		-- Cancel
			local btnCancel = CreateFrame("Button", "$parentCancel", frame, "UIPanelButtonTemplate");
			btnCancel:SetHeight(21);
			btnCancel:SetWidth(125);
			btnCancel:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -15, 11);
			btnCancel:SetScript("OnClick", function(this) this.OnClick(this); end);
			btnCancel:SetScript("OnEnter", ShowTooltip);
			btnCancel:SetScript("OnLeave", HideTooltip);
			
			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 ScrollingTable = LibStub("ScrollingTable");
		local scrollTable = ScrollingTable:CreateST({}, 4, 15, nil, frame); -- inserting a dummy cols, real cols to be set in SetFrameSettings
		scrollTable.frame:SetPoint("TOP", frame.lblDescription, "BOTTOM", 0, -18);
		scrollTable.frame:SetPoint("LEFT", frame, "LEFT", 15, 0);
		scrollTable.frame:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -15, 35);
		-- When moving over a row, provide a tooltip for the item
		scrollTable: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.itemId then
						GameTooltip:SetOwner(rowFrame, "ANCHOR_NONE");
						GameTooltip:SetPoint("TOPLEFT", rowFrame, "BOTTOMLEFT");
						GameTooltip:SetHyperlink(("item:%d"):format(data[realrow].rowData.itemId));
						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,
			["OnClick"] = function() end,
		});
		
		frame.scrollTable = scrollTable;
	
	-- 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 < 4 and 4) 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

function addon:SetMoverFrameSettings(title, description, proceed, cancel, headers)
	local frame = InventoriumItemMover;
	
	frame.lblTitle:SetText(title);
	-- Adjust size for the title background
	frame.titleBackground:SetWidth((frame.lblTitle:GetWidth() or 0) + 10); -- 10 pixels margin
	
	frame.lblDescription:SetText(description);
	
	frame.btnProceed:SetText(proceed.text);
	frame.btnProceed.tooltipTitle = proceed.tooltipTitle;
	frame.btnProceed.tooltip = proceed.tooltip;
	frame.btnProceed.OnClick = proceed.onClick;
	
	frame.btnCancel:SetText(cancel.text);
	frame.btnCancel.tooltipTitle = cancel.tooltipTitle;
	frame.btnCancel.tooltip = cancel.tooltip;
	frame.btnCancel.OnClick = cancel.onClick;
	
	frame.scrollTable:SetDisplayCols(headers);
end

function addon:CreateQueueFrame()
	if InventoriumQueuer then
		return;
	end
	
	do
		local frameWidth = 400;
		
		-- Main window
			local frame = CreateFrame("Frame", "InventoriumQueuer", 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(430);
			-- 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);
			-- Set event handlers
			frame:SetScript("OnMouseUp", function(this) this:StopMovingOrSizing(); end);
			frame:SetScript("OnShow", function(this)
				this:AdjustScrollTableRows();
			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);
			
			frame.titleBackground = titleBackground;
			
			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);
			
			frame.lblTitle = lblTitle;
			
		-- Expand button
			local btnExpander = CreateFrame("Button", "$parentExpander", frame);
			btnExpander:SetWidth(32);
			btnExpander:SetHeight(32);
			btnExpander:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -10, -10);
			btnExpander:SetNormalTexture("Interface\\Buttons\\UI-SpellbookIcon-NextPage-Up");
			btnExpander:SetPushedTexture("Interface\\Buttons\\UI-SpellbookIcon-NextPage-Down");
			btnExpander:SetDisabledTexture("Interface\\Buttons\\UI-SpellbookIcon-NextPage-Disabled");
			btnExpander:SetHighlightTexture("Interface\\Buttons\\UI-Common-MouseHilight", "ADD");
			btnExpander.tooltipTitle = "Show unqueueables";
			btnExpander.tooltip = "Click to show a list of all unqueueable but tracked items.";
			btnExpander:SetScript("OnEnter", ShowTooltip);
			btnExpander:SetScript("OnLeave", HideTooltip);
			btnExpander:SetScript("OnClick", function(this)
				if this.Expanded then
					-- Collapsing
					this.Expanded = nil;
					InventoriumQueuerUnqueueables:Hide();
					PlaySound("igCharacterInfoClose");
					
					-- Next is an expand
					this:SetNormalTexture("Interface\\Buttons\\UI-SpellbookIcon-NextPage-Up");
					this:SetPushedTexture("Interface\\Buttons\\UI-SpellbookIcon-NextPage-Down");
					this:SetDisabledTexture("Interface\\Buttons\\UI-SpellbookIcon-NextPage-Disabled");
				else
					-- Expanding
					this.Expanded = true;
					
					-- Position the frame against the queuer window
					InventoriumQueuerUnqueueables:ClearAllPoints();
					InventoriumQueuerUnqueueables:SetPoint("TOPLEFT", this:GetParent(), "TOPRIGHT", 0, 0);
					InventoriumQueuerUnqueueables:SetPoint("BOTTOMLEFT", this:GetParent(), "BOTTOMLEFT", 0, 0);
					InventoriumQueuerUnqueueables:Show();
					PlaySound("igCharacterInfoOpen");
					
					-- Next is a collapse
					this:SetNormalTexture("Interface\\Buttons\\UI-SpellbookIcon-PrevPage-Up");
					this:SetPushedTexture("Interface\\Buttons\\UI-SpellbookIcon-PrevPage-Down");
					this:SetDisabledTexture("Interface\\Buttons\\UI-SpellbookIcon-PrevPage-Disabled");
				end
			end);
		
		-- Description
			local lblDescription = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal");
			lblDescription:SetPoint("TOPLEFT", frame, "TOPLEFT", 15, -27);
			lblDescription:SetPoint("RIGHT", btnExpander, "LEFT", -15, 0);
			lblDescription:SetJustifyH("LEFT");
			lblDescription:SetJustifyV("TOP");
			lblDescription:SetWidth(frameWidth - 70);
			
			frame.lblDescription = lblDescription;
		
		-- Buttons
			-- Proceed
				local btnProceed = CreateFrame("Button", "$parentProceed", frame, "UIPanelButtonTemplate");
				btnProceed:SetHeight(21);
				btnProceed:SetWidth(125);
				btnProceed:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", 15, 11);
				btnProceed:SetScript("OnClick", function(this) this.OnClick(this); end);
				btnProceed:SetScript("OnEnter", ShowTooltip);
				btnProceed:SetScript("OnLeave", HideTooltip);
				
				frame.btnProceed = btnProceed;
				
			-- Cancel
				local btnCancel = CreateFrame("Button", "$parentCancel", frame, "UIPanelButtonTemplate");
				btnCancel:SetHeight(21);
				btnCancel:SetWidth(125);
				btnCancel:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -15, 11);
				btnCancel:SetScript("OnClick", function(this) this.OnClick(this); end);
				btnCancel:SetScript("OnEnter", ShowTooltip);
				btnCancel:SetScript("OnLeave", HideTooltip);
				
				frame.btnCancel = btnCancel;
			
		-- Because the scrolling table code-behind will change the scrolltable 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 queued
			local ScrollingTable = LibStub("ScrollingTable");
			local scrollTable = ScrollingTable:CreateST({}, 4, 15, nil, frame); -- inserting a dummy cols, real cols to be set in SetFrameSettings
			scrollTable.frame:SetPoint("TOP", frame.lblDescription, "BOTTOM", 0, -18);
			scrollTable.frame:SetPoint("LEFT", frame, "LEFT", 15, 0);
			scrollTable.frame:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -15, 35);
			-- When moving over a row, provide a tooltip for the item
			scrollTable:RegisterEvents({
				["OnEnter"] = function(rowFrame, cellFrame, data, cols, row, realrow, column)
					if row and realrow then
						-- Data row
						
						if cols[column].name == "X" then
							cellFrame.tooltipTitle = "Remove";
							cellFrame.tooltip = "Remove this item from the queue.";
							cellFrame.tooltipLocation = "BOTTOM";
							
							ShowTooltip(cellFrame);
						elseif data[realrow] and data[realrow].rowData and data[realrow].rowData.itemId then
							GameTooltip:SetOwner(rowFrame, "ANCHOR_NONE");
							GameTooltip:SetPoint("TOPLEFT", rowFrame, "BOTTOMLEFT");
							GameTooltip:SetHyperlink(("item:%d"):format(data[realrow].rowData.itemId));
							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()
					HideTooltip();
				end,
				["OnClick"] = function(rowFrame, cellFrame, data, cols, row, realrow, column)
					if row and realrow then
						-- Data row
						
						if cols[column].name == "X" then
							cols[column].onClick(data[realrow].rowData);
							
							return true; -- cancel default event
						end
					end
				end,
			});
			scrollTable:EnableSelection(true);
			
			frame.scrollTable = scrollTable;
		
		-- 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 < 4 and 4) or newRows;
				
				this.scrollTable:SetDisplayRows(newRows, 15);
			end;
			frame:SetScript("OnSizeChanged", frame.AdjustScrollTableRows);
	end
	do
		local frameWidth = 300;
		
		-- Main window
			local frame = CreateFrame("Frame", "InventoriumQueuerUnqueueables", InventoriumQueuer);
			-- Hide by default
			frame:Hide();
			-- Position the frame against the queuer window
			frame:SetPoint("TOPLEFT", InventoriumQueuer, "TOPRIGHT", 0, 0);
			frame:SetPoint("BOTTOMLEFT", InventoriumQueuer, "BOTTOMLEFT", 0, 0);
			-- Put in front of other windows
			frame:SetFrameStrata("FULLSCREEN_DIALOG");
			frame:SetToplevel(true);
			-- Give it a size
			frame:SetWidth(frameWidth);
			-- 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);
			-- Set event handlers
			frame:SetScript("OnMouseUp", function(this) this:StopMovingOrSizing(); end);
			frame:SetScript("OnShow", function(this)
				this:AdjustScrollTableRows();
			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(90);
			titleBackground:SetHeight(40);
			
			frame.titleBackground = titleBackground;
			
			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("Unqueueables");
			
		-- 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("TOPLEFT", frame, "TOPLEFT", 15, -42);
			frmMeasureDummy:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -15, 15);
			
			frame.frmMeasureDummy = frmMeasureDummy;
			
		-- Scrolling table with a list of items to be queued
			local ScrollingTable = LibStub("ScrollingTable");
			local scrollTable = ScrollingTable:CreateST({}, 4, 15, nil, frame); -- inserting a dummy cols, real cols to be set in SetFrameSettings
			scrollTable.frame:SetPoint("TOPLEFT", frame, "TOPLEFT", 15, -42);
			scrollTable.frame:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -15, 15);
			-- When moving over a row, provide a tooltip for the item
			scrollTable: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.itemId then
							if column == 1 then
								GameTooltip:SetOwner(rowFrame, "ANCHOR_NONE");
								GameTooltip:SetPoint("TOPLEFT", rowFrame, "BOTTOMLEFT");
								GameTooltip:SetHyperlink(("item:%d"):format(data[realrow].rowData.itemId));
								GameTooltip:Show();
							else
								GameTooltip:SetOwner(cellFrame, "ANCHOR_NONE");
								GameTooltip:SetPoint("TOPLEFT", cellFrame, "BOTTOMLEFT");
								GameTooltip:SetText(data[realrow].rowData.reason[1]);
								GameTooltip:AddLine(data[realrow].rowData.reason[2], 1, 1, 1, 1);
								GameTooltip:Show();
							end
						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,
				["OnClick"] = function() end,
			});
			
			frame.scrollTable = scrollTable;
		
		-- 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 < 4 and 4) or newRows;
				
				this.scrollTable:SetDisplayRows(newRows, 15);
			end;
			frame:SetScript("OnSizeChanged", frame.AdjustScrollTableRows);
	end
end

function addon:SetQueueFrameData(queueable, unqueueables)
	InventoriumQueuer.scrollTable:SetData(queueable);
	InventoriumQueuerUnqueueables.scrollTable:SetData(unqueueables);
	
	InventoriumQueuer:Show();
end

function addon:SetQueueFrameSettings(title, description, proceed, cancel, headers, unqueueablesHeaders)
	local frame = InventoriumQueuer;
	
	frame.lblTitle:SetText(title);
	-- Adjust size for the title background
	frame.titleBackground:SetWidth((frame.lblTitle:GetWidth() or 0) + 10); -- 10 pixels margin
	
	frame.lblDescription:SetText(description);
	
	frame.btnProceed:SetText(proceed.text);
	frame.btnProceed.tooltipTitle = proceed.tooltipTitle;
	frame.btnProceed.tooltip = proceed.tooltip;
	frame.btnProceed.OnClick = proceed.onClick;
	
	frame.btnCancel:SetText(cancel.text);
	frame.btnCancel.tooltipTitle = cancel.tooltipTitle;
	frame.btnCancel.tooltip = cancel.tooltip;
	frame.btnCancel.OnClick = cancel.onClick;
	
	frame.scrollTable:SetDisplayCols(headers);
	
	InventoriumQueuerUnqueueables.scrollTable:SetDisplayCols(unqueueablesHeaders);
end