view Frames.lua @ 241:65a9ef84d18f

User manual update.
author Zerotorescue
date Sat, 12 Feb 2011 20:15:40 +0100
parents 5d13830e8b0d
children
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);
			-- Close on escape
			tinsert(UISpecialFrames, "InventoriumQueuer");
			-- 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;
				
			-- Craft
				local btnCraft = CreateFrame("Button", "$parentCraft", frame, "UIPanelButtonTemplate");
				btnCraft:SetHeight(21);
				--btnCraft:SetWidth(125);
				btnCraft:SetPoint("TOPLEFT", btnProceed, "TOPRIGHT", 15, 0);
				btnCraft:SetPoint("BOTTOMRIGHT", btnCancel, "BOTTOMLEFT", -15, 0);
				btnCraft:SetScript("OnClick", function(this) this.OnClick(this); end);
				btnCraft:SetScript("OnEnter", ShowTooltip);
				btnCraft:SetScript("OnLeave", HideTooltip);
				
				frame.btnCraft = btnCraft;
			
		-- 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, craft, 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.btnCraft:SetText(craft.text);
	frame.btnCraft.tooltipTitle = craft.tooltipTitle;
	frame.btnCraft.tooltip = craft.tooltip;
	frame.btnCraft.OnClick = craft.onClick;
	
	frame.scrollTable:SetDisplayCols(headers);
	
	InventoriumQueuerUnqueueables.scrollTable:SetDisplayCols(unqueueablesHeaders);
end