📄 earthtable.lua
字号:
--[[---- Earth Table-- By Alexander Brazie---- A spreadsheet style organization system.----]]EARTHTABLE_HEADER_HEIGHT = 24;EARTHTABLE_ROW_HEIGHT = 16;EARTHTABLE_HEADER_MAX = 6;EARTHTABLE_ROW_MAX = 20;EARTHTABLE_DEFAULT_HEADER_COLOR = NORMAL_FONT_COLOR;EARTHTABLE_DEFAULT_DATA_COLOR = HIGHLIGHT_FONT_COLOR;EARTHTABLE_DEBUG = false;ETABLE_DEBUG = "EARTHTABLE_DEBUG";--[[---- Using EarthTable---- Create a frame which inherits EarthTableFrameTemplate---- Then create your database, a table with key-value pairs. This can be-- any type of lua table, so long as the first level index is numbers only.---- e.g. database = {-- [1] = {name="Alex";class="Warlock";onClick=function() Sea.io.print("hi!");};-- [2] = {name="John";class="Priest";onClick=function() Sea.io.print("GoAway!");};-- };---- ---- Then create the headers. ---- The header list should be a list of all possible headers. -- Each header can have:-- -- .title - Header title-- .titleColor - color of the title text-- .textColor - color of the table text for that col.-- .key - [REQUIRED] the database key used for that row. -- (In this case, "name" or "class" would work).-- .disabled - not clickable if true---- .stick - true if the header should not be removed when changing pages. -- No more than 1 of these per table for your own sake.---- .width - maximum width of the column.-- If the width is larger than the whole table, it will be shrunken.-- -- Then call -- EarthTable_LoadDatabase(MyTableFrame, myDatabase);-- EarthTable_LoadHeaders(MyTableFrame, myHeaders);-- EarthTable_UpdateFrame(MyTableFrame);----]]--[[ Updates a single frame ]]--function EarthTable_UpdateFrame(frame) local headerBudget = frame.headerSpace; local vOffset = FauxScrollFrame_GetOffset(getglobal(frame:GetName().."ListScrollFrameV")); local hOffset = FauxScrollFrame_GetOffset(getglobal(frame:GetName().."ListScrollFrameH")); local currentOffset = nil; local newActiveHeaders = {}; local stickCount = 0; for k,v in frame.activeHeaders do if ( frame.headerList[v].stick and headerBudget > frame.headerList[v].width ) then table.insert(newActiveHeaders, v); headerBudget = headerBudget - frame.headerList[v].width; stickCount = stickCount + 1; end end -- Cycle through all headers. Fit as many as possible for i=hOffset+1, table.getn(frame.headerList) do if ( frame.headerList[i] ) then local alreadyAdded = false; -- Ensure we don't add the same header multiple times for k,v in newActiveHeaders do if ( v == i ) then alreadyAdded = true; end end -- If its not already added... if ( not alreadyAdded ) then -- If we have any headerspace left if ( headerBudget >= frame.headerList[i].width and table.getn(newActiveHeaders) <= frame.headerMax ) then table.insert(newActiveHeaders, i); headerBudget = headerBudget - frame.headerList[i].width; -- But if we also have no headers, accept this header elseif ( table.getn(newActiveHeaders) == stickCount ) then table.insert(newActiveHeaders, i); break; else break; end end end end -- Clear all headers and cells for j=1,EARTHTABLE_HEADER_MAX do local header = getglobal(frame:GetName().."ColumnHeader"..j); EarthTable_Header_Clear(header); header:Hide(); for i=1,frame.rowCount do local nth = i + vOffset; local cell = getglobal(frame:GetName().."Row"..i.."Cell"..j); -- Hide unused cells. EarthTable_Cell_Clear(cell); end end frame.activeHeaders = newActiveHeaders; -- Reset the headerBudget headerBudget = frame.headerSpace; local lastHeader = 0; for k,v in frame.activeHeaders do local header = getglobal(frame:GetName().."ColumnHeader"..k); lastHeader = k; if ( frame.headerList[v] and headerBudget > 0 ) then header:SetText(frame.headerList[v].title); header:Show(); -- Set the Width if ( frame.headerList[v].width <= headerBudget ) then EarthTable_Header_SetWidth(frame.headerList[v].width, header); else EarthTable_Header_SetWidth(headerBudget, header); end -- Set the header color if ( frame.headerList[v].titleColor ) then header:SetTextColor(frame.headerList[v].titleColor.r,frame.headerList[v].titleColor.g,frame.headerList[v].titleColor.b); else header:SetTextColor(EARTHTABLE_DEFAULT_HEADER_COLOR.r,EARTHTABLE_DEFAULT_HEADER_COLOR.g,EARTHTABLE_DEFAULT_HEADER_COLOR.b); end -- Check if its clickable if ( frame.headerList[v].disabled ) then header:Disable(); else header:Enable(); end local key = frame.headerList[v].key; for i=1,frame.rowCount do local nth = i + vOffset; local cell = getglobal(frame:GetName().."Row"..i.."Cell"..k); -- If an index exists, fill the cell if ( frame.database[nth] ) then local text = EarthTable_GetInfo(frame.database[nth][key]); cell:SetText(text); if ( frame.headerList[v].width <= headerBudget ) then cell:SetWidth(frame.headerList[v].width); else cell:SetWidth(headerBudget); end -- Ooh text color! if ( frame.headerList[v].textColor ) then cell:SetTextColor(frame.headerList[v].textColor.r,frame.headerList[v].textColor.g,frame.headerList[v].textColor.b); else cell:SetTextColor(EARTHTABLE_DEFAULT_DATA_COLOR.r,EARTHTABLE_DEFAULT_DATA_COLOR.g,EARTHTABLE_DEFAULT_DATA_COLOR.b); end cell:Show(); else end end -- Empty the header budget headerBudget = headerBudget - frame.headerList[v].width; end end -- ScrollFrame update FauxScrollFrame_Update(getglobal(frame:GetName().."ListScrollFrameV"), table.getn(frame.database), frame.rowCount, EARTHTABLE_ROW_HEIGHT); local newmax = table.getn(frame.headerList)-1; if ( newmax < 0 ) then newmax = 0; end getglobal(frame:GetName().."ListScrollFrameH".."ScrollBar"):SetMinMaxValues(stickCount,newmax); getglobal(frame:GetName().."ListScrollFrameH".."ScrollBar"):SetValueStep(1);end--[[ Sets the Table's database ]]--function EarthTable_LoadDatabase(frame,database) frame.database = database;end--[[ Sets the table's headers ]]--function EarthTable_LoadHeaders(frame,headers) if ( EarthTable_CheckHeaders(headers) ) then frame.headerList = headers; frame.activeHeaders = {}; else Sea.io.error("Invalid header for ", frame, "! ", this:GetName()); endend--[[ Validates a Header Table ]]--function EarthTable_CheckHeaders(headers) for k,v in headers do if ( not EarthTable_CheckHeader(v) ) then Sea.io.error("Invalid header! ",this:GetName()); return false; end end return true;end--[[ Validates a single header table ]]--function EarthTable_CheckHeader(header) if ( not header.key ) then Sea.io.error("No key specified in header! ",this:GetName()); return false; end if ( not header.title ) then header.title = header.key; end if ( not header.width or header.width <= 0 ) then header.width = 50; end return true;end--[[ The Workhorse ]]--function EarthTable_HandleEvent(frame, id, action, a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20 ) Sea.io.dprint(ETABLE_DEBUG, frame,": ",id," ",action); local vOffset = FauxScrollFrame_GetOffset(getglobal(frame:GetName().."ListScrollFrameV")); local nth = id + vOffset; local update = true; if ( action == "CLICK_HEADER" ) then local currentHeader = frame.activeHeaders[id]; -- Lets see if its already there. local found = false; if ( frame.sortingOrder.headerId == currentHeader ) then frame.sortingOrder = { headerId = currentHeader; key = frame.headerList[currentHeader].key; reverse = not frame.sortingOrder.reverse; }; -- If this sort hasn't been added, then add it else frame.sortingOrder = { headerId = currentHeader; key = frame.headerList[currentHeader].key; reverse = false; }; end -- Perform the sorting, oh hat! table.sort(frame.database, EarthTable_CreateComparator(frame.sortingOrder)); elseif ( action == "CLICK_ROW" ) then local item = EarthTable_GetDatabaseItemByID(frame,id); if ( item and item.onClick ) then item.onClick(item); end elseif ( action == "DOUBLECLICK_ROW" ) then local item = EarthTable_GetDatabaseItemByID(frame,id); if ( item and item.onDoubleClick ) then item.onDoubleClick(item); end elseif ( action == "ENTER_ROW" ) then local item = EarthTable_GetDatabaseItemByID(frame, id); if ( item and item.tooltip ) then EarthTable_SetTooltip(frame, item.tooltip); end update = false; elseif ( action == "ENTER_HEADER" ) then local header = EarthTable_GetHeaderByID(frame,id); if ( header and header.tooltip ) then EarthTable_SetTooltip(frame, header.tooltip); end update = false; elseif ( action == "LEAVE_HEADER" or action == "LEAVE_ROW" ) then EarthTable_HideTooltip(frame); update = false; end -- Update the gui if ( update ) then EarthTable_UpdateFrame(frame); endend--[[-- GUI Modifiers----]]function EarthTable_Header_SetWidth(width, frame)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -