xMKHx Posted June 21, 2017 Posted June 21, 2017 Hello Community, Im MKH, i'm learning DirectX and everything about the DirectX, i've made a Dx Gui, Buttons, Tabs, but my problem is in Dx Gridlists Actually i'm working on GTA V Server, i've joined a server have a Dx Guies like GTA V's one Like This: Can you just give me an examples or the functions to make something like that and Thanks
AE. Posted June 21, 2017 Posted June 21, 2017 (edited) make a function for making a column and create a rectangle with width and height thats a one column but make sure to make a variable that hold the end pos of the x rectangle - there is a column now when someone creating new column with the function you created you will use the variable of the last end pos and add it to the new x pos like this function column(x,y,bla,bla) newx = x + oldx dxDrawRectangle(newx,bla,bla) end make the same for the row but with y pos note : oldx must be 0 for a new gridlist , oldy too Edited June 21, 2017 by 3laa33
#LorD-.? Posted June 21, 2017 Posted June 21, 2017 check this may be it's help you dxGrid = { items = {} }; local cursorOn; local NATIVE_RESOLUTION = { nil } -- put your screen resolution here to fit the gridlists to all resolutions (ex: { 1366, 768 } ) if ( table.maxn ( NATIVE_RESOLUTION ) == 2 ) then FIT_MODE = true RES = { guiGetScreenSize() }; X,Y = RES[1] / NATIVE_RESOLUTION[1], RES[2] / NATIVE_RESOLUTION[2]; SCALE = ( 1 / NATIVE_RESOLUTION[1] ) * RES[1]; end --=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Core - functions function dxGrid:Create ( x, y, width, height, postGUI ) -- table dxGrid:Create ( int x, int y, int width, int height[, bool postGUI ] ) if __checkParams ( "Create", "nnnn", x, y, width, height ) then local data = { x = FIT_MODE and ( x * X ) or x; -- X position y = FIT_MODE and ( y * Y ) or y; -- Y position w = FIT_MODE and ( width * X ) or width; -- Width h = FIT_MODE and ( height * Y ) or height; -- Height pg = postGUI or false; -- PostGUI i = {}; -- Items mi = __calcMaxItems ( FIT_MODE and ( height * Y ) or height ); -- Max items s = 1; -- Scroll Level r = -1; -- Row count se = -1; -- Selected item mo = nil; -- Mouse-on item vis = true -- Visible }; setmetatable ( data, { __index = dxGrid } ); table.insert ( dxGrid.items, data ); return data; end end function dxGrid:Destroy () -- bool dxGrid:Destroy () for k, v in pairs ( dxGrid.items ) do if v == self then dxGrid.items[k] = nil; return true; end end return false; end function dxGrid:SetVisible ( visible ) -- bool Gridlist:SetVisible ( bool state ) if __checkParams ( "SetVisible", "b", visible ) then self.vis = visible return true else return false end end function dxGrid:IsVisible ( ) -- bool Gridlist:IsVisible() return self.vis end function dxGrid:AddColumn ( title, width ) -- int Gridlist:AddColumn ( string title, int width ) if __checkParams ( "AddColumn", "sn", title, width ) then local data = { info = { title = title, width = FIT_MODE and ( width * X ) or width } }; table.insert ( self.i, data ); return #self.i; end end function dxGrid:RemoveColumn ( columnIndex ) -- bool Gridlist:RemoveColumn ( int columnIndex ) if __checkParams ( "RemoveColumn", "n", columnIndex ) then self.i[columnIndex] = nil; -- Recalculate the highest item count local highest = -1; for _, v in ipairs ( self.i ) do if #v > highest then highest = ( #v - 1 ); end end self.r = highest; -- Recalculate the scroll level (if necessary) if ( ( ( self.s + self.mi ) - 2 ) == self.r ) then self.s = ( self.r - self.mi ) + 1; end return true end return false end function dxGrid:GetColumnCount () -- int Gridlist:GetColumnCount() return #self.i end function dxGrid:AddItem ( columnIndex, text, data, r, g, b ) -- int Gridlist:AddItem ( int columnIndex, string title[, mixed data, int r, int g, int b ] ) if __checkParams ( "AddItem", "ns", columnIndex, text ) then if self.i[columnIndex] then local tColor = __checkRGB ( r, g, b ) and { r, g, b } or { 255, 255, 255 }; table.insert ( self.i[columnIndex], { id = #self.i[columnIndex] + 1, text = tostring( text ), data = data, color = tColor } ); if #self.i[columnIndex] > self.r then self.r = #self.i[columnIndex]; end return #self.i[columnIndex]; end return false; end end function dxGrid:RemoveItem ( column, itemID ) -- bool Gridlist:RemoveItem ( int columnIndex, int itemIndex ) if __checkParams ( "RemoveItem", "nn", column, itemID ) then if self.i[column] and self.i[column][itemID] then -- Recalculate the highest item count if self.r == #self.i[column] then local highest = -1; for _, v in ipairs ( self.i ) do if #v > highest then highest = ( #v - 1 ); end end self.r = highest; end -- Recalculate the scroll level (if necessary) if ( ( ( self.s + self.mi ) - 2 ) == self.r ) then self.s = ( self.r - self.mi ) + 1; end -- Reset the selected item if necessary² if itemID == self.se then local newItem = self.se - 1 if newItem <= self.r then self.se = math.max ( 0, newItem ); else self.se = -1 end end table.remove ( self.i[column], itemID ); return true; end return false end end function dxGrid:GetItemCount ( columnID ) -- int Gridlist:GetItemCount ( int columnIndex ) if __checkParams ( "GetItemCount", "n", columnID ) then if self.i[columnID] then return #self.i[columnID] end return false end end function dxGrid:Clear () -- bool Gridlist:Clear() for k, v in ipairs ( self.i ) do self.i[k] = { info = v.info } end self.r = -1 self.se = nil -- Recalculate the scroll level self.s = 1; return true end function dxGrid:GetSelectedItem ( ) -- int Gridlist:GetSelectedItem () return self.se; end function dxGrid:SetSelectedItem ( itemID ) -- bool Gridlist:SetSelectedItem ( int itemIndex ) if __checkParams ( "SetSelectedItem", "n", itemID ) then if itemID <= self.r then self.se = itemID; return self.se == itemID; end return false; end end function dxGrid:GetItemDetails ( column, itemID ) -- string, mixed Gridlist:GetItemDetails ( int columnIndex, int itemIndex ) column = column or 1 if __checkParams ( "GetItemDetails", "nn", columnID, itemID ) then if self.i[column] then if self.i[column][itemID] then return self.i[column][itemID].text, self.i[column][itemID].data end end end return false end --=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Core - render/move addEventHandler ( "onClientRender", root, function ( ) -- Is there any gridlist to render? if #dxGrid.items > 0 then -- Loop through all grid lists for index, data in ipairs ( dxGrid.items ) do -- Is the gridlist visible? if data.vis then -- Draw the 'gridlist' itself dxDrawRectangle ( data.x, data.y, data.w, data.h, tocolor ( 0, 0, 0, 200 ), data.pg ); -- Draw the column bar dxDrawRectangle ( data.x, data.y, data.w, 30 % data.h, tocolor ( 0, 0, 0, 220 ), data.pg ); -- Set cursorOn variable to the current gridlist, if it's selected cursorOn = nil if __isMouseInPosition ( data.x, data.y, data.w, data.h ) then cursorOn = index; end -- Check if there's any selected item local seeFrom = data.s; local seeTo = ( data.s + data.mi ) - 1; if data.se and data.se <= data.r and data.se >= seeFrom and data.se <= seeTo then local index = data.se - ( data.s - 1 ); local y2 = data.y + ( ( index - 1 ) * 25 ); -- Draw a rectangle to make it looks like selected dxDrawRectangle ( data.x, ( 30 % data.h ) + y2, data.w, 20, tocolor ( 0, 0, 0, 100 ), data.pg ); end -- Is there any column? if #data.i > 0 then local cWidth = 0 -- Loop through all columns for cIndex, cData in ipairs ( data.i ) do -- we'll go beyond the gridlist width with this column ? if ( ( cWidth + cData.info.width ) <= data.w ) then local x = data.x + cWidth; -- Draw the column title dxDrawText ( cData.info.title, x, data.y, cData.info.width + x, ( 30 % data.h ) + data.y, tocolor ( 255, 255, 255 ), FIT_MODE and ( 1 * SCALE ) or 1, "default-bold", "center", "center", true, true, data.pg, false, true ); -- Reset the selected item cData.info.selected = -1; -- Is there any item ? if #cData > 0 then local seeFrom = data.s; local seeTo = ( data.s + data.mi ) - 1; -- Loop the items for iIndex = seeFrom, seeTo do -- There's a row with this index in the current column? if cData[iIndex] then local index = iIndex - ( data.s - 1 ); local y = data.y + ( index * 25 ); local y2 = data.y + ( ( index - 1 ) * 25 ); -- Check if cursor is on item position if __isMouseInPosition ( data.x, ( 30 % data.h ) + y2, data.w, 20 ) then -- Define the mouse-on variable data.mo = iIndex; end -- Draw the item text dxDrawText ( cData[iIndex]["text"], x, y, cData.info.width + x, ( 30 % data.h ) + y, tocolor ( unpack ( cData[iIndex]["color"] ) ), FIT_MODE and ( 1 * SCALE ) or 1, "default-bold", "center", "center", true, true, data.pg, false, true ); end end end -- Increase cWidth variable (to draw the columns correctly) cWidth = cWidth + cData.info.width; end end end end end end end , true, "low-5") addEventHandler ( "onClientKey", root, function ( button, press ) -- Is cursor showing? if isCursorShowing () then -- Is there any gridlist? if #dxGrid.items > 0 then -- Is there any selected gridlist? if cursorOn then -- We pressed the scroll? if press and #button > 6 then -- Does the gridlist requires scroll? if dxGrid.items[cursorOn].r > dxGrid.items[cursorOn].mi then -- Define some variables local index = cursorOn; local currentValue = dxGrid.items[index].s; local newValue = math.max ( 1, button == "mouse_wheel_down" and currentValue + 2 or currentValue -1 ); -- Check if we have spent the row's limit with the new value if ( ( newValue + dxGrid.items[index].mi ) > dxGrid.items[index].r ) then newValue = ( dxGrid.items[index].r - dxGrid.items[index].mi ) + 1; end -- Set the new scroll level dxGrid.items[index].s = newValue; end elseif press and button == "mouse1" and dxGrid.items[cursorOn].mo then dxGrid.items[cursorOn].se = dxGrid.items[cursorOn].mo; end end end end end ) function __calcMaxItems ( height ) for i = 0, 9999 do if ( ( ( i + 1 ) * 25 ) >= math.floor ( height ) ) then return ( ( ( i + 1 ) * 25 ) > math.floor ( height ) and ( i - 1 ) or i ); end end return false; end function __checkParams ( methodName, pattern, ... ) local cTable = { ["string"] = "s"; ["number"] = "n"; ["boolean"] = "b"; ["s"] = "string"; ["n"] = "number"; ["b"] = "boolean" }; if #pattern > table.maxn ( { ... } ) then local index = table.maxn ( { ... } ) == 0 and 1 or table.maxn ( { ... } ) + 1 return false, error ( "Bad Argument @ '"..methodName.."' [Expected "..cTable[ pattern:sub ( index, index ) ].." at argument "..index..", got none]" ) end for k, v in pairs ( { ... } ) do if cTable[ type ( v ) ] ~= pattern:sub ( k, k ) then return false, error ( "Bad Argument @ '"..methodName.."' [Expected "..cTable[ pattern:sub ( k, k ) ].." at argument "..k..", got "..( type ( v ) or "none" ).."]" ) end end return true; end function __checkRGB ( r, g, b ) -- Check if all parameters were passed if ( not r ) or ( not g ) or ( not b ) then return false; end for _, v in ipairs ( { r, g, b } ) do if ( type ( v ) ~= "number" ) or ( v < 0 ) or ( v > 255 ) then return false; end end return true; end function __isMouseInPosition ( x, y, w, h ) if not isCursorShowing() then return false end local res = { guiGetScreenSize() }; local cpos = { getCursorPosition() }; local fpos = { res[1] * cpos[1], res[2] * cpos[2] }; return ( fpos[1] >= x and fpos[1] <= x + w ) and ( fpos[2] >= y and fpos[2] <= y + h ) end
Deeze Posted June 21, 2017 Posted June 21, 2017 (edited) --Gridlist Class local Gridlist = {} Gridlist.__index = Gridlist --Create a new Gridlist at screenPosition x, y with a given width and displaying visibleRows to the client function Gridlist.new(x, y, width, visibleRows) local self = setmetatable({}, Gridlist) self._startRow = 1 self._selectedRow = 1 self._visibleRows = visibleRows self._rowHeight = 20 self._position = {x = x, y = y} --VisibleRows + 1 because we will display a header self._size = {width = width, height = (1 + visibleRows) * self._rowHeight} self._columns = {} self._rows = {} self._listeners = {} addEventHandler("onClientKey", root, function(button, isPress) if (isPress) then if (button == "arrow_u") then self:setSelectedRowID(self:getSelectedRowID() - 1) elseif (button == "arrow_d") then self:setSelectedRowID(self:getSelectedRowID() + 1) end end end) return self end --Works similar to MTA Event system. function Gridlist:addListener(eventName, callback) if (not self._listeners[eventName]) then self._listeners[eventName] = {} end self._listeners[eventName][#self._listeners[eventName] + 1] = callback end function Gridlist:callListeners(eventName, ...) if (not self._listeners[eventName]) then return false end for i, v in pairs(self._listeners[eventName]) do v(...) end end --Add a new visible column with the given title, width and textAlign function Gridlist:addColumn(title, size, textAlign) self._columns[#self._columns + 1] = {name = title, width = size, align = textAlign} end --Set the ColumnTitle of a given column to the newTitle function Gridlist:setColumnTitle(columnIDOrName, newTitle) --In case we've used a name as ID if (type(columnIDOrName) == "string") then local foundEntry = false --Figure out which actual ID belongs to the column for i, v in pairs(self._columns) do if (v.name == columnIDOrName) then columnIDOrName = i foundEntry = true break end end if (not foundEntry) then outputDebugString("Tried to edit Gridlist Column title, but column was not found!") return false end end self._columns[columnIDOrName].name = newTitle end --Set the selected row ID function Gridlist:setSelectedRowID(ID) if (not self._rows[ID]) then outputDebugString("Tried to edit Gridlist Selected Row ID, but rowID was not found!") return false end self._selectedRow = ID self:callListeners("selectedRowChanged", ID) self:adjustStartRow() end --Adjust start row (for scrolling) function Gridlist:adjustStartRow() if (self._selectedRow > (self._startRow + self._visibleRows - 1)) then self._startRow = self._selectedRow - self._visibleRows + 1 elseif (self._selectedRow < self._startRow) then self._startRow = self._selectedRow end end --Returns currently selected row (id) use gridlist:getRows()[gridlist:getSelectedRowID] to access row directly function Gridlist:getSelectedRowID() return self._selectedRow end --Returns all rows of this gridlist function Gridlist:getRows() return self._rows end --adds a new row to this gridlist, parameters have to fill columns, like normal GUI gridlist function Gridlist:addRow(...) self._rows[#self._rows + 1] = {...} end --Draws the headers of this gridlist function Gridlist:drawHeaders() local x = self._position.x for i,v in pairs(self._columns) do dxDrawText(v.name, x, self._position.y, x + v.width, self._position.y + self._rowHeight, tocolor(255, 255, 255, 255), 1, "default-bold", v.align, "center") x = x + v.width end end --Draws the rows of this gridlist function Gridlist:drawRows() local y = self._position.y + self._rowHeight for i = self._startRow, self._startRow + self._visibleRows - 1, 1 do local row = self._rows[i] if (row) then --Is this the selected row? local textColor = tocolor(255, 255, 255, 255) if (self:getSelectedRowID() == i) then dxDrawRectangle(self._position.x, y, self._size.width, self._rowHeight, tocolor(255, 255, 255, 255)) textColor = tocolor(0, 0, 0, 255) end --Draw it local x = self._position.x for id, text in pairs(row) do local col = self._columns[id] dxDrawText(text, x, y, x + col.width,y + self._rowHeight, textColor, 1, "default-bold", col.align, "center") x = x + col.width end y = y + self._rowHeight end end end --Renders this gridlist function Gridlist:render() --Background dxDrawRectangle(self._position.x, self._position.y, self._size.width, self._size.height, tocolor(0, 0, 0, 200)) self:drawHeaders() self:drawRows() end ------------------------------------------------------------------------------------------ local sX, sY = guiGetScreenSize() local w, elements = 300, 6 --Create a new gridlist at the center of the screen which displays (6) elements with the width of 300 pixels local grid = Gridlist.new(sX * 0.5 - (w * 0.5), sY * 0.5, w, elements) --Add 2 columns, both are 150 pixels wide (300 * 0.5) grid:addColumn("INTERACTION MENU", (w * 0.5), "left") grid:addColumn("0 / 0", (w * 0.5), "right") --Add different rows grid:addRow("QUICK GPS", "None") grid:addRow("Inventory", "") grid:addRow("Action", "Crew: The Bird") grid:addRow("Player Mood", "Normal") grid:addRow("Disable Passive Mode", "") grid:addRow("Highlight Player", "") grid:addRow("Another Option #1", "") grid:addRow("Another Option #2", "") grid:addRow("Another Option #3", "") grid:addRow("Another Option #4", "") grid:addRow("Another Option #5", "") --Update our column title local function newRowSelected(row) grid:setColumnTitle(2, grid:getSelectedRowID() .. "/ " .. #grid:getRows()) end grid:addListener("selectedRowChanged", newRowSelected) grid:setSelectedRowID(1) --Let's draw our gridlist! addEventHandler("onClientRender", root, function() grid:render() end) Here's a small example of how you could do it, obviously this doesn't have all the features you need, but this should work as a base that you can expand on. Edited June 21, 2017 by Deeze 1
xMKHx Posted June 24, 2017 Author Posted June 24, 2017 On 6/21/2017 at 13:05, Deeze said: --Gridlist Class local Gridlist = {} Gridlist.__index = Gridlist --Create a new Gridlist at screenPosition x, y with a given width and displaying visibleRows to the client function Gridlist.new(x, y, width, visibleRows) local self = setmetatable({}, Gridlist) self._startRow = 1 self._selectedRow = 1 self._visibleRows = visibleRows self._rowHeight = 20 self._position = {x = x, y = y} --VisibleRows + 1 because we will display a header self._size = {width = width, height = (1 + visibleRows) * self._rowHeight} self._columns = {} self._rows = {} self._listeners = {} addEventHandler("onClientKey", root, function(button, isPress) if (isPress) then if (button == "arrow_u") then self:setSelectedRowID(self:getSelectedRowID() - 1) elseif (button == "arrow_d") then self:setSelectedRowID(self:getSelectedRowID() + 1) end end end) return self end --Works similar to MTA Event system. function Gridlist:addListener(eventName, callback) if (not self._listeners[eventName]) then self._listeners[eventName] = {} end self._listeners[eventName][#self._listeners[eventName] + 1] = callback end function Gridlist:callListeners(eventName, ...) if (not self._listeners[eventName]) then return false end for i, v in pairs(self._listeners[eventName]) do v(...) end end --Add a new visible column with the given title, width and textAlign function Gridlist:addColumn(title, size, textAlign) self._columns[#self._columns + 1] = {name = title, width = size, align = textAlign} end --Set the ColumnTitle of a given column to the newTitle function Gridlist:setColumnTitle(columnIDOrName, newTitle) --In case we've used a name as ID if (type(columnIDOrName) == "string") then local foundEntry = false --Figure out which actual ID belongs to the column for i, v in pairs(self._columns) do if (v.name == columnIDOrName) then columnIDOrName = i foundEntry = true break end end if (not foundEntry) then outputDebugString("Tried to edit Gridlist Column title, but column was not found!") return false end end self._columns[columnIDOrName].name = newTitle end --Set the selected row ID function Gridlist:setSelectedRowID(ID) if (not self._rows[ID]) then outputDebugString("Tried to edit Gridlist Selected Row ID, but rowID was not found!") return false end self._selectedRow = ID self:callListeners("selectedRowChanged", ID) self:adjustStartRow() end --Adjust start row (for scrolling) function Gridlist:adjustStartRow() if (self._selectedRow > (self._startRow + self._visibleRows - 1)) then self._startRow = self._selectedRow - self._visibleRows + 1 elseif (self._selectedRow < self._startRow) then self._startRow = self._selectedRow end end --Returns currently selected row (id) use gridlist:getRows()[gridlist:getSelectedRowID] to access row directly function Gridlist:getSelectedRowID() return self._selectedRow end --Returns all rows of this gridlist function Gridlist:getRows() return self._rows end --adds a new row to this gridlist, parameters have to fill columns, like normal GUI gridlist function Gridlist:addRow(...) self._rows[#self._rows + 1] = {...} end --Draws the headers of this gridlist function Gridlist:drawHeaders() local x = self._position.x for i,v in pairs(self._columns) do dxDrawText(v.name, x, self._position.y, x + v.width, self._position.y + self._rowHeight, tocolor(255, 255, 255, 255), 1, "default-bold", v.align, "center") x = x + v.width end end --Draws the rows of this gridlist function Gridlist:drawRows() local y = self._position.y + self._rowHeight for i = self._startRow, self._startRow + self._visibleRows - 1, 1 do local row = self._rows[i] if (row) then --Is this the selected row? local textColor = tocolor(255, 255, 255, 255) if (self:getSelectedRowID() == i) then dxDrawRectangle(self._position.x, y, self._size.width, self._rowHeight, tocolor(255, 255, 255, 255)) textColor = tocolor(0, 0, 0, 255) end --Draw it local x = self._position.x for id, text in pairs(row) do local col = self._columns[id] dxDrawText(text, x, y, x + col.width,y + self._rowHeight, textColor, 1, "default-bold", col.align, "center") x = x + col.width end y = y + self._rowHeight end end end --Renders this gridlist function Gridlist:render() --Background dxDrawRectangle(self._position.x, self._position.y, self._size.width, self._size.height, tocolor(0, 0, 0, 200)) self:drawHeaders() self:drawRows() end ------------------------------------------------------------------------------------------ local sX, sY = guiGetScreenSize() local w, elements = 300, 6 --Create a new gridlist at the center of the screen which displays (6) elements with the width of 300 pixels local grid = Gridlist.new(sX * 0.5 - (w * 0.5), sY * 0.5, w, elements) --Add 2 columns, both are 150 pixels wide (300 * 0.5) grid:addColumn("INTERACTION MENU", (w * 0.5), "left") grid:addColumn("0 / 0", (w * 0.5), "right") --Add different rows grid:addRow("QUICK GPS", "None") grid:addRow("Inventory", "") grid:addRow("Action", "Crew: The Bird") grid:addRow("Player Mood", "Normal") grid:addRow("Disable Passive Mode", "") grid:addRow("Highlight Player", "") grid:addRow("Another Option #1", "") grid:addRow("Another Option #2", "") grid:addRow("Another Option #3", "") grid:addRow("Another Option #4", "") grid:addRow("Another Option #5", "") --Update our column title local function newRowSelected(row) grid:setColumnTitle(2, grid:getSelectedRowID() .. "/ " .. #grid:getRows()) end grid:addListener("selectedRowChanged", newRowSelected) grid:setSelectedRowID(1) --Let's draw our gridlist! addEventHandler("onClientRender", root, function() grid:render() end) Here's a small example of how you could do it, obviously this doesn't have all the features you need, but this should work as a base that you can expand on. Thnx a lot ♥
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now