Jump to content

Drag'n'Drop


ds1-e

Recommended Posts

You could use the following functions/events >

(Event) -> onClientClick -> Returns: you'll need to identify the clickedElement as the type of GUI you want to move

button, state, absoluteX, absoluteY, worldX, worldY, worldZ, clickedElement

Instead of the above you could use:

(Event) -> onClientGUIClick -> which returns the clicked GUI element rather than an element clicked -> returns: 

button, state, absoluteX, absoluteY

(Event) -> onClientCursorMove -> Returns: use absoluteX, absoluteY as your X / Y params needed to move.

cursorX, cursorY, absoluteX, absoluteY, worldX, worldY, worldZ

(Function) -> guiSetPosition() -> usage: 

 guiSetPosition(clickedElement, absoluteX, absoluteY, false)

Use onClientRender/onClientPreRender to render the moving transition of the element you're moving. Not sure if this is the best way, but most simple. Goodluck

  • Thanks 1
Link to comment
  • Scripting Moderators
22 hours ago, XaskeL said:

click (working area) - get item to memory - move to new area - release the mouse button - overwrite data.

if i can access my computer, i will show you an example

I have found this event:

onClientGUIMouseDown - This event is fired when the user clicks certain mouse button on a GUI element.

And example for it:

-- This example show how to add very basic click'n'drag feature for GUI elements (only for those which parent element is gui-root)
addEventHandler( "onClientGUIMouseDown", getRootElement( ),
    function ( btn, x, y )
        if btn == "left" then
            clickedElement = source; -- store the clicked element in a global variable
            local elementPos = { guiGetPosition( source, false ) };
            offsetPos = { x - elementPos[ 1 ], y - elementPos[ 2 ] }; -- get the offset position
        end
    end
);

addEventHandler( "onClientGUIMouseUp", getRootElement( ),
    function ( btn, x, y )
        if btn == "left" then
            clickedElement = nil;
        end
    end
);

addEventHandler( "onClientCursorMove", getRootElement( ),
    function ( _, _, x, y )
        if clickedElement then
            guiSetPosition( clickedElement, x - offsetPos[ 1 ], y - offsetPos[ 2 ], false );
        end
    end
);

 

Those three events should work for row(s)? After some changes.

UPD: @Ab-47 i will try it. 

Edited by majqq
  • Like 1
Link to comment
  • Scripting Moderators

bump, make it works. but for some reason it creates a window, even if gui item isn't marked, and not always shows title of marked item.

local bindWindow
local isHolding = false

function onClientGUIMouseDown(button, absoluteX, absoluteY)
	if button == "left" and getElementType(source) == "gui-gridlist" then
		local itemSelected = guiGridListGetItemText(source, guiGridListGetSelectedItem(source), 1)
		if itemSelected then
			bindWindow = guiCreateWindow(absoluteX, absoluteY, 2, 0.2, itemSelected, false)
			isHolding = true
		end
	end
end
addEventHandler("onClientGUIMouseDown", inventoryGridlist["inventory"], onClientGUIMouseDown)

function onClientGUIMouseUp(button, absoluteX, absoluteY)
	if button == "left" then
		if isHolding then
			isHolding = false
			if isElement(bindWindow) then
				destroyElement(bindWindow)
			end
		end
	end
end
addEventHandler("onClientGUIMouseUp", getRootElement(), onClientGUIMouseUp)

function onClientCursorMove(cursorX, cursorY, absoluteX, absoluteY, worldX, worldY, worldZ)
	if bindWindow and isHolding then
		guiSetPosition(bindWindow, absoluteX, absoluteY, false)
	end
end
addEventHandler("onClientCursorMove", getRootElement(), onClientCursorMove)

 

Edited by majqq
Link to comment

You're creating a GUI in your code, I just modified the code you sent above including the variables you mentioned in your code. Try this

isHolding = false

addEventHandler( "onClientGUIMouseDown", getRootElement( ),
    function ( btn, x, y )
		if (source ~= inventoryGridlist["inventory"]) then return end
        if btn == "left" and getElementType(source) == "gui-gridlist" then
            clickedElement = source
            local elementPos = { guiGetPosition( source, false ) }
            offsetPos = { x - elementPos[ 1 ], y - elementPos[ 2 ] }
			isHolding = true
        end
    end
)

addEventHandler( "onClientGUIMouseUp", getRootElement( ),
    function ( btn, x, y )
        if btn == "left" then
			if isHolding then
				isHolding = false
				clickedElement = nil
			end
        end
    end
)

addEventHandler( "onClientCursorMove", getRootElement( ),
    function ( _, _, x, y )
        if clickedElement and isHolding then
            guiSetPosition( clickedElement, x - offsetPos[ 1 ], y - offsetPos[ 2 ], false )
        end
    end
)

 

  • Like 1
Link to comment
  • Scripting Moderators
8 hours ago, Ab-47 said:

You're creating a GUI in your code, I just modified the code you sent above including the variables you mentioned in your code. Try this


isHolding = false

addEventHandler( "onClientGUIMouseDown", getRootElement( ),
    function ( btn, x, y )
		if (source ~= inventoryGridlist["inventory"]) then return end
        if btn == "left" and getElementType(source) == "gui-gridlist" then
            clickedElement = source
            local elementPos = { guiGetPosition( source, false ) }
            offsetPos = { x - elementPos[ 1 ], y - elementPos[ 2 ] }
			isHolding = true
        end
    end
)

