(Latest update) The code below redirects print()
output from the output pane to one or more panes on the viewer. The code is too long to include in a single comment, and has been divided into three parts. An example of its use follows the code itself.
Inspiration came from Codea written in Codea by @Simeon.
This version includes extra functions suggested and first implemented by @KilamMalik. Early versions of the code were first discussed here.
Part 1/3 of the code:
--
-- Redirect, version 2012.09.18.21.30
--
-- Simple use:
-- print.redirect.font(name, size) to set the font used, before
-- first use
-- print.redirect.on() to turn redirection on
-- print.redirect.off() to turn it off
--
-- Complex use:
-- index = print.redirect.addPane(left, base, width, height, title)
-- print.redirect.removePane(index)
-- print.redirect.currentPane(index)
--
-- Works with Codea's 'dependencies'.
local defaultFont = "Inconsolata"
local defaultFontSize = 17
local stream = false
local pane = {}
local cPane = nil
local paneCount = 0
------------------------------------------------------------------------
-- CloseButton class
-- Handles a close button
------------------------------------------------------------------------
local CloseButton = class()
function CloseButton:init(left, base, size, onTouch, parent)
self.rect = {
l = left,
b = base,
w = size,
h = size,
r = left + size,
t = base + size
}
self.onTouch = onTouch
self.parent = parent
return self
end
function CloseButton:draw()
pushStyle()
noStroke()
local l = self.rect.l
local b = self.rect.b
local w = self.rect.w
local h = self.rect.h
local x = l + w/2
local y = b + h/2
fill(0)
ellipse(x, y, 16, 16)
fill(255, 0, 0)
ellipse(x, y, 14, 14)
fill(255)
ellipse(x, y + 4, 7, 4)
fill(255, 127)
ellipse(x, y - 4, 9, 6)
popStyle()
end
function CloseButton:touched(touch)
local state = touch.state
local x = touch.x
local y = touch.y
local l = self.rect.l
local r = self.rect.r
local b = self.rect.b
local t = self.rect.t
if x >= l and x <= r and y >= b and y <= t then
if state == BEGAN then
if self.onTouch then self.onTouch() end
end
return true
end
return false
end
------------------------------------------------------------------------
-- TitleBar class
-- Handles a title bar
------------------------------------------------------------------------
local TitleBar = class()
function TitleBar:init(left, base, width, height, title, onClose,
parent)
self.rect = {
l = left,
b = base,
w = width,
h = height,
r = left + width,
t = base + height
}
self.title = title
self.cb = CloseButton(left, base, height, onClose, self)
self.parent = parent
return self
end
function TitleBar:draw()
local l = self.rect.l
local b = self.rect.b
local w = self.rect.w
local h = self.rect.h
pushStyle()
noStroke()
fill(127, 127)
rectMode(CORNER)
rect(l, b, w, h)
font("Inconsolata")
fontSize(17)
textMode(CORNER)
textAlign(LEFT)
textWrapWidth(0)
fill(255)
text(self.title, l + self.cb.rect.w, self.rect.t - self.cb.rect.h)
popStyle()
self.cb:draw()
end
function TitleBar:touched(touch)
return self.cb:touched(touch)
end
------------------------------------------------------------------------
-- VSBar class
-- Handles a vertical scroll bar
------------------------------------------------------------------------
local VSBar = class()
function VSBar:init(left, base, width, height, min, max, value, length,
onChanged, parent)
self.rect = {
l = left,
b = base,
w = width,
h = height,
r = left + width,
t = base + height
}
self.min = min
self.max = max
self.value = value
self.length = length
self.onChanged = onChanged
self.parent = parent
self.visible = false
self.touchId = nil
self.d = 8
return self
end
function VSBar:visible(...)
local n = arg["n"]
if n > 0 then
local isVisible = arg[1]
self.visible = isVisible
end
return self.visible
end
function VSBar:draw()
pushStyle()
fill(127, 127)
rectMode(CORNER)
rect(self.rect.l, self.rect.b, self.rect.w, self.rect.h)
if not self.visible then return end
local l = self.length/(self.max - self.min + 1) *
(self.rect.h - self.d)
fill(127, 255)
local t = self.rect.t - self.d/2 -
(self.value - self.min)/(self.max - self.min) *
(self.rect.h - self.d)
local x = self.rect.r - self.d - 1
rect(x, t - l, self.d, l)
ellipse(x + self.d/2, t, self.d)
ellipse(x + self.d/2, t - l, self.d)
popStyle()
end
function VSBar:touched(touch)
local state = touch.state
local id = touch.id
local x = touch.x
local y = touch.y
local l = self.rect.l
local b = self.rect.b
local r = self.rect.r
local t = self.rect.t
if state == BEGAN then
if x >= l and x <= r and y >= b and y<= t then
if not self.touchId then
self.touchId = id
self.oy = y
self.ov = self.value
self.visible = true
end
return true
end
return false
end
if state == MOVING then
if id == self.touchId then
local dv = -math.floor(
(y - self.oy)/(self.rect.h - self.d) *
(self.max - self.min))
local v = self.ov + dv
local v = math.max(self.min, v)
local v = math.min(self.max - self.length, v)
if v ~= self.value then
self.value = v
self.onChanged(self)
end
return true
end
return false
end
if id == self.touchId then
self.touchId = nil
self.oy = nil
self.ov = nil
self.visible = false
return true
else
return false
end
end