mirror of
https://github.com/kepler155c/opus
synced 2025-01-22 21:26:53 +00:00
redo input translation + shift-paste
This commit is contained in:
parent
9b8b5238b0
commit
2721840596
129
sys/apis/input.lua
Normal file
129
sys/apis/input.lua
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
local Util = require('util')
|
||||||
|
|
||||||
|
local keys = _G.keys
|
||||||
|
local os = _G.os
|
||||||
|
|
||||||
|
local modifiers = Util.transpose {
|
||||||
|
keys.leftCtrl, keys.rightCtrl,
|
||||||
|
keys.leftShift, keys.rightShift,
|
||||||
|
--keys.leftAlt, keys.rightAlt,
|
||||||
|
}
|
||||||
|
|
||||||
|
local input = {
|
||||||
|
pressed = { },
|
||||||
|
}
|
||||||
|
|
||||||
|
function input:toCode(code)
|
||||||
|
|
||||||
|
local ch = self.ch or keys.getName(code)
|
||||||
|
local result = { }
|
||||||
|
|
||||||
|
if self.pressed[keys.leftCtrl] or self.pressed[keys.rightCtrl] then
|
||||||
|
table.insert(result, 'control')
|
||||||
|
end
|
||||||
|
|
||||||
|
--if self.pressed[keys.leftAlt] or self.pressed[keys.rightAlt] then
|
||||||
|
-- table.insert(result, 'alt')
|
||||||
|
--end
|
||||||
|
|
||||||
|
if self.pressed[keys.leftShift] or self.pressed[keys.rightShift] then
|
||||||
|
if modifiers[code] or #ch > 1 then
|
||||||
|
table.insert(result, 'shift')
|
||||||
|
else
|
||||||
|
ch = ch:upper()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not modifiers[code] then
|
||||||
|
table.insert(result, ch)
|
||||||
|
end
|
||||||
|
|
||||||
|
return table.concat(result, '-')
|
||||||
|
end
|
||||||
|
|
||||||
|
function input:reset()
|
||||||
|
self.pressed = { }
|
||||||
|
self.ch = nil
|
||||||
|
self.fired = nil
|
||||||
|
self.timer = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function input:translate(event, code, p1, p2)
|
||||||
|
if event == 'key' then
|
||||||
|
if p1 then -- key is held down
|
||||||
|
if not modifiers[code] then
|
||||||
|
self.fired = input:toCode(code)
|
||||||
|
return self.fired
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self.fired = nil
|
||||||
|
self.ch = nil
|
||||||
|
self.pressed[code] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif event == 'char' then
|
||||||
|
self.ch = code
|
||||||
|
|
||||||
|
elseif event == 'key_up' then
|
||||||
|
if not self.fired then
|
||||||
|
if self.pressed[code] then
|
||||||
|
self.fired = input:toCode(code)
|
||||||
|
self.pressed[code] = nil
|
||||||
|
return self.fired
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
self.pressed[code] = nil
|
||||||
|
|
||||||
|
elseif event == 'mouse_click' then
|
||||||
|
|
||||||
|
local buttons = { 'mouse_click', 'mouse_rightclick' }
|
||||||
|
self.ch = buttons[code]
|
||||||
|
self.fired = nil
|
||||||
|
--self.fired = input:toCode(0)
|
||||||
|
--return self.fired
|
||||||
|
|
||||||
|
elseif event == 'mouse_drag' then
|
||||||
|
self.ch = 'mouse_drag'
|
||||||
|
self.fired = input:toCode(0)
|
||||||
|
return self.fired
|
||||||
|
|
||||||
|
elseif event == 'mouse_up' then
|
||||||
|
if not self.fired then
|
||||||
|
local clock = os.clock()
|
||||||
|
if self.timer and
|
||||||
|
p1 == self.x and p2 == self.y and
|
||||||
|
(clock - self.timer < .5) then
|
||||||
|
|
||||||
|
self.ch = 'mouse_doubleclick'
|
||||||
|
self.timer = nil
|
||||||
|
else
|
||||||
|
self.timer = os.clock()
|
||||||
|
self.x = p1
|
||||||
|
self.y = p2
|
||||||
|
end
|
||||||
|
self.fired = input:toCode(0)
|
||||||
|
else
|
||||||
|
self.ch = 'mouse_up'
|
||||||
|
self.fired = input:toCode(0)
|
||||||
|
end
|
||||||
|
return self.fired
|
||||||
|
|
||||||
|
elseif event == "mouse_scroll" then
|
||||||
|
local directions = {
|
||||||
|
[ -1 ] = 'scrollUp',
|
||||||
|
[ 1 ] = 'scrollDown'
|
||||||
|
}
|
||||||
|
self.ch = directions[code]
|
||||||
|
return input:toCode(0)
|
||||||
|
|
||||||
|
elseif event == 'paste' then
|
||||||
|
self.ch = 'paste'
|
||||||
|
self.pressed[keys.leftCtrl] = nil
|
||||||
|
self.pressed[keys.rightCtrl] = nil
|
||||||
|
self.fired = input:toCode(0)
|
||||||
|
return self.fired
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return input
|
126
sys/apis/ui.lua
126
sys/apis/ui.lua
@ -1,6 +1,7 @@
|
|||||||
local Canvas = require('ui.canvas')
|
local Canvas = require('ui.canvas')
|
||||||
local class = require('class')
|
local class = require('class')
|
||||||
local Event = require('event')
|
local Event = require('event')
|
||||||
|
local Input = require('input')
|
||||||
local Transition = require('ui.transition')
|
local Transition = require('ui.transition')
|
||||||
local Util = require('util')
|
local Util = require('util')
|
||||||
|
|
||||||
@ -43,9 +44,6 @@ end
|
|||||||
--[[-- Top Level Manager --]]--
|
--[[-- Top Level Manager --]]--
|
||||||
local Manager = class()
|
local Manager = class()
|
||||||
function Manager:init()
|
function Manager:init()
|
||||||
local control = false
|
|
||||||
local shift = false
|
|
||||||
local mouseDragged = false
|
|
||||||
local running = false
|
local running = false
|
||||||
|
|
||||||
-- single thread all input events
|
-- single thread all input events
|
||||||
@ -55,10 +53,16 @@ function Manager:init()
|
|||||||
running = true
|
running = true
|
||||||
fn(...)
|
fn(...)
|
||||||
running = false
|
running = false
|
||||||
|
else
|
||||||
|
Input:translate(event, ...)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Event.on('multishell_focus', function()
|
||||||
|
Input:reset()
|
||||||
|
end)
|
||||||
|
|
||||||
singleThread('term_resize', function(side)
|
singleThread('term_resize', function(side)
|
||||||
if self.currentPage then
|
if self.currentPage then
|
||||||
-- the parent doesn't have any children set...
|
-- the parent doesn't have any children set...
|
||||||
@ -99,16 +103,9 @@ function Manager:init()
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
singleThread('mouse_click', function(button, x, y)
|
singleThread('mouse_click', function(button, x, y)
|
||||||
|
Input:translate('mouse_click', button, x, y)
|
||||||
|
|
||||||
mouseDragged = false
|
if self.currentPage then
|
||||||
if button == 1 and shift and control then -- debug hack
|
|
||||||
local event = self:pointToChild(self.target, x, y)
|
|
||||||
multishell.openTab({
|
|
||||||
path = 'sys/apps/Lua.lua',
|
|
||||||
args = { event.element, self:dump(self.currentPage) },
|
|
||||||
focused = true })
|
|
||||||
|
|
||||||
elseif self.currentPage then
|
|
||||||
if not self.currentPage.parent.device.side then
|
if not self.currentPage.parent.device.side then
|
||||||
local event = self:pointToChild(self.target, x, y)
|
local event = self:pointToChild(self.target, x, y)
|
||||||
if event.element.focus and not event.element.inactive then
|
if event.element.focus and not event.element.inactive then
|
||||||
@ -120,75 +117,64 @@ function Manager:init()
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
singleThread('mouse_up', function(button, x, y)
|
singleThread('mouse_up', function(button, x, y)
|
||||||
|
local ch = Input:translate('mouse_up', button, x, y)
|
||||||
|
|
||||||
if self.currentPage and not mouseDragged then
|
if ch == 'control-shift-mouse_click' then -- hack
|
||||||
|
local event = self:pointToChild(self.target, x, y)
|
||||||
|
multishell.openTab({
|
||||||
|
path = 'sys/apps/Lua.lua',
|
||||||
|
args = { event.element, self:dump(self.currentPage) },
|
||||||
|
focused = true })
|
||||||
|
|
||||||
|
elseif ch and self.currentPage then
|
||||||
if not self.currentPage.parent.device.side then
|
if not self.currentPage.parent.device.side then
|
||||||
self:click(button, x, y)
|
self:click(ch, button, x, y)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
singleThread('mouse_drag', function(button, x, y)
|
singleThread('mouse_drag', function(button, x, y)
|
||||||
|
local ch = Input:translate('mouse_drag', button, x, y)
|
||||||
mouseDragged = true
|
if ch and self.target then
|
||||||
if self.target then
|
|
||||||
local event = self:pointToChild(self.target, x, y)
|
local event = self:pointToChild(self.target, x, y)
|
||||||
|
|
||||||
-- revisit - should send out scroll_up and scroll_down events
|
-- revisit - should send out scroll_up and scroll_down events
|
||||||
-- let the element convert them to up / down
|
-- let the element convert them to up / down
|
||||||
self:inputEvent(event.element,
|
self:inputEvent(event.element,
|
||||||
{ type = 'mouse_drag', button = button, x = event.x, y = event.y })
|
{ type = ch, button = button, x = event.x, y = event.y })
|
||||||
self.currentPage:sync()
|
self.currentPage:sync()
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
singleThread('paste', function(text)
|
singleThread('paste', function(text)
|
||||||
|
Input:translate('paste')
|
||||||
self:emitEvent({ type = 'paste', text = text })
|
self:emitEvent({ type = 'paste', text = text })
|
||||||
self.currentPage:sync()
|
self.currentPage:sync()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
singleThread('char', function(ch)
|
singleThread('char', function(ch)
|
||||||
control = false
|
Input:translate('char', ch)
|
||||||
if self.currentPage then
|
end)
|
||||||
|
|
||||||
|
singleThread('key_up', function(code)
|
||||||
|
local ch = Input:translate('key_up', code)
|
||||||
|
|
||||||
|
if ch and self.currentPage then
|
||||||
local target = self.currentPage.focused or self.currentPage
|
local target = self.currentPage.focused or self.currentPage
|
||||||
self:inputEvent(target, { type = 'key', key = ch })
|
self:inputEvent(target,
|
||||||
|
{ type = 'key', key = ch, element = target })
|
||||||
self.currentPage:sync()
|
self.currentPage:sync()
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
singleThread('key_up', function(code)
|
singleThread('key', function(code, held)
|
||||||
if code == keys.leftCtrl or code == keys.rightCtrl then
|
local ch = Input:translate('key', code, held)
|
||||||
control = false
|
|
||||||
elseif code == keys.leftShift or code == keys.rightShift then
|
|
||||||
shift = false
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
singleThread('key', function(code)
|
if ch and self.currentPage then
|
||||||
local ch = keys.getName(code)
|
local target = self.currentPage.focused or self.currentPage
|
||||||
if not ch then
|
self:inputEvent(target,
|
||||||
return
|
{ type = 'key', key = ch, element = target })
|
||||||
end
|
self.currentPage:sync()
|
||||||
|
|
||||||
if code == keys.leftCtrl or code == keys.rightCtrl then
|
|
||||||
control = true
|
|
||||||
elseif code == keys.leftShift or code == keys.rightShift then
|
|
||||||
shift = true
|
|
||||||
elseif control then
|
|
||||||
ch = 'control-' .. ch
|
|
||||||
elseif shift and ch == 'tab' then
|
|
||||||
ch = 'shiftTab'
|
|
||||||
end
|
|
||||||
|
|
||||||
-- filter out a through z and numbers as they will be get picked up
|
|
||||||
-- as char events
|
|
||||||
if ch and #ch > 1 and (code < 2 or code > 11) then
|
|
||||||
if self.currentPage then
|
|
||||||
local target = self.currentPage.focused or self.currentPage
|
|
||||||
self:inputEvent(target,
|
|
||||||
{ type = 'key', key = ch, element = target })
|
|
||||||
self.currentPage:sync()
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
@ -306,7 +292,7 @@ function Manager:pointToChild(parent, x, y)
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
function Manager:click(button, x, y)
|
function Manager:click(code, button, x, y)
|
||||||
if self.target then
|
if self.target then
|
||||||
|
|
||||||
local target = self.target
|
local target = self.target
|
||||||
@ -322,38 +308,23 @@ function Manager:click(button, x, y)
|
|||||||
|
|
||||||
local clickEvent = self:pointToChild(target, x, y)
|
local clickEvent = self:pointToChild(target, x, y)
|
||||||
|
|
||||||
if button == 1 then
|
if code == 'mouse_doubleclick' then
|
||||||
local c = os.clock()
|
if self.doubleClickElement ~= clickEvent.element then
|
||||||
|
return
|
||||||
--if self.doubleClickTimer then
|
|
||||||
-- debug(c - self.doubleClickTimer)
|
|
||||||
--end
|
|
||||||
|
|
||||||
if self.doubleClickTimer and (c - self.doubleClickTimer < 1.9) and
|
|
||||||
self.doubleClickX == x and self.doubleClickY == y and
|
|
||||||
self.doubleClickElement == clickEvent.element then
|
|
||||||
button = 3
|
|
||||||
self.doubleClickTimer = nil
|
|
||||||
else
|
|
||||||
self.doubleClickTimer = c
|
|
||||||
self.doubleClickX = x
|
|
||||||
self.doubleClickY = y
|
|
||||||
self.doubleClickElement = clickEvent.element
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
self.doubleClickTimer = nil
|
self.doubleClickElement = clickEvent.element
|
||||||
end
|
end
|
||||||
|
|
||||||
local events = { 'mouse_click', 'mouse_rightclick', 'mouse_doubleclick' }
|
|
||||||
|
|
||||||
clickEvent.button = button
|
clickEvent.button = button
|
||||||
clickEvent.type = events[button]
|
clickEvent.type = code
|
||||||
clickEvent.key = events[button]
|
clickEvent.key = code
|
||||||
|
|
||||||
if clickEvent.element.focus then
|
if clickEvent.element.focus then
|
||||||
self.currentPage:setFocus(clickEvent.element)
|
self.currentPage:setFocus(clickEvent.element)
|
||||||
end
|
end
|
||||||
if not self:inputEvent(clickEvent.element, clickEvent) then
|
if not self:inputEvent(clickEvent.element, clickEvent) then
|
||||||
|
--[[
|
||||||
if button == 3 then
|
if button == 3 then
|
||||||
-- if the double-click was not captured
|
-- if the double-click was not captured
|
||||||
-- send through a single-click
|
-- send through a single-click
|
||||||
@ -362,6 +333,7 @@ function Manager:click(button, x, y)
|
|||||||
clickEvent.key = events[1]
|
clickEvent.key = events[1]
|
||||||
self:inputEvent(clickEvent.element, clickEvent)
|
self:inputEvent(clickEvent.element, clickEvent)
|
||||||
end
|
end
|
||||||
|
]]
|
||||||
end
|
end
|
||||||
|
|
||||||
self.currentPage:sync()
|
self.currentPage:sync()
|
||||||
@ -1152,7 +1124,7 @@ UI.Page.defaults = {
|
|||||||
down = 'focus_next',
|
down = 'focus_next',
|
||||||
enter = 'focus_next',
|
enter = 'focus_next',
|
||||||
tab = 'focus_next',
|
tab = 'focus_next',
|
||||||
shiftTab = 'focus_prev',
|
['shift-tab' ] = 'focus_prev',
|
||||||
up = 'focus_prev',
|
up = 'focus_prev',
|
||||||
},
|
},
|
||||||
backgroundColor = colors.cyan,
|
backgroundColor = colors.cyan,
|
||||||
|
@ -6,6 +6,7 @@ end
|
|||||||
_G.requireInjector()
|
_G.requireInjector()
|
||||||
|
|
||||||
local Config = require('config')
|
local Config = require('config')
|
||||||
|
local Input = require('input')
|
||||||
local Opus = require('opus')
|
local Opus = require('opus')
|
||||||
local Util = require('util')
|
local Util = require('util')
|
||||||
|
|
||||||
@ -27,9 +28,7 @@ local overviewTab
|
|||||||
local runningTab
|
local runningTab
|
||||||
local tabsDirty = false
|
local tabsDirty = false
|
||||||
local closeInd = '*'
|
local closeInd = '*'
|
||||||
local redrawTimer
|
|
||||||
local hooks = { }
|
local hooks = { }
|
||||||
local control
|
|
||||||
local hotkeys = { }
|
local hotkeys = { }
|
||||||
local downState = { }
|
local downState = { }
|
||||||
|
|
||||||
@ -49,7 +48,7 @@ if not os.getComputerLabel() then
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if Util.getVersion() >= 1.79 then
|
if Util.getVersion() >= 1.76 then
|
||||||
closeInd = '\215'
|
closeInd = '\215'
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -85,33 +84,6 @@ local function redrawMenu()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function selectTab(tab)
|
|
||||||
if not tab then
|
|
||||||
for _,ftab in pairs(tabs) do
|
|
||||||
if not ftab.hidden then
|
|
||||||
tab = ftab
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if not tab then
|
|
||||||
tab = overviewTab
|
|
||||||
end
|
|
||||||
|
|
||||||
if currentTab and currentTab ~= tab then
|
|
||||||
currentTab.window.setVisible(false)
|
|
||||||
if tab and not currentTab.hidden then
|
|
||||||
tab.previousTabId = currentTab.tabId
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if tab then
|
|
||||||
currentTab = tab
|
|
||||||
tab.window.setVisible(true)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function resumeTab(tab, event, eventData)
|
local function resumeTab(tab, event, eventData)
|
||||||
if not tab or coroutine.status(tab.co) == 'dead' then
|
if not tab or coroutine.status(tab.co) == 'dead' then
|
||||||
return
|
return
|
||||||
@ -136,6 +108,39 @@ local function resumeTab(tab, event, eventData)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function selectTab(tab)
|
||||||
|
if not tab then
|
||||||
|
for _,ftab in pairs(tabs) do
|
||||||
|
if not ftab.hidden then
|
||||||
|
tab = ftab
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not tab then
|
||||||
|
tab = overviewTab
|
||||||
|
end
|
||||||
|
|
||||||
|
if currentTab and currentTab ~= tab then
|
||||||
|
currentTab.window.setVisible(false)
|
||||||
|
if coroutine.status(currentTab.co) == 'suspended' then
|
||||||
|
-- the process that opens a new tab won't get the lose focus event
|
||||||
|
-- os.queueEvent('multishell_notifyfocus', currentTab.tabId)
|
||||||
|
resumeTab(currentTab, 'multishell_losefocus')
|
||||||
|
end
|
||||||
|
if tab and not currentTab.hidden then
|
||||||
|
tab.previousTabId = currentTab.tabId
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if tab ~= currentTab then
|
||||||
|
currentTab = tab
|
||||||
|
tab.window.setVisible(true)
|
||||||
|
resumeTab(tab, 'multishell_focus')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local function nextTabId()
|
local function nextTabId()
|
||||||
_tabId = _tabId + 1
|
_tabId = _tabId + 1
|
||||||
return _tabId
|
return _tabId
|
||||||
@ -227,10 +232,10 @@ function multishell.getTitle(tabId)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function multishell.setTitle(tabId, sTitle)
|
function multishell.setTitle(tabId, title)
|
||||||
local tab = tabs[tabId]
|
local tab = tabs[tabId]
|
||||||
if tab then
|
if tab then
|
||||||
tab.title = sTitle or ''
|
tab.title = title or ''
|
||||||
redrawMenu()
|
redrawMenu()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -332,10 +337,20 @@ function multishell.showMessage(text)
|
|||||||
text = text .. string.rep(' ', w - #text - 3)
|
text = text .. string.rep(' ', w - #text - 3)
|
||||||
end
|
end
|
||||||
parentTerm.write(text)
|
parentTerm.write(text)
|
||||||
redrawTimer = os.startTimer(2)
|
|
||||||
if currentTab then
|
if currentTab then
|
||||||
currentTab.window.restoreCursor()
|
currentTab.window.restoreCursor()
|
||||||
end
|
end
|
||||||
|
local redrawTimer = os.startTimer(2)
|
||||||
|
|
||||||
|
local redraw
|
||||||
|
function redraw(event, eventData)
|
||||||
|
if eventData[1] == redrawTimer then
|
||||||
|
redrawMenu()
|
||||||
|
multishell.unhook(event, redraw)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
multishell.hook('timer', redraw)
|
||||||
end
|
end
|
||||||
|
|
||||||
function multishell.hook(event, fn)
|
function multishell.hook(event, fn)
|
||||||
@ -347,7 +362,18 @@ function multishell.hook(event, fn)
|
|||||||
if not hooks[event] then
|
if not hooks[event] then
|
||||||
hooks[event] = { }
|
hooks[event] = { }
|
||||||
end
|
end
|
||||||
table.insert(hooks[event], 1, fn)
|
table.insert(hooks[event], fn)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- you can only unhook from within the function that hooked
|
||||||
|
function multishell.unhook(event, fn)
|
||||||
|
local eventHooks = hooks[event]
|
||||||
|
if eventHooks then
|
||||||
|
Util.removeByValue(eventHooks, fn)
|
||||||
|
if #eventHooks == 0 then
|
||||||
|
hooks[event] = nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -366,22 +392,29 @@ end)
|
|||||||
multishell.hook('multishell_redraw', function()
|
multishell.hook('multishell_redraw', function()
|
||||||
tabsDirty = false
|
tabsDirty = false
|
||||||
|
|
||||||
parentTerm.setBackgroundColor( _colors.tabBarBackgroundColor )
|
local function write(x, text, bg, fg)
|
||||||
if currentTab and currentTab.isOverview then
|
parentTerm.setBackgroundColor(bg)
|
||||||
parentTerm.setTextColor( _colors.focusTextColor )
|
parentTerm.setTextColor(fg)
|
||||||
else
|
parentTerm.setCursorPos(x, 1)
|
||||||
parentTerm.setTextColor( _colors.tabBarTextColor )
|
parentTerm.write(text)
|
||||||
end
|
end
|
||||||
parentTerm.setCursorPos( 1, 1 )
|
|
||||||
|
local bg = _colors.tabBarBackgroundColor
|
||||||
|
parentTerm.setBackgroundColor(bg)
|
||||||
|
parentTerm.setCursorPos(1, 1)
|
||||||
parentTerm.clearLine()
|
parentTerm.clearLine()
|
||||||
parentTerm.write('+')
|
|
||||||
|
if currentTab and currentTab.isOverview then
|
||||||
|
write(1, '+', bg, _colors.focusTextColor)
|
||||||
|
else
|
||||||
|
write(1, '+', bg, _colors.tabBarTextColor)
|
||||||
|
end
|
||||||
|
|
||||||
local tabX = 2
|
local tabX = 2
|
||||||
local function compareTab(a, b)
|
local function compareTab(a, b)
|
||||||
return a.tabId < b.tabId
|
return a.tabId < b.tabId
|
||||||
end
|
end
|
||||||
for _,tab in Util.spairs(tabs, compareTab) do
|
for _,tab in Util.spairs(tabs, compareTab) do
|
||||||
|
|
||||||
if tab.hidden and tab ~= currentTab or tab.isOverview then
|
if tab.hidden and tab ~= currentTab or tab.isOverview then
|
||||||
tab.sx = nil
|
tab.sx = nil
|
||||||
tab.ex = nil
|
tab.ex = nil
|
||||||
@ -394,21 +427,15 @@ multishell.hook('multishell_redraw', function()
|
|||||||
for _,tab in Util.spairs(tabs) do
|
for _,tab in Util.spairs(tabs) do
|
||||||
if tab.sx then
|
if tab.sx then
|
||||||
if tab == currentTab then
|
if tab == currentTab then
|
||||||
parentTerm.setTextColor(_colors.focusTextColor)
|
write(tab.sx, tab.title, _colors.focusBackgroundColor, _colors.focusTextColor)
|
||||||
parentTerm.setBackgroundColor(_colors.focusBackgroundColor)
|
|
||||||
else
|
else
|
||||||
parentTerm.setTextColor(_colors.textColor)
|
write(tab.sx, tab.title, _colors.backgroundColor, _colors.textColor)
|
||||||
parentTerm.setBackgroundColor(_colors.backgroundColor)
|
|
||||||
end
|
end
|
||||||
parentTerm.setCursorPos(tab.sx, 1)
|
|
||||||
parentTerm.write(tab.title)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if currentTab and not currentTab.isOverview then
|
if currentTab and not currentTab.isOverview then
|
||||||
parentTerm.setTextColor(_colors.focusTextColor)
|
write(w, closeInd, _colors.backgroundColor, _colors.focusTextColor)
|
||||||
parentTerm.setBackgroundColor(_colors.backgroundColor)
|
|
||||||
parentTerm.setCursorPos( w, 1 )
|
|
||||||
parentTerm.write(closeInd)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if currentTab then
|
if currentTab then
|
||||||
@ -439,14 +466,11 @@ multishell.hook('term_resize', function(_, eventData)
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- downstate should be stored in the tab
|
-- downstate should be stored in the tab (maybe)
|
||||||
|
|
||||||
multishell.hook('key_up', function(_, eventData)
|
multishell.hook('key_up', function(_, eventData)
|
||||||
local code = eventData[1]
|
local code = eventData[1]
|
||||||
|
|
||||||
if code == keys.leftCtrl or code == keys.rightCtrl then
|
|
||||||
control = false
|
|
||||||
end
|
|
||||||
if downState[code] ~= currentTab then
|
if downState[code] ~= currentTab then
|
||||||
downState[code] = nil
|
downState[code] = nil
|
||||||
return true
|
return true
|
||||||
@ -454,25 +478,12 @@ multishell.hook('key_up', function(_, eventData)
|
|||||||
downState[code] = nil
|
downState[code] = nil
|
||||||
end)
|
end)
|
||||||
|
|
||||||
multishell.hook('char', function()
|
|
||||||
control = false -- is this right ??
|
|
||||||
end)
|
|
||||||
|
|
||||||
multishell.hook('key', function(_, eventData)
|
multishell.hook('key', function(_, eventData)
|
||||||
local code = eventData[1]
|
local code = eventData[1]
|
||||||
local firstPress = not eventData[2]
|
local firstPress = not eventData[2]
|
||||||
|
|
||||||
if firstPress then
|
if firstPress then
|
||||||
downState[code] = currentTab
|
downState[code] = currentTab
|
||||||
if code == keys.leftCtrl or code == keys.rightCtrl then
|
|
||||||
control = true
|
|
||||||
elseif control then
|
|
||||||
local hotkey = hotkeys[code]
|
|
||||||
--control = false
|
|
||||||
if hotkey then
|
|
||||||
hotkey()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
--key was pressed initially in a previous window
|
--key was pressed initially in a previous window
|
||||||
if downState[code] ~= currentTab then
|
if downState[code] ~= currentTab then
|
||||||
@ -481,7 +492,15 @@ multishell.hook('key', function(_, eventData)
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
multishell.hook({ 'mouse_click' }, function(_, eventData)
|
multishell.hook({ 'key', 'key_up', 'char', 'paste' }, function(event, eventData)
|
||||||
|
local code = Input:translate(event, eventData[1], eventData[2])
|
||||||
|
|
||||||
|
if code and hotkeys[code] then
|
||||||
|
hotkeys[code](event, eventData)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
multishell.hook('mouse_click', function(_, eventData)
|
||||||
local x, y = eventData[2], eventData[3]
|
local x, y = eventData[2], eventData[3]
|
||||||
if y == 1 then
|
if y == 1 then
|
||||||
if x == 1 then
|
if x == 1 then
|
||||||
@ -519,7 +538,7 @@ multishell.hook({ 'mouse_up', 'mouse_drag' }, function(event, eventData)
|
|||||||
eventData[3] = eventData[3] - 1
|
eventData[3] = eventData[3] - 1
|
||||||
end)
|
end)
|
||||||
|
|
||||||
multishell.hook({ 'mouse_scroll' }, function(_, eventData)
|
multishell.hook('mouse_scroll', function(_, eventData)
|
||||||
local dir, y = eventData[1], eventData[3]
|
local dir, y = eventData[1], eventData[3]
|
||||||
|
|
||||||
if y == 1 then
|
if y == 1 then
|
||||||
@ -586,14 +605,10 @@ while true do
|
|||||||
local sEvent = table.remove(tEventData, 1)
|
local sEvent = table.remove(tEventData, 1)
|
||||||
local stopPropagation
|
local stopPropagation
|
||||||
|
|
||||||
if sEvent == 'timer' and tEventData[1] == redrawTimer then
|
|
||||||
redrawMenu()
|
|
||||||
end
|
|
||||||
|
|
||||||
local eventHooks = hooks[sEvent]
|
local eventHooks = hooks[sEvent]
|
||||||
if eventHooks then
|
if eventHooks then
|
||||||
for _,fn in pairs(eventHooks) do
|
for i = #eventHooks, 1, -1 do
|
||||||
stopPropagation = fn(sEvent, tEventData)
|
stopPropagation = eventHooks[i](sEvent, tEventData)
|
||||||
if stopPropagation then
|
if stopPropagation then
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
@ -2,44 +2,20 @@ _G.requireInjector()
|
|||||||
|
|
||||||
local Util = require('util')
|
local Util = require('util')
|
||||||
|
|
||||||
local keys = _G.keys
|
|
||||||
local multishell = _ENV.multishell
|
local multishell = _ENV.multishell
|
||||||
local textutils = _G.textutils
|
local textutils = _G.textutils
|
||||||
|
|
||||||
local clipboard = { }
|
local data
|
||||||
|
|
||||||
function clipboard.getText()
|
|
||||||
if clipboard.data then
|
|
||||||
if type(clipboard.data) == 'table' then
|
|
||||||
local s, m = pcall(textutils.serialize, clipboard.data)
|
|
||||||
clipboard.data = (s and m) or Util.tostring(clipboard.data)
|
|
||||||
end
|
|
||||||
return Util.tostring(clipboard.data)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function clipboard.useInternal(mode)
|
|
||||||
if mode ~= clipboard.internal then
|
|
||||||
clipboard.internal = mode
|
|
||||||
local text = 'Clipboard (^m): ' .. ((mode and 'internal') or 'normal')
|
|
||||||
multishell.showMessage(text)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
multishell.hook('clipboard_copy', function(_, args)
|
multishell.hook('clipboard_copy', function(_, args)
|
||||||
clipboard.data = args[1]
|
data = args[1]
|
||||||
if clipboard.data then
|
|
||||||
clipboard.useInternal(true)
|
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
multishell.hook('paste', function(_, args)
|
multishell.addHotkey('shift-paste', function(_, args)
|
||||||
if clipboard.internal then
|
if type(data) == 'table' then
|
||||||
args[1] = clipboard.getText() or ''
|
local s, m = pcall(textutils.serialize, data)
|
||||||
|
data = (s and m) or Util.tostring(data)
|
||||||
end
|
end
|
||||||
end)
|
-- replace the event paste data with our internal data
|
||||||
|
args[1] = Util.tostring(data or '')
|
||||||
-- control-m - toggle clipboard mode
|
|
||||||
multishell.addHotkey(keys.m, function()
|
|
||||||
clipboard.useInternal(not clipboard.internal)
|
|
||||||
end)
|
end)
|
||||||
|
@ -2,12 +2,10 @@ _G.requireInjector()
|
|||||||
|
|
||||||
local Util = require('util')
|
local Util = require('util')
|
||||||
|
|
||||||
local keys = _G.keys
|
|
||||||
|
|
||||||
local multishell = _ENV.multishell
|
local multishell = _ENV.multishell
|
||||||
|
|
||||||
-- control-o - overview
|
-- overview
|
||||||
multishell.addHotkey(keys.o, function()
|
multishell.addHotkey('control-o', function()
|
||||||
for _,tab in pairs(multishell.getTabs()) do
|
for _,tab in pairs(multishell.getTabs()) do
|
||||||
if tab.isOverview then
|
if tab.isOverview then
|
||||||
multishell.setFocus(tab.tabId)
|
multishell.setFocus(tab.tabId)
|
||||||
@ -15,8 +13,8 @@ multishell.addHotkey(keys.o, function()
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- control-backspace - restart tab
|
-- restart tab
|
||||||
multishell.addHotkey(keys.backspace, function()
|
multishell.addHotkey('control-backspace', function()
|
||||||
local tabs = multishell.getTabs()
|
local tabs = multishell.getTabs()
|
||||||
local tabId = multishell.getFocus()
|
local tabId = multishell.getFocus()
|
||||||
local tab = tabs[tabId]
|
local tab = tabs[tabId]
|
||||||
@ -29,8 +27,8 @@ multishell.addHotkey(keys.backspace, function()
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- control-tab - next tab
|
-- next tab
|
||||||
multishell.addHotkey(keys.tab, function()
|
multishell.addHotkey('control-tab', function()
|
||||||
local tabs = multishell.getTabs()
|
local tabs = multishell.getTabs()
|
||||||
local visibleTabs = { }
|
local visibleTabs = { }
|
||||||
local currentTabId = multishell.getFocus()
|
local currentTabId = multishell.getFocus()
|
||||||
|
@ -3,7 +3,6 @@ _G.requireInjector()
|
|||||||
local Terminal = require('terminal')
|
local Terminal = require('terminal')
|
||||||
local Util = require('util')
|
local Util = require('util')
|
||||||
|
|
||||||
local keys = _G.keys
|
|
||||||
local multishell = _ENV.multishell
|
local multishell = _ENV.multishell
|
||||||
local os = _G.os
|
local os = _G.os
|
||||||
local term = _G.term
|
local term = _G.term
|
||||||
@ -26,7 +25,7 @@ end
|
|||||||
print('Debug started')
|
print('Debug started')
|
||||||
print('Press ^d to activate debug window')
|
print('Press ^d to activate debug window')
|
||||||
|
|
||||||
multishell.addHotkey(keys.d, function()
|
multishell.addHotkey('control-d', function()
|
||||||
local currentId = multishell.getFocus()
|
local currentId = multishell.getFocus()
|
||||||
if currentId ~= tabId then
|
if currentId ~= tabId then
|
||||||
previousId = currentId
|
previousId = currentId
|
||||||
@ -41,4 +40,4 @@ os.pullEventRaw('terminate')
|
|||||||
print('Debug stopped')
|
print('Debug stopped')
|
||||||
|
|
||||||
_G.debug = function() end
|
_G.debug = function() end
|
||||||
multishell.removeHotkey(keys.d)
|
multishell.removeHotkey('control-d')
|
||||||
|
Loading…
Reference in New Issue
Block a user