Jump to content

[Help] dxGridlist edit


AlvarO

Recommended Posts

Hey guys, I'm trying to edit a dxGridlist whose owner is t3wz, all rights goes for he. So I tried to make that for when the cursor clicks on the colum, it will show the items, and when one item is selected, the list of items will get closed, but I don't know how to make it, so if someone more experimented could help me I would be glad of it, the code is the following:

  
dxGrid          =   { items = {} };
local cursorOn;
local shown = false
 
local NATIVE_RESOLUTION     =   { 1920, 1080 }
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 )
    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 )
 
    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
        return false
    end
end
 
--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Core - render/move
 
function drawDxGridlist( button, state, absoluteX, absoluteY, wx, wy, wz, clickedElement )
        -- 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 =
Link to comment
  • 2 weeks later...

Hi AlvarO,

Check out this wiki for his framework: https://github.com/t3wz/dxGridlists/wiki

To do what you want, you can use these:

Events:

onClientClick

Functions:

SetVisible()

GetSelectedItem()

Let me know if you need any help with them.

You can also check the code of our Cinema script where we use the same framework.

Also, I'll warn you,

There are some nasty bugs in this framework, mainly with the way the items are handled.

For example, if you have a full list and delete an item from the bottom, it'll create an empty space at the top of the gridlist instead of at the bottom.

It's weird and it screws up the entire gridlist and the information each item holds.

To avoid this we just refresh/clear the gridlist each time an item is removed or added (using a table) then we add everything back in.

I haven't reported it to t3wz yet.

Link to comment

I still need a bit of help, i checked if the mouse is on the categorie rectangle, and then i checked if the key pressed is mouse1 (the left button of mouse), but still don't know how to continue, im newbie in this of making/editing dxGUIs

CODE:

  
hover = false 
  
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, 30 % data.h, tocolor ( 255, 102, 0, 220 ), true ); 
  
                    -- 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, true, false, true ); 
  
                                -- Reset the selected item 
                                cData.info.selected = -1; 
  
                                -- Is there any item ? 
                                if __isMouseInPosition(data.x, data.y, data.w, data.h) then 
                                    if getKeyState("mouse1") then 
                                        hover = true 
                                        if #cData > 0 and hover == true 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 ); 
                                                    dxDrawRectangle ( data.x, data.y, data.w, data.h, tocolor ( 0, 0, 0, 200 ), data.pg ); 
                                                end 
                                            end 
                                        end 
                                        -- Increase cWidth variable (to draw the columns correctly) 
                                        cWidth = cWidth + cData.info.width; 
                                    end 
                                end 
                            end 
                        end 
                    end 
                end 
            end 
        end 
    end 
, true, "low-5") 
  

Link to comment

Ah I see what you mean now. I don't have much experience with it myself, I've tried to edit the framework before and failed badly. Only managed to make some small changes.

However, you can use the functions I mentioned in my other post, in your own script.

For example,

myList = dxGrid:Create(852, 298, 391, 628) 
  
function onDxClick(button,state) 
    if button == "left" and state == "up" then 
        if getMouseWithinPos(852, 298, 391, 628) then 
            local selectedItem = myList:GetSelectedItem() 
            if selectedItem == 0 then 
                myList:SetVisible(false) 
            end 
        end 
    end 
end 
addEventHandler("onClientDoubleClick",root,onDxClick) 

And this neat little function that I use in all my scripts (or variations of it at least)

function getMouseWithinPos(x, y, w, h) 
    if isCursorShowing() then 
        local srw,srh = 1280,720 -- change to your resolution (same one as in the dxGrid lua) 
        local cx, cy = getCursorPosition() 
        local cx, cy = cx*srw,cy*srh 
        if cx >= x and cx <= x+w and cy >= y and cy <= y+h then 
         
            return cx, cy 
        end 
    end 
end 

Note the srw,srh in the getMouseWithinPos function. It's to make the click positions match up with the gridlist, since the gridlist click positions are setup the same way. This function only works in this particular situation. If you want it to work for your other scripts, you have to make your dxGui relative first or replace the first line with srw,srh = guiGetScreenSize() but then your clicking position will be off on different resolutions.

Scripting dxGui can get pretty complicated (I'm still learning more about it), so I hope this doesn't confuse you. Let me know if you need more help.

Link to comment

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...