View Single Post
Old 11-17-2019, 07:25 AM   #2
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,577
Default

For anyone interested, here's a test script for docking/undocking a script window by "dragging and dropping":



I'm using "gfx.init" to move the window, so the latest REAPER version might be needed.
Code:
local reaper = reaper
local abs = math.abs
local left, top, right, bottom = reaper.my_getViewport(0, 0, 0, 0, 0, 0, 0, 0, 0)

local GUI = {}
GUI.dock = 0
GUI.x, GUI.y, GUI.w, GUI.h = 0, 0, 0, 0
GUI.drag = false

-- window moving is triggered when lmb is down and cursor is moved by this many pixels:
GUI.drag_start_offset = 40

local mouse = {
                cap = 0,
                last_cap = 0,
                x = -1,
                y = -1,
                last_x = -1,
                last_y = -1,
                x_screen = -1,
                y_screen = -1,
                last_x_screen = -1,
                last_y_screen = -1,
                ctrl = false,
                shift = false,
                alt = false,
                lmb_down_time = 0,
                rmb_down_time = 0,
                lmb_up_time = 0,
                rmb_up_time = 0,
                ox = -1,
                oy = -1,
                ox_screen = -1,
                oy_screen = -1     
              }


-----------------------------------------------------------------------
function on_lmb_down()
  if mouse.last_cap&1 == 0 then
    -- store click position (screen coordinates)
    mouse.ox_screen, mouse.oy_screen = mouse.x_screen, mouse.y_screen
    -- get GUI position/dimension
    _, GUI.x, GUI.y, GUI.w, GUI.h = gfx.dock(-1,0,0,0,0)
  -- check if mouse position has changed from "click position"
  elseif mouse.moved and (mouse.x_screen ~= mouse.ox_screen or mouse.y_screen ~= mouse.oy_screen) then
    -- check if mouse position has changed enough for triggering the window moving
    if not GUI.drag and
      (abs(mouse.x_screen - mouse.ox_screen) > GUI.drag_start_offset or
       abs(mouse.y_screen - mouse.oy_screen) > GUI.drag_start_offset) then
      GUI.drag = true -- set the drag flag
      -- update mouse click positions (to prevent the window from jumping by "GUI.drag_start_offset" pixels)
      -- 
      mouse.ox_screen = mouse.x_screen
      mouse.oy_screen = mouse.y_screen
    end
    if GUI.drag then
      -- if window is docked...
      if gfx.dock(-1)&1 == 1 then
        gfx.dock(0) -- ...undock it
        -- move the undocked window to mouse position (centered to mouse cursor)
        GUI.x, GUI.y = mouse.x_screen-0.5*GUI.w, mouse.y_screen-0.5*GUI.h
        gfx.init("", GUI.w, GUI.h, 0, GUI.x, GUI.y) -- move window to new position
      -- if window is undocked...
      elseif gfx.dock(-1)&1 == 0 then
        -- calculate new window position
        local new_x = GUI.x-mouse.ox_screen+mouse.x_screen
        local new_y = GUI.y-mouse.oy_screen+mouse.y_screen
        gfx.init("", GUI.w, GUI.h, 0, new_x, new_y) -- move window to new position
      end  
    end
  end
end

-----------------------------------------------------------------------
function on_lmb_up()
  local dock, x, y, w, h =  gfx.dock(-1,0,0,0,0)
  if GUI.drag and gfx.dock(-1)&1 == 0 then
    if y <= 0 then
      gfx.dock(769) -- top
    elseif x <= 0 then
      gfx.dock(269) -- left
    elseif
      x + w >= right then
      gfx.dock(513) -- right
    end
  end
  if GUI.drag then
    GUI.drag = false
  end
end

-----------------------------------------------------------------------
function get_mod_keys()
  mouse.ctrl = mouse.cap&4==4
  mouse.shift = mouse.cap&8==8
  mouse.alt = mouse.cap&16==16
end

-----------------------------------------------------------------------
function get_mouse_btn_states()
  get_mod_keys()
  --     left btn down   right btn down  middle btn down
  return mouse.cap&1==1, mouse.cap&2==2, mouse.cap&64==64
end

------------------------------------------------------------
function get_mouse_state()
  mouse.x, mouse.y = gfx.mouse_x, gfx.mouse_y
  mouse.x_screen, mouse.y_screen = reaper.GetMousePosition()
  mouse.moved = mouse.x_screen ~= mouse.last_x_screen or mouse.y_screen ~= mouse.last_y_screen
  mouse.cap = gfx.mouse_cap
  local lmb_down, rmb_down = get_mouse_btn_states()
  if lmb_down then
    on_lmb_down()
  elseif mouse.last_cap&1 == 1 then
    on_lmb_up()
  end
end

------------------------------------------------------------
function init()
  gfx.init("Dock test",600,200)
  gfx.set(1,1,1,1)
  gfx.setfont(1, "Arial", 20)
end

------------------------------------------------------------
function main()
  get_mouse_state() -- update mouse table
  gfx.x = 10
  gfx.y = 10
  local dock = gfx.dock(-1)
  gfx.drawstr("Dock index: " .. tostring(dock))
  gfx.x = 10
  gfx.y = gfx.y+20
  gfx.drawstr("Click here and drag to move the window")
  gfx.x = 10
  gfx.y = gfx.y+20
  gfx.drawstr("Move the window to the top,left or right of the screen to dock the window")
  mouse.last_cap = mouse.cap
  mouse.last_x = mouse.x
  mouse.last_y = mouse.y
  mouse.last_x_screen = mouse.x_screen
  mouse.last_y_screen = mouse.y_screen
  if char~=-1 then reaper.defer(main) end
  gfx.update()
end

init()
main()
spk77 is offline   Reply With Quote