Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
LyqydOS/window
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
594 lines (583 sloc)
19.4 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| local unpack = unpack or table.unpack | |
| local standard = { | |
| clean = { | |
| ul = {"+", "0", "f"}, | |
| ur = {"+", "0", "f"}, | |
| ll = {"+", "0", "f"}, | |
| lr = {"+", "0", "f"}, | |
| top = {"-", "0", "f"}, | |
| bottom = {"-", "0", "f"}, | |
| left = {"|", "0", "f"}, | |
| right = {"|", "0", "f"}, | |
| min = {"-", "0", "f"}, | |
| max = {"-", "0", "f"}, | |
| restore = {"-", "0", "f"}, | |
| close = {"-", "e", "f"}, | |
| caption = {"", "0", "f"}, | |
| minPos = 0, | |
| maxPos = 0, | |
| closePos = 0, | |
| captionSize = {3, -3}, | |
| }, | |
| window = { | |
| ul = {"+", "0", "f"}, | |
| ur = {"+", "0", "f"}, | |
| ll = {"+", "0", "f"}, | |
| lr = {"*", "0", "f"}, | |
| top = {"-", "0", "f"}, | |
| bottom = {"-", "0", "f"}, | |
| left = {"|", "0", "f"}, | |
| right = {"|", "0", "f"}, | |
| min = {"_", "0", "f"}, | |
| max = {"M", "0", "f"}, | |
| restore = {"R", "0", "f"}, | |
| close = {"X", "e", "f"}, | |
| caption = {"", "0", "f"}, | |
| minPos = -5, | |
| maxPos = -4, | |
| closePos = -3, | |
| captionSize = {3, -7}, | |
| }, | |
| menu = { | |
| ul = {"/", "0", "f"}, | |
| ur = {"\\", "0", "f"}, | |
| ll = {"\\", "0", "f"}, | |
| lr = {"/", "0", "f"}, | |
| top = {"-", "0", "f"}, | |
| bottom = {"-", "0", "f"}, | |
| left = {"|", "0", "f"}, | |
| right = {"|", "0", "f"}, | |
| min = {"-", "0", "f"}, | |
| max = {"-", "0", "f"}, | |
| restore = {"-", "0", "f"}, | |
| close = {"-", "e", "f"}, | |
| caption = {"", "0", "f"}, | |
| minPos = 0, | |
| maxPos = 0, | |
| closePos = 0, | |
| captionSize = {3, -3}, | |
| }, | |
| modal = { | |
| ul = {"+", "0", "f"}, | |
| ur = {"+", "0", "f"}, | |
| ll = {"+", "0", "f"}, | |
| lr = {"+", "0", "f"}, | |
| top = {"-", "0", "f"}, | |
| bottom = {"-", "0", "f"}, | |
| left = {"|", "0", "f"}, | |
| right = {"|", "0", "f"}, | |
| min = {"-", "0", "f"}, | |
| max = {"-", "0", "f"}, | |
| restore = {"-", "0", "f"}, | |
| close = {"X", "e", "f"}, | |
| caption = {"", "0", "f"}, | |
| minPos = 0, | |
| maxPos = 0, | |
| closePos = -3, | |
| captionSize = {3, -5}, | |
| }, | |
| } | |
| local pretty = { | |
| clean = { | |
| ul = {" ", "0", "8"}, | |
| ur = {" ", "0", "8"}, | |
| ll = {" ", "0", "8"}, | |
| lr = {" ", "0", "8"}, | |
| top = {" ", "0", "8"}, | |
| bottom = {" ", "0", "8"}, | |
| left = {" ", "0", "8"}, | |
| right = {" ", "0", "8"}, | |
| min = {" ", "0", "8"}, | |
| max = {" ", "0", "8"}, | |
| restore = {" ", "0", "8"}, | |
| close = {" ", "0", "8"}, | |
| caption = {"", "f", "8"}, | |
| minPos = 0, | |
| maxPos = 0, | |
| closePos = 0, | |
| captionSize = {3, -3}, | |
| }, | |
| window = { | |
| ul = {" ", "0", "8"}, | |
| ur = {" ", "0", "8"}, | |
| ll = {" ", "0", "8"}, | |
| lr = {"/", "7", "8"}, | |
| top = {" ", "0", "8"}, | |
| bottom = {" ", "0", "8"}, | |
| left = {" ", "0", "8"}, | |
| right = {" ", "0", "8"}, | |
| min = {"-", "0", "9"}, | |
| max = {"M", "0", "9"}, | |
| restore = {"R", "0", "9"}, | |
| close = {"X", "0", "e"}, | |
| caption = {"", "f", "8"}, | |
| minPos = -5, | |
| maxPos = -4, | |
| closePos = -3, | |
| captionSize = {3, -7}, | |
| }, | |
| menu = { | |
| ul = {" ", "0", "8"}, | |
| ur = {" ", "0", "8"}, | |
| ll = {" ", "0", "8"}, | |
| lr = {" ", "0", "8"}, | |
| top = {" ", "0", "8"}, | |
| bottom = {" ", "0", "8"}, | |
| left = {" ", "0", "8"}, | |
| right = {" ", "0", "8"}, | |
| min = {" ", "0", "8"}, | |
| max = {" ", "0", "8"}, | |
| restore = {" ", "0", "8"}, | |
| close = {" ", "0", "8"}, | |
| caption = {"", "f", "8"}, | |
| minPos = 0, | |
| maxPos = 0, | |
| closePos = 0, | |
| captionSize = {3, -3}, | |
| }, | |
| modal = { | |
| ul = {" ", "0", "8"}, | |
| ur = {" ", "0", "8"}, | |
| ll = {" ", "0", "8"}, | |
| lr = {" ", "0", "8"}, | |
| top = {" ", "0", "8"}, | |
| bottom = {" ", "0", "8"}, | |
| left = {" ", "0", "8"}, | |
| right = {" ", "0", "8"}, | |
| min = {" ", "0", "8"}, | |
| max = {" ", "0", "8"}, | |
| restore = {" ", "0", "8"}, | |
| close = {"X", "0", "e"}, | |
| caption = {"", "f", "8"}, | |
| minPos = 0, | |
| maxPos = 0, | |
| closePos = -3, | |
| captionSize = {3, -5}, | |
| }, | |
| } | |
| local themes = theme.newSet("window", "standard", standard) | |
| if themes then | |
| themes:add("pretty", pretty) | |
| else | |
| themes = theme.getSet("window") | |
| if not themes:get("standard") then themes:add("standard", standard) end | |
| if not themes:get("pretty") then themes:add("pretty", pretty) end | |
| end | |
| local Window = { | |
| draw = function(self, mode) | |
| --render window to table | |
| local maxX, maxY = self.target.getSize() | |
| local redirect = framebuffer.new(maxX, maxY, self.target.isColor()) | |
| local outputBuffer = redirect.buffer | |
| local function findBoundaries(position) | |
| local first, second | |
| if position < 0 then | |
| first = maxX - (maxX - (self.x + self.w)) - (math.abs(position) - 1) - 2 | |
| second = maxX - (maxX - (self.x + self.w)) - (math.abs(position) - 1) | |
| elseif position > 0 then | |
| first = self.x + position - 2 | |
| second = self.x + position | |
| end | |
| return first, second | |
| end | |
| local function drawDecoration(decoration, position, line) | |
| local len, start = findBoundaries(position) | |
| if len and start then | |
| outputBuffer.text[line] = string.sub(outputBuffer.text[line], 1, len)..decoration[1]..string.sub(outputBuffer.text[line], start) | |
| outputBuffer.textColor[line] = string.sub(outputBuffer.textColor[line], 1, len)..decoration[2]..string.sub(outputBuffer.textColor[line], start) | |
| outputBuffer.backColor[line] = string.sub(outputBuffer.backColor[line], 1, len)..decoration[3]..string.sub(outputBuffer.backColor[line], start) | |
| return true | |
| else | |
| return false | |
| end | |
| end | |
| if mode ~= "cursor" then | |
| local prelineBuffer = self.x - 1 | |
| local postlineBuffer = maxX - (self.x + self.w - 1) | |
| for i=1, maxY do | |
| if self.borderless and i >= self.y and i <= self.y + self.h - 1 then | |
| outputBuffer.text[i] = string.rep(" ", prelineBuffer)..string.sub(self.redirect.buffer.text[i - self.y + 1], 1, self.w)..string.rep(" ", postlineBuffer) | |
| outputBuffer.textColor[i] = string.rep("0", prelineBuffer)..string.sub(self.redirect.buffer.textColor[i - self.y + 1], 1, self.w)..string.rep("0", postlineBuffer) | |
| outputBuffer.backColor[i] = string.rep("f", prelineBuffer)..string.sub(self.redirect.buffer.backColor[i - self.y + 1], 1, self.w)..string.rep("f", postlineBuffer) | |
| elseif i == self.y then | |
| outputBuffer.text[i] = string.rep(" ", prelineBuffer)..self.decorations.ul[1]..string.rep(self.decorations.top[1], self.w - 2)..self.decorations.ur[1]..string.rep(" ", postlineBuffer) | |
| outputBuffer.textColor[i] = string.rep("0", prelineBuffer)..self.decorations.ul[2]..string.rep(self.decorations.top[2], self.w - 2)..self.decorations.ur[2]..string.rep("0", postlineBuffer) | |
| outputBuffer.backColor[i] = string.rep("f", prelineBuffer)..self.decorations.ul[3]..string.rep(self.decorations.top[3], self.w - 2)..self.decorations.ur[3]..string.rep("f", postlineBuffer) | |
| if self.caption then | |
| local captionLength = math.max(self.w - (self.decorations.captionSize[1] - 1) - (math.abs(self.decorations.captionSize[2]) - 1), 0) | |
| local caption = string.sub(self.caption, 1, captionLength) | |
| local preCapSize = self.x + self.decorations.captionSize[1] - 2 | |
| local postCapStart = maxX - (maxX - (self.x + self.w)) - (math.abs(self.decorations.captionSize[2]) - 1) | |
| if captionLength > 0 and preCapSize + 1 < postCapStart then | |
| outputBuffer.text[i] = string.sub(outputBuffer.text[i], 1, preCapSize)..caption..string.rep(self.decorations.top[1], captionLength - #caption)..string.sub(outputBuffer.text[i], postCapStart) | |
| outputBuffer.textColor[i] = string.sub(outputBuffer.textColor[i], 1, preCapSize)..string.rep(self.decorations.caption[2], #caption)..string.rep(self.decorations.top[2], captionLength - #caption)..string.sub(outputBuffer.textColor[i], postCapStart) | |
| outputBuffer.backColor[i] = string.sub(outputBuffer.backColor[i], 1, preCapSize)..string.rep(self.decorations.caption[3], #caption)..string.rep(self.decorations.top[3], captionLength - #caption)..string.sub(outputBuffer.backColor[i], postCapStart) | |
| end | |
| end | |
| if self.windowType == "modal" or self.windowType == "window" then | |
| if not drawDecoration(self.decorations.close, self.decorations.closePos, i) then | |
| --invalid decoration, set theme and exit | |
| self:setTheme("standard") | |
| return self:draw() | |
| end | |
| if self.windowType == "window" then | |
| if not drawDecoration(self.decorations.min, self.decorations.minPos, i) then | |
| --invalid decoration, set theme and exit | |
| self:setTheme("standard") | |
| return self:draw() | |
| end | |
| if not drawDecoration(self.maximized and self.decorations.restore or self.decorations.max, self.decorations.maxPos, i) then | |
| --invalid decoration, set theme and exit | |
| self:setTheme("standard") | |
| return self:draw() | |
| end | |
| end | |
| end | |
| elseif i == self.y + self.h - 1 then | |
| outputBuffer.text[i] = string.rep(" ", prelineBuffer)..self.decorations.ll[1]..string.rep(self.decorations.bottom[1], self.w - 2)..self.decorations.lr[1]..string.rep(" ", postlineBuffer) | |
| outputBuffer.textColor[i] = string.rep("0", prelineBuffer)..self.decorations.ll[2]..string.rep(self.decorations.bottom[2], self.w - 2)..self.decorations.lr[2]..string.rep("0", postlineBuffer) | |
| outputBuffer.backColor[i] = string.rep("f", prelineBuffer)..self.decorations.ll[3]..string.rep(self.decorations.bottom[3], self.w - 2)..self.decorations.lr[3]..string.rep("f", postlineBuffer) | |
| elseif i >= self.y and i <= self.y + self.h - 1 then | |
| outputBuffer.text[i] = string.rep(" ", prelineBuffer)..self.decorations.left[1]..string.sub(self.redirect.buffer.text[i - self.y], 1, self.w - 2)..self.decorations.right[1]..string.rep(" ", postlineBuffer) | |
| outputBuffer.textColor[i] = string.rep("0", prelineBuffer)..self.decorations.left[2]..string.sub(self.redirect.buffer.textColor[i - self.y], 1, self.w - 2)..self.decorations.right[2]..string.rep("0", postlineBuffer) | |
| outputBuffer.backColor[i] = string.rep("f", prelineBuffer)..self.decorations.left[3]..string.sub(self.redirect.buffer.backColor[i - self.y], 1, self.w - 2)..self.decorations.right[3]..string.rep("f", postlineBuffer) | |
| else | |
| outputBuffer.text[i] = string.rep(" ", maxX) | |
| outputBuffer.textColor[i] = string.rep("0", maxX) | |
| outputBuffer.backColor[i] = string.rep("f", maxX) | |
| end | |
| end | |
| local _old = term.redirect(self.target) | |
| local maxX, maxY = term.getSize() | |
| if not self.minimized then | |
| local isColor = term.isColor() | |
| outputBuffer.sizeX, outputBuffer.sizeY = maxX, maxY | |
| outputBuffer.color = isColor | |
| outputBuffer.cursorX, outputBuffer.cursorY = self.x + self.redirect.buffer.cursorX, self.y + self.redirect.buffer.cursorY | |
| if self.borderless then outputBuffer.cursorX, outputBuffer.cursorY = outputBuffer.cursorX - 1, outputBuffer.cursorY - 1 end | |
| outputBuffer.cursorBlink = self.redirect.buffer.cursorBlink | |
| outputBuffer.curTextColor = self.redirect.buffer.curTextColor | |
| outputBuffer.curBackColor = self.redirect.buffer.curTextColor | |
| if self.target.setBounds then self.target.setBounds(self.x, self.y, self.x + self.w - 1, self.y + self.h - 1) end | |
| else | |
| for i=1, maxY do | |
| outputBuffer.text[i] = string.rep(" ", maxX) | |
| outputBuffer.textColor[i] = string.rep("0", maxX) | |
| outputBuffer.backColor[i] = string.rep("f", maxX) | |
| end | |
| if self.target.setBounds then self.target.setBounds(0, 0, 0, 0) end | |
| end | |
| if self.compatibility then | |
| redirect.setBounds(self.x, self.y, self.x + self.w - 1, self.y + self.h - 1) | |
| framebuffer.draw(outputBuffer) | |
| elseif not self.target.render then | |
| framebuffer.draw(outputBuffer) | |
| else | |
| self.target.render(outputBuffer) | |
| term.setCursorPos(outputBuffer.cursorX, outputBuffer.cursorY) | |
| term.setCursorBlink(outputBuffer.cursorBlink) | |
| term.setTextColor(2 ^ tonumber(outputBuffer.curTextColor, 16)) | |
| end | |
| if _old then | |
| term.redirect(_old) | |
| else | |
| term.restore() | |
| end | |
| else | |
| local _old = term.redirect(self.target) | |
| outputBuffer.cursorX, outputBuffer.cursorY = self.x + self.redirect.buffer.cursorX, self.y + self.redirect.buffer.cursorY | |
| if self.borderless then outputBuffer.cursorX, outputBuffer.cursorY = outputBuffer.cursorX - 1, outputBuffer.cursorY - 1 end | |
| outputBuffer.cursorBlink = self.redirect.buffer.cursorBlink | |
| outputBuffer.curTextColor = self.redirect.buffer.curTextColor | |
| term.setCursorPos(outputBuffer.cursorX, outputBuffer.cursorY) | |
| term.setCursorBlink(outputBuffer.cursorBlink) | |
| term.setTextColor(2 ^ tonumber(outputBuffer.curTextColor, 16)) | |
| if _old then | |
| term.redirect(_old) | |
| else | |
| term.restore() | |
| end | |
| end | |
| end, | |
| move = function(self, x, y) | |
| if not self.movable then return nil, "not movable" end | |
| if x and y then | |
| local xlim, ylim = self.target.getSize() | |
| if (x < 1 or x + self.w - 1 > xlim) and (y < 1 or y + self.h - 1 > ylim) then | |
| return nil, "location out of bounds" | |
| end | |
| if x >= 1 and x + self.w - 1 <= xlim then | |
| self.x = x | |
| end | |
| if y >= 1 and y + self.h - 1 <= ylim then | |
| self.y = y | |
| end | |
| if not self.deferDraw then self:draw() end | |
| return true | |
| else | |
| return nil, "must specify x and y" | |
| end | |
| end, | |
| resize = function(self, w, h) | |
| if not self.resizable then return nil, "not resizable" end | |
| if w and h then | |
| local w = tonumber(w) | |
| local h = tonumber(h) | |
| local xlim, ylim = self.target.getSize() | |
| if self.x + w - 1 > xlim or self.y + h - 1 > ylim then | |
| return nil, "window sized out of bounds" | |
| end | |
| local buf = self.redirect.buffer | |
| if self.borderless then | |
| buf.sizeX = w | |
| buf.sizeY = h | |
| else | |
| buf.sizeX = w - 2 | |
| buf.sizeY = h - 2 | |
| end | |
| if buf.sizeX >= 3 and buf.sizeY >= 1 then | |
| --adjust buffer vertical size | |
| if #buf.text > buf.sizeY then | |
| --remove entries to trim buffer | |
| repeat | |
| table.remove(buf.text) | |
| table.remove(buf.textColor) | |
| table.remove(buf.backColor) | |
| until #buf.text == buf.sizeY | |
| elseif #buf.text < buf.sizeY then | |
| repeat | |
| table.insert(buf.text, string.rep(" ", buf.sizeX)) | |
| table.insert(buf.textColor, string.rep(buf.curTextColor, buf.sizeX)) | |
| table.insert(buf.backColor, string.rep(buf.curBackColor, buf.sizeX)) | |
| until #buf.text == buf.sizeY | |
| end | |
| self.h = h | |
| --adjust buffer horizontal size. | |
| if #buf.text[1] > buf.sizeX then | |
| --make less wide. | |
| for i = 1, #buf.text do | |
| buf.text[i] = string.sub(buf.text[i], 1, buf.sizeX) | |
| buf.textColor[i] = string.sub(buf.textColor[i], 1, buf.sizeX) | |
| buf.backColor[i] = string.sub(buf.backColor[i], 1, buf.sizeX) | |
| end | |
| elseif #buf.text[1] < buf.sizeX then | |
| --make wider. | |
| local expand = buf.sizeX - #buf.text[1] | |
| for i = 1, #buf.text do | |
| buf.text[i] = buf.text[i]..string.rep(" ", expand) | |
| buf.textColor[i] = buf.textColor[i]..string.rep(buf.curTextColor, expand) | |
| buf.backColor[i] = buf.backColor[i]..string.rep(buf.curBackColor, expand) | |
| end | |
| end | |
| self.w = w | |
| if not self.deferDraw then self:draw() end | |
| return true | |
| else | |
| return nil, "size too small" | |
| end | |
| else | |
| return nil, "must specify width and height" | |
| end | |
| end, | |
| destroy = function(self) | |
| if process and process.compositor then | |
| process.compositor:removeBuffer(self.target.buffer) | |
| end | |
| end, | |
| setTheme = function(self, themeName) | |
| if not themeName then | |
| return nil, "Invalid theme" | |
| elseif type(themeName) == "string" then | |
| if themes:get(themeName) then | |
| self.theme = themeName | |
| for k,v in pairs((themes:get(themeName))[self.windowType]) do | |
| self.decorations[k] = v | |
| end | |
| else | |
| return nil, "Invalid theme" | |
| end | |
| end | |
| if not self.deferDraw then self:draw() end | |
| end, | |
| setDecorations = function(self, decoration) | |
| if not decoration then | |
| return nil, "Invalid decoration" | |
| elseif type(decoration) == "table" then | |
| for k,v in pairs(themes.themes.standard.window) do | |
| --check for completeness. | |
| if type(decoration[k]) ~= "table" or #decoration[k] < 3 then | |
| return nil, "Invalid decoration" | |
| end | |
| end | |
| for k,v in pairs(decoration) do | |
| self.decorations[k] = v | |
| end | |
| else | |
| return nil, "Invalid decoration" | |
| end | |
| if not self.deferDraw then self:draw() end | |
| end, | |
| maximize = function(self) | |
| if not self.resizable then return nil, "not resizable" end | |
| self.normalSize = {x = self.x, y = self.y, w = self.w, h = self.h} | |
| self:move(1, 1) | |
| self.maximized = true | |
| self:resize(self.target.getSize()) | |
| end, | |
| minimize = function(self) | |
| if not self.minimizable then return nil, "not minimizable" end | |
| self.minimized = true | |
| if not self.deferDraw then self:draw() end | |
| end, | |
| fullscreen = function(self) | |
| if not self.resizable then return nil, "not resizable" end | |
| self:maximize() | |
| self:setBorderless(true) | |
| end, | |
| unMinimize = function(self) | |
| self.minimized = false | |
| if not self.deferDraw then self:draw() end | |
| end, | |
| restore = function(self) | |
| if not self.resizable then return nil, "not resizable" end | |
| self.maximized = false | |
| if self.borderless then | |
| self.borderless = false | |
| end | |
| self:resize(self.normalSize.w, self.normalSize.h) | |
| self:move(self.normalSize.x, self.normalSize.y) | |
| self.normalSize = nil | |
| end, | |
| setType = function(self, winType) | |
| self.windowType = winType | |
| self:setTheme(self.theme) | |
| --setTheme draws the window if able | |
| end, | |
| setMode = function(self, mode) | |
| self.mode = mode | |
| end, | |
| setCaption = function(self, text) | |
| self.caption = text | |
| if not self.deferDraw then self:draw() end | |
| end, | |
| setBorderless = function(self, mode) | |
| self.borderless = mode | |
| local resizable = self.resizable | |
| self.resizable = true | |
| self:resize(self.w, self.h) | |
| self.resizable = resizable | |
| end, | |
| } | |
| local wmetatable = { | |
| __index = Window, | |
| } | |
| function new(w, h, x, y, caption, target) | |
| local win = { | |
| target = target or (type(term.native) == "function" and term.current() or term.native), | |
| w = tonumber(w) or 19, | |
| h = tonumber(h) or 8, | |
| x = tonumber(x) or 1, | |
| y = tonumber(y) or 1, | |
| caption = caption or nil, | |
| --windowType: clean, window, modal | |
| --clean is normal window, window includes _MX controls, modal includes X control only. | |
| windowType = "clean", | |
| theme = "standard", | |
| --mode is normal, ephemeral or modal | |
| mode = "normal", | |
| decorations = { | |
| ul = {"+", "0", "f"}, | |
| ur = {"+", "0", "f"}, | |
| ll = {"+", "0", "f"}, | |
| lr = {"+", "0", "f"}, | |
| top = {"-", "0", "f"}, | |
| bottom = {"-", "0", "f"}, | |
| left = {"|", "0", "f"}, | |
| right = {"|", "0", "f"}, | |
| min = {"-", "0", "f"}, | |
| max = {"-", "0", "f"}, | |
| restore = {"-", "0", "f"}, | |
| close = {"-", "e", "f"}, | |
| caption = {"", "0", "f"}, | |
| minPos = 0, | |
| maxPos = 0, | |
| closePos = 0, | |
| captionSize = {3, -3}, | |
| }, | |
| maximized = false, | |
| minimized = false, | |
| borderless = false, | |
| minimizable = true, | |
| resizable = true, | |
| movable = true, | |
| closable = true, | |
| compatibility = false, | |
| deferDraw = false, | |
| } | |
| if win.target.setBounds then win.target.setBounds(win.x, win.y, win.x + win.w - 1, win.y + win.h - 1) end | |
| local xlim, ylim = win.target.getSize() | |
| --x and y bounding for initial window. | |
| if win.x < 1 then | |
| win.x = 1 | |
| elseif win.x + win.w - 1 > xlim then | |
| win.x = xlim - win.w + 1 | |
| end | |
| if win.y < 1 then | |
| win.y = 1 | |
| elseif win.y + win.h - 1 > ylim then | |
| win.y = ylim - win.h + 1 | |
| end | |
| local _redirect = framebuffer.new(w - 2, h - 2, target.isColor()) | |
| win.redirect = {} | |
| for k, v in pairs(_redirect) do | |
| if type(k) == "string" and type(v) == "function" then | |
| win.redirect[k] = function(...) | |
| local result = {_redirect[k](...)} | |
| if not win.deferDraw then win:draw() end | |
| return unpack(result) | |
| end | |
| else | |
| win.redirect[k] = _redirect[k] | |
| end | |
| end | |
| setmetatable( win, wmetatable ) | |
| return win | |
| end | |
| function active() | |
| return process and process.id() and process.getWindow() | |
| end | |
| --compatibility with CC 1.6 window API. | |
| function create(parent, x, y, width, height, visible) | |
| local win = window.new(width, height, x, y, "", parent) | |
| win.compatibility = true | |
| win:setBorderless(true) | |
| if not visible then | |
| win:minimize() | |
| end | |
| win.redirect.setVisible = function(b) | |
| if b then | |
| win:unMinimize() | |
| else | |
| win:minimize() | |
| end | |
| end | |
| win.redirect.redraw = function() | |
| win:draw() | |
| end | |
| win.redirect.restoreCursor = function() | |
| win:draw("cursor") | |
| end | |
| win.redirect.getPosition = function() | |
| return win.x, win.y | |
| end | |
| win.redirect.reposition = function(x, y, w, h) | |
| local min = win.minimized | |
| win:minimize() | |
| win:resize(w, h) | |
| win:move(x, y) | |
| if not min then | |
| win:unMinimize() | |
| end | |
| end | |
| return win.redirect | |
| end |