addEventHandler( "onClientGUIMouseUp", getRootElement( ),
    function ( btn, x, y )
        if btn == "left" then
			if isHolding then
				isHolding = false
				clickedElement = nil
			end
        end
    end
)

addEventHandler( "onClientCursorMove", getRootElement( ),
    function ( _, _, x, y )
        if clickedElement and isHolding then
            guiSetPosition( clickedElement, x - offsetPos[ 1 ], y - offsetPos[ 2 ], false )
        end
    end
)

 

 

Thanks but it's not that what i need. Functions which i send above, it's working and it's a good example, what i want to create.

I have made some changes in code, changed creating GUI window to dxDrawRectangle to simulate (not moving it in fact) holding a marked row (within OnClientRender).

So for now i need to resolve my problems:

- How to get where i dropped row? I thought to use isCursorOnElement.

- Creating rectangle even if row isn't marked, it shouldn't be like that.

- Item title isn't showing all the time.

 

Link to comment
  • Scripting Moderators

Sorry for double post, i can't edit my post above.

Updated code:

local posX
local posY
local isHolding = false

function onClientGUIMouseDown(button, absoluteX, absoluteY)
	if button == "left" then
		if getElementType(source) == "gui-gridlist" then
			local itemSelected = guiGridListGetItemText(source, guiGridListGetSelectedItem(source), 1)
			if itemSelected then
				posX = absoluteX
				posY = absoluteY
				isHolding = true
			end
		end
	end
end
addEventHandler("onClientGUIMouseDown", inventoryGridlist["inventory"], onClientGUIMouseDown)

function onClientKey(button, press)
	if not press and button == "mouse1" then
		isHolding = false
	end
end
addEventHandler("onClientKey", getRootElement(), onClientKey)

function onClientCursorMove(cursorX, cursorY, absoluteX, absoluteY, worldX, worldY, worldZ)
	if isHolding then
		posX = absoluteX
		posY = absoluteY
	end
end
addEventHandler("onClientCursorMove", getRootElement(), onClientCursorMove)

function onClientRender()
	if not isHolding then return end
	dxDrawRectangle(posX, posY, 100, 15, tocolor(74, 94, 183, 255), true)
end
addEventHandler("onClientRender", getRootElement(), onClientRender)

 

Fixed that rectangle doesn't hide after leaving mouse1 click.

But following problem still exist:

- Rectangle draws, even if item isn't selected.

I think i could fix not showing title, but i don't have idea, what i can do with things above.

 

Link to comment
  • Moderators
1 hour ago, majqq said:

But following problem still exist:

- Rectangle draws, even if item isn't selected.

 I think i could fix not showing title, but i don't have idea, what i can do with things above. 

How would you reproduce that? Based to a quick look to your code that should be fine. Unless something is not working etc.

See also this function:

https://wiki.multitheftauto.com/wiki/GetKeyState

Edited by IIYAMA
  • Like 1
Link to comment
  • Scripting Moderators
3 hours ago, IIYAMA said:

How would you reproduce that? Based to a quick look to your code that should be fine. Unless something is not working etc.

See also this function:

https://wiki.multitheftauto.com/wiki/GetKeyState

I have already fixed it, and i fixed a bit that with drawing rectangle if item isn't marked. Now, i need to check somehow, if i user is holding an "row", and if he drops it on button. 

Any suggestions, for now excluding isCursorOnElement?

function onClientGUIMouseDown(button, absoluteX, absoluteY)
	if button == "left" then
		if getElementType(source) == "gui-gridlist" then
			--local itemSelected = guiGridListGetItemText(source, guiGridListGetSelectedItem(source), 1)
			local itemSelected = guiGridListGetSelectedItem(source)
			if itemSelected and itemSelected >= 0 then
				posX = absoluteX
				posY = absoluteY
				isHolding = true
			end
		end
	end
end
addEventHandler("onClientGUIMouseDown", inventoryGridlist["inventory"], onClientGUIMouseDown)

function onClientKey(button, press)
	if not press and button == "mouse1" then
		isHolding = false
	end
end
addEventHandler("onClientKey", getRootElement(), onClientKey)

function onClientCursorMove(cursorX, cursorY, absoluteX, absoluteY, worldX, worldY, worldZ)
	if isHolding then
		posX = absoluteX
		posY = absoluteY
	end
end
addEventHandler("onClientCursorMove", getRootElement(), onClientCursorMove)

function onClientRender()
	if not isHolding then return end
	dxDrawRectangle(posX, posY, 200, 15, tocolor(74, 94, 183, 255), true)
end
addEventHandler("onClientRender", getRootElement(), onClientRender)

 

Link to comment
  • Moderators
51 minutes ago, majqq said:

Any suggestions, for now excluding isCursorOnElement?

 

Not sure if this works:

 

https://wiki.multitheftauto.com/wiki/OnClientMouseMove

Attach it to the gridlist.

 

+

 

-- doing some cursor position recalculation ...
-- ...
-- some more till you get the inner bounding box of the gridlist

 

+

 

https://wiki.multitheftauto.com/wiki/GuiGridListGetRowCount

 

math.ceil(cursorInBoxPositionY / boxHeight * columns)

 

 

  • Like 1
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...