xMKHx Posted June 21, 2017 Share 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 Link to comment
AE. Posted June 21, 2017 Share 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 Link to comment
#LorD-.? Posted June 21, 2017 Share 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 Link to comment
Deeze Posted June 21, 2017 Share 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 Link to comment
xMKHx Posted June 24, 2017 Author Share 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 ♥ Link to comment
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