This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
zacpier's profile picture

[ADV. Comp] Mouse drag

Started by zacpier, 27 January 2013 - 07:55 PM
zacpier #1
Posted 27 January 2013 - 08:55 PM
I'm going to assume that you can at least understand this:

colorOptions = {colors.red, colors.white, colors.blue, colors.green, colors.orange}
function dPixed(x,y)
  local lastX, lastY = term.getCursorPos()
  term.setBackgroundColor(colorOptions[math.random(1,#colorOptions])
  term.setCursorPos(x,y)
  write(" ")
  term.setCursorPos(lastX,lastY)
end
while true do
  type, btn, x, y = os.pullEvent("mouse_click")
  dPixel(x,y)
end

If you didn't get that, then here's an explanation.
SpoilerWhen you click, draw a randomly-colored pixel where I clicked.
It will be either red, white, blue, green, or orange.
It will last until you ctrl-t terminate it or break the computer.

As you may know, you can use os.startTimer(paramTime) to queue a timed event. What you may not know is: it returns a unique timer ID.
With this id and a little ingenuity, you can make it only call a function when the last timer is called. EX:

--CurrentTimer
cT = 0 --Init the var (so we don't crash)
--Let us draw text at mouse's last pos
lastX = 0
lastY = 0
while true do
  type, v1, v2, v3 = os.pullEvent()
  if (type=="timer" and v1==cT) then
	term.setCursorPos(lastX,lastY)
	print("X")
	term.setCursorPos(0,0)
  end
  if (type=="mouse_click") then
	cT = os.startTimer(2)
	lastX = v2
	lastY = v3
  end
end

If you need an explanation:
SpoilerIt will draw an "x" at your mouse's last position IF you wait for 2 seconds.
It will draw nothing if you click before the 2 seconds passes.

I hope you're following me, this is my first tutorial in awhile :P/>

Now, to make it a drag function.

Initialize the currentTimer as 0 so we don't get errors.
Initialize drag so we don't get errors.

cTimer = 0
drag = false

Let's make a function that runs when we perform a "proper drag"

function myDragFunc(x,y)
  term.setCursorPos(x,y)
  write("O")
end

Next, I'll start our loop

while true do
  --In the loop
end
Everything from here on out is inside that loop.

Get input

-- Event type, argument 1, argument 2, argument 3 = os.pullEvent()
type,v1,v2,v3 = os.pullEvent()

Let's see if the timer went off.
If it did, let's tell the program that we can no longer drag, and tell the same to the user.

if (type=="timer" and v1==cTimer) then
  term.setCursorPos(1,1)
  write("dragEnd")
  drag=false
end

Now let's see if the input is a mouse_drag.


if (type=="mouse_drag") then


end

Everything from here on out will be inside the if.

See if it's where a drag can start. (In this example, a box starting at 5,5 and ending at 15,10)

if (v2>4 and v2<16 and v3>4 and v3<11) then
  drag = true
  cTimer = os.startTimer(1)
  myDragFunc(v2,v3)

  --Let's clear the "dragEnd" text
  term.setCursorPos(1,1)
  write("		")
end

And finially let's put in code for when drag==true.


if (drag) then
  cTimer = os.startTimer(1)
  myDragFunc(v2,v3)
end

All assembled, that would be:
Spoiler

cTimer = 0
drag = false

function myDragFunc(x,y)
  term.setCursorPos(x,y)
  write("O")
end

while true do
-- Event type, argument 1, argument 2, argument 3 = os.pullEvent()
  type,v1,v2,v3 = os.pullEvent()
  if (type=="timer" and v1==cTimer) then
	term.setCursorPos(1,1)
	write("dragEnd")
    drag=false
  end
  if (type=="mouse_drag") then
	if (v2>4 and v2<16 and v3>4 and v3<11) then
	  drag = true
	  cTimer = os.startTimer(1)
	  myDragFunc(v2,v3)

	  --Let's clear the "dragEnd" text
	  term.setCursorPos(1,1)
	  write("		")
	end
	if (drag) then
	  cTimer = os.startTimer(1)
	  myDragFunc(v2,v3)
	end
  end
end

Hopefully, you learned something.
If you use this knowledge in any way, I ask that you (not require) post what you made in my topic. I love seeing creativity in action!
remiX #2
Posted 28 January 2013 - 09:52 AM
if (type=="timer" and v1==cT) then

As you may know, you can use os.startTimer(paramTime) to queue a timed event.

You may want to fix that :P/>
Andan #3
Posted 16 April 2014 - 03:17 PM
Sorry 2 reply after 1 year but I need to know something. Is it possible to get the x,y of the starting pixel and the x,y of the last pixel? Like "You dragged from x,y to x,y which means x pixels up and y pixels down"
Cranium #4
Posted 16 April 2014 - 03:32 PM
Yes you can, you simply record the first known position when the drag starts, and the last recorded position after a drag.
Edited on 16 April 2014 - 01:33 PM
Bomb Bloke #5
Posted 19 April 2014 - 08:44 AM
Well, you sorta can. Unfortunately you can't directly determine where the "last" position is, as there's no "mouse_release" event (for whatever reason).

This means you'll need to infer (… or guess) as to when the drag operation ended, by eg using a timer or by waiting for another click event.