From a3c2e7a043faacdfbe6c68b53f49aa9be4c2b390 Mon Sep 17 00:00:00 2001 From: Robert Jelic <36573031+NoryiE@users.noreply.github.com> Date: Fri, 29 Jul 2022 14:32:52 +0200 Subject: [PATCH] Delete oldVersions directory Not necessary anymore, if you are looking for different versions go and look into the release section. --- oldVersions/lastVersion/basalt-source.lua | 4981 ----------------- oldVersions/lastVersion/basalt.lua | 1 - oldVersions/lastVersion/source/compiler.lua | 7 - oldVersions/lastVersion/source/loader.lua | 4 - oldVersions/lastVersion/source/packager.lua | 68 - .../lastVersion/source/project/Frame.lua | 657 --- .../lastVersion/source/project/Object.lua | 573 -- .../source/project/defaultTheme.lua | 23 - .../source/project/lib/bigfont.lua | 135 - .../source/project/lib/drawHelper.lua | 181 - .../source/project/lib/eventSystem.lua | 37 - .../source/project/lib/process.lua | 50 - .../lastVersion/source/project/lib/utils.lua | 158 - .../lastVersion/source/project/mainBottom.lua | 154 - .../lastVersion/source/project/mainTop.lua | 31 - .../source/project/objects/Animation.lua | 95 - .../source/project/objects/Button.lua | 55 - .../source/project/objects/Checkbox.lua | 58 - .../source/project/objects/Dropdown.lua | 170 - .../source/project/objects/Image.lua | 193 - .../source/project/objects/Input.lua | 242 - .../source/project/objects/Label.lua | 99 - .../source/project/objects/List.lua | 161 - .../source/project/objects/Menubar.lua | 201 - .../source/project/objects/Pane.lua | 25 - .../source/project/objects/Program.lua | 646 --- .../source/project/objects/Progressbar.lua | 100 - .../source/project/objects/Radio.lua | 125 - .../source/project/objects/Scrollbar.lua | 130 - .../source/project/objects/Slider.lua | 129 - .../source/project/objects/Switch.lua | 68 - .../source/project/objects/Textfield.lua | 341 -- .../source/project/objects/Thread.lua | 69 - .../source/project/objects/Timer.lua | 75 - .../source/project/objects/example.lua | 45 - oldVersions/lastVersion/source/readme.md | 23 - oldVersions/old/basalt.lua | 1 - oldVersions/old/v1.0/basalt.lua | 4246 -------------- oldVersions/old/v1.1/basalt.lua | 1 - 39 files changed, 14358 deletions(-) delete mode 100644 oldVersions/lastVersion/basalt-source.lua delete mode 100644 oldVersions/lastVersion/basalt.lua delete mode 100644 oldVersions/lastVersion/source/compiler.lua delete mode 100644 oldVersions/lastVersion/source/loader.lua delete mode 100644 oldVersions/lastVersion/source/packager.lua delete mode 100644 oldVersions/lastVersion/source/project/Frame.lua delete mode 100644 oldVersions/lastVersion/source/project/Object.lua delete mode 100644 oldVersions/lastVersion/source/project/defaultTheme.lua delete mode 100644 oldVersions/lastVersion/source/project/lib/bigfont.lua delete mode 100644 oldVersions/lastVersion/source/project/lib/drawHelper.lua delete mode 100644 oldVersions/lastVersion/source/project/lib/eventSystem.lua delete mode 100644 oldVersions/lastVersion/source/project/lib/process.lua delete mode 100644 oldVersions/lastVersion/source/project/lib/utils.lua delete mode 100644 oldVersions/lastVersion/source/project/mainBottom.lua delete mode 100644 oldVersions/lastVersion/source/project/mainTop.lua delete mode 100644 oldVersions/lastVersion/source/project/objects/Animation.lua delete mode 100644 oldVersions/lastVersion/source/project/objects/Button.lua delete mode 100644 oldVersions/lastVersion/source/project/objects/Checkbox.lua delete mode 100644 oldVersions/lastVersion/source/project/objects/Dropdown.lua delete mode 100644 oldVersions/lastVersion/source/project/objects/Image.lua delete mode 100644 oldVersions/lastVersion/source/project/objects/Input.lua delete mode 100644 oldVersions/lastVersion/source/project/objects/Label.lua delete mode 100644 oldVersions/lastVersion/source/project/objects/List.lua delete mode 100644 oldVersions/lastVersion/source/project/objects/Menubar.lua delete mode 100644 oldVersions/lastVersion/source/project/objects/Pane.lua delete mode 100644 oldVersions/lastVersion/source/project/objects/Program.lua delete mode 100644 oldVersions/lastVersion/source/project/objects/Progressbar.lua delete mode 100644 oldVersions/lastVersion/source/project/objects/Radio.lua delete mode 100644 oldVersions/lastVersion/source/project/objects/Scrollbar.lua delete mode 100644 oldVersions/lastVersion/source/project/objects/Slider.lua delete mode 100644 oldVersions/lastVersion/source/project/objects/Switch.lua delete mode 100644 oldVersions/lastVersion/source/project/objects/Textfield.lua delete mode 100644 oldVersions/lastVersion/source/project/objects/Thread.lua delete mode 100644 oldVersions/lastVersion/source/project/objects/Timer.lua delete mode 100644 oldVersions/lastVersion/source/project/objects/example.lua delete mode 100644 oldVersions/lastVersion/source/readme.md delete mode 100644 oldVersions/old/basalt.lua delete mode 100644 oldVersions/old/v1.0/basalt.lua delete mode 100644 oldVersions/old/v1.1/basalt.lua diff --git a/oldVersions/lastVersion/basalt-source.lua b/oldVersions/lastVersion/basalt-source.lua deleted file mode 100644 index 167ba69..0000000 --- a/oldVersions/lastVersion/basalt-source.lua +++ /dev/null @@ -1,4981 +0,0 @@ -local basalt = { debugger = true, version = 1 } -local keyActive = {} -local focusedObject -local frames = {} -local activeFrame - -local mainFrame -local monFrames = {} - -local parentTerminal = term.current() - -local sub = string.sub - -local tHex = { -- copy paste is a very important feature - [colors.white] = "0", - [colors.orange] = "1", - [colors.magenta] = "2", - [colors.lightBlue] = "3", - [colors.yellow] = "4", - [colors.lime] = "5", - [colors.pink] = "6", - [colors.gray] = "7", - [colors.lightGray] = "8", - [colors.cyan] = "9", - [colors.purple] = "a", - [colors.blue] = "b", - [colors.brown] = "c", - [colors.green] = "d", - [colors.red] = "e", - [colors.black] = "f", -} --- current version 1 -local theme = { - basaltBG = colors.lightGray, - basaltFG = colors.black, - FrameBG = colors.gray, - FrameFG = colors.black, - ButtonBG = colors.gray, - ButtonFG = colors.black, - CheckboxBG = colors.gray, - CheckboxFG = colors.black, - InputBG = colors.gray, - InputFG = colors.black, - textfieldBG = colors.gray, - textfieldFG = colors.black, - listBG = colors.gray, - listFG = colors.black, - dropdownBG = colors.gray, - dropdownFG = colors.black, - radioBG = colors.gray, - radioFG = colors.black, - selectionBG = colors.black, - selectionFG = colors.lightGray, -} -------------------------------------------------------------------------------------- --- Wojbies API 5.0 - Bigfont - functions to write bigger font using drawing sybols -- -------------------------------------------------------------------------------------- --- Copyright (c) 2015-2022 Wojbie (wojbie@wojbie.net) --- Redistribution and use in source and binary forms, with or without modification, are permitted (subject to the limitations in the disclaimer below) provided that the following conditions are met: --- 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. --- 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. --- 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. --- 4. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. --- 5. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. --- NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. YOU ACKNOWLEDGE THAT THIS SOFTWARE IS NOT DESIGNED, LICENSED OR INTENDED FOR USE IN THE DESIGN, CONSTRUCTION, OPERATION OR MAINTENANCE OF ANY NUCLEAR FACILITY. - -local rawFont = {{"\32\32\32\137\156\148\158\159\148\135\135\144\159\139\32\136\157\32\159\139\32\32\143\32\32\143\32\32\32\32\32\32\32\32\147\148\150\131\148\32\32\32\151\140\148\151\140\147", "\32\32\32\149\132\149\136\156\149\144\32\133\139\159\129\143\159\133\143\159\133\138\32\133\138\32\133\32\32\32\32\32\32\150\150\129\137\156\129\32\32\32\133\131\129\133\131\132", "\32\32\32\130\131\32\130\131\32\32\129\32\32\32\32\130\131\32\130\131\32\32\32\32\143\143\143\32\32\32\32\32\32\130\129\32\130\135\32\32\32\32\131\32\32\131\32\131", "\139\144\32\32\143\148\135\130\144\149\32\149\150\151\149\158\140\129\32\32\32\135\130\144\135\130\144\32\149\32\32\139\32\159\148\32\32\32\32\159\32\144\32\148\32\147\131\132", "\159\135\129\131\143\149\143\138\144\138\32\133\130\149\149\137\155\149\159\143\144\147\130\132\32\149\32\147\130\132\131\159\129\139\151\129\148\32\32\139\131\135\133\32\144\130\151\32", "\32\32\32\32\32\32\130\135\32\130\32\129\32\129\129\131\131\32\130\131\129\140\141\132\32\129\32\32\129\32\32\32\32\32\32\32\131\131\129\32\32\32\32\32\32\32\32\32", "\32\32\32\32\149\32\159\154\133\133\133\144\152\141\132\133\151\129\136\153\32\32\154\32\159\134\129\130\137\144\159\32\144\32\148\32\32\32\32\32\32\32\32\32\32\32\151\129", "\32\32\32\32\133\32\32\32\32\145\145\132\141\140\132\151\129\144\150\146\129\32\32\32\138\144\32\32\159\133\136\131\132\131\151\129\32\144\32\131\131\129\32\144\32\151\129\32", "\32\32\32\32\129\32\32\32\32\130\130\32\32\129\32\129\32\129\130\129\129\32\32\32\32\130\129\130\129\32\32\32\32\32\32\32\32\133\32\32\32\32\32\129\32\129\32\32", "\150\156\148\136\149\32\134\131\148\134\131\148\159\134\149\136\140\129\152\131\32\135\131\149\150\131\148\150\131\148\32\148\32\32\148\32\32\152\129\143\143\144\130\155\32\134\131\148", "\157\129\149\32\149\32\152\131\144\144\131\148\141\140\149\144\32\149\151\131\148\32\150\32\150\131\148\130\156\133\32\144\32\32\144\32\130\155\32\143\143\144\32\152\129\32\134\32", "\130\131\32\131\131\129\131\131\129\130\131\32\32\32\129\130\131\32\130\131\32\32\129\32\130\131\32\130\129\32\32\129\32\32\133\32\32\32\129\32\32\32\130\32\32\32\129\32", "\150\140\150\137\140\148\136\140\132\150\131\132\151\131\148\136\147\129\136\147\129\150\156\145\138\143\149\130\151\32\32\32\149\138\152\129\149\32\32\157\152\149\157\144\149\150\131\148", "\149\143\142\149\32\149\149\32\149\149\32\144\149\32\149\149\32\32\149\32\32\149\32\149\149\32\149\32\149\32\144\32\149\149\130\148\149\32\32\149\32\149\149\130\149\149\32\149", "\130\131\129\129\32\129\131\131\32\130\131\32\131\131\32\131\131\129\129\32\32\130\131\32\129\32\129\130\131\32\130\131\32\129\32\129\131\131\129\129\32\129\129\32\129\130\131\32", "\136\140\132\150\131\148\136\140\132\153\140\129\131\151\129\149\32\149\149\32\149\149\32\149\137\152\129\137\152\129\131\156\133\149\131\32\150\32\32\130\148\32\152\137\144\32\32\32", "\149\32\32\149\159\133\149\32\149\144\32\149\32\149\32\149\32\149\150\151\129\138\155\149\150\130\148\32\149\32\152\129\32\149\32\32\32\150\32\32\149\32\32\32\32\32\32\32", "\129\32\32\130\129\129\129\32\129\130\131\32\32\129\32\130\131\32\32\129\32\129\32\129\129\32\129\32\129\32\131\131\129\130\131\32\32\32\129\130\131\32\32\32\32\140\140\132", "\32\154\32\159\143\32\149\143\32\159\143\32\159\144\149\159\143\32\159\137\145\159\143\144\149\143\32\32\145\32\32\32\145\149\32\144\32\149\32\143\159\32\143\143\32\159\143\32", "\32\32\32\152\140\149\151\32\149\149\32\145\149\130\149\157\140\133\32\149\32\154\143\149\151\32\149\32\149\32\144\32\149\149\153\32\32\149\32\149\133\149\149\32\149\149\32\149", "\32\32\32\130\131\129\131\131\32\130\131\32\130\131\129\130\131\129\32\129\32\140\140\129\129\32\129\32\129\32\137\140\129\130\32\129\32\130\32\129\32\129\129\32\129\130\131\32", "\144\143\32\159\144\144\144\143\32\159\143\144\159\138\32\144\32\144\144\32\144\144\32\144\144\32\144\144\32\144\143\143\144\32\150\129\32\149\32\130\150\32\134\137\134\134\131\148", "\136\143\133\154\141\149\151\32\129\137\140\144\32\149\32\149\32\149\154\159\133\149\148\149\157\153\32\154\143\149\159\134\32\130\148\32\32\149\32\32\151\129\32\32\32\32\134\32", "\133\32\32\32\32\133\129\32\32\131\131\32\32\130\32\130\131\129\32\129\32\130\131\129\129\32\129\140\140\129\131\131\129\32\130\129\32\129\32\130\129\32\32\32\32\32\129\32", "\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32", "\32\32\32\32\32\32\32\32\32\32\32\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\32\32\32\32\32\32\32\32\32\32\32", "\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32", "\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32", "\32\32\32\32\32\32\32\32\32\32\32\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\32\32\32\32\32\32\32\32\32\32\32", "\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32", "\32\32\32\32\145\32\159\139\32\151\131\132\155\143\132\134\135\145\32\149\32\158\140\129\130\130\32\152\147\155\157\134\32\32\144\144\32\32\32\32\32\32\152\131\155\131\131\129", "\32\32\32\32\149\32\149\32\145\148\131\32\149\32\149\140\157\132\32\148\32\137\155\149\32\32\32\149\154\149\137\142\32\153\153\32\131\131\149\131\131\129\149\135\145\32\32\32", "\32\32\32\32\129\32\130\135\32\131\131\129\134\131\132\32\129\32\32\129\32\131\131\32\32\32\32\130\131\129\32\32\32\32\129\129\32\32\32\32\32\32\130\131\129\32\32\32", "\150\150\32\32\148\32\134\32\32\132\32\32\134\32\32\144\32\144\150\151\149\32\32\32\32\32\32\145\32\32\152\140\144\144\144\32\133\151\129\133\151\129\132\151\129\32\145\32", "\130\129\32\131\151\129\141\32\32\142\32\32\32\32\32\149\32\149\130\149\149\32\143\32\32\32\32\142\132\32\154\143\133\157\153\132\151\150\148\151\158\132\151\150\148\144\130\148", "\32\32\32\140\140\132\32\32\32\32\32\32\32\32\32\151\131\32\32\129\129\32\32\32\32\134\32\32\32\32\32\32\32\129\129\32\129\32\129\129\130\129\129\32\129\130\131\32", "\156\143\32\159\141\129\153\140\132\153\137\32\157\141\32\159\142\32\150\151\129\150\131\132\140\143\144\143\141\145\137\140\148\141\141\144\157\142\32\159\140\32\151\134\32\157\141\32", "\157\140\149\157\140\149\157\140\149\157\140\149\157\140\149\157\140\149\151\151\32\154\143\132\157\140\32\157\140\32\157\140\32\157\140\32\32\149\32\32\149\32\32\149\32\32\149\32", "\129\32\129\129\32\129\129\32\129\129\32\129\129\32\129\129\32\129\129\131\129\32\134\32\131\131\129\131\131\129\131\131\129\131\131\129\130\131\32\130\131\32\130\131\32\130\131\32", "\151\131\148\152\137\145\155\140\144\152\142\145\153\140\132\153\137\32\154\142\144\155\159\132\150\156\148\147\32\144\144\130\145\136\137\32\146\130\144\144\130\145\130\136\32\151\140\132", "\151\32\149\151\155\149\149\32\149\149\32\149\149\32\149\149\32\149\149\32\149\152\137\144\157\129\149\149\32\149\149\32\149\149\32\149\149\32\149\130\150\32\32\157\129\149\32\149", "\131\131\32\129\32\129\130\131\32\130\131\32\130\131\32\130\131\32\130\131\32\32\32\32\130\131\32\130\131\32\130\131\32\130\131\32\130\131\32\32\129\32\130\131\32\133\131\32", "\156\143\32\159\141\129\153\140\132\153\137\32\157\141\32\159\142\32\159\159\144\152\140\144\156\143\32\159\141\129\153\140\132\157\141\32\130\145\32\32\147\32\136\153\32\130\146\32", "\152\140\149\152\140\149\152\140\149\152\140\149\152\140\149\152\140\149\149\157\134\154\143\132\157\140\133\157\140\133\157\140\133\157\140\133\32\149\32\32\149\32\32\149\32\32\149\32", "\130\131\129\130\131\129\130\131\129\130\131\129\130\131\129\130\131\129\130\130\131\32\134\32\130\131\129\130\131\129\130\131\129\130\131\129\32\129\32\32\129\32\32\129\32\32\129\32", "\159\134\144\137\137\32\156\143\32\159\141\129\153\140\132\153\137\32\157\141\32\32\132\32\159\143\32\147\32\144\144\130\145\136\137\32\146\130\144\144\130\145\130\138\32\146\130\144", "\149\32\149\149\32\149\149\32\149\149\32\149\149\32\149\149\32\149\149\32\149\131\147\129\138\134\149\149\32\149\149\32\149\149\32\149\149\32\149\154\143\149\32\157\129\154\143\149", "\130\131\32\129\32\129\130\131\32\130\131\32\130\131\32\130\131\32\130\131\32\32\32\32\130\131\32\130\131\129\130\131\129\130\131\129\130\131\129\140\140\129\130\131\32\140\140\129" }, {[[000110000110110000110010101000000010000000100101]], [[000000110110000000000010101000000010000000100101]], [[000000000000000000000000000000000000000000000000]], [[100010110100000010000110110000010100000100000110]], [[000000110000000010110110000110000000000000110000]], [[000000000000000000000000000000000000000000000000]], [[000000110110000010000000100000100000000000000010]], [[000000000110110100010000000010000000000000000100]], [[000000000000000000000000000000000000000000000000]], [[010000000000100110000000000000000000000110010000]], [[000000000000000000000000000010000000010110000000]], [[000000000000000000000000000000000000000000000000]], [[011110110000000100100010110000000100000000000000]], [[000000000000000000000000000000000000000000000000]], [[000000000000000000000000000000000000000000000000]], [[110000110110000000000000000000010100100010000000]], [[000010000000000000110110000000000100010010000000]], [[000000000000000000000000000000000000000000000000]], [[010110010110100110110110010000000100000110110110]], [[000000000000000000000110000000000110000000000000]], [[000000000000000000000000000000000000000000000000]], [[010100010110110000000000000000110000000010000000]], [[110110000000000000110000110110100000000010000000]], [[000000000000000000000000000000000000000000000000]], [[000100011111000100011111000100011111000100011111]], [[000000000000100100100100011011011011111111111111]], [[000000000000000000000000000000000000000000000000]], [[000100011111000100011111000100011111000100011111]], [[000000000000100100100100011011011011111111111111]], [[100100100100100100100100100100100100100100100100]], [[000000110100110110000010000011110000000000011000]], [[000000000100000000000010000011000110000000001000]], [[000000000000000000000000000000000000000000000000]], [[010000100100000000000000000100000000010010110000]], [[000000000000000000000000000000110110110110110000]], [[000000000000000000000000000000000000000000000000]], [[110110110110110110000000110110110110110110110110]], [[000000000000000000000110000000000000000000000000]], [[000000000000000000000000000000000000000000000000]], [[000000000000110110000110010000000000000000010010]], [[000010000000000000000000000000000000000000000000]], [[000000000000000000000000000000000000000000000000]], [[110110110110110110110000110110110110000000000000]], [[000000000000000000000110000000000000000000000000]], [[000000000000000000000000000000000000000000000000]], [[110110110110110110110000110000000000000000010000]], [[000000000000000000000000100000000000000110000110]], [[000000000000000000000000000000000000000000000000]] }} - ---### Genarate fonts using 3x3 chars per a character. (1 character is 6x9 pixels) -local fonts = {} -local firstFont = {} -do - local char = 0 - local height = #rawFont[1] - local length = #rawFont[1][1] - for i = 1, height, 3 do - for j = 1, length, 3 do - local thisChar = string.char(char) - - local temp = {} - temp[1] = rawFont[1][i]:sub(j, j + 2) - temp[2] = rawFont[1][i + 1]:sub(j, j + 2) - temp[3] = rawFont[1][i + 2]:sub(j, j + 2) - - local temp2 = {} - temp2[1] = rawFont[2][i]:sub(j, j + 2) - temp2[2] = rawFont[2][i + 1]:sub(j, j + 2) - temp2[3] = rawFont[2][i + 2]:sub(j, j + 2) - - firstFont[thisChar] = {temp, temp2} - char = char + 1 - end - end - fonts[1] = firstFont -end - -local function generateFontSize(size,yeld) - local inverter = {["0"] = "1", ["1"] = "0"} --:gsub("[01]",inverter) - if size<= #fonts then return true end - for f = #fonts+1, size do - --automagicly make bigger fonts using firstFont and fonts[f-1]. - local nextFont = {} - local lastFont = fonts[f - 1] - for char = 0, 255 do - local thisChar = string.char(char) - --sleep(0) print(f,thisChar) - - local temp = {} - local temp2 = {} - - local templateChar = lastFont[thisChar][1] - local templateBack = lastFont[thisChar][2] - for i = 1, #templateChar do - local line1, line2, line3, back1, back2, back3 = {}, {}, {}, {}, {}, {} - for j = 1, #templateChar[1] do - local currentChar = firstFont[templateChar[i]:sub(j, j)][1] - table.insert(line1, currentChar[1]) - table.insert(line2, currentChar[2]) - table.insert(line3, currentChar[3]) - - local currentBack = firstFont[templateChar[i]:sub(j, j)][2] - if templateBack[i]:sub(j, j) == "1" then - table.insert(back1, (currentBack[1]:gsub("[01]", inverter))) - table.insert(back2, (currentBack[2]:gsub("[01]", inverter))) - table.insert(back3, (currentBack[3]:gsub("[01]", inverter))) - else - table.insert(back1, currentBack[1]) - table.insert(back2, currentBack[2]) - table.insert(back3, currentBack[3]) - end - end - table.insert(temp, table.concat(line1)) - table.insert(temp, table.concat(line2)) - table.insert(temp, table.concat(line3)) - table.insert(temp2, table.concat(back1)) - table.insert(temp2, table.concat(back2)) - table.insert(temp2, table.concat(back3)) - end - - nextFont[thisChar] = {temp, temp2} - if yeld then yeld = "Font"..f.."Yeld"..char os.queueEvent(yeld) os.pullEvent(yeld) end - end - fonts[f] = nextFont - end - return true -end - -local function makeText(nSize, sString, nFC, nBC, bBlit) - if not type(sString) == "string" then error("Not a String",3) end --this should never happend with expects in place. - local cFC = type(nFC) == "string" and nFC:sub(1, 1) or tHex[nFC] or error("Wrong Front Color",3) - local cBC = type(nBC) == "string" and nBC:sub(1, 1) or tHex[nBC] or error("Wrong Back Color",3) - if(fonts[nSize]==nil)then generateFontSize(3,false) end - local font = fonts[nSize] or error("Wrong font size selected",3) - if sString == "" then return {{""}, {""}, {""}} end - - local input = {} - for i in sString:gmatch('.') do table.insert(input, i) end - - local tText = {} - local height = #font[input[1]][1] - - - for nLine = 1, height do - local outLine = {} - for i = 1, #input do - outLine[i] = font[input[i]] and font[input[i]][1][nLine] or "" - end - tText[nLine] = table.concat(outLine) - end - - local tFront = {} - local tBack = {} - local tFrontSub = {["0"] = cFC, ["1"] = cBC} - local tBackSub = {["0"] = cBC, ["1"] = cFC} - - for nLine = 1, height do - local front = {} - local back = {} - for i = 1, #input do - local template = font[input[i]] and font[input[i]][2][nLine] or "" - front[i] = template:gsub("[01]", bBlit and {["0"] = nFC:sub(i, i), ["1"] = nBC:sub(i, i)} or tFrontSub) - back[i] = template:gsub("[01]", bBlit and {["0"] = nBC:sub(i, i), ["1"] = nFC:sub(i, i)} or tBackSub) - end - tFront[nLine] = table.concat(front) - tBack[nLine] = table.concat(back) - end - - return {tText, tFront, tBack} -end -local function basaltDrawHelper(drawTerm) - local terminal = drawTerm - local width, height = terminal.getSize() - local cacheT = {} - local cacheBG = {} - local cacheFG = {} - - local _cacheT = {} - local _cacheBG = {} - local _cacheFG = {} - - local emptySpaceLine - local emptyColorLines = {} - - local function createEmptyLines() - emptySpaceLine = (" "):rep(width) - for n = 0, 15 do - local nColor = 2 ^ n - local sHex = tHex[nColor] - emptyColorLines[nColor] = sHex:rep(width) - end - end - ---- - createEmptyLines() - - local function recreateWindowArray() - local emptyText = emptySpaceLine - local emptyFG = emptyColorLines[colors.white] - local emptyBG = emptyColorLines[colors.black] - for currentY = 1, height do - cacheT[currentY] = sub(cacheT[currentY] == nil and emptyText or cacheT[currentY] .. emptyText:sub(1, width - cacheT[currentY]:len()), 1, width) - cacheFG[currentY] = sub(cacheFG[currentY] == nil and emptyFG or cacheFG[currentY] .. emptyFG:sub(1, width - cacheFG[currentY]:len()), 1, width) - cacheBG[currentY] = sub(cacheBG[currentY] == nil and emptyBG or cacheBG[currentY] .. emptyBG:sub(1, width - cacheBG[currentY]:len()), 1, width) - end - end - recreateWindowArray() - - local function setText(x, y, text) - if (y >= 1) and (y <= height) then - if (x + text:len() > 0) and (x <= width) then - local oldCache = cacheT[y] - local newCache - local nEnd = x + #text - 1 - - if (x < 1) then - local startN = 1 - x + 1 - local endN = width - x + 1 - text = sub(text, startN, endN) - elseif (nEnd > width) then - local endN = width - x + 1 - text = sub(text, 1, endN) - end - - if (x > 1) then - local endN = x - 1 - newCache = sub(oldCache, 1, endN) .. text - else - newCache = text - end - if nEnd < width then - newCache = newCache .. sub(oldCache, nEnd + 1, width) - end - cacheT[y] = newCache - end - end - end - - local function setBG(x, y, colorStr) - if (y >= 1) and (y <= height) then - if (x + colorStr:len() > 0) and (x <= width) then - local oldCache = cacheBG[y] - local newCache - local nEnd = x + #colorStr - 1 - - if (x < 1) then - colorStr = sub(colorStr, 1 - x + 1, width - x + 1) - elseif (nEnd > width) then - colorStr = sub(colorStr, 1, width - x + 1) - end - - if (x > 1) then - newCache = sub(oldCache, 1, x - 1) .. colorStr - else - newCache = colorStr - end - if nEnd < width then - newCache = newCache .. sub(oldCache, nEnd + 1, width) - end - cacheBG[y] = newCache - end - end - end - - local function setFG(x, y, colorStr) - if (y >= 1) and (y <= height) then - if (x + colorStr:len() > 0) and (x <= width) then - local oldCache = cacheFG[y] - local newCache - local nEnd = x + #colorStr - 1 - - if (x < 1) then - local startN = 1 - x + 1 - local endN = width - x + 1 - colorStr = sub(colorStr, startN, endN) - elseif (nEnd > width) then - local endN = width - x + 1 - colorStr = sub(colorStr, 1, endN) - end - - if (x > 1) then - local endN = x - 1 - newCache = sub(oldCache, 1, endN) .. colorStr - else - newCache = colorStr - end - if nEnd < width then - newCache = newCache .. sub(oldCache, nEnd + 1, width) - end - cacheFG[y] = newCache - end - end - end - - local drawHelper = { - setBG = function(x, y, colorStr) - setBG(x, y, colorStr) - end; - - setText = function(x, y, text) - setText(x, y, text) - end; - - setFG = function(x, y, colorStr) - setFG(x, y, colorStr) - end; - - drawBackgroundBox = function(x, y, width, height, bgCol) - for n = 1, height do - setBG(x, y + (n - 1), tHex[bgCol]:rep(width)) - end - end; - drawForegroundBox = function(x, y, width, height, fgCol) - for n = 1, height do - setFG(x, y + (n - 1), tHex[fgCol]:rep(width)) - end - end; - drawTextBox = function(x, y, width, height, symbol) - for n = 1, height do - setText(x, y + (n - 1), symbol:rep(width)) - end - end; - writeText = function(x, y, text, bgCol, fgCol) - bgCol = bgCol or terminal.getBackgroundColor() - fgCol = fgCol or terminal.getTextColor() - setText(x, y, text) - setBG(x, y, tHex[bgCol]:rep(text:len())) - setFG(x, y, tHex[fgCol]:rep(text:len())) - end; - - update = function() - local xC, yC = terminal.getCursorPos() - local isBlinking = false - if (terminal.getCursorBlink ~= nil) then - isBlinking = terminal.getCursorBlink() - end - terminal.setCursorBlink(false) - for n = 1, height do - terminal.setCursorPos(1, n) - terminal.blit(cacheT[n], cacheFG[n], cacheBG[n]) - end - terminal.setBackgroundColor(colors.black) - terminal.setCursorBlink(isBlinking) - terminal.setCursorPos(xC, yC) - end; - - setTerm = function(newTerm) - terminal = newTerm; - end; - } - return drawHelper -end -local function BasaltEvents() - - local events = {} - local index = {} - - local event = { - registerEvent = function(self, _event, func) - if (events[_event] == nil) then - events[_event] = {} - index[_event] = 1 - end - events[_event][index[_event]] = func - index[_event] = index[_event] + 1 - return index[_event] - 1 - end; - - removeEvent = function(self, _event, index) - events[_event][index[_event]] = nil - end; - - sendEvent = function(self, _event, ...) - local returnValue - if (events[_event] ~= nil) then - for _, value in pairs(events[_event]) do - local val = value(...) - if(val==false)then - returnValue = val - end - end - end - return returnValue - end; - } - event.__index = event - return event -end -local eventSystem = BasaltEvents() -local processes = {} -local process = {} -local processId = 0 - -function process:new(path, window, ...) - local args = table.pack(...) - local newP = setmetatable({ path = path }, { __index = self }) - newP.window = window - newP.processId = processId - newP.coroutine = coroutine.create(function() - os.run({ }, path, table.unpack(args)) - end) - processes[processId] = newP - processId = processId + 1 - return newP -end - -function process:resume(event, ...) - term.redirect(self.window) - local ok, result = coroutine.resume(self.coroutine, event, ...) - self.window = term.current() - if ok then - self.filter = result - else - basalt.debug(result) - end -end - -function process:isDead() - if (self.coroutine ~= nil) then - if (coroutine.status(self.coroutine) == "dead") then - table.remove(processes, self.processId) - return true - end - else - return true - end - return false -end - -function process:getStatus() - if (self.coroutine ~= nil) then - return coroutine.status(self.coroutine) - end - return nil -end - -function process:start() - coroutine.resume(self.coroutine) -end -local function getTextHorizontalAlign(text, width, textAlign, replaceChar) - text = string.sub(text, 1, width) - local offset = width - string.len(text) - if (textAlign == "right") then - text = string.rep(replaceChar or " ", offset) .. text - elseif (textAlign == "center") then - text = string.rep(replaceChar or " ", math.floor(offset / 2)) .. text .. string.rep(replaceChar or " ", math.floor(offset / 2)) - text = text .. (string.len(text) < width and (replaceChar or " ") or "") - else - text = text .. string.rep(replaceChar or " ", offset) - end - return text -end - -local function getTextVerticalAlign(h, textAlign) - local offset = 0 - if (textAlign == "center") then - offset = math.ceil(h / 2) - if (offset < 1) then - offset = 1 - end - end - if (textAlign == "bottom") then - offset = h - end - if(offset<1)then offset=1 end - return offset -end - -local function rpairs(t) - return function(t, i) - i = i - 1 - if i ~= 0 then - return i, t[i] - end - end, t, #t + 1 -end - --- shrink system is copy pasted (and slightly changed) from blittle by Bomb Bloke: http://www.computercraft.info/forums2/index.php?/topic/25354-cc-176-blittle-api/ -local function shrink(bLittleData, bgColor) - local relations = { [0] = { 8, 4, 3, 6, 5 }, { 4, 14, 8, 7 }, { 6, 10, 8, 7 }, { 9, 11, 8, 0 }, { 1, 14, 8, 0 }, { 13, 12, 8, 0 }, { 2, 10, 8, 0 }, { 15, 8, 10, 11, 12, 14 }, - { 0, 7, 1, 9, 2, 13 }, { 3, 11, 8, 7 }, { 2, 6, 7, 15 }, { 9, 3, 7, 15 }, { 13, 5, 7, 15 }, { 5, 12, 8, 7 }, { 1, 4, 7, 15 }, { 7, 10, 11, 12, 14 } } - - local colourNum, exponents, colourChar = {}, {}, {} - for i = 0, 15 do - exponents[2 ^ i] = i - end - do - local hex = "0123456789abcdef" - for i = 1, 16 do - colourNum[hex:sub(i, i)] = i - 1 - colourNum[i - 1] = hex:sub(i, i) - colourChar[hex:sub(i, i)] = 2 ^ (i - 1) - colourChar[2 ^ (i - 1)] = hex:sub(i, i) - - local thisRel = relations[i - 1] - for i = 1, #thisRel do - thisRel[i] = 2 ^ thisRel[i] - end - end - end - - local function getBestColourMatch(usage) - local lastCol = relations[exponents[usage[#usage][1]]] - if(lastCol~=nil)then - for j = 1, #lastCol do - local thisRelation = lastCol[j] - for i = 1, #usage - 1 do - if usage[i][1] == thisRelation then - return i - end - end - end - end - return 1 - end - - local function colsToChar(pattern, totals) - if not totals then - local newPattern = {} - totals = {} - for i = 1, 6 do - local thisVal = pattern[i] - local thisTot = totals[thisVal] - totals[thisVal], newPattern[i] = thisTot and (thisTot + 1) or 1, thisVal - end - pattern = newPattern - end - - local usage = {} - for key, value in pairs(totals) do - usage[#usage + 1] = { key, value } - end - - if #usage > 1 then - -- Reduce the chunk to two colours: - while #usage > 2 do - table.sort(usage, function(a, b) - return a[2] > b[2] - end) - local matchToInd, usageLen = getBestColourMatch(usage), #usage - local matchFrom, matchTo = usage[usageLen][1], usage[matchToInd][1] - for i = 1, 6 do - if pattern[i] == matchFrom then - pattern[i] = matchTo - usage[matchToInd][2] = usage[matchToInd][2] + 1 - end - end - usage[usageLen] = nil - end - - -- Convert to character. Adapted from oli414's function: - -- http://www.computercraft.info/forums2/index.php?/topic/25340-cc-176-easy-drawing-characters/ - local data = 128 - for i = 1, #pattern - 1 do - if pattern[i] ~= pattern[6] then - data = data + 2 ^ (i - 1) - end - end - return string.char(data), colourChar[usage[1][1] == pattern[6] and usage[2][1] or usage[1][1]], colourChar[pattern[6]] - else - -- Solid colour character: - return "\128", colourChar[pattern[1]], colourChar[pattern[1]] - end - end - - local results, width, height, bgCol = { {}, {}, {} }, 0, #bLittleData + #bLittleData % 3, bgColor or colors.black - for i = 1, #bLittleData do - if #bLittleData[i] > width then - width = #bLittleData[i] - end - end - - for y = 0, height - 1, 3 do - local cRow, tRow, bRow, counter = {}, {}, {}, 1 - - for x = 0, width - 1, 2 do - -- Grab a 2x3 chunk: - local pattern, totals = {}, {} - - for yy = 1, 3 do - for xx = 1, 2 do - pattern[#pattern + 1] = (bLittleData[y + yy] and bLittleData[y + yy][x + xx]) and (bLittleData[y + yy][x + xx] == 0 and bgCol or bLittleData[y + yy][x + xx]) or bgCol - totals[pattern[#pattern]] = totals[pattern[#pattern]] and (totals[pattern[#pattern]] + 1) or 1 - end - end - - cRow[counter], tRow[counter], bRow[counter] = colsToChar(pattern, totals) - counter = counter + 1 - end - - results[1][#results[1] + 1], results[2][#results[2] + 1], results[3][#results[3] + 1] = table.concat(cRow), table.concat(tRow), table.concat(bRow) - end - - results.width, results.height = #results[1][1], #results[1] - - return results -end -local function Object(name) - -- Base object - local objectType = "Object" -- not changeable - local value - local zIndex = 1 - local anchor = "topLeft" - local ignOffset = false - local isVisible = false - - local shadow = false - local borderLeft = false - local borderTop = false - local borderRight = false - local borderBottom = false - - local shadowColor = colors.black - local borderColor = colors.black - - local visualsChanged = true - - local eventSystem = BasaltEvents() - - local object = { - x = 1, - y = 1, - width = 1, - height = 1, - bgColor = colors.black, - fgColor = colors.white, - name = name or "Object", - parent = nil, - - show = function(self) - isVisible = true - visualsChanged = true - return self - end; - - hide = function(self) - isVisible = false - visualsChanged = true - return self - end; - - isVisible = function(self) - return isVisible - end; - - setFocus = function(self) - if (self.parent ~= nil) then - self.parent:setFocusedObject(self) - end - return self - end; - - setZIndex = function(self, index) - zIndex = index - if (self.parent ~= nil) then - self.parent:removeObject(self) - self.parent:addObject(self) - end - return self - end; - - getZIndex = function(self) - return zIndex; - end; - - getType = function(self) - return objectType - end; - - getName = function(self) - return self.name - end; - - remove = function(self) - if (self.parent ~= nil) then - self.parent:removeObject(self) - end - return self - end; - - setParent = function(self, frame) - if (frame.getType ~= nil and frame:getType() == "Frame") then - self:remove() - frame:addObject(self) - if (self.draw) then - self:show() - end - end - return self - end; - - setValue = function(self, _value) - if (value ~= _value) then - value = _value - visualsChanged = true - self:valueChangedHandler() - end - return self - end; - - getValue = function(self) - return value - end; - - getVisualChanged = function(self) - return visualsChanged - end; - - setVisualChanged = function(self, change) - visualsChanged = change or true - if(change == nil)then visualsChanged = true end - return self - end; - - - getEventSystem = function(self) - return eventSystem - end; - - - getParent = function(self) - return self.parent - end; - - setPosition = function(self, xPos, yPos, rel) - if (rel) then - self.x, self.y = math.floor(self.x + xPos), math.floor(self.y + yPos) - else - self.x, self.y = math.floor(xPos), math.floor(yPos) - end - visualsChanged = true - return self - end; - - getPosition = function(self) - return self.x, self.y - end; - - getVisibility = function(self) - return isVisible - end; - - setVisibility = function(self, _isVisible) - isVisible = _isVisible or not isVisible - visualsChanged = true - return self - end; - - setSize = function(self, width, height) - self.width, self.height = width, height - eventSystem:sendEvent("basalt_resize", self) - visualsChanged = true - return self - end; - - getHeight = function(self) - return self.height - end; - - getWidth = function(self) - return self.width - end; - - getSize = function(self) - return self.width, self.height - end; - - setBackground = function(self, color) - self.bgColor = color - visualsChanged = true - return self - end; - - getBackground = function(self) - return self.bgColor - end; - - setForeground = function(self, color) - self.fgColor = color - visualsChanged = true - return self - end; - - getForeground = function(self) - return self.fgColor - end; - - showShadow = function(self, show) - shadow = show or (not shadow) - return self - end; - - setShadow = function(self, color) - shadowColor = color - return self - end; - - isShadowActive = function(self) - return shadow; - end; - - showBorder = function(self, ...) - for _,v in pairs(table.pack(...))do - if(v=="left")then - borderLeft = true - end - if(v=="top")then - borderTop = true - end - if(v=="right")then - borderRight = true - end - if(v=="bottom")then - borderBottom = true - end - end - return self - end; - - setBorder = function(self, color) - shadowColor = color - return self - end; - - getBorder = function(self, side) - if(side=="left")then - return borderLeft; - end - if(side=="top")then - return borderTop; - end - if(side=="right")then - return borderRight; - end - if(side=="bottom")then - return borderBottom; - end - end; - - draw = function(self) - if (isVisible) then - if(self.parent~=nil)then - local x, y = self:getAnchorPosition() - if(shadow)then - self.parent:drawBackgroundBox(x+1, y+self.height, self.width, 1, shadowColor) - self.parent:drawBackgroundBox(x+self.width, y+1, 1, self.height, shadowColor) - self.parent:drawForegroundBox(x+1, y+self.height, self.width, 1, shadowColor) - self.parent:drawForegroundBox(x+self.width, y+1, 1, self.height, shadowColor) - end - if(borderLeft)then - self.parent:drawTextBox(x-1, y, 1, self.height, "\149") - self.parent:drawForegroundBox(x-1, y, 1, self.height, borderColor) - if(self.bgColor~=false)then self.parent:drawBackgroundBox(x-1, y, 1, self.height, self.bgColor) end - end - if(borderLeft)and(borderTop)then - self.parent:drawTextBox(x-1, y-1, 1, 1, "\151") - self.parent:drawForegroundBox(x-1, y-1, 1, 1, borderColor) - if(self.bgColor~=false)then self.parent:drawBackgroundBox(x-1, y-1, 1, 1, self.bgColor) end - end - if(borderTop)then - self.parent:drawTextBox(x, y-1, self.width, 1, "\131") - self.parent:drawForegroundBox(x, y-1, self.width, 1, borderColor) - if(self.bgColor~=false)then self.parent:drawBackgroundBox(x, y-1, self.width, 1, self.bgColor) end - end - if(borderTop)and(borderRight)then - self.parent:drawTextBox(x+self.width, y-1, 1, 1, "\149") - self.parent:drawForegroundBox(x+self.width, y-1, 1, 1, borderColor) - end - if(borderRight)then - self.parent:drawTextBox(x+self.width, y, 1, self.height, "\149") - self.parent:drawForegroundBox(x+self.width, y, 1, self.height, borderColor) - end - if(borderRight)and(borderBottom)then - self.parent:drawTextBox(x+self.width, y+self.height, 1, 1, "\129") - self.parent:drawForegroundBox(x+self.width, y+self.height, 1, 1, borderColor) - end - if(borderBottom)then - self.parent:drawTextBox(x, y+self.height, self.width, 1, "\131") - self.parent:drawForegroundBox(x, y+self.height, self.width, 1, borderColor) - end - if(borderBottom)and(borderLeft)then - self.parent:drawTextBox(x-1, y+self.height, 1, 1, "\131") - self.parent:drawForegroundBox(x-1, y+self.height, 1, 1, borderColor) - end - end - return true - end - return false - end; - - - getAbsolutePosition = function(self, x, y) - -- relative position to absolute position - if (x == nil) or (y == nil) then - x, y = self:getAnchorPosition() - end - - if (self.parent ~= nil) then - local fx, fy = self.parent:getAbsolutePosition(self.parent:getAnchorPosition()) - x = fx + x - 1 - y = fy + y - 1 - end - return x, y - end; - - getAnchorPosition = function(self, x, y, ignOff) - if (x == nil) then - x = self.x - end - if (y == nil) then - y = self.y - end - if (anchor == "top") then - x = math.floor(self.parent.width/2) + x - 1 - elseif(anchor == "topRight") then - x = self.parent.width + x - 1 - elseif(anchor == "right") then - x = self.parent.width + x - 1 - y = math.floor(self.parent.height/2) + y - 1 - elseif(anchor == "bottomRight") then - x = self.parent.width + x - 1 - y = self.parent.height + y - 1 - elseif(anchor == "bottom") then - x = math.floor(self.parent.width/2) + x - 1 - y = self.parent.height + y - 1 - elseif(anchor == "bottomLeft") then - y = self.parent.height + y - 1 - elseif(anchor == "left") then - y = math.floor(self.parent.height/2) + y - 1 - elseif(anchor == "center") then - x = math.floor(self.parent.width/2) + x - 1 - y = math.floor(self.parent.height/2) + y - 1 - end - local xO, yO = self:getOffset() - if not(ignOffset or ignOff) then - return x+xO, y+yO - end - return x, y - end; - - getOffset = function(self) - if (self.parent ~= nil) then - return self.parent:getFrameOffset() - end - return 0, 0 - end; - - ignoreOffset = function(self, ignore) - ignOffset = ignore - if(ignore==nil)then ignOffset = true end - return self - end; - - getBaseFrame = function(self) - if(self.parent~=nil)then - return self.parent:getBaseFrame() - end - return self - end; - - setAnchor = function(self, newAnchor) - anchor = newAnchor - visualsChanged = true - return self - end; - - getAnchor = function(self) - return anchor - end; - - onChange = function(self, ...) - for _,v in pairs(table.pack(...))do - if(type(v)=="function")then - self:registerEvent("value_changed", v) - end - end - return self - end; - - onClick = function(self, ...) - for _,v in pairs(table.pack(...))do - if(type(v)=="function")then - self:registerEvent("mouse_click", v) - self:registerEvent("monitor_touch", v) - end - end - return self - end; - - onClickUp = function(self, ...) - for _,v in pairs(table.pack(...))do - if(type(v)=="function")then - self:registerEvent("mouse_up", v) - end - end - return self - end; - - - onScroll = function(self, ...) - for _,v in pairs(table.pack(...))do - if(type(v)=="function")then - self:registerEvent("mouse_scroll", v) - end - end - return self - end; - - onDrag = function(self, ...) - for _,v in pairs(table.pack(...))do - if(type(v)=="function")then - self:registerEvent("mouse_drag", v) - end - end - return self - end; - - onEvent = function(self, ...) - for _,v in pairs(table.pack(...))do - if(type(v)=="function")then - self:registerEvent("custom_event_handler", v) - end - end - return self - end; - - onKey = function(self, ...) - for _,v in pairs(table.pack(...))do - if(type(v)=="function")then - self:registerEvent("key", v) - self:registerEvent("char", v) - end - end - return self - end; - - onResize = function(self, ...) - for _,v in pairs(table.pack(...))do - if(type(v)=="function")then - self:registerEvent("basalt_resize", v) - end - end - return self - end; - - onKeyUp = function(self, ...) - for _,v in pairs(table.pack(...))do - if(type(v)=="function")then - self:registerEvent("key_up", v) - end - end - return self - end; - - onBackgroundKey = function(self, ...) - for _,v in pairs(table.pack(...))do - if(type(v)=="function")then - self:registerEvent("background_key", v) - self:registerEvent("background_char", v) - end - end - return self - end; - - onBackgroundKeyUp = function(self, ...) - for _,v in pairs(table.pack(...))do - if(type(v)=="function")then - self:registerEvent("background_key_up", v) - end - end - return self - end; - - isFocused = function(self) - if (self.parent ~= nil) then - return self.parent:getFocusedObject() == self - end - return false - end; - - onGetFocus = function(self, ...) - for _,v in pairs(table.pack(...))do - if(type(v)=="function")then - self:registerEvent("get_focus", v) - end - end - return self - end; - - onLoseFocus = function(self, ...) - for _,v in pairs(table.pack(...))do - if(type(v)=="function")then - self:registerEvent("lose_focus", v) - end - end - return self - end; - - registerEvent = function(self, event, func) - return eventSystem:registerEvent(event, func) - end; - - removeEvent = function(self, event, index) - return eventSystem:removeEvent(event, index) - end; - - sendEvent = function(self, event, ...) - return eventSystem:sendEvent(event, self, ...) - end; - - mouseHandler = function(self, event, button, x, y) - local objX, objY = self:getAbsolutePosition(self:getAnchorPosition()) - local yOff = false - if(objY-1 == y)and(self:getBorder("top"))then - y = y+1 - yOff = true - end - - if (objX <= x) and (objX + self.width > x) and (objY <= y) and (objY + self.height > y) and (isVisible) then - if (self.parent ~= nil) then - self.parent:setFocusedObject(self) - end - local val = eventSystem:sendEvent(event, self, event, button, x, y) - if(val~=nil)then return val end - return true - end - return false - end; - - keyHandler = function(self, event, key) - if (self:isFocused()) then - local val = eventSystem:sendEvent(event, self, event, key) - if(val~=nil)then return val end - return true - end - return false - end; - - backgroundKeyHandler = function(self, event, key) - local val = eventSystem:sendEvent("background_"..event, self, event, key) - if(val~=nil)then return val end - return true - end; - - valueChangedHandler = function(self) - eventSystem:sendEvent("value_changed", self) - end; - - eventHandler = function(self, event, p1, p2, p3, p4) - eventSystem:sendEvent("custom_event_handler", self, event, p1, p2, p3, p4) - end; - - getFocusHandler = function(self) - local val = eventSystem:sendEvent("get_focus", self) - if(val~=nil)then return val end - return true - end; - - loseFocusHandler = function(self) - local val = eventSystem:sendEvent("lose_focus", self) - if(val~=nil)then return val end - return true - end; - - - } - - object.__index = object - return object -end -local function Animation(name) - local object = {} - local objectType = "Animation" - - local timerObj - - local animations = {} - local index = 1 - - local nextWaitTimer = 0 - local lastFunc - - local function onPlay() - if (animations[index] ~= nil) then - animations[index].f(object, index) - end - index = index + 1 - if (animations[index] ~= nil) then - if (animations[index].t > 0) then - timerObj = os.startTimer(animations[index].t) - else - onPlay() - end - end - end - - object = { - name = name, - getType = function(self) - return objectType - end; - - getZIndex = function(self) - return 1 - end; - - getName = function(self) - return self.name - end; - - add = function(self, func, wait) - lastFunc = func - table.insert(animations, { f = func, t = wait or nextWaitTimer }) - return self - end; - - wait = function(self, wait) - nextWaitTimer = wait - return self - end; - - rep = function(self, reps) - for x = 1, reps do - table.insert(animations, { f = lastFunc, t = nextWaitTimer }) - end - return self - end; - - clear = function(self) - animations = {} - lastFunc = nil - nextWaitTimer = 0 - index = 1 - return self - end; - - play = function(self) - index = 1 - if (animations[index] ~= nil) then - if (animations[index].t > 0) then - timerObj = os.startTimer(animations[index].t) - else - onPlay() - end - end - return self - end; - - cancel = function(self) - os.cancelTimer(timerObj) - return self - end; - - eventHandler = function(self, event, tObj) - if (event == "timer") and (tObj == timerObj) then - if (animations[index] ~= nil) then - onPlay() - end - end - end; - } - object.__index = object - - return object -end -local function Button(name) - -- Button - local base = Object(name) - local objectType = "Button" - - base:setValue("Button") - base:setZIndex(5) - base.width = 8 - base.bgColor = theme.ButtonBG - base.fgColor = theme.ButtonFG - - local textHorizontalAlign = "center" - local textVerticalAlign = "center" - - local object = { - getType = function(self) - return objectType - end; - setHorizontalAlign = function(self, pos) - textHorizontalAlign = pos - end; - - setVerticalAlign = function(self, pos) - textVerticalAlign = pos - end; - - setText = function(self, text) - base:setValue(text) - return self - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - local verticalAlign = getTextVerticalAlign(self.height, textVerticalAlign) - - if(self.bgColor~=false)then - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - self.parent:drawTextBox(obx, oby, self.width, self.height, " ") - end - if(self.fgColor~=false)then self.parent:drawForegroundBox(obx, oby, self.width, self.height, self.fgColor) end - for n = 1, self.height do - if (n == verticalAlign) then - self.parent:setText(obx, oby + (n - 1), getTextHorizontalAlign(self:getValue(), self.width, textHorizontalAlign)) - end - end - end - self:setVisualChanged(false) - end - end; - - } - return setmetatable(object, base) -end -local function Checkbox(name) - -- Checkbox - local base = Object(name) - local objectType = "Checkbox" - - base:setZIndex(5) - base:setValue(false) - base.width = 1 - base.height = 1 - base.bgColor = theme.CheckboxBG - base.fgColor = theme.CheckboxFG - - local object = { - symbol = "\42", - - getType = function(self) - return objectType - end; - - mouseHandler = function(self, event, button, x, y) - if (base.mouseHandler(self, event, button, x, y)) then - if ((event == "mouse_click") and (button == 1)) or (event == "monitor_touch") then - if (self:getValue() ~= true) and (self:getValue() ~= false) then - self:setValue(false) - else - self:setValue(not self:getValue()) - end - end - return true - end - return false - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - local verticalAlign = getTextVerticalAlign(self.height, "center") - - if(self.bgColor~=false)then self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) end - for n = 1, self.height do - if (n == verticalAlign) then - if (self:getValue() == true) then - self.parent:writeText(obx, oby + (n - 1), getTextHorizontalAlign(self.symbol, self.width, "center"), self.bgColor, self.fgColor) - else - self.parent:writeText(obx, oby + (n - 1), getTextHorizontalAlign(" ", self.width, "center"), self.bgColor, self.fgColor) - end - end - end - end - self:setVisualChanged(false) - end - end; - - } - - return setmetatable(object, base) -end -local function Dropdown(name) - local base = Object(name) - local objectType = "Dropdown" - base.width = 12 - base.height = 1 - base.bgColor = theme.dropdownBG - base.fgColor = theme.dropdownFG - base:setZIndex(6) - - local list = {} - local itemSelectedBG = theme.selectionBG - local itemSelectedFG = theme.selectionFG - local selectionColorActive = true - local align = "left" - local yOffset = 0 - - local dropdownW = 16 - local dropdownH = 6 - local closedSymbol = "\16" - local openedSymbol = "\31" - local isOpened = false - - local object = { - getType = function(self) - return objectType - end; - - setIndexOffset = function(self, yOff) - yOffset = yOff - return self - end; - - getIndexOffset = function(self) - return yOffset - end; - - addItem = function(self, text, bgCol, fgCol, ...) - table.insert(list, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } }) - return self - end; - - getAll = function(self) - return list - end; - - removeItem = function(self, index) - table.remove(list, index) - return self - end; - - getItem = function(self, index) - return list[index] - end; - - getItemIndex = function(self) - local selected = self:getValue() - for key, value in pairs(list) do - if (value == selected) then - return key - end - end - end; - - clear = function(self) - list = {} - self:setValue({}) - return self - end; - - getItemCount = function(self) - return #list - end; - - editItem = function(self, index, text, bgCol, fgCol, ...) - table.remove(list, index) - table.insert(list, index, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } }) - return self - end; - - selectItem = function(self, index) - self:setValue(list[index] or {}) - return self - end; - - setSelectedItem = function(self, bgCol, fgCol, active) - itemSelectedBG = bgCol or self.bgColor - itemSelectedFG = fgCol or self.fgColor - selectionColorActive = active - return self - end; - - setDropdownSize = function(self, width, height) - dropdownW, dropdownH = width, height - return self - end; - - mouseHandler = function(self, event, button, x, y) - if (isOpened) then - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - if ((event == "mouse_click") and (button == 1)) or (event == "monitor_touch") then - - if (#list > 0) then - for n = 1, dropdownH do - if (list[n + yOffset] ~= nil) then - if (obx <= x) and (obx + dropdownW > x) and (oby + n == y) then - self:setValue(list[n + yOffset]) - return true - end - end - end - end - end - - if (event == "mouse_scroll") then - yOffset = yOffset + button - if (yOffset < 0) then - yOffset = 0 - end - if (button == 1) then - if (#list > dropdownH) then - if (yOffset > #list - dropdownH) then - yOffset = #list - dropdownH - end - else - yOffset = list - 1 - end - end - return true - end - self:setVisualChanged() - end - if (base.mouseHandler(self, event, button, x, y)) then - isOpened = true - else - isOpened = false - end - end; - - draw = function(self) - if (base.draw(self)) then - local obx, oby = self:getAnchorPosition() - if (self.parent ~= nil) then - if(self.bgColor~=false)then self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) end - local val = self:getValue() - local text = getTextHorizontalAlign((val~=nil and val.text or ""), self.width, align):sub(1, self.width - 1) .. (isOpened and openedSymbol or closedSymbol) - self.parent:writeText(obx, oby, text, self.bgColor, self.fgColor) - - if (isOpened) then - for n = 1, dropdownH do - if (list[n + yOffset] ~= nil) then - if (list[n + yOffset] == val) then - if (selectionColorActive) then - self.parent:writeText(obx, oby + n, getTextHorizontalAlign(list[n + yOffset].text, dropdownW, align), itemSelectedBG, itemSelectedFG) - else - self.parent:writeText(obx, oby + n, getTextHorizontalAlign(list[n + yOffset].text, dropdownW, align), list[n + yOffset].bgCol, list[n + yOffset].fgCol) - end - else - self.parent:writeText(obx, oby + n, getTextHorizontalAlign(list[n + yOffset].text, dropdownW, align), list[n + yOffset].bgCol, list[n + yOffset].fgCol) - end - end - end - end - end - self:setVisualChanged(false) - end - end; - } - - return setmetatable(object, base) -end -local function Image(name) - -- Pane - local base = Object(name) - local objectType = "Image" - base:setZIndex(2) - local image - local shrinkedImage - local imageGotShrinked = false - - local function shrink() - - -- shrinkSystem is copy pasted (and slightly changed) from blittle by Bomb Bloke: http://www.computercraft.info/forums2/index.php?/topic/25354-cc-176-blittle-api/ - local relations = { [0] = { 8, 4, 3, 6, 5 }, { 4, 14, 8, 7 }, { 6, 10, 8, 7 }, { 9, 11, 8, 0 }, { 1, 14, 8, 0 }, { 13, 12, 8, 0 }, { 2, 10, 8, 0 }, { 15, 8, 10, 11, 12, 14 }, - { 0, 7, 1, 9, 2, 13 }, { 3, 11, 8, 7 }, { 2, 6, 7, 15 }, { 9, 3, 7, 15 }, { 13, 5, 7, 15 }, { 5, 12, 8, 7 }, { 1, 4, 7, 15 }, { 7, 10, 11, 12, 14 } } - - local colourNum, exponents, colourChar = {}, {}, {} - for i = 0, 15 do - exponents[2 ^ i] = i - end - do - local hex = "0123456789abcdef" - for i = 1, 16 do - colourNum[hex:sub(i, i)] = i - 1 - colourNum[i - 1] = hex:sub(i, i) - colourChar[hex:sub(i, i)] = 2 ^ (i - 1) - colourChar[2 ^ (i - 1)] = hex:sub(i, i) - - local thisRel = relations[i - 1] - for i = 1, #thisRel do - thisRel[i] = 2 ^ thisRel[i] - end - end - end - - local function getBestColourMatch(usage) - local lastCol = relations[exponents[usage[#usage][1]]] - - for j = 1, #lastCol do - local thisRelation = lastCol[j] - for i = 1, #usage - 1 do - if usage[i][1] == thisRelation then - return i - end - end - end - - return 1 - end - - local function colsToChar(pattern, totals) - if not totals then - local newPattern = {} - totals = {} - for i = 1, 6 do - local thisVal = pattern[i] - local thisTot = totals[thisVal] - totals[thisVal], newPattern[i] = thisTot and (thisTot + 1) or 1, thisVal - end - pattern = newPattern - end - - local usage = {} - for key, value in pairs(totals) do - usage[#usage + 1] = { key, value } - end - - if #usage > 1 then - -- Reduce the chunk to two colours: - while #usage > 2 do - table.sort(usage, function(a, b) - return a[2] > b[2] - end) - local matchToInd, usageLen = getBestColourMatch(usage), #usage - local matchFrom, matchTo = usage[usageLen][1], usage[matchToInd][1] - for i = 1, 6 do - if pattern[i] == matchFrom then - pattern[i] = matchTo - usage[matchToInd][2] = usage[matchToInd][2] + 1 - end - end - usage[usageLen] = nil - end - - -- Convert to character. Adapted from oli414's function: - -- http://www.computercraft.info/forums2/index.php?/topic/25340-cc-176-easy-drawing-characters/ - local data = 128 - for i = 1, #pattern - 1 do - if pattern[i] ~= pattern[6] then - data = data + 2 ^ (i - 1) - end - end - return string.char(data), colourChar[usage[1][1] == pattern[6] and usage[2][1] or usage[1][1]], colourChar[pattern[6]] - else - -- Solid colour character: - return "\128", colourChar[pattern[1]], colourChar[pattern[1]] - end - end - - local results, width, height, bgCol = { {}, {}, {} }, 0, #image + #image % 3, base.bgColor or colors.black - for i = 1, #image do - if #image[i] > width then - width = #image[i] - end - end - - for y = 0, height - 1, 3 do - local cRow, tRow, bRow, counter = {}, {}, {}, 1 - - for x = 0, width - 1, 2 do - -- Grab a 2x3 chunk: - local pattern, totals = {}, {} - - for yy = 1, 3 do - for xx = 1, 2 do - pattern[#pattern + 1] = (image[y + yy] and image[y + yy][x + xx]) and (image[y + yy][x + xx] == 0 and bgCol or image[y + yy][x + xx]) or bgCol - totals[pattern[#pattern]] = totals[pattern[#pattern]] and (totals[pattern[#pattern]] + 1) or 1 - end - end - - cRow[counter], tRow[counter], bRow[counter] = colsToChar(pattern, totals) - counter = counter + 1 - end - - results[1][#results[1] + 1], results[2][#results[2] + 1], results[3][#results[3] + 1] = table.concat(cRow), table.concat(tRow), table.concat(bRow) - end - - results.width, results.height = #results[1][1], #results[1] - - shrinkedImage = results - end - - local object = { - getType = function(self) - return objectType - end; - - loadImage = function(self, path) - image = paintutils.loadImage(path) - imageGotShrinked = false - return self - end; - - loadBlittleImage = function(self, path) -- not done yet - --image = paintutils.loadImage(path) - --imageGotShrinked = true - return self - end; - - shrink = function(self) - shrink() - imageGotShrinked = true - return self - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - if (image ~= nil) then - local obx, oby = self:getAnchorPosition() - if (imageGotShrinked) then - -- this is copy pasted (and slightly changed) from blittle by Bomb Bloke: http://www.computercraft.info/forums2/index.php?/topic/25354-cc-176-blittle-api/ - local t, tC, bC = shrinkedImage[1], shrinkedImage[2], shrinkedImage[3] - for i = 1, shrinkedImage.height do - local tI = t[i] - if type(tI) == "string" then - self.parent:setText(obx, oby + i - 1, tI) - self.parent:setFG(obx, oby + i - 1, tC[i]) - self.parent:setBG(obx, oby + i - 1, bC[i]) - elseif type(tI) == "table" then - self.parent:setText(obx, oby + i - 1, tI[2]) - self.parent:setFG(obx, oby + i - 1, tC[i]) - self.parent:setBG(obx, oby + i - 1, bC[i]) - end - end - else - for yPos = 1, math.min(#image, self.height) do - local line = image[yPos] - for xPos = 1, math.min(#line, self.width) do - if line[xPos] > 0 then - self.parent:drawBackgroundBox(obx + xPos - 1, oby + yPos - 1, 1, 1, line[xPos]) - end - end - end - end - end - end - self:setVisualChanged(false) - end - end; - } - - return setmetatable(object, base) -end -local function Input(name) - -- Input - local base = Object(name) - local objectType = "Input" - - local inputType = "text" - local inputLimit = 0 - base:setZIndex(5) - base:setValue("") - base.width = 10 - base.height = 1 - base.bgColor = theme.InputBG - base.fgColor = theme.InputFG - - local textX = 1 - local wIndex = 1 - - local defaultText = "" - local defaultBGCol - local defaultFGCol - local showingText = defaultText - local internalValueChange = false - - local object = { - - getType = function(self) - return objectType - end; - - setInputType = function(self, iType) - if (iType == "password") or (iType == "number") or (iType == "text") then - inputType = iType - end - return self - end; - - setDefaultText = function(self, text, fCol, bCol) - defaultText = text - defaultBGCol = bCol or defaultBGCol - defaultFGCol = fCol or defaultFGCol - if (self:isFocused()) then - showingText = "" - else - showingText = defaultText - end - return self - end; - - getInputType = function(self) - return inputType - end; - - setValue = function(self, val) - base.setValue(self, tostring(val)) - if not (internalValueChange) then - textX = tostring(val):len() + 1 - end - return self - end; - - getValue = function(self) - local val = base.getValue(self) - return inputType == "number" and tonumber(val) or val - end; - - setInputLimit = function(self, limit) - inputLimit = tonumber(limit) or inputLimit - return self - end; - - getInputLimit = function(self) - return inputLimit - end; - - getFocusHandler = function(self) - base.getFocusHandler(self) - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - showingText = "" - if (self.parent ~= nil) then - self.parent:setCursor(true, obx + textX - wIndex, oby+math.floor(self.height/2), self.fgColor) - end - end - end; - - loseFocusHandler = function(self) - base.loseFocusHandler(self) - if (self.parent ~= nil) then - self.parent:setCursor(false) - showingText = defaultText - end - end; - - keyHandler = function(self, event, key) - if (base.keyHandler(self, event, key)) then - internalValueChange = true - if (event == "key") then - if (key == keys.backspace) then - -- on backspace - local text = tostring(base.getValue()) - if (textX > 1) then - self:setValue(text:sub(1, textX - 2) .. text:sub(textX, text:len())) - if (textX > 1) then - textX = textX - 1 - end - if (wIndex > 1) then - if (textX < wIndex) then - wIndex = wIndex - 1 - end - end - end - end - if (key == keys.enter) then - -- on enter - if (self.parent ~= nil) then - --self.parent:removeFocusedObject(self) - end - end - if (key == keys.right) then - -- right arrow - local tLength = tostring(base.getValue()):len() - textX = textX + 1 - - if (textX > tLength) then - textX = tLength + 1 - end - if (textX < 1) then - textX = 1 - end - if (textX < wIndex) or (textX >= self.width + wIndex) then - wIndex = textX - self.width + 1 - end - if (wIndex < 1) then - wIndex = 1 - end - end - - if (key == keys.left) then - -- left arrow - textX = textX - 1 - if (textX >= 1) then - if (textX < wIndex) or (textX >= self.width + wIndex) then - wIndex = textX - end - end - if (textX < 1) then - textX = 1 - end - if (wIndex < 1) then - wIndex = 1 - end - end - end - - if (event == "char") then - local text = base.getValue() - if (text:len() < inputLimit or inputLimit <= 0) then - if (inputType == "number") then - local cache = text - if (key == ".") or (tonumber(key) ~= nil) then - self:setValue(text:sub(1, textX - 1) .. key .. text:sub(textX, text:len())) - textX = textX + 1 - end - if (tonumber(base.getValue()) == nil) then - self:setValue(cache) - end - else - self:setValue(text:sub(1, textX - 1) .. key .. text:sub(textX, text:len())) - textX = textX + 1 - end - if (textX >= self.width + wIndex) then - wIndex = wIndex + 1 - end - end - end - local obx, oby = self:getAnchorPosition() - local val = tostring(base.getValue()) - local cursorX = (textX <= val:len() and textX - 1 or val:len()) - (wIndex - 1) - - if (cursorX > self.x + self.width - 1) then - cursorX = self.x + self.width - 1 - end - if (self.parent ~= nil) then - self.parent:setCursor(true, obx + cursorX, oby+math.floor(self.height/2), self.fgColor) - end - internalValueChange = false - end - end; - - mouseHandler = function(self, event, button, x, y) - if (base.mouseHandler(self, event, button, x, y)) then - if (event == "mouse_click") and (button == 1) then - - end - return true - end - return false - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - local verticalAlign = getTextVerticalAlign(self.height, "center") - - if(self.bgColor~=false)then self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) end - for n = 1, self.height do - if (n == verticalAlign) then - local val = tostring(base.getValue()) - local bCol = self.bgColor - local fCol = self.fgColor - local text - if (val:len() <= 0) then - text = showingText - bCol = defaultBGCol or bCol - fCol = defaultFGCol or fCol - end - - text = showingText - if (val ~= "") then - text = val - end - text = text:sub(wIndex, self.width + wIndex - 1) - local space = self.width - text:len() - if (space < 0) then - space = 0 - end - if (inputType == "password") and (val ~= "") then - text = string.rep("*", text:len()) - end - text = text .. string.rep(" ", space) - self.parent:writeText(obx, oby + (n - 1), text, bCol, fCol) - end - end - end - self:setVisualChanged(false) - end - end; - } - - return setmetatable(object, base) -end -local function Label(name) - -- Label - local base = Object(name) - local objectType = "Label" - - base:setZIndex(3) - base.fgColor = colors.white - base.bgcolor = colors.black - - local autoSize = true - base:setValue("") - - local textHorizontalAlign = "left" - local textVerticalAlign = "top" - local fontsize = 0 - - local object = { - getType = function(self) - return objectType - end; - setText = function(self, text) - text = tostring(text) - base:setValue(text) - if (autoSize) then - self.width = text:len() - end - return self - end; - - setTextAlign = function(self, hor, vert) - textHorizontalAlign = hor or textHorizontalAlign - textVerticalAlign = vert or textVerticalAlign - self:setVisualChanged() - return self - end; - - setFontSize = function(self, size) - if(size>0)and(size<=4)then - fontsize = size-1 or 0 - end - return self - end; - - getFontSize = function(self) - return fontsize+1 - end; - - setSize = function(self, width, height) - base.setSize(self, width, height) - autoSize = false - self:setVisualChanged() - return self - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - local verticalAlign = getTextVerticalAlign(self.height, textVerticalAlign) - if(self.bgColor~=false)then - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - self.parent:drawTextBox(obx, oby, self.width, self.height, " ") end - if(self.fgColor~=false)then self.parent:drawForegroundBox(obx, oby, self.width, self.height, self.fgColor) end - if(fontsize==0)then - for n = 1, self.height do - if (n == verticalAlign) then - self.parent:setText(obx, oby + (n - 1), getTextHorizontalAlign(self:getValue(), self.width, textHorizontalAlign)) - end - end - else - local tData = makeText(fontsize, self:getValue(), self.fgColor, self.bgColor or colors.black) - if(autoSize)then - self.height = #tData[1]-1 - self.width = #tData[1][1] - end - for n = 1, self.height do - if (n == verticalAlign) then - local oX, oY = self.parent:getSize() - local cX, cY = #tData[1][1], #tData[1] - obx = obx or math.floor((oX - cX) / 2) + 1 - oby = oby or math.floor((oY - cY) / 2) + 1 - - for i = 1, cY do - self.parent:setFG(obx, oby + i + n - 2, getTextHorizontalAlign(tData[2][i], self.width, textHorizontalAlign)) - self.parent:setBG(obx, oby + i + n - 2, getTextHorizontalAlign(tData[3][i], self.width, textHorizontalAlign, tHex[self.bgColor or colors.black])) - self.parent:setText(obx, oby + i + n - 2, getTextHorizontalAlign(tData[1][i], self.width, textHorizontalAlign)) - end - end - end - end - end - self:setVisualChanged(false) - end - end; - - } - - return setmetatable(object, base) -end -local function List(name) - local base = Object(name) - local objectType = "List" - base.width = 16 - base.height = 6 - base.bgColor = theme.listBG - base.fgColor = theme.listFG - base:setZIndex(5) - - local list = {} - local itemSelectedBG = theme.selectionBG - local itemSelectedFG = theme.selectionFG - local selectionColorActive = true - local align = "left" - local yOffset = 0 - local scrollable = true - - local object = { - getType = function(self) - return objectType - end; - - addItem = function(self, text, bgCol, fgCol, ...) - table.insert(list, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } }) - if (#list == 1) then - self:setValue(list[1]) - end - return self - end; - - setIndexOffset = function(self, yOff) - yOffset = yOff - return self - end; - - getIndexOffset = function(self) - return yOffset - end; - - removeItem = function(self, index) - table.remove(list, index) - return self - end; - - getItem = function(self, index) - return list[index] - end; - - getAll = function(self) - return list - end; - - getItemIndex = function(self) - local selected = self:getValue() - for key, value in pairs(list) do - if (value == selected) then - return key - end - end - end; - - clear = function(self) - list = {} - self:setValue({}) - return self - end; - - getItemCount = function(self) - return #list - end; - - editItem = function(self, index, text, bgCol, fgCol, ...) - table.remove(list, index) - table.insert(list, index, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } }) - return self - end; - - selectItem = function(self, index) - self:setValue(list[index] or {}) - return self - end; - - setSelectedItem = function(self, bgCol, fgCol, active) - itemSelectedBG = bgCol or self.bgColor - itemSelectedFG = fgCol or self.fgColor - selectionColorActive = active - return self - end; - - setScrollable = function(self, scroll) - scrollable = scroll - return self - end; - - mouseHandler = function(self, event, button, x, y) - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - if (obx <= x) and (obx + self.width > x) and (oby <= y) and (oby + self.height > y) and (self:isVisible()) then - if (((event == "mouse_click") or (event == "mouse_drag"))and(button==1))or(event=="monitor_touch") then - if (#list > 0) then - for n = 1, self.height do - if (list[n + yOffset] ~= nil) then - if (obx <= x) and (obx + self.width > x) and (oby + n - 1 == y) then - self:setValue(list[n + yOffset]) - self:getEventSystem():sendEvent("mouse_click", self, "mouse_click", 0, x, y, list[n + yOffset]) - end - end - end - end - end - - if (event == "mouse_scroll") and (scrollable) then - yOffset = yOffset + button - if (yOffset < 0) then - yOffset = 0 - end - if (button >= 1) then - if (#list > self.height) then - if (yOffset > #list - self.height) then - yOffset = #list - self.height - end - if (yOffset >= #list) then - yOffset = #list - 1 - end - else - yOffset = yOffset - 1 - end - end - end - self:setVisualChanged() - return true - end - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - if(self.bgColor~=false)then - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - end - for n = 1, self.height do - if (list[n + yOffset] ~= nil) then - if (list[n + yOffset] == self:getValue()) then - if (selectionColorActive) then - self.parent:writeText(obx, oby + n - 1, getTextHorizontalAlign(list[n + yOffset].text, self.width, align), itemSelectedBG, itemSelectedFG) - else - self.parent:writeText(obx, oby + n - 1, getTextHorizontalAlign(list[n + yOffset].text, self.width, align), list[n + yOffset].bgCol, list[n + yOffset].fgCol) - end - else - self.parent:writeText(obx, oby + n - 1, getTextHorizontalAlign(list[n + yOffset].text, self.width, align), list[n + yOffset].bgCol, list[n + yOffset].fgCol) - end - end - end - end - self:setVisualChanged(false) - end - end; - } - - return setmetatable(object, base) -end -local function Menubar(name) - local base = Object(name) - local objectType = "Menubar" - local object = {} - - base.width = 30 - base.height = 1 - base.bgColor = colors.gray - base.fgColor = colors.lightGray - base:setZIndex(5) - - local list = {} - local itemSelectedBG = theme.selectionBG - local itemSelectedFG = theme.selectionFG - local selectionColorActive = true - local align = "left" - local itemOffset = 0 - local space = 1 - local scrollable = false - - local function maxScroll() - local mScroll = 0 - local xPos = 0 - for n = 1, #list do - if (xPos + list[n].text:len() + space * 2 > object.width) then - if(xPos < object.width)then - mScroll = mScroll + (list[n].text:len() + space * 2-(object.width - xPos)) - else - mScroll = mScroll + list[n].text:len() + space * 2 - end - end - xPos = xPos + list[n].text:len() + space * 2 - - end - return mScroll - end - - object = { - getType = function(self) - return objectType - end; - - addItem = function(self, text, bgCol, fgCol, ...) - table.insert(list, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } }) - if (#list == 1) then - self:setValue(list[1]) - end - return self - end; - - getAll = function(self) - return list - end; - - getItemIndex = function(self) - local selected = self:getValue() - for key, value in pairs(list) do - if (value == selected) then - return key - end - end - end; - - clear = function(self) - list = {} - self:setValue({}) - return self - end; - - setSpace = function(self, _space) - space = _space or space - return self - end; - - setPositionOffset = function(self, offset) - itemOffset = offset or 0 - if (itemOffset < 0) then - itemOffset = 0 - end - - local mScroll = maxScroll() - if (itemOffset > mScroll) then - itemOffset = mScroll - end - return self - end; - - getPositionOffset = function(self) - return itemOffset - end; - - setScrollable = function(self, scroll) - scrollable = scroll - if(scroll==nil)then scrollable = true end - return self - end; - - removeItem = function(self, index) - table.remove(list, index) - return self - end; - - getItem = function(self, index) - return list[index] - end; - - getItemCount = function(self) - return #list - end; - - editItem = function(self, index, text, bgCol, fgCol, ...) - table.remove(list, index) - table.insert(list, index, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } }) - return self - end; - - selectItem = function(self, index) - self:setValue(list[index] or {}) - return self - end; - - setSelectedItem = function(self, bgCol, fgCol, active) - itemSelectedBG = bgCol or self.bgColor - itemSelectedFG = fgCol or self.fgColor - selectionColorActive = active - return self - end; - - mouseHandler = function(self, event, button, x, y) - if(base.mouseHandler(self, event, button, x, y))then - local objX, objY = self:getAbsolutePosition(self:getAnchorPosition()) - if (objX <= x) and (objX + self.width > x) and (objY <= y) and (objY + self.height > y) and (self:isVisible()) then - if (self.parent ~= nil) then - self.parent:setFocusedObject(self) - end - if (event == "mouse_click") or (event == "monitor_touch") then - local xPos = 0 - for n = 1, #list do - if (list[n] ~= nil) then - --if (xPos-1 + list[n].text:len() + space * 2 <= self.width) then - if (objX + xPos <= x + itemOffset) and (objX + xPos + list[n].text:len() + (space*2) > x + itemOffset) and (objY == y) then - self:setValue(list[n]) - self:getEventSystem():sendEvent(event, self, event, 0, x, y, list[n]) - end - xPos = xPos + list[n].text:len() + space * 2 - end - end - - end - if (event == "mouse_scroll") and (scrollable) then - itemOffset = itemOffset + button - if (itemOffset < 0) then - itemOffset = 0 - end - - local mScroll = maxScroll() - - if (itemOffset > mScroll) then - itemOffset = mScroll - end - end - self:setVisualChanged(true) - return true - end - end - return false - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - if(self.bgColor~=false)then - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - end - local text = "" - local textBGCol = "" - local textFGCol = "" - for _, v in pairs(list) do - local newItem = (" "):rep(space) .. v.text .. (" "):rep(space) - text = text .. newItem - if(v == self:getValue())then - textBGCol = textBGCol .. tHex[itemSelectedBG or v.bgCol or self.bgColor]:rep(newItem:len()) - textFGCol = textFGCol .. tHex[itemSelectedFG or v.FgCol or self.fgColor]:rep(newItem:len()) - else - textBGCol = textBGCol .. tHex[v.bgCol or self.bgColor]:rep(newItem:len()) - textFGCol = textFGCol .. tHex[v.FgCol or self.fgColor]:rep(newItem:len()) - end - end - - self.parent:setText(obx, oby, text:sub(itemOffset+1, self.width+itemOffset)) - self.parent:setBG(obx, oby, textBGCol:sub(itemOffset+1, self.width+itemOffset)) - self.parent:setFG(obx, oby, textFGCol:sub(itemOffset+1, self.width+itemOffset)) - end - self:setVisualChanged(false) - end - end; - } - - return setmetatable(object, base) -end -local function Pane(name) - -- Pane - local base = Object(name) - local objectType = "Pane" - - local object = { - getType = function(self) - return objectType - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - self.parent:drawForegroundBox(obx, oby, self.width, self.height, self.bgColor) - end - self:setVisualChanged(false) - end - end; - - } - - return setmetatable(object, base) -end -local function Program(name) - local base = Object(name) - local objectType = "Program" - base:setZIndex(5) - local object - - local function createBasaltWindow(x, y, width, height) - local xCursor, yCursor = 1, 1 - local bgColor, fgColor = colors.black, colors.white - local cursorBlink = false - local visible = false - - local cacheT = {} - local cacheBG = {} - local cacheFG = {} - - local tPalette = {} - - local emptySpaceLine - local emptyColorLines = {} - - for i = 0, 15 do - local c = 2 ^ i - tPalette[c] = { parentTerminal.getPaletteColour(c) } - end - - local function createEmptyLines() - emptySpaceLine = (" "):rep(width) - for n = 0, 15 do - local nColor = 2 ^ n - local sHex = tHex[nColor] - emptyColorLines[nColor] = sHex:rep(width) - end - end - - local function recreateWindowArray() - createEmptyLines() - local emptyText = emptySpaceLine - local emptyFG = emptyColorLines[colors.white] - local emptyBG = emptyColorLines[colors.black] - for n = 1, height do - cacheT[n] = sub(cacheT[n] == nil and emptyText or cacheT[n] .. emptyText:sub(1, width - cacheT[n]:len()), 1, width) - cacheFG[n] = sub(cacheFG[n] == nil and emptyFG or cacheFG[n] .. emptyFG:sub(1, width - cacheFG[n]:len()), 1, width) - cacheBG[n] = sub(cacheBG[n] == nil and emptyBG or cacheBG[n] .. emptyBG:sub(1, width - cacheBG[n]:len()), 1, width) - end - end - recreateWindowArray() - - local function updateCursor() - if xCursor >= 1 and yCursor >= 1 and xCursor <= width and yCursor <= height then - --parentTerminal.setCursorPos(xCursor + x - 1, yCursor + y - 1) - else - --parentTerminal.setCursorPos(0, 0) - end - --parentTerminal.setTextColor(fgColor) - end - - local function internalBlit(sText, sTextColor, sBackgroundColor) - -- copy pasti strikes again (cc: window.lua) - local nStart = xCursor - local nEnd = nStart + #sText - 1 - if yCursor >= 1 and yCursor <= height then - if nStart <= width and nEnd >= 1 then - -- Modify line - if nStart == 1 and nEnd == width then - cacheT[yCursor] = sText - cacheFG[yCursor] = sTextColor - cacheBG[yCursor] = sBackgroundColor - else - local sClippedText, sClippedTextColor, sClippedBackgroundColor - if nStart < 1 then - local nClipStart = 1 - nStart + 1 - local nClipEnd = width - nStart + 1 - sClippedText = sub(sText, nClipStart, nClipEnd) - sClippedTextColor = sub(sTextColor, nClipStart, nClipEnd) - sClippedBackgroundColor = sub(sBackgroundColor, nClipStart, nClipEnd) - elseif nEnd > width then - local nClipEnd = width - nStart + 1 - sClippedText = sub(sText, 1, nClipEnd) - sClippedTextColor = sub(sTextColor, 1, nClipEnd) - sClippedBackgroundColor = sub(sBackgroundColor, 1, nClipEnd) - else - sClippedText = sText - sClippedTextColor = sTextColor - sClippedBackgroundColor = sBackgroundColor - end - - local sOldText = cacheT[yCursor] - local sOldTextColor = cacheFG[yCursor] - local sOldBackgroundColor = cacheBG[yCursor] - local sNewText, sNewTextColor, sNewBackgroundColor - if nStart > 1 then - local nOldEnd = nStart - 1 - sNewText = sub(sOldText, 1, nOldEnd) .. sClippedText - sNewTextColor = sub(sOldTextColor, 1, nOldEnd) .. sClippedTextColor - sNewBackgroundColor = sub(sOldBackgroundColor, 1, nOldEnd) .. sClippedBackgroundColor - else - sNewText = sClippedText - sNewTextColor = sClippedTextColor - sNewBackgroundColor = sClippedBackgroundColor - end - if nEnd < width then - local nOldStart = nEnd + 1 - sNewText = sNewText .. sub(sOldText, nOldStart, width) - sNewTextColor = sNewTextColor .. sub(sOldTextColor, nOldStart, width) - sNewBackgroundColor = sNewBackgroundColor .. sub(sOldBackgroundColor, nOldStart, width) - end - - cacheT[yCursor] = sNewText - cacheFG[yCursor] = sNewTextColor - cacheBG[yCursor] = sNewBackgroundColor - end - end - xCursor = nEnd + 1 - if (visible) then - updateCursor() - end - end - end - - local function setText(_x, _y, text) - if (text ~= nil) then - local gText = cacheT[_y] - if (gText ~= nil) then - cacheT[_y] = sub(gText:sub(1, _x - 1) .. text .. gText:sub(_x + (text:len()), width), 1, width) - end - end - end - - local function setBG(_x, _y, colorStr) - if (colorStr ~= nil) then - local gBG = cacheBG[_y] - if (gBG ~= nil) then - cacheBG[_y] = sub(gBG:sub(1, _x - 1) .. colorStr .. gBG:sub(_x + (colorStr:len()), width), 1, width) - end - end - end - - local function setFG(_x, _y, colorStr) - if (colorStr ~= nil) then - local gFG = cacheFG[_y] - if (gFG ~= nil) then - cacheFG[_y] = sub(gFG:sub(1, _x - 1) .. colorStr .. gFG:sub(_x + (colorStr:len()), width), 1, width) - end - end - end - - local setTextColor = function(color) - if type(color) ~= "number" then - error("bad argument #1 (expected number, got " .. type(color) .. ")", 2) - elseif tHex[color] == nil then - error("Invalid color (got " .. color .. ")", 2) - end - fgColor = color - end - - local setBackgroundColor = function(color) - if type(color) ~= "number" then - error("bad argument #1 (expected number, got " .. type(color) .. ")", 2) - elseif tHex[color] == nil then - error("Invalid color (got " .. color .. ")", 2) - end - bgColor = color - end - - local setPaletteColor = function(colour, r, g, b) - -- have to work on - if type(colour) ~= "number" then - error("bad argument #1 (expected number, got " .. type(colour) .. ")", 2) - end - - if tHex[colour] == nil then - error("Invalid color (got " .. colour .. ")", 2) - end - - local tCol - if type(r) == "number" and g == nil and b == nil then - tCol = { colours.rgb8(r) } - tPalette[colour] = tCol - else - if type(r) ~= "number" then - error("bad argument #2 (expected number, got " .. type(r) .. ")", 2) - end - if type(g) ~= "number" then - error("bad argument #3 (expected number, got " .. type(g) .. ")", 2) - end - if type(b) ~= "number" then - error("bad argument #4 (expected number, got " .. type(b) .. ")", 2) - end - - tCol = tPalette[colour] - tCol[1] = r - tCol[2] = g - tCol[3] = b - end - end - - local getPaletteColor = function(colour) - if type(colour) ~= "number" then - error("bad argument #1 (expected number, got " .. type(colour) .. ")", 2) - end - if tHex[colour] == nil then - error("Invalid color (got " .. colour .. ")", 2) - end - local tCol = tPalette[colour] - return tCol[1], tCol[2], tCol[3] - end - - local basaltwindow = { - setCursorPos = function(_x, _y) - if type(_x) ~= "number" then - error("bad argument #1 (expected number, got " .. type(_x) .. ")", 2) - end - if type(_y) ~= "number" then - error("bad argument #2 (expected number, got " .. type(_y) .. ")", 2) - end - xCursor = math.floor(_x) - yCursor = math.floor(_y) - if (visible) then - updateCursor() - end - end; - - getCursorPos = function() - return xCursor, yCursor - end; - - setCursorBlink = function(blink) - if type(blink) ~= "boolean" then - error("bad argument #1 (expected boolean, got " .. type(blink) .. ")", 2) - end - cursorBlink = blink - end; - - getCursorBlink = function() - return cursorBlink - end; - - - getPaletteColor = getPaletteColor, - getPaletteColour = getPaletteColor, - - setBackgroundColor = setBackgroundColor, - setBackgroundColour = setBackgroundColor, - - setTextColor = setTextColor, - setTextColour = setTextColor, - - setPaletteColor = setPaletteColor, - setPaletteColour = setPaletteColor, - - getBackgroundColor = function() - return bgColor - end; - getBackgroundColour = function() - return bgColor - end; - - getSize = function() - return width, height - end; - - getTextColor = function() - return fgColor - end; - getTextColour = function() - return fgColor - end; - - basalt_resize = function(_width, _height) - width, height = _width, _height - recreateWindowArray() - end; - - basalt_reposition = function(_x, _y) - x, y = _x, _y - end; - - basalt_setVisible = function(vis) - visible = vis - end; - - drawBackgroundBox = function(_x, _y, _width, _height, bgCol) - for n = 1, _height do - setBG(_x, _y + (n - 1), tHex[bgCol]:rep(_width)) - end - end; - drawForegroundBox = function(_x, _y, _width, _height, fgCol) - for n = 1, _height do - setFG(_x, _y + (n - 1), tHex[fgCol]:rep(_width)) - end - end; - drawTextBox = function(_x, _y, _width, _height, symbol) - for n = 1, _height do - setText(_x, _y + (n - 1), symbol:rep(_width)) - end - end; - - writeText = function(_x, _y, text, bgCol, fgCol) - bgCol = bgCol or bgColor - fgCol = fgCol or fgColor - setText(x, _y, text) - setBG(_x, _y, tHex[bgCol]:rep(text:len())) - setFG(_x, _y, tHex[fgCol]:rep(text:len())) - end; - - basalt_update = function() - if (object.parent ~= nil) then - for n = 1, height do - object.parent:setText(x, y + (n - 1), cacheT[n]) - object.parent:setBG(x, y + (n - 1), cacheBG[n]) - object.parent:setFG(x, y + (n - 1), cacheFG[n]) - end - end - end; - - scroll = function(offset) - if type(offset) ~= "number" then - error("bad argument #1 (expected number, got " .. type(offset) .. ")", 2) - end - if offset ~= 0 then - local sEmptyText = emptySpaceLine - local sEmptyTextColor = emptyColorLines[fgColor] - local sEmptyBackgroundColor = emptyColorLines[bgColor] - for newY = 1, height do - local y = newY + offset - if y >= 1 and y <= height then - cacheT[newY] = cacheT[y] - cacheBG[newY] = cacheBG[y] - cacheFG[newY] = cacheFG[y] - else - cacheT[newY] = sEmptyText - cacheFG[newY] = sEmptyTextColor - cacheBG[newY] = sEmptyBackgroundColor - end - end - end - if (visible) then - updateCursor() - end - end; - - - isColor = function() - return parentTerminal.isColor() - end; - - isColour = function() - return parentTerminal.isColor() - end; - - write = function(text) - text = tostring(text) - if (visible) then - internalBlit(text, tHex[fgColor]:rep(text:len()), tHex[bgColor]:rep(text:len())) - end - end; - - clearLine = function() - if (visible) then - setText(1, yCursor, (" "):rep(width)) - setBG(1, yCursor, tHex[bgColor]:rep(width)) - setFG(1, yCursor, tHex[fgColor]:rep(width)) - end - if (visible) then - updateCursor() - end - end; - - clear = function() - for n = 1, height do - setText(1, n, (" "):rep(width)) - setBG(1, n, tHex[bgColor]:rep(width)) - setFG(1, n, tHex[fgColor]:rep(width)) - end - if (visible) then - updateCursor() - end - end; - - blit = function(text, fgcol, bgcol) - if type(text) ~= "string" then - error("bad argument #1 (expected string, got " .. type(text) .. ")", 2) - end - if type(fgcol) ~= "string" then - error("bad argument #2 (expected string, got " .. type(fgcol) .. ")", 2) - end - if type(bgcol) ~= "string" then - error("bad argument #3 (expected string, got " .. type(bgcol) .. ")", 2) - end - if #fgcol ~= #text or #bgcol ~= #text then - error("Arguments must be the same length", 2) - end - if (visible) then - --setText(xCursor, yCursor, text) - --setBG(xCursor, yCursor, bgcol) - --setFG(xCursor, yCursor, fgcol) - --xCursor = xCursor+text:len() - internalBlit(text, fgcol, bgcol) - end - end - - - } - - return basaltwindow - end - - base.width = 30 - base.height = 12 - local pWindow = createBasaltWindow(1, 1, base.width, base.height) - local curProcess - local paused = false - local queuedEvent = {} - - object = { - getType = function(self) - return objectType - end; - - show = function(self) - base.show(self) - pWindow.setBackgroundColor(self.bgColor) - pWindow.setTextColor(self.fgColor) - pWindow.basalt_setVisible(true) - return self - end; - - hide = function(self) - base.hide(self) - pWindow.basalt_setVisible(false) - return self - end; - - setPosition = function(self, x, y, rel) - base.setPosition(self, x, y, rel) - pWindow.basalt_reposition(self:getAnchorPosition()) - return self - end; - - getBasaltWindow = function() - return pWindow - end; - - getBasaltProcess = function() - return curProcess - end; - - setSize = function(self, width, height) - base.setSize(self, width, height) - pWindow.basalt_resize(self.width, self.height) - return self - end; - - getStatus = function(self) - if (curProcess ~= nil) then - return curProcess:getStatus() - end - return "inactive" - end; - - execute = function(self, path, ...) - curProcess = process:new(path, pWindow, ...) - pWindow.setBackgroundColor(colors.black) - pWindow.setTextColor(colors.white) - pWindow.clear() - pWindow.setCursorPos(1, 1) - curProcess:resume() - paused = false - return self - end; - - stop = function(self) - if (curProcess ~= nil) then - if not (curProcess:isDead()) then - curProcess:resume("terminate") - if (curProcess:isDead()) then - if (self.parent ~= nil) then - self.parent:setCursor(false) - end - end - end - end - return self - end; - - pause = function(self, p) - paused = p or (not paused) - if (curProcess ~= nil) then - if not (curProcess:isDead()) then - if not (paused) then - self:injectEvents(queuedEvent) - queuedEvent = {} - end - end - end - return self - end; - - isPaused = function(self) - return paused - end; - - injectEvent = function(self, event, p1, p2, p3, p4, ign) - if (curProcess ~= nil) then - if not (curProcess:isDead()) then - if (paused == false) or (ign) then - curProcess:resume(event, p1, p2, p3, p4) - else - table.insert(queuedEvent, { event = event, args = { p1, p2, p3, p4 } }) - end - end - end - return self - end; - - getQueuedEvents = function(self) - return queuedEvent - end; - - updateQueuedEvents = function(self, events) - queuedEvent = events or queuedEvent - return self - end; - - injectEvents = function(self, events) - if (curProcess ~= nil) then - if not (curProcess:isDead()) then - for _, value in pairs(events) do - curProcess:resume(value.event, table.unpack(value.args)) - end - end - end - return self - end; - - mouseHandler = function(self, event, button, x, y) - if (base.mouseHandler(self, event, button, x, y)) then - if (curProcess == nil) then - return false - end - if not (curProcess:isDead()) then - if not (paused) then - local absX, absY = self:getAbsolutePosition(self:getAnchorPosition(nil, nil, true)) - curProcess:resume(event, button, x - (absX - 1), y - (absY - 1)) - basalt.debug(event, button, x - (absX - 1), y - (absY - 1)) - end - end - return true - end - end; - - keyHandler = function(self, event, key) - base.keyHandler(self, event, key) - if (self:isFocused()) then - if (curProcess == nil) then - return false - end - if not (curProcess:isDead()) then - if not (paused) then - if (self.draw) then - curProcess:resume(event, key) - end - end - end - end - end; - - getFocusHandler = function(self) - base.getFocusHandler(self) - if (curProcess ~= nil) then - if not (curProcess:isDead()) then - if not (paused) then - if (self.parent ~= nil) then - local xCur, yCur = pWindow.getCursorPos() - local obx, oby = self:getAnchorPosition() - if (self.parent ~= nil) then - if (obx + xCur - 1 >= 1 and obx + xCur - 1 <= obx + self.width - 1 and yCur + oby - 1 >= 1 and yCur + oby - 1 <= oby + self.height - 1) then - self.parent:setCursor(pWindow.getCursorBlink(), obx + xCur - 1, yCur + oby - 1, pWindow.getTextColor()) - end - end - end - end - end - end - end; - - loseFocusHandler = function(self) - base.loseFocusHandler(self) - if (curProcess ~= nil) then - if not (curProcess:isDead()) then - if (self.parent ~= nil) then - self.parent:setCursor(false) - end - end - end - end; - - eventHandler = function(self, event, p1, p2, p3, p4) - if (curProcess == nil) then - return - end - if not (curProcess:isDead()) then - if not (paused) then - if (event ~= "mouse_click") and (event ~= "monitor_touch") and (event ~= "mouse_up") and (event ~= "mouse_scroll") and (event ~= "mouse_drag") and (event ~= "key_up") and (event ~= "key") and (event ~= "char") and (event ~= "terminate") then - curProcess:resume(event, p1, p2, p3, p4) - end - if (self:isFocused()) then - local obx, oby = self:getAnchorPosition() - local xCur, yCur = pWindow.getCursorPos() - if (self.parent ~= nil) then - if (obx + xCur - 1 >= 1 and obx + xCur - 1 <= obx + self.width - 1 and yCur + oby - 1 >= 1 and yCur + oby - 1 <= oby + self.height - 1) then - self.parent:setCursor(pWindow.getCursorBlink(), obx + xCur - 1, yCur + oby - 1, pWindow.getTextColor()) - end - end - - if (event == "terminate") and (self:isFocused()) then - self:stop() - end - end - else - if (event ~= "mouse_click") and (event ~= "monitor_touch") and (event ~= "mouse_up") and (event ~= "mouse_scroll") and (event ~= "mouse_drag") and (event ~= "key_up") and (event ~= "key") and (event ~= "char") and (event ~= "terminate") then - table.insert(queuedEvent, { event = event, args = { p1, p2, p3, p4 } }) - end - end - end - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - pWindow.basalt_reposition(obx, oby) - if(self.bgColor~=false)then - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - end - pWindow.basalt_update() - end - self:setVisualChanged(false) - end - end; - - } - - return setmetatable(object, base) -end -local function Progressbar(name) - -- Checkbox - local base = Object(name) - local objectType = "Progressbar" - - local progress = 0 - - base:setZIndex(5) - base:setValue(false) - base.width = 25 - base.height = 1 - base.bgColor = theme.CheckboxBG - base.fgColor = theme.CheckboxFG - - local activeBarColor = colors.black - local activeBarSymbol = "" - local activeBarSymbolCol = colors.white - local bgBarSymbol = "" - local direction = 0 - - local object = { - - getType = function(self) - return objectType - end; - - setDirection = function(self, dir) - direction = dir - return self - end; - - setProgressBar = function(self, color, symbol, symbolcolor) - activeBarColor = color or activeBarColor - activeBarSymbol = symbol or activeBarSymbol - activeBarSymbolCol = symbolcolor or activeBarSymbolCol - return self - end; - - setBackgroundSymbol = function(self, symbol) - bgBarSymbol = symbol:sub(1, 1) - return self - end; - - setProgress = function(self, value) - if (value >= 0) and (value <= 100) and (progress ~= value) then - progress = value - self:setValue(progress) - if (progress == 100) then - self:progressDoneHandler() - end - end - return self - end; - - getProgress = function(self) - return progress - end; - - onProgressDone = function(self, f) - self:registerEvent("progress_done", f) - return self - end; - - progressDoneHandler = function(self) - self:sendEvent("progress_done", self) - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - self.parent:drawForegroundBox(obx, oby, self.width, self.height, self.fgColor) - self.parent:drawTextBox(obx, oby, self.width, self.height, bgBarSymbol) - if (direction == 1) then - self.parent:drawBackgroundBox(obx, oby, self.width, self.height / 100 * progress, activeBarColor) - self.parent:drawForegroundBox(obx, oby, self.width, self.height / 100 * progress, activeBarSymbolCol) - self.parent:drawTextBox(obx, oby, self.width, self.height / 100 * progress, activeBarSymbol) - elseif (direction == 2) then - self.parent:drawBackgroundBox(obx, oby + math.ceil(self.height - self.height / 100 * progress), self.width, self.height / 100 * progress, activeBarColor) - self.parent:drawForegroundBox(obx, oby + math.ceil(self.height - self.height / 100 * progress), self.width, self.height / 100 * progress, activeBarSymbolCol) - self.parent:drawTextBox(obx, oby + math.ceil(self.height - self.height / 100 * progress), self.width, self.height / 100 * progress, activeBarSymbol) - elseif (direction == 3) then - self.parent:drawBackgroundBox(obx + math.ceil(self.width - self.width / 100 * progress), oby, self.width / 100 * progress, self.height, activeBarColor) - self.parent:drawForegroundBox(obx + math.ceil(self.width - self.width / 100 * progress), oby, self.width / 100 * progress, self.height, activeBarSymbolCol) - self.parent:drawTextBox(obx + math.ceil(self.width - self.width / 100 * progress), oby, self.width / 100 * progress, self.height, activeBarSymbol) - else - self.parent:drawBackgroundBox(obx, oby, self.width / 100 * progress, self.height, activeBarColor) - self.parent:drawForegroundBox(obx, oby, self.width / 100 * progress, self.height, activeBarSymbolCol) - self.parent:drawTextBox(obx, oby, self.width / 100 * progress, self.height, activeBarSymbol) - end - end - self:setVisualChanged(false) - end - end; - - } - - return setmetatable(object, base) -end -local function Radio(name) - local base = Object(name) - local objectType = "Radio" - base.width = 8 - base.bgColor = theme.listBG - base.fgColor = theme.listFG - base:setZIndex(5) - - local list = {} - local itemSelectedBG = theme.selectionBG - local itemSelectedFG = theme.selectionFG - local boxSelectedBG = base.bgColor - local boxSelectedFG = base.fgColor - local selectionColorActive = true - local symbol = "\7" - local align = "left" - - local object = { - getType = function(self) - return objectType - end; - - addItem = function(self, text, x, y, bgCol, fgCol, ...) - table.insert(list, { x = x or 1, y = y or 1, text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } }) - if (#list == 1) then - self:setValue(list[1]) - end - return self - end; - - getAll = function(self) - return list - end; - - removeItem = function(self, index) - table.remove(list, index) - return self - end; - - getItem = function(self, index) - return list[index] - end; - - getItemIndex = function(self) - local selected = self:getValue() - for key, value in pairs(list) do - if (value == selected) then - return key - end - end - end; - - clear = function(self) - list = {} - self:setValue({}) - return self - end; - - getItemCount = function(self) - return #list - end; - - editItem = function(self, index, text, x, y, bgCol, fgCol, ...) - table.remove(list, index) - table.insert(list, index, { x = x or 1, y = y or 1, text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } }) - return self - end; - - selectItem = function(self, index) - self:setValue(list[index] or {}) - return self - end; - - setSelectedItem = function(self, bgCol, fgCol, boxBG, boxFG, active) - itemSelectedBG = bgCol or itemSelectedBG - itemSelectedFG = fgCol or itemSelectedFG - boxSelectedBG = boxBG or boxSelectedBG - boxSelectedFG = boxFG or boxSelectedFG - selectionColorActive = active - return self - end; - - mouseHandler = function(self, event, button, x, y) - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - if ((event == "mouse_click")and(button==1))or(event=="monitor_touch") then - if (#list > 0) then - for _, value in pairs(list) do - if (obx + value.x - 1 <= x) and (obx + value.x - 1 + value.text:len() + 2 >= x) and (oby + value.y - 1 == y) then - self:setValue(value) - if (self.parent ~= nil) then - self.parent:setFocusedObject(self) - end - --eventSystem:sendEvent(event, self, event, button, x, y) - self:setVisualChanged() - return true - end - end - end - end - return false - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - for _, value in pairs(list) do - if (value == self:getValue()) then - if (align == "left") then - self.parent:writeText(value.x + obx - 1, value.y + oby - 1, symbol, boxSelectedBG, boxSelectedFG) - self.parent:writeText(value.x + 2 + obx - 1, value.y + oby - 1, value.text, itemSelectedBG, itemSelectedFG) - end - else - self.parent:drawBackgroundBox(value.x + obx - 1, value.y + oby - 1, 1, 1, self.bgColor) - self.parent:writeText(value.x + 2 + obx - 1, value.y + oby - 1, value.text, value.bgCol, value.fgCol) - end - end - end - self:setVisualChanged(false) - end - end; - } - - return setmetatable(object, base) -end -local function Scrollbar(name) - local base = Object(name) - local objectType = "Scrollbar" - - base.width = 1 - base.height = 8 - base.bgColor = colors.lightGray - base.fgColor = colors.gray - base:setValue(1) - base:setZIndex(2) - - local barType = "vertical" - local symbol = " " - local symbolColor = colors.black - local bgSymbol = "\127" - local maxValue = base.height - local index = 1 - local symbolSize = 1 - - local object = { - getType = function(self) - return objectType - end; - - setSymbol = function(self, _symbol) - symbol = _symbol:sub(1, 1) - self:setVisualChanged() - return self - end; - - setSymbolSize = function(self, size) - symbolSize = tonumber(size) or 1 - if (barType == "vertical") then - self:setValue(index - 1 * (maxValue / (self.height - (symbolSize - 1))) - (maxValue / (self.height - (symbolSize - 1)))) - elseif (barType == "horizontal") then - self:setValue(index - 1 * (maxValue / (self.width - (symbolSize - 1))) - (maxValue / (self.width - (symbolSize - 1)))) - end - self:setVisualChanged() - return self - end; - - setMaxValue = function(self, val) - maxValue = val - return self - end; - - setBackgroundSymbol = function(self, _bgSymbol) - bgSymbol = string.sub(_bgSymbol, 1, 1) - self:setVisualChanged() - return self - end; - - setSymbolColor = function(self, col) - symbolColor = col - self:setVisualChanged() - return self - end; - - setBarType = function(self, _typ) - barType = _typ:lower() - return self - end; - - mouseHandler = function(self, event, button, x, y) - if (base.mouseHandler(self, event, button, x, y)) then - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - if (((event == "mouse_click") or (event == "mouse_drag")) and (button == 1))or(event=="monitor_touch") then - if (barType == "horizontal") then - for _index = 0, self.width do - if (obx + _index == x) and (oby <= y) and (oby + self.height > y) then - index = math.min(_index + 1, self.width - (symbolSize - 1)) - self:setValue(maxValue / self.width * (index)) - self:setVisualChanged() - end - end - end - if (barType == "vertical") then - for _index = 0, self.height do - if (oby + _index == y) and (obx <= x) and (obx + self.width > x) then - index = math.min(_index + 1, self.height - (symbolSize - 1)) - self:setValue(maxValue / self.height * (index)) - self:setVisualChanged() - end - end - end - end - if (event == "mouse_scroll") then - index = index + button - if (index < 1) then - index = 1 - end - index = math.min(index, (barType == "vertical" and self.height or self.width) - (symbolSize - 1)) - self:setValue(maxValue / (barType == "vertical" and self.height or self.width) * index) - end - return true - end - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - if (barType == "horizontal") then - self.parent:writeText(obx, oby, bgSymbol:rep(index - 1), self.bgColor, self.fgColor) - self.parent:writeText(obx + index - 1, oby, symbol:rep(symbolSize), symbolColor, symbolColor) - self.parent:writeText(obx + index + symbolSize - 1, oby, bgSymbol:rep(self.width - (index + symbolSize - 1)), self.bgColor, self.fgColor) - end - - if (barType == "vertical") then - for n = 0, self.height - 1 do - - if (index == n + 1) then - for curIndexOffset = 0, math.min(symbolSize - 1, self.height) do - self.parent:writeText(obx, oby + n + curIndexOffset, symbol, symbolColor, symbolColor) - end - else - if (n + 1 < index) or (n + 1 > index - 1 + symbolSize) then - self.parent:writeText(obx, oby + n, bgSymbol, self.bgColor, self.fgColor) - end - end - end - end - end - self:setVisualChanged(false) - end - end; - } - - return setmetatable(object, base) -end -local function Slider(name) - local base = Object(name) - local objectType = "Slider" - - base.width = 8 - base.height = 1 - base.bgColor = colors.lightGray - base.fgColor = colors.gray - base:setValue(1) - - local barType = "horizontal" - local symbol = " " - local symbolColor = colors.black - local bgSymbol = "\140" - local maxValue = base.width - local index = 1 - local symbolSize = 1 - - local object = { - getType = function(self) - return objectType - end; - - setSymbol = function(self, _symbol) - symbol = _symbol:sub(1, 1) - self:setVisualChanged() - return self - end; - - setSymbolSize = function(self, size) - symbolSize = tonumber(size) or 1 - if (barType == "vertical") then - self:setValue(index - 1 * (maxValue / (self.height - (symbolSize - 1))) - (maxValue / (self.height - (symbolSize - 1)))) - elseif (barType == "horizontal") then - self:setValue(index - 1 * (maxValue / (self.width - (symbolSize - 1))) - (maxValue / (self.width - (symbolSize - 1)))) - end - self:setVisualChanged() - return self - end; - - setMaxValue = function(self, val) - maxValue = val - return self - end; - - setBackgroundSymbol = function(self, _bgSymbol) - bgSymbol = string.sub(_bgSymbol, 1, 1) - self:setVisualChanged() - return self - end; - - setSymbolColor = function(self, col) - symbolColor = col - self:setVisualChanged() - return self - end; - - setBarType = function(self, _typ) - barType = _typ:lower() - return self - end; - - mouseHandler = function(self, event, button, x, y) - if (base.mouseHandler(self, event, button, x, y)) then - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - if (((event == "mouse_click") or (event == "mouse_drag")) and (button == 1))or(event=="monitor_touch") then - if (barType == "horizontal") then - for _index = 0, self.width do - if (obx + _index == x) and (oby <= y) and (oby + self.height > y) then - index = math.min(_index + 1, self.width - (symbolSize - 1)) - self:setValue(maxValue / self.width * (index)) - self:setVisualChanged() - end - end - end - if (barType == "vertical") then - for _index = 0, self.height do - if (oby + _index == y) and (obx <= x) and (obx + self.width > x) then - index = math.min(_index + 1, self.height - (symbolSize - 1)) - self:setValue(maxValue / self.height * (index)) - self:setVisualChanged() - end - end - end - end - if (event == "mouse_scroll") then - index = index + button - if (index < 1) then - index = 1 - end - index = math.min(index, (barType == "vertical" and self.height or self.width) - (symbolSize - 1)) - self:setValue(maxValue / (barType == "vertical" and self.height or self.width) * index) - end - return true - end - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - if (barType == "horizontal") then - self.parent:writeText(obx, oby, bgSymbol:rep(index - 1), self.bgColor, self.fgColor) - self.parent:writeText(obx + index - 1, oby, symbol:rep(symbolSize), symbolColor, symbolColor) - self.parent:writeText(obx + index + symbolSize - 1, oby, bgSymbol:rep(self.width - (index + symbolSize - 1)), self.bgColor, self.fgColor) - end - - if (barType == "vertical") then - for n = 0, self.height - 1 do - - if (index == n + 1) then - for curIndexOffset = 0, math.min(symbolSize - 1, self.height) do - self.parent:writeText(obx, oby + n + curIndexOffset, symbol, symbolColor, symbolColor) - end - else - if (n + 1 < index) or (n + 1 > index - 1 + symbolSize) then - self.parent:writeText(obx, oby + n, bgSymbol, self.bgColor, self.fgColor) - end - end - end - end - end - self:setVisualChanged(false) - end - end; - } - - return setmetatable(object, base) -end -local function Switch(name) - local base = Object(name) - local objectType = "Switch" - - base.width = 2 - base.height = 1 - base.bgColor = colors.lightGray - base.fgColor = colors.gray - base:setValue(false) - base:setZIndex(5) - - local bgSymbol = colors.black - local inactiveBG = colors.red - local activeBG = colors.green - - local object = { - getType = function(self) - return objectType - end; - - setSymbolColor = function(self, symbolColor) - bgSymbol = symbolColor - self:setVisualChanged() - return self - end; - - setActiveBackground = function(self, bgcol) - activeBG = bgcol - self:setVisualChanged() - return self - end; - - setInactiveBackground = function(self, bgcol) - inactiveBG = bgcol - self:setVisualChanged() - return self - end; - - mouseHandler = function(self, event, button, x, y) - if (base.mouseHandler(self, event, button, x, y)) then - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - if ((event == "mouse_click") and (button == 1))or(event=="monitor_touch") then - self:setValue(not self:getValue()) - end - return true - end - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - if(self:getValue())then - self.parent:drawBackgroundBox(obx, oby, 1, self.height, activeBG) - self.parent:drawBackgroundBox(obx+1, oby, 1, self.height, bgSymbol) - else - self.parent:drawBackgroundBox(obx, oby, 1, self.height, bgSymbol) - self.parent:drawBackgroundBox(obx+1, oby, 1, self.height, inactiveBG) - end - end - self:setVisualChanged(false) - end - end; - } - - return setmetatable(object, base) -end -local function Textfield(name) - local base = Object(name) - local objectType = "Textfield" - local hIndex, wIndex, textX, textY = 1, 1, 1, 1 - - local lines = { "" } - local keyWords = { [colors.purple] = { "break" } } - - base.width = 20 - base.height = 8 - base.bgColor = theme.textfieldBG - base.fgColor = theme.textfieldFG - base:setZIndex(5) - - local object = { - getType = function(self) - return objectType - end; - - getLines = function(self) - return lines - end; - - getLine = function(self, index) - return lines[index] or "" - end; - - editLine = function(self, index, text) - lines[index] = text or lines[index] - return self - end; - - addLine = function(self, text, index) - if (index ~= nil) then - table.insert(lines, index, text) - else - table.insert(lines, text) - end - return self - end; - - addKeyword = function(self, keyword, color) - - end; - - removeLine = function(self, index) - table.remove(lines, index or #lines) - if (#lines <= 0) then - table.insert(lines, "") - end - return self - end; - - getTextCursor = function(self) - return textX, textY - end; - - getFocusHandler = function(self) - base.getFocusHandler(self) - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - if (self.parent ~= nil) then - self.parent:setCursor(true, obx + textX - wIndex, oby + textY - hIndex, self.fgColor) - end - end - end; - - loseFocusHandler = function(self) - base.loseFocusHandler(self) - if (self.parent ~= nil) then - self.parent:setCursor(false) - end - end; - - keyHandler = function(self, event, key) - if (base.keyHandler(self, event, key)) then - local obx, oby = self:getAnchorPosition() - if (event == "key") then - if (key == keys.backspace) then - -- on backspace - if (lines[textY] == "") then - if (textY > 1) then - table.remove(lines, textY) - textX = lines[textY - 1]:len() + 1 - wIndex = textX - self.width + 1 - if (wIndex < 1) then - wIndex = 1 - end - textY = textY - 1 - end - elseif (textX <= 1) then - if (textY > 1) then - textX = lines[textY - 1]:len() + 1 - wIndex = textX - self.width + 1 - if (wIndex < 1) then - wIndex = 1 - end - lines[textY - 1] = lines[textY - 1] .. lines[textY] - table.remove(lines, textY) - textY = textY - 1 - end - else - lines[textY] = lines[textY]:sub(1, textX - 2) .. lines[textY]:sub(textX, lines[textY]:len()) - if (textX > 1) then - textX = textX - 1 - end - if (wIndex > 1) then - if (textX < wIndex) then - wIndex = wIndex - 1 - end - end - end - if (textY < hIndex) then - hIndex = hIndex - 1 - end - self:setValue("") - end - - if (key == keys.delete) then - -- on delete - if (textX > lines[textY]:len()) then - if (lines[textY + 1] ~= nil) then - lines[textY] = lines[textY] .. lines[textY + 1] - table.remove(lines, textY + 1) - end - else - lines[textY] = lines[textY]:sub(1, textX - 1) .. lines[textY]:sub(textX + 1, lines[textY]:len()) - end - end - - if (key == keys.enter) then - -- on enter - table.insert(lines, textY + 1, lines[textY]:sub(textX, lines[textY]:len())) - lines[textY] = lines[textY]:sub(1, textX - 1) - textY = textY + 1 - textX = 1 - wIndex = 1 - if (textY - hIndex >= self.height) then - hIndex = hIndex + 1 - end - self:setValue("") - end - - if (key == keys.up) then - -- arrow up - if (textY > 1) then - textY = textY - 1 - if (textX > lines[textY]:len() + 1) then - textX = lines[textY]:len() + 1 - end - if (wIndex > 1) then - if (textX < wIndex) then - wIndex = textX - self.width + 1 - if (wIndex < 1) then - wIndex = 1 - end - end - end - if (hIndex > 1) then - if (textY < hIndex) then - hIndex = hIndex - 1 - end - end - end - end - if (key == keys.down) then - -- arrow down - if (textY < #lines) then - textY = textY + 1 - if (textX > lines[textY]:len() + 1) then - textX = lines[textY]:len() + 1 - end - - if (textY >= hIndex + self.height) then - hIndex = hIndex + 1 - end - end - end - if (key == keys.right) then - -- arrow right - textX = textX + 1 - if (textY < #lines) then - if (textX > lines[textY]:len() + 1) then - textX = 1 - textY = textY + 1 - end - elseif (textX > lines[textY]:len()) then - textX = lines[textY]:len() + 1 - end - if (textX < 1) then - textX = 1 - end - if (textX < wIndex) or (textX >= self.width + wIndex) then - wIndex = textX - self.width + 1 - end - if (wIndex < 1) then - wIndex = 1 - end - - end - if (key == keys.left) then - -- arrow left - textX = textX - 1 - if (textX >= 1) then - if (textX < wIndex) or (textX >= self.width + wIndex) then - wIndex = textX - end - end - if (textY > 1) then - if (textX < 1) then - textY = textY - 1 - textX = lines[textY]:len() + 1 - wIndex = textX - self.width + 1 - end - end - if (textX < 1) then - textX = 1 - end - if (wIndex < 1) then - wIndex = 1 - end - end - end - - if (event == "char") then - lines[textY] = lines[textY]:sub(1, textX - 1) .. key .. lines[textY]:sub(textX, lines[textY]:len()) - textX = textX + 1 - if (textX >= self.width + wIndex) then - wIndex = wIndex + 1 - end - self:setValue("") - end - - local cursorX = (textX <= lines[textY]:len() and textX - 1 or lines[textY]:len()) - (wIndex - 1) - if (cursorX > self.x + self.width - 1) then - cursorX = self.x + self.width - 1 - end - local cursorY = (textY - hIndex < self.height and textY - hIndex or textY - hIndex - 1) - if (cursorX < 1) then - cursorX = 0 - end - self.parent:setCursor(true, obx + cursorX, oby + cursorY, self.fgColor) - return true - end - end; - - mouseHandler = function(self, event, button, x, y) - if (base.mouseHandler(self, event, button, x, y)) then - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - local anchx, anchy = self:getAnchorPosition() - if (event == "mouse_click")or(event=="monitor_touch") then - if (lines[y - oby + hIndex] ~= nil) then - textX = x - obx + wIndex - textY = y - oby + hIndex - if (textX > lines[textY]:len()) then - textX = lines[textY]:len() + 1 - end - if (textX < wIndex) then - wIndex = textX - 1 - if (wIndex < 1) then - wIndex = 1 - end - end - if (self.parent ~= nil) then - self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self.fgColor) - end - end - end - if (event == "mouse_drag") then - if (lines[y - oby + hIndex] ~= nil) then - textX = x - obx + wIndex - textY = y - oby + hIndex - if (textX > lines[textY]:len()) then - textX = lines[textY]:len() + 1 - end - if (textX < wIndex) then - wIndex = textX - 1 - if (wIndex < 1) then - wIndex = 1 - end - end - if (self.parent ~= nil) then - self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self.fgColor) - end - end - end - - if (event == "mouse_scroll") then - hIndex = hIndex + button - if (hIndex > #lines - (self.height - 1)) then - hIndex = #lines - (self.height - 1) - end - - if (hIndex < 1) then - hIndex = 1 - end - - if (self.parent ~= nil) then - if (obx + textX - wIndex >= obx and obx + textX - wIndex <= obx + self.width) and (oby + textY - hIndex >= oby and oby + textY - hIndex <= oby + self.height) then - self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self.fgColor) - else - self.parent:setCursor(false) - end - end - end - self:setVisualChanged() - return true - end - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - if(self.bgColor~=false)then - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - end - if(self.fgColor~=false)then - self.parent:drawForegroundBox(obx, oby, self.width, self.height, self.fgColor) - end - for n = 1, self.height do - local text = "" - if (lines[n + hIndex - 1] ~= nil) then - text = lines[n + hIndex - 1] - end - text = text:sub(wIndex, self.width + wIndex - 1) - local space = self.width - text:len() - if (space < 0) then - space = 0 - end - text = text .. string.rep(" ", space) - self.parent:setText(obx, oby + n - 1, text) - end - end - self:setVisualChanged(false) - end - end; - } - - return setmetatable(object, base) -end -local function Thread(name) - local object - local objectType = "Thread" - - local func - local cRoutine - local isActive = false - - object = { - name = name, - getType = function(self) - return objectType - end; - getZIndex = function(self) - return 1 - end; - getName = function(self) - return self.name - end; - - start = function(self, f) - if (f == nil) then - error("Function provided to thread is nil") - end - func = f - cRoutine = coroutine.create(func) - isActive = true - local ok, result = coroutine.resume(cRoutine) - if not (ok) then - if (result ~= "Terminated") then - error("Thread Error Occurred - " .. result) - end - end - return self - end; - - getStatus = function(self, f) - if (cRoutine ~= nil) then - return coroutine.status(cRoutine) - end - return nil - end; - - stop = function(self, f) - isActive = false - return self - end; - - eventHandler = function(self, event, p1, p2, p3) - if (isActive) then - if (coroutine.status(cRoutine) ~= "dead") then - local ok, result = coroutine.resume(cRoutine, event, p1, p2, p3) - if not (ok) then - if (result ~= "Terminated") then - error("Thread Error Occurred - " .. result) - end - end - else - isActive = false - end - end - end; - - } - - object.__index = object - - return object -end -local function Timer(name) - local objectType = "Timer" - - local timer = 0 - local savedRepeats = 0 - local repeats = 0 - local timerObj - local eventSystem = BasaltEvents() - local timerIsActive = false - - local object = { - name = name, - getType = function(self) - return objectType - end; - - getZIndex = function(self) - return 1 - end; - - getName = function(self) - return self.name - end; - - setTime = function(self, _timer, _repeats) - timer = _timer or 0 - savedRepeats = _repeats or 1 - return self - end; - - start = function(self) - if(timerIsActive)then - os.cancelTimer(timerObj) - end - repeats = savedRepeats - timerObj = os.startTimer(timer) - timerIsActive = true - return self - end; - - isActive = function(self) - return timerIsActive - end; - - cancel = function(self) - if (timerObj ~= nil) then - os.cancelTimer(timerObj) - end - timerIsActive = false - return self - end; - - onCall = function(self, func) - eventSystem:registerEvent("timed_event", func) - return self - end; - - eventHandler = function(self, event, tObj) - if event == "timer" and tObj == timerObj and timerIsActive then - eventSystem:sendEvent("timed_event", self) - if (repeats >= 1) then - repeats = repeats - 1 - if (repeats >= 1) then - timerObj = os.startTimer(timer) - end - elseif (repeats == -1) then - timerObj = os.startTimer(timer) - end - end - end; - } - object.__index = object - - return object -end -local function Frame(name, parent) - -- Frame - local base = Object(name) - local objectType = "Frame" - local objects = {} - local objZIndex = {} - local object = {} - local termObject = parentTerminal - - local monSide = "" - local isMonitor = false - local monitorAttached = false - local dragXOffset = 0 - local dragYOffset = 0 - - base:setZIndex(10) - - local drawHelper = basaltDrawHelper(termObject) - - local cursorBlink = false - local xCursor = 1 - local yCursor = 1 - local cursorColor = colors.white - - local xOffset, yOffset = 0, 0 - - if (parent ~= nil) then - base.parent = parent - base.width, base.height = parent:getSize() - base.bgColor = theme.FrameBG - base.fgColor = theme.FrameFG - else - base.width, base.height = termObject.getSize() - base.bgColor = theme.basaltBG - base.fgColor = theme.basaltFG - end - - local function getObject(name) - for _, value in pairs(objects) do - for _, b in pairs(value) do - if (b.name == name) then - return value - end - end - end - end - - local function addObject(obj) - local zIndex = obj:getZIndex() - if (getObject(obj.name) ~= nil) then - return nil - end - if (objects[zIndex] == nil) then - for x = 1, #objZIndex + 1 do - if (objZIndex[x] ~= nil) then - if (zIndex == objZIndex[x]) then - break - end - if (zIndex > objZIndex[x]) then - table.insert(objZIndex, x, zIndex) - break - end - else - table.insert(objZIndex, zIndex) - end - end - if (#objZIndex <= 0) then - table.insert(objZIndex, zIndex) - end - objects[zIndex] = {} - end - obj.parent = object - table.insert(objects[zIndex], obj) - return obj - end - - local function removeObject(obj) - for a, b in pairs(objects) do - for key, value in pairs(b) do - if (value == obj) then - table.remove(objects[a], key) - return true; - end - end - end - return false - end - - object = { - barActive = false, - barBackground = colors.gray, - barTextcolor = colors.black, - barText = "New Frame", - barTextAlign = "left", - isMoveable = false, - - getType = function(self) - return objectType - end; - - setFocusedObject = function(self, obj) - if (focusedObject ~= nil) then - focusedObject:loseFocusHandler() - focusedObject = nil - end - if(obj~=nil)then - focusedObject = obj - obj:getFocusHandler() - end - return self - end; - - setSize = function(self, w, h) - base.setSize(self, w, h) - for _, index in pairs(objZIndex) do - if (objects[index] ~= nil) then - for _, value in pairs(objects[index]) do - if (value.eventHandler ~= nil) then - value:sendEvent("basalt_resize", value, self) - end - end - end - end - return self - end; - - setOffset = function(self, xO, yO) - xOffset = xO ~= nil and math.floor(xO < 0 and math.abs(xO) or -xO) or xOffset - yOffset = yO ~= nil and math.floor(yO < 0 and math.abs(yO) or -yO) or yOffset - return self - end; - - getFrameOffset = function(self) -- internal - return xOffset, yOffset - end; - - removeFocusedObject = function(self) - if (focusedObject ~= nil) then - focusedObject:loseFocusHandler() - end - focusedObject = nil - return self - end; - - getFocusedObject = function(self) - return focusedObject - end; - - setCursor = function(self, _blink, _xCursor, _yCursor, color) - if(self.parent~=nil)then - local obx, oby = self:getAnchorPosition() - self.parent:setCursor(_blink or false, (_xCursor or 0)+obx-1, (_yCursor or 0)+oby-1, color or cursorColor) - else - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - cursorBlink = _blink or false - if (_xCursor ~= nil) then - xCursor = obx + _xCursor - 1 - end - if (_yCursor ~= nil) then - yCursor = oby + _yCursor - 1 - end - cursorColor = color or cursorColor - self:setVisualChanged() - end - return self - end; - - setMoveable = function(self, moveable) - self.isMoveable = moveable or not self.isMoveable - self:setVisualChanged() - return self; - end; - - show = function(self) - base.show(self) - if(self.parent==nil)then - activeFrame = self; - if(isMonitor)then - monFrames[monSide] = self; - else - mainFrame = self; - end - end - return self; - end; - - hide = function (self) - base.hide(self) - if(self.parent==nil)then - if(activeFrame == self)then activeFrame = nil end - if(isMonitor)then - if(monFrames[monSide] == self)then - monFrames[monSide] = nil; - end - else - if(mainFrame == self)then - mainFrame = nil; - end - end - end - return self - end; - - - showBar = function(self, showIt) - self.barActive = showIt or not self.barActive - self:setVisualChanged() - return self - end; - - setBar = function(self, text, bgCol, fgCol) - self.barText = text or "" - self.barBackground = bgCol or self.barBackground - self.barTextcolor = fgCol or self.barTextcolor - self:setVisualChanged() - return self - end; - - setBarTextAlign = function(self, align) - self.barTextAlign = align or "left" - self:setVisualChanged() - return self - end; - - setMonitor = function(self, side) - if(side~=nil)and(side~=false)then - if(peripheral.getType(side)=="monitor")then - termObject = peripheral.wrap(side) - monitorAttached = true - end - isMonitor = true - else - termObject = parentTerminal - isMonitor = false - if(monFrames[monSide]==self)then - monFrames[monSide] = nil - end - end - drawHelper = basaltDrawHelper(termObject) - monSide = side or nil - return self; - end; - - getVisualChanged = function(self) - local changed = base.getVisualChanged(self) - for _, index in pairs(objZIndex) do - if (objects[index] ~= nil) then - for _, value in pairs(objects[index]) do - if (value.getVisualChanged ~= nil and value:getVisualChanged()) then - changed = true - end - end - end - end - return changed - end; - - loseFocusHandler = function(self) - base.loseFocusHandler(self) - end; - - getFocusHandler = function(self) - base.getFocusHandler(self) - if (self.parent ~= nil) then - self.parent:removeObject(self) - self.parent:addObject(self) - end - end; - - keyHandler = function(self, event, key) - if (focusedObject ~= nil) then - if(focusedObject~=self)then - if (focusedObject.keyHandler ~= nil) then - if (focusedObject:keyHandler(event, key)) then - return true - end - end - else - base.keyHandler(self, event, key) - end - end - return false - end; - - backgroundKeyHandler = function(self, event, key) - base.backgroundKeyHandler(self, event, key) - for _, index in pairs(objZIndex) do - if (objects[index] ~= nil) then - for _, value in pairs(objects[index]) do - if (value.backgroundKeyHandler ~= nil) then - value:backgroundKeyHandler(event, key) - end - end - end - end - end; - - eventHandler = function(self, event, p1, p2, p3, p4) - base.eventHandler(self, event, p1, p2, p3, p4) - for _, index in pairs(objZIndex) do - if (objects[index] ~= nil) then - for _, value in pairs(objects[index]) do - if (value.eventHandler ~= nil) then - value:eventHandler(event, p1, p2, p3, p4) - end - end - end - end - if(isMonitor)then - if(event == "peripheral")and(p1==monSide)then - if(peripheral.getType(monSide)=="monitor")then - monitorAttached = true - termObject = peripheral.wrap(monSide) - drawHelper = basaltDrawHelper(termObject) - end - end - if(event == "peripheral_detach")and(p1==monSide)then - monitorAttached = false - end - end - if (event == "terminate") then - termObject.clear() - termObject.setCursorPos(1, 1) - basalt.stop() - end - end; - - mouseHandler = function(self, event, button, x, y) - local xO, yO = self:getOffset() - xO = xO < 0 and math.abs(xO) or -xO - yO = yO < 0 and math.abs(yO) or -yO - if (self.drag) then - if (event == "mouse_drag") then - local parentX = 1; - local parentY = 1 - if (self.parent ~= nil) then - parentX, parentY = self.parent:getAbsolutePosition(self.parent:getAnchorPosition()) - end - self:setPosition(x + dragXOffset - (parentX - 1) + xO, y + dragYOffset - (parentY - 1) + yO) - end - if (event == "mouse_up") then - self.drag = false - end - return true - end - - local objX, objY = self:getAbsolutePosition(self:getAnchorPosition()) - local yOff = false - if(objY-1 == y)and(self:getBorder("top"))then - y = y+1 - yOff = true - end - - if (base.mouseHandler(self, event, button, x, y)) then - local fx, fy = self:getAbsolutePosition(self:getAnchorPosition()) - fx = fx + xOffset;fy = fy + yOffset; - for _, index in pairs(objZIndex) do - if (objects[index] ~= nil) then - for _, value in rpairs(objects[index]) do - if (value.mouseHandler ~= nil) then - if (value:mouseHandler(event, button, x, y)) then - return true - end - end - end - end - end - if (self.isMoveable) then - local fx, fy = self:getAbsolutePosition(self:getAnchorPosition()) - if (x >= fx) and (x <= fx + self.width - 1) and (y == fy) and (event == "mouse_click") then - self.drag = true - dragXOffset = fx - x - dragYOffset = yOff and 1 or 0 - end - end - if (focusedObject ~= nil) then - focusedObject:loseFocusHandler() - focusedObject = nil - end - return true - end - return false - end; - - setText = function(self, x, y, text) - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - if (y >= 1) and (y <= self.height) then - if (self.parent ~= nil) then - local parentX, parentY = self.parent:getAnchorPosition() - self.parent:setText(math.max(x + (obx - 1), obx) - (parentX - 1), oby + y - 1 - (parentY - 1), sub(text, math.max(1 - x + 1, 1), math.max(self.width - x + 1,1))) - else - drawHelper.setText(math.max(x + (obx - 1), obx), oby + y - 1, sub(text, math.max(1 - x + 1, 1), math.max(self.width - x + 1,1))) -- math.max(self.width - x + 1,1) now, before: self.width - x + 1 - end - end - end; - - setBG = function(self, x, y, bgCol) - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - if (y >= 1) and (y <= self.height) then - if (self.parent ~= nil) then - local parentX, parentY = self.parent:getAnchorPosition() - self.parent:setBG(math.max(x + (obx - 1), obx) - (parentX - 1), oby + y - 1 - (parentY - 1), sub(bgCol, math.max(1 - x + 1, 1), math.max(self.width - x + 1,1))) - else - drawHelper.setBG(math.max(x + (obx - 1), obx), oby + y - 1, sub(bgCol, math.max(1 - x + 1, 1), math.max(self.width - x + 1,1))) - end - end - end; - - setFG = function(self, x, y, fgCol) - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - if (y >= 1) and (y <= self.height) then - if (self.parent ~= nil) then - local parentX, parentY = self.parent:getAnchorPosition() - self.parent:setFG(math.max(x + (obx - 1), obx) - (parentX - 1), oby + y - 1 - (parentY - 1), sub(fgCol, math.max(1 - x + 1, 1), math.max(self.width - x + 1,1))) - else - drawHelper.setFG(math.max(x + (obx - 1), obx), oby + y - 1, sub(fgCol, math.max(1 - x + 1, 1), math.max(self.width - x + 1,1))) - end - end - end; - - writeText = function(self, x, y, text, bgCol, fgCol) - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - if (y >= 1) and (y <= self.height) then - if (self.parent ~= nil) then - local parentX, parentY = self.parent:getAnchorPosition() - self.parent:writeText(math.max(x + (obx - 1), obx) - (parentX - 1), oby + y - 1 - (parentY - 1), sub(text, math.max(1 - x + 1, 1), self.width - x + 1), bgCol, fgCol) - else - drawHelper.writeText(math.max(x + (obx - 1), obx), oby + y - 1, sub(text, math.max(1 - x + 1, 1), math.max(self.width - x + 1,1)), bgCol, fgCol) - end - end - end; - - drawBackgroundBox = function(self, x, y, width, height, bgCol) - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - height = (y < 1 and (height + y > self.height and self.height or height + y - 1) or (height + y > self.height and self.height - y + 1 or height)) - width = (x < 1 and (width + x > self.width and self.width or width + x - 1) or (width + x > self.width and self.width - x + 1 or width)) - if (self.parent ~= nil) then - local parentX, parentY = self.parent:getAnchorPosition() - self.parent:drawBackgroundBox(math.max(x + (obx - 1), obx) - (parentX - 1), math.max(y + (oby - 1), oby) - (parentY - 1), width, height, bgCol) - else - drawHelper.drawBackgroundBox(math.max(x + (obx - 1), obx), math.max(y + (oby - 1), oby), width, height, bgCol) - end - end; - - drawTextBox = function(self, x, y, width, height, symbol) - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - height = (y < 1 and (height + y > self.height and self.height or height + y - 1) or (height + y > self.height and self.height - y + 1 or height)) - width = (x < 1 and (width + x > self.width and self.width or width + x - 1) or (width + x > self.width and self.width - x + 1 or width)) - if (self.parent ~= nil) then - local parentX, parentY = self.parent:getAnchorPosition() - self.parent:drawTextBox(math.max(x + (obx - 1), obx) - (parentX - 1), math.max(y + (oby - 1), oby) - (parentY - 1), width, height, symbol:sub(1, 1)) - else - drawHelper.drawTextBox(math.max(x + (obx - 1), obx), math.max(y + (oby - 1), oby), width, height, symbol:sub(1, 1)) - end - end; - - drawForegroundBox = function(self, x, y, width, height, fgCol) - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - height = (y < 1 and (height + y > self.height and self.height or height + y - 1) or (height + y > self.height and self.height - y + 1 or height)) - width = (x < 1 and (width + x > self.width and self.width or width + x - 1) or (width + x > self.width and self.width - x + 1 or width)) - if (self.parent ~= nil) then - local parentX, parentY = self.parent:getAnchorPosition() - self.parent:drawForegroundBox(math.max(x + (obx - 1), obx) - (parentX - 1), math.max(y + (oby - 1), oby) - (parentY - 1), width, height, fgCol) - else - drawHelper.drawForegroundBox(math.max(x + (obx - 1), obx), math.max(y + (oby - 1), oby), width, height, fgCol) - end - end; - - draw = function(self) - if(isMonitor)and not(monitorAttached)then return false end; - if (self:getVisualChanged()) then - if (base.draw(self)) then - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - local anchx, anchy = self:getAnchorPosition() - if (self.parent ~= nil) then - if(self.bgColor~=false)then - self.parent:drawBackgroundBox(anchx, anchy, self.width, self.height, self.bgColor) - self.parent:drawTextBox(anchx, anchy, self.width, self.height, " ") - end - if(self.bgColor~=false)then self.parent:drawForegroundBox(anchx, anchy, self.width, self.height, self.fgColor) end - else - if(self.bgColor~=false)then - drawHelper.drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - drawHelper.drawTextBox(obx, oby, self.width, self.height, " ") - end - if(self.fgColor~=false)then drawHelper.drawForegroundBox(obx, oby, self.width, self.height, self.fgColor) end - end - termObject.setCursorBlink(false) - if (self.barActive) then - if (self.parent ~= nil) then - self.parent:writeText(anchx, anchy, getTextHorizontalAlign(self.barText, self.width, self.barTextAlign), self.barBackground, self.barTextcolor) - else - drawHelper.writeText(obx, oby, getTextHorizontalAlign(self.barText, self.width, self.barTextAlign), self.barBackground, self.barTextcolor) - end - if(self:getBorder("left"))then - if (self.parent ~= nil) then - self.parent:drawBackgroundBox(anchx-1, anchy, 1, 1, self.barBackground) - if(self.bgColor~=false)then - self.parent:drawBackgroundBox(anchx-1, anchy+1, 1, self.height-1, self.bgColor) - end - end - end - if(self:getBorder("top"))then - if (self.parent ~= nil) then - self.parent:drawBackgroundBox(anchx-1, anchy-1, self.width+1, 1, self.barBackground) - end - end - end - - for _, index in rpairs(objZIndex) do - if (objects[index] ~= nil) then - for _, value in pairs(objects[index]) do - if (value.draw ~= nil) then - value:draw() - end - end - end - end - - if (cursorBlink) then - termObject.setTextColor(cursorColor) - termObject.setCursorPos(xCursor, yCursor) - if (self.parent ~= nil) then - termObject.setCursorBlink(self:isFocused()) - else - termObject.setCursorBlink(cursorBlink) - end - end - self:setVisualChanged(false) - end - end - end; - - drawUpdate = function(self) - if(isMonitor)and not(monitorAttached)then return false end; - drawHelper.update() - end; - - addObject = function(self, obj) - return addObject(obj) - end; - - removeObject = function(self, obj) - return removeObject(obj) - end; - - getObject = function(self, obj) - return getObject(obj) - end; - - addButton = function(self, name) - local obj = Button(name) - obj.name = name - return addObject(obj) - end; - - addLabel = function(self, name) - local obj = Label(name) - obj.bgColor = self.bgColor - obj.fgColor = self.fgColor - return addObject(obj) - end; - - addCheckbox = function(self, name) - local obj = Checkbox(name) - return addObject(obj) - end; - - addInput = function(self, name) - local obj = Input(name) - return addObject(obj) - end; - - addProgram = function(self, name) - local obj = Program(name) - return addObject(obj) - end; - - addTextfield = function(self, name) - local obj = Textfield(name) - return addObject(obj) - end; - - addList = function(self, name) - local obj = List(name) - obj.name = nam - return addObject(obj) - end; - - addDropdown = function(self, name) - local obj = Dropdown(name) - return addObject(obj) - end; - - addRadio = function(self, name) - local obj = Radio(name) - return addObject(obj) - end; - - addTimer = function(self, name) - local obj = Timer(name) - return addObject(obj) - end; - - addAnimation = function(self, name) - local obj = Animation(name) - return addObject(obj) - end; - - addSlider = function(self, name) - local obj = Slider(name) - return addObject(obj) - end; - - addScrollbar = function(self, name) - local obj = Scrollbar(name) - return addObject(obj) - end; - - addMenubar = function(self, name) - local obj = Menubar(name) - return addObject(obj) - end; - - addThread = function(self, name) - local obj = Thread(name) - return addObject(obj) - end; - - addPane = function(self, name) - local obj = Pane(name) - return addObject(obj) - end; - - addImage = function(self, name) - local obj = Image(name) - return addObject(obj) - end; - - addProgressbar = function(self, name) - local obj = Progressbar(name) - return addObject(obj) - end; - - addSwitch = function(self, name) - local obj = Switch(name) - return addObject(obj) - end; - - addFrame = function(self, name) - local obj = Frame(name, self) - return addObject(obj) - end; - } - setmetatable(object, base) - return object -end -local function drawFrames() - mainFrame:draw() - mainFrame:drawUpdate() - for _,v in pairs(monFrames)do - v:draw() - v:drawUpdate() - end -end - -local updaterActive = false -local function basaltUpdateEvent(event, p1, p2, p3, p4) - if(eventSystem:sendEvent("basaltEventCycle", event, p1, p2, p3, p4)==false)then return end - if(mainFrame~=nil)then - if (event == "mouse_click") then - mainFrame:mouseHandler(event, p1, p2, p3, p4) - activeFrame = mainFrame - elseif (event == "mouse_drag") then - mainFrame:mouseHandler(event, p1, p2, p3, p4) - activeFrame = mainFrame - elseif (event == "mouse_up") then - mainFrame:mouseHandler(event, p1, p2, p3, p4) - activeFrame = mainFrame - elseif (event == "mouse_scroll") then - mainFrame:mouseHandler(event, p1, p2, p3, p4) - activeFrame = mainFrame - elseif (event == "monitor_touch") then - if(monFrames[p1]~=nil)then - monFrames[p1]:mouseHandler(event, p1, p2, p3, p4) - activeFrame = monFrames[p1] - end - end - end - - if(event == "key") or (event == "char") then - activeFrame:keyHandler(event, p1) - activeFrame:backgroundKeyHandler(event, p1) - end - - if(event == "key")then - keyActive[p1] = true - end - - if(event == "key_up")then - keyActive[p1] = false - end - - for _, v in pairs(frames) do - v:eventHandler(event, p1, p2, p3, p4) - end - drawFrames() -end - -function basalt.autoUpdate(isActive) - updaterActive = isActive - if(isActive==nil)then updaterActive = true end - drawFrames() - while updaterActive do - local event, p1, p2, p3, p4 = os.pullEventRaw() -- change to raw later - basaltUpdateEvent(event, p1, p2, p3, p4) - end -end - -function basalt.update(event, p1, p2, p3, p4) - if (event ~= nil) then - basaltUpdateEvent(event, p1, p2, p3, p4) - end -end - -function basalt.stop() - updaterActive = false -end - -function basalt.isKeyDown(key) - if(keyActive[key]==nil)then return false end - return keyActive[key]; -end - -function basalt.getFrame(name) - for _, value in pairs(frames) do - if (value.name == name) then - return value - end - end -end - -function basalt.getActiveFrame() - return activeFrame -end - -function basalt.setActiveFrame(frame) - if (frame:getType() == "Frame") then - activeFrame = frame - return true - end - return false -end - -function basalt.onEvent(...) - for _,v in pairs(table.pack(...))do - if(type(v)=="function")then - eventSystem:registerEvent("basaltEventCycle", v) - end - end -end - -function basalt.createFrame(name) - for _, v in pairs(frames) do - if (v.name == name) then - return nil - end - end - local newFrame = Frame(name) - table.insert(frames, newFrame) - return newFrame -end - -function basalt.removeFrame(name) - frames[name] = nil -end - - -if (basalt.debugger) then - basalt.debugFrame = basalt.createFrame("basaltDebuggingFrame"):showBar():setBackground(colors.lightGray):setBar("Debug", colors.black, colors.gray) - basalt.debugList = basalt.debugFrame:addList("debugList"):setSize(basalt.debugFrame.width - 2, basalt.debugFrame.height - 3):setPosition(2, 3):setScrollable(true):show() - basalt.debugFrame:addButton("back"):setAnchor("topRight"):setSize(1, 1):setText("\22"):onClick(function() basalt.oldFrame:show() end):setBackground(colors.red):show() - basalt.debugLabel = basalt.debugFrame:addLabel("debugLabel"):onClick(function() basalt.oldFrame = mainFrame basalt.debugFrame:show() end):setBackground(colors.black):setForeground(colors.white):setAnchor("bottomLeft"):ignoreOffset():setZIndex(20):show() -end - -if (basalt.debugger) then - function basalt.debug(...) - local args = { ... } - if (mainFrame.name ~= "basaltDebuggingFrame") then - if (mainFrame ~= basalt.debugFrame) then - basalt.debugLabel:setParent(mainFrame) - end - end - local str = "" - for key, value in pairs(args) do - str = str .. tostring(value) .. (#args ~= key and ", " or "") - end - basalt.debugLabel:setText("[Debug] " .. str) - basalt.debugList:addItem(str) - if (basalt.debugList:getItemCount() > 50) then - basalt.debugList:removeItem(1) - end - basalt.debugList:setValue(basalt.debugList:getItem(basalt.debugList:getItemCount())) - if(basalt.debugList.getItemCount() > basalt.debugList:getHeight())then - basalt.debugList:setIndexOffset(basalt.debugList:getItemCount() - basalt.debugList:getHeight()) - end - basalt.debugLabel:show() - end -end - -return basalt diff --git a/oldVersions/lastVersion/basalt.lua b/oldVersions/lastVersion/basalt.lua deleted file mode 100644 index 249a5da..0000000 --- a/oldVersions/lastVersion/basalt.lua +++ /dev/null @@ -1 +0,0 @@ -local a={debugger=true,version=1}local b={}local c;local d={}local e;local f;local g={}local h=term.current()local i=string.sub;local j={[colors.white]="0",[colors.orange]="1",[colors.magenta]="2",[colors.lightBlue]="3",[colors.yellow]="4",[colors.lime]="5",[colors.pink]="6",[colors.gray]="7",[colors.lightGray]="8",[colors.cyan]="9",[colors.purple]="a",[colors.blue]="b",[colors.brown]="c",[colors.green]="d",[colors.red]="e",[colors.black]="f"}local k={basaltBG=colors.lightGray,basaltFG=colors.black,FrameBG=colors.gray,FrameFG=colors.black,ButtonBG=colors.gray,ButtonFG=colors.black,CheckboxBG=colors.gray,CheckboxFG=colors.black,InputBG=colors.gray,InputFG=colors.black,textfieldBG=colors.gray,textfieldFG=colors.black,listBG=colors.gray,listFG=colors.black,dropdownBG=colors.gray,dropdownFG=colors.black,radioBG=colors.gray,radioFG=colors.black,selectionBG=colors.black,selectionFG=colors.lightGray}local l={{"\32\32\32\137\156\148\158\159\148\135\135\144\159\139\32\136\157\32\159\139\32\32\143\32\32\143\32\32\32\32\32\32\32\32\147\148\150\131\148\32\32\32\151\140\148\151\140\147","\32\32\32\149\132\149\136\156\149\144\32\133\139\159\129\143\159\133\143\159\133\138\32\133\138\32\133\32\32\32\32\32\32\150\150\129\137\156\129\32\32\32\133\131\129\133\131\132","\32\32\32\130\131\32\130\131\32\32\129\32\32\32\32\130\131\32\130\131\32\32\32\32\143\143\143\32\32\32\32\32\32\130\129\32\130\135\32\32\32\32\131\32\32\131\32\131","\139\144\32\32\143\148\135\130\144\149\32\149\150\151\149\158\140\129\32\32\32\135\130\144\135\130\144\32\149\32\32\139\32\159\148\32\32\32\32\159\32\144\32\148\32\147\131\132","\159\135\129\131\143\149\143\138\144\138\32\133\130\149\149\137\155\149\159\143\144\147\130\132\32\149\32\147\130\132\131\159\129\139\151\129\148\32\32\139\131\135\133\32\144\130\151\32","\32\32\32\32\32\32\130\135\32\130\32\129\32\129\129\131\131\32\130\131\129\140\141\132\32\129\32\32\129\32\32\32\32\32\32\32\131\131\129\32\32\32\32\32\32\32\32\32","\32\32\32\32\149\32\159\154\133\133\133\144\152\141\132\133\151\129\136\153\32\32\154\32\159\134\129\130\137\144\159\32\144\32\148\32\32\32\32\32\32\32\32\32\32\32\151\129","\32\32\32\32\133\32\32\32\32\145\145\132\141\140\132\151\129\144\150\146\129\32\32\32\138\144\32\32\159\133\136\131\132\131\151\129\32\144\32\131\131\129\32\144\32\151\129\32","\32\32\32\32\129\32\32\32\32\130\130\32\32\129\32\129\32\129\130\129\129\32\32\32\32\130\129\130\129\32\32\32\32\32\32\32\32\133\32\32\32\32\32\129\32\129\32\32","\150\156\148\136\149\32\134\131\148\134\131\148\159\134\149\136\140\129\152\131\32\135\131\149\150\131\148\150\131\148\32\148\32\32\148\32\32\152\129\143\143\144\130\155\32\134\131\148","\157\129\149\32\149\32\152\131\144\144\131\148\141\140\149\144\32\149\151\131\148\32\150\32\150\131\148\130\156\133\32\144\32\32\144\32\130\155\32\143\143\144\32\152\129\32\134\32","\130\131\32\131\131\129\131\131\129\130\131\32\32\32\129\130\131\32\130\131\32\32\129\32\130\131\32\130\129\32\32\129\32\32\133\32\32\32\129\32\32\32\130\32\32\32\129\32","\150\140\150\137\140\148\136\140\132\150\131\132\151\131\148\136\147\129\136\147\129\150\156\145\138\143\149\130\151\32\32\32\149\138\152\129\149\32\32\157\152\149\157\144\149\150\131\148","\149\143\142\149\32\149\149\32\149\149\32\144\149\32\149\149\32\32\149\32\32\149\32\149\149\32\149\32\149\32\144\32\149\149\130\148\149\32\32\149\32\149\149\130\149\149\32\149","\130\131\129\129\32\129\131\131\32\130\131\32\131\131\32\131\131\129\129\32\32\130\131\32\129\32\129\130\131\32\130\131\32\129\32\129\131\131\129\129\32\129\129\32\129\130\131\32","\136\140\132\150\131\148\136\140\132\153\140\129\131\151\129\149\32\149\149\32\149\149\32\149\137\152\129\137\152\129\131\156\133\149\131\32\150\32\32\130\148\32\152\137\144\32\32\32","\149\32\32\149\159\133\149\32\149\144\32\149\32\149\32\149\32\149\150\151\129\138\155\149\150\130\148\32\149\32\152\129\32\149\32\32\32\150\32\32\149\32\32\32\32\32\32\32","\129\32\32\130\129\129\129\32\129\130\131\32\32\129\32\130\131\32\32\129\32\129\32\129\129\32\129\32\129\32\131\131\129\130\131\32\32\32\129\130\131\32\32\32\32\140\140\132","\32\154\32\159\143\32\149\143\32\159\143\32\159\144\149\159\143\32\159\137\145\159\143\144\149\143\32\32\145\32\32\32\145\149\32\144\32\149\32\143\159\32\143\143\32\159\143\32","\32\32\32\152\140\149\151\32\149\149\32\145\149\130\149\157\140\133\32\149\32\154\143\149\151\32\149\32\149\32\144\32\149\149\153\32\32\149\32\149\133\149\149\32\149\149\32\149","\32\32\32\130\131\129\131\131\32\130\131\32\130\131\129\130\131\129\32\129\32\140\140\129\129\32\129\32\129\32\137\140\129\130\32\129\32\130\32\129\32\129\129\32\129\130\131\32","\144\143\32\159\144\144\144\143\32\159\143\144\159\138\32\144\32\144\144\32\144\144\32\144\144\32\144\144\32\144\143\143\144\32\150\129\32\149\32\130\150\32\134\137\134\134\131\148","\136\143\133\154\141\149\151\32\129\137\140\144\32\149\32\149\32\149\154\159\133\149\148\149\157\153\32\154\143\149\159\134\32\130\148\32\32\149\32\32\151\129\32\32\32\32\134\32","\133\32\32\32\32\133\129\32\32\131\131\32\32\130\32\130\131\129\32\129\32\130\131\129\129\32\129\140\140\129\131\131\129\32\130\129\32\129\32\130\129\32\32\32\32\32\129\32","\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32","\32\32\32\32\32\32\32\32\32\32\32\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\32\32\32\32\32\32\32\32\32\32\32","\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32","\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32","\32\32\32\32\32\32\32\32\32\32\32\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\32\32\32\32\32\32\32\32\32\32\32","\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32","\32\32\32\32\145\32\159\139\32\151\131\132\155\143\132\134\135\145\32\149\32\158\140\129\130\130\32\152\147\155\157\134\32\32\144\144\32\32\32\32\32\32\152\131\155\131\131\129","\32\32\32\32\149\32\149\32\145\148\131\32\149\32\149\140\157\132\32\148\32\137\155\149\32\32\32\149\154\149\137\142\32\153\153\32\131\131\149\131\131\129\149\135\145\32\32\32","\32\32\32\32\129\32\130\135\32\131\131\129\134\131\132\32\129\32\32\129\32\131\131\32\32\32\32\130\131\129\32\32\32\32\129\129\32\32\32\32\32\32\130\131\129\32\32\32","\150\150\32\32\148\32\134\32\32\132\32\32\134\32\32\144\32\144\150\151\149\32\32\32\32\32\32\145\32\32\152\140\144\144\144\32\133\151\129\133\151\129\132\151\129\32\145\32","\130\129\32\131\151\129\141\32\32\142\32\32\32\32\32\149\32\149\130\149\149\32\143\32\32\32\32\142\132\32\154\143\133\157\153\132\151\150\148\151\158\132\151\150\148\144\130\148","\32\32\32\140\140\132\32\32\32\32\32\32\32\32\32\151\131\32\32\129\129\32\32\32\32\134\32\32\32\32\32\32\32\129\129\32\129\32\129\129\130\129\129\32\129\130\131\32","\156\143\32\159\141\129\153\140\132\153\137\32\157\141\32\159\142\32\150\151\129\150\131\132\140\143\144\143\141\145\137\140\148\141\141\144\157\142\32\159\140\32\151\134\32\157\141\32","\157\140\149\157\140\149\157\140\149\157\140\149\157\140\149\157\140\149\151\151\32\154\143\132\157\140\32\157\140\32\157\140\32\157\140\32\32\149\32\32\149\32\32\149\32\32\149\32","\129\32\129\129\32\129\129\32\129\129\32\129\129\32\129\129\32\129\129\131\129\32\134\32\131\131\129\131\131\129\131\131\129\131\131\129\130\131\32\130\131\32\130\131\32\130\131\32","\151\131\148\152\137\145\155\140\144\152\142\145\153\140\132\153\137\32\154\142\144\155\159\132\150\156\148\147\32\144\144\130\145\136\137\32\146\130\144\144\130\145\130\136\32\151\140\132","\151\32\149\151\155\149\149\32\149\149\32\149\149\32\149\149\32\149\149\32\149\152\137\144\157\129\149\149\32\149\149\32\149\149\32\149\149\32\149\130\150\32\32\157\129\149\32\149","\131\131\32\129\32\129\130\131\32\130\131\32\130\131\32\130\131\32\130\131\32\32\32\32\130\131\32\130\131\32\130\131\32\130\131\32\130\131\32\32\129\32\130\131\32\133\131\32","\156\143\32\159\141\129\153\140\132\153\137\32\157\141\32\159\142\32\159\159\144\152\140\144\156\143\32\159\141\129\153\140\132\157\141\32\130\145\32\32\147\32\136\153\32\130\146\32","\152\140\149\152\140\149\152\140\149\152\140\149\152\140\149\152\140\149\149\157\134\154\143\132\157\140\133\157\140\133\157\140\133\157\140\133\32\149\32\32\149\32\32\149\32\32\149\32","\130\131\129\130\131\129\130\131\129\130\131\129\130\131\129\130\131\129\130\130\131\32\134\32\130\131\129\130\131\129\130\131\129\130\131\129\32\129\32\32\129\32\32\129\32\32\129\32","\159\134\144\137\137\32\156\143\32\159\141\129\153\140\132\153\137\32\157\141\32\32\132\32\159\143\32\147\32\144\144\130\145\136\137\32\146\130\144\144\130\145\130\138\32\146\130\144","\149\32\149\149\32\149\149\32\149\149\32\149\149\32\149\149\32\149\149\32\149\131\147\129\138\134\149\149\32\149\149\32\149\149\32\149\149\32\149\154\143\149\32\157\129\154\143\149","\130\131\32\129\32\129\130\131\32\130\131\32\130\131\32\130\131\32\130\131\32\32\32\32\130\131\32\130\131\129\130\131\129\130\131\129\130\131\129\140\140\129\130\131\32\140\140\129"},{[[000110000110110000110010101000000010000000100101]],[[000000110110000000000010101000000010000000100101]],[[000000000000000000000000000000000000000000000000]],[[100010110100000010000110110000010100000100000110]],[[000000110000000010110110000110000000000000110000]],[[000000000000000000000000000000000000000000000000]],[[000000110110000010000000100000100000000000000010]],[[000000000110110100010000000010000000000000000100]],[[000000000000000000000000000000000000000000000000]],[[010000000000100110000000000000000000000110010000]],[[000000000000000000000000000010000000010110000000]],[[000000000000000000000000000000000000000000000000]],[[011110110000000100100010110000000100000000000000]],[[000000000000000000000000000000000000000000000000]],[[000000000000000000000000000000000000000000000000]],[[110000110110000000000000000000010100100010000000]],[[000010000000000000110110000000000100010010000000]],[[000000000000000000000000000000000000000000000000]],[[010110010110100110110110010000000100000110110110]],[[000000000000000000000110000000000110000000000000]],[[000000000000000000000000000000000000000000000000]],[[010100010110110000000000000000110000000010000000]],[[110110000000000000110000110110100000000010000000]],[[000000000000000000000000000000000000000000000000]],[[000100011111000100011111000100011111000100011111]],[[000000000000100100100100011011011011111111111111]],[[000000000000000000000000000000000000000000000000]],[[000100011111000100011111000100011111000100011111]],[[000000000000100100100100011011011011111111111111]],[[100100100100100100100100100100100100100100100100]],[[000000110100110110000010000011110000000000011000]],[[000000000100000000000010000011000110000000001000]],[[000000000000000000000000000000000000000000000000]],[[010000100100000000000000000100000000010010110000]],[[000000000000000000000000000000110110110110110000]],[[000000000000000000000000000000000000000000000000]],[[110110110110110110000000110110110110110110110110]],[[000000000000000000000110000000000000000000000000]],[[000000000000000000000000000000000000000000000000]],[[000000000000110110000110010000000000000000010010]],[[000010000000000000000000000000000000000000000000]],[[000000000000000000000000000000000000000000000000]],[[110110110110110110110000110110110110000000000000]],[[000000000000000000000110000000000000000000000000]],[[000000000000000000000000000000000000000000000000]],[[110110110110110110110000110000000000000000010000]],[[000000000000000000000000100000000000000110000110]],[[000000000000000000000000000000000000000000000000]]}}local m={}local n={}do local o=0;local p=#l[1]local q=#l[1][1]for r=1,p,3 do for s=1,q,3 do local t=string.char(o)local u={}u[1]=l[1][r]:sub(s,s+2)u[2]=l[1][r+1]:sub(s,s+2)u[3]=l[1][r+2]:sub(s,s+2)local v={}v[1]=l[2][r]:sub(s,s+2)v[2]=l[2][r+1]:sub(s,s+2)v[3]=l[2][r+2]:sub(s,s+2)n[t]={u,v}o=o+1 end end;m[1]=n end;local function w(x,y)local z={["0"]="1",["1"]="0"}if x<=#m then return true end;for A=#m+1,x do local B={}local C=m[A-1]for o=0,255 do local t=string.char(o)local u={}local v={}local D=C[t][1]local E=C[t][2]for r=1,#D do local F,G,H,I,J,K={},{},{},{},{},{}for s=1,#D[1]do local L=n[D[r]:sub(s,s)][1]table.insert(F,L[1])table.insert(G,L[2])table.insert(H,L[3])local M=n[D[r]:sub(s,s)][2]if E[r]:sub(s,s)=="1"then table.insert(I,M[1]:gsub("[01]",z))table.insert(J,M[2]:gsub("[01]",z))table.insert(K,M[3]:gsub("[01]",z))else table.insert(I,M[1])table.insert(J,M[2])table.insert(K,M[3])end end;table.insert(u,table.concat(F))table.insert(u,table.concat(G))table.insert(u,table.concat(H))table.insert(v,table.concat(I))table.insert(v,table.concat(J))table.insert(v,table.concat(K))end;B[t]={u,v}if y then y="Font"..A.."Yeld"..o;os.queueEvent(y)os.pullEvent(y)end end;m[A]=B end;return true end;local function N(O,P,Q,R,S)if not type(P)=="string"then error("Not a String",3)end;local T=type(Q)=="string"and Q:sub(1,1)or j[Q]or error("Wrong Front Color",3)local U=type(R)=="string"and R:sub(1,1)or j[R]or error("Wrong Back Color",3)if m[O]==nil then w(3,false)end;local V=m[O]or error("Wrong font size selected",3)if P==""then return{{""},{""},{""}}end;local W={}for r in P:gmatch('.')do table.insert(W,r)end;local X={}local p=#V[W[1]][1]for Y=1,p do local Z={}for r=1,#W do Z[r]=V[W[r]]and V[W[r]][1][Y]or""end;X[Y]=table.concat(Z)end;local _={}local a0={}local a1={["0"]=T,["1"]=U}local a2={["0"]=U,["1"]=T}for Y=1,p do local a3={}local a4={}for r=1,#W do local a5=V[W[r]]and V[W[r]][2][Y]or""a3[r]=a5:gsub("[01]",S and{["0"]=Q:sub(r,r),["1"]=R:sub(r,r)}or a1)a4[r]=a5:gsub("[01]",S and{["0"]=R:sub(r,r),["1"]=Q:sub(r,r)}or a2)end;_[Y]=table.concat(a3)a0[Y]=table.concat(a4)end;return{X,_,a0}end;local function a6(a7)local a8=a7;local a9,p=a8.getSize()local aa={}local ab={}local ac={}local ad={}local ae={}local af={}local ag;local ah={}local function ai()ag=(" "):rep(a9)for aj=0,15 do local ak=2^aj;local al=j[ak]ah[ak]=al:rep(a9)end end;ai()local function am()local an=ag;local ao=ah[colors.white]local ap=ah[colors.black]for aq=1,p do aa[aq]=i(aa[aq]==nil and an or aa[aq]..an:sub(1,a9-aa[aq]:len()),1,a9)ac[aq]=i(ac[aq]==nil and ao or ac[aq]..ao:sub(1,a9-ac[aq]:len()),1,a9)ab[aq]=i(ab[aq]==nil and ap or ab[aq]..ap:sub(1,a9-ab[aq]:len()),1,a9)end end;am()local function ar(as,at,au)if at>=1 and at<=p then if as+au:len()>0 and as<=a9 then local av=aa[at]local aw;local ax=as+#au-1;if as<1 then local ay=1-as+1;local az=a9-as+1;au=i(au,ay,az)elseif ax>a9 then local az=a9-as+1;au=i(au,1,az)end;if as>1 then local az=as-1;aw=i(av,1,az)..au else aw=au end;if ax=1 and at<=p then if as+aB:len()>0 and as<=a9 then local av=ab[at]local aw;local ax=as+#aB-1;if as<1 then aB=i(aB,1-as+1,a9-as+1)elseif ax>a9 then aB=i(aB,1,a9-as+1)end;if as>1 then aw=i(av,1,as-1)..aB else aw=aB end;if ax=1 and at<=p then if as+aB:len()>0 and as<=a9 then local av=ac[at]local aw;local ax=as+#aB-1;if as<1 then local ay=1-as+1;local az=a9-as+1;aB=i(aB,ay,az)elseif ax>a9 then local az=a9-as+1;aB=i(aB,1,az)end;if as>1 then local az=as-1;aw=i(av,1,az)..aB else aw=aB end;if ax1 then while#bm>2 do table.sort(bm,function(bw,bx)return bw[2]>bx[2]end)local by,bz=bl(bm),#bm;local bA,bB=bm[bz][1],bm[by][1]for r=1,6 do if bq[r]==bA then bq[r]=bB;bm[by][2]=bm[by][2]+1 end end;bm[bz]=nil end;local bC=128;for r=1,#bq-1 do if bq[r]~=bq[6]then bC=bC+2^(r-1)end end;return string.char(bC),bi[bm[1][1]==bq[6]and bm[2][1]or bm[1][1]],bi[bq[6]]else return"\128",bi[bq[1]],bi[bq[1]]end end;local bD,a9,p,aE={{},{},{}},0,#bd+#bd%3,be or colors.black;for r=1,#bd do if#bd[r]>a9 then a9=#bd[r]end end;for at=0,p-1,3 do local bE,bF,bG,bH={},{},{},1;for as=0,a9-1,2 do local bq,br={},{}for bI=1,3 do for bJ=1,2 do bq[#bq+1]=bd[at+bI]and bd[at+bI][as+bJ]and(bd[at+bI][as+bJ]==0 and aE or bd[at+bI][as+bJ])or aE;br[bq[#bq]]=br[bq[#bq]]and br[bq[#bq]]+1 or 1 end end;bE[bH],bF[bH],bG[bH]=bp(bq,br)bH=bH+1 end;bD[1][#bD[1]+1],bD[2][#bD[2]+1],bD[3][#bD[3]+1]=table.concat(bE),table.concat(bF),table.concat(bG)end;bD.width,bD.height=#bD[1][1],#bD[1]return bD end;local function bK(bL)local bM="Object"local aT;local bN=1;local bO="topLeft"local bP=false;local bQ=false;local bR=false;local bS=false;local bT=false;local bU=false;local bV=false;local bW=colors.black;local bX=colors.black;local bY=true;local aV=aL()local bZ={x=1,y=1,width=1,height=1,bgColor=colors.black,fgColor=colors.white,name=bL or"Object",parent=nil,show=function(self)bQ=true;bY=true;return self end,hide=function(self)bQ=false;bY=true;return self end,isVisible=function(self)return bQ end,setFocus=function(self)if self.parent~=nil then self.parent:setFocusedObject(self)end;return self end,setZIndex=function(self,aN)bN=aN;if self.parent~=nil then self.parent:removeObject(self)self.parent:addObject(self)end;return self end,getZIndex=function(self)return bN end,getType=function(self)return bM end,getName=function(self)return self.name end,remove=function(self)if self.parent~=nil then self.parent:removeObject(self)end;return self end,setParent=function(self,b_)if b_.getType~=nil and b_:getType()=="Frame"then self:remove()b_:addObject(self)if self.draw then self:show()end end;return self end,setValue=function(self,c0)if aT~=c0 then aT=c0;bY=true;self:valueChangedHandler()end;return self end,getValue=function(self)return aT end,getVisualChanged=function(self)return bY end,setVisualChanged=function(self,c1)bY=c1 or true;if c1==nil then bY=true end;return self end,getEventSystem=function(self)return aV end,getParent=function(self)return self.parent end,setPosition=function(self,c2,c3,c4)if c4 then self.x,self.y=math.floor(self.x+c2),math.floor(self.y+c3)else self.x,self.y=math.floor(c2),math.floor(c3)end;bY=true;return self end,getPosition=function(self)return self.x,self.y end,getVisibility=function(self)return bQ end,setVisibility=function(self,c5)bQ=c5 or not bQ;bY=true;return self end,setSize=function(self,a9,p)self.width,self.height=a9,p;aV:sendEvent("basalt_resize",self)bY=true;return self end,getHeight=function(self)return self.height end,getWidth=function(self)return self.width end,getSize=function(self)return self.width,self.height end,setBackground=function(self,c6)self.bgColor=c6;bY=true;return self end,getBackground=function(self)return self.bgColor end,setForeground=function(self,c6)self.fgColor=c6;bY=true;return self end,getForeground=function(self)return self.fgColor end,showShadow=function(self,c7)bR=c7 or not bR;return self end,setShadow=function(self,c6)bW=c6;return self end,isShadowActive=function(self)return bR end,showBorder=function(self,...)for aS,c8 in pairs(table.pack(...))do if c8=="left"then bS=true end;if c8=="top"then bT=true end;if c8=="right"then bU=true end;if c8=="bottom"then bV=true end end;return self end,setBorder=function(self,c6)bW=c6;return self end,getBorder=function(self,c9)if c9=="left"then return bS end;if c9=="top"then return bT end;if c9=="right"then return bU end;if c9=="bottom"then return bV end end,draw=function(self)if bQ then if self.parent~=nil then local as,at=self:getAnchorPosition()if bR then self.parent:drawBackgroundBox(as+1,at+self.height,self.width,1,bW)self.parent:drawBackgroundBox(as+self.width,at+1,1,self.height,bW)self.parent:drawForegroundBox(as+1,at+self.height,self.width,1,bW)self.parent:drawForegroundBox(as+self.width,at+1,1,self.height,bW)end;if bS then self.parent:drawTextBox(as-1,at,1,self.height,"\149")self.parent:drawForegroundBox(as-1,at,1,self.height,bX)if self.bgColor~=false then self.parent:drawBackgroundBox(as-1,at,1,self.height,self.bgColor)end end;if bS and bT then self.parent:drawTextBox(as-1,at-1,1,1,"\151")self.parent:drawForegroundBox(as-1,at-1,1,1,bX)if self.bgColor~=false then self.parent:drawBackgroundBox(as-1,at-1,1,1,self.bgColor)end end;if bT then self.parent:drawTextBox(as,at-1,self.width,1,"\131")self.parent:drawForegroundBox(as,at-1,self.width,1,bX)if self.bgColor~=false then self.parent:drawBackgroundBox(as,at-1,self.width,1,self.bgColor)end end;if bT and bU then self.parent:drawTextBox(as+self.width,at-1,1,1,"\149")self.parent:drawForegroundBox(as+self.width,at-1,1,1,bX)end;if bU then self.parent:drawTextBox(as+self.width,at,1,self.height,"\149")self.parent:drawForegroundBox(as+self.width,at,1,self.height,bX)end;if bU and bV then self.parent:drawTextBox(as+self.width,at+self.height,1,1,"\129")self.parent:drawForegroundBox(as+self.width,at+self.height,1,1,bX)end;if bV then self.parent:drawTextBox(as,at+self.height,self.width,1,"\131")self.parent:drawForegroundBox(as,at+self.height,self.width,1,bX)end;if bV and bS then self.parent:drawTextBox(as-1,at+self.height,1,1,"\131")self.parent:drawForegroundBox(as-1,at+self.height,1,1,bX)end end;return true end;return false end,getAbsolutePosition=function(self,as,at)if as==nil or at==nil then as,at=self:getAnchorPosition()end;if self.parent~=nil then local ca,cb=self.parent:getAbsolutePosition(self.parent:getAnchorPosition())as=ca+as-1;at=cb+at-1 end;return as,at end,getAnchorPosition=function(self,as,at,cc)if as==nil then as=self.x end;if at==nil then at=self.y end;if bO=="top"then as=math.floor(self.parent.width/2)+as-1 elseif bO=="topRight"then as=self.parent.width+as-1 elseif bO=="right"then as=self.parent.width+as-1;at=math.floor(self.parent.height/2)+at-1 elseif bO=="bottomRight"then as=self.parent.width+as-1;at=self.parent.height+at-1 elseif bO=="bottom"then as=math.floor(self.parent.width/2)+as-1;at=self.parent.height+at-1 elseif bO=="bottomLeft"then at=self.parent.height+at-1 elseif bO=="left"then at=math.floor(self.parent.height/2)+at-1 elseif bO=="center"then as=math.floor(self.parent.width/2)+as-1;at=math.floor(self.parent.height/2)+at-1 end;local cd,ce=self:getOffset()if not(bP or cc)then return as+cd,at+ce end;return as,at end,getOffset=function(self)if self.parent~=nil then return self.parent:getFrameOffset()end;return 0,0 end,ignoreOffset=function(self,cf)bP=cf;if cf==nil then bP=true end;return self end,getBaseFrame=function(self)if self.parent~=nil then return self.parent:getBaseFrame()end;return self end,setAnchor=function(self,cg)bO=cg;bY=true;return self end,getAnchor=function(self)return bO end,onChange=function(self,...)for aS,c8 in pairs(table.pack(...))do if type(c8)=="function"then self:registerEvent("value_changed",c8)end end;return self end,onClick=function(self,...)for aS,c8 in pairs(table.pack(...))do if type(c8)=="function"then self:registerEvent("mouse_click",c8)self:registerEvent("monitor_touch",c8)end end;return self end,onClickUp=function(self,...)for aS,c8 in pairs(table.pack(...))do if type(c8)=="function"then self:registerEvent("mouse_up",c8)end end;return self end,onScroll=function(self,...)for aS,c8 in pairs(table.pack(...))do if type(c8)=="function"then self:registerEvent("mouse_scroll",c8)end end;return self end,onDrag=function(self,...)for aS,c8 in pairs(table.pack(...))do if type(c8)=="function"then self:registerEvent("mouse_drag",c8)end end;return self end,onEvent=function(self,...)for aS,c8 in pairs(table.pack(...))do if type(c8)=="function"then self:registerEvent("custom_event_handler",c8)end end;return self end,onKey=function(self,...)for aS,c8 in pairs(table.pack(...))do if type(c8)=="function"then self:registerEvent("key",c8)self:registerEvent("char",c8)end end;return self end,onResize=function(self,...)for aS,c8 in pairs(table.pack(...))do if type(c8)=="function"then self:registerEvent("basalt_resize",c8)end end;return self end,onKeyUp=function(self,...)for aS,c8 in pairs(table.pack(...))do if type(c8)=="function"then self:registerEvent("key_up",c8)end end;return self end,onBackgroundKey=function(self,...)for aS,c8 in pairs(table.pack(...))do if type(c8)=="function"then self:registerEvent("background_key",c8)self:registerEvent("background_char",c8)end end;return self end,onBackgroundKeyUp=function(self,...)for aS,c8 in pairs(table.pack(...))do if type(c8)=="function"then self:registerEvent("background_key_up",c8)end end;return self end,isFocused=function(self)if self.parent~=nil then return self.parent:getFocusedObject()==self end;return false end,onGetFocus=function(self,...)for aS,c8 in pairs(table.pack(...))do if type(c8)=="function"then self:registerEvent("get_focus",c8)end end;return self end,onLoseFocus=function(self,...)for aS,c8 in pairs(table.pack(...))do if type(c8)=="function"then self:registerEvent("lose_focus",c8)end end;return self end,registerEvent=function(self,aO,aQ)return aV:registerEvent(aO,aQ)end,removeEvent=function(self,aO,aN)return aV:removeEvent(aO,aN)end,sendEvent=function(self,aO,...)return aV:sendEvent(aO,self,...)end,mouseHandler=function(self,aO,ch,as,at)local ci,cj=self:getAbsolutePosition(self:getAnchorPosition())local ck=false;if cj-1==at and self:getBorder("top")then at=at+1;ck=true end;if ci<=as and ci+self.width>as and cj<=at and cj+self.height>at and bQ then if self.parent~=nil then self.parent:setFocusedObject(self)end;local aU=aV:sendEvent(aO,self,aO,ch,as,at)if aU~=nil then return aU end;return true end;return false end,keyHandler=function(self,aO,bv)if self:isFocused()then local aU=aV:sendEvent(aO,self,aO,bv)if aU~=nil then return aU end;return true end;return false end,backgroundKeyHandler=function(self,aO,bv)local aU=aV:sendEvent("background_"..aO,self,aO,bv)if aU~=nil then return aU end;return true end,valueChangedHandler=function(self)aV:sendEvent("value_changed",self)end,eventHandler=function(self,aO,cl,cm,cn,co)aV:sendEvent("custom_event_handler",self,aO,cl,cm,cn,co)end,getFocusHandler=function(self)local aU=aV:sendEvent("get_focus",self)if aU~=nil then return aU end;return true end,loseFocusHandler=function(self)local aU=aV:sendEvent("lose_focus",self)if aU~=nil then return aU end;return true end}bZ.__index=bZ;return bZ end;local function cp(bL)local bZ={}local bM="Animation"local cq;local cr={}local aN=1;local cs=0;local ct;local function cu()if cr[aN]~=nil then cr[aN].f(bZ,aN)end;aN=aN+1;if cr[aN]~=nil then if cr[aN].t>0 then cq=os.startTimer(cr[aN].t)else cu()end end end;bZ={name=bL,getType=function(self)return bM end,getZIndex=function(self)return 1 end,getName=function(self)return self.name end,add=function(self,aQ,cv)ct=aQ;table.insert(cr,{f=aQ,t=cv or cs})return self end,wait=function(self,cv)cs=cv;return self end,rep=function(self,cw)for as=1,cw do table.insert(cr,{f=ct,t=cs})end;return self end,clear=function(self)cr={}ct=nil;cs=0;aN=1;return self end,play=function(self)aN=1;if cr[aN]~=nil then if cr[aN].t>0 then cq=os.startTimer(cr[aN].t)else cu()end end;return self end,cancel=function(self)os.cancelTimer(cq)return self end,eventHandler=function(self,aO,cx)if aO=="timer"and cx==cq then if cr[aN]~=nil then cu()end end end}bZ.__index=bZ;return bZ end;local function cy(bL)local cz=bK(bL)local bM="Button"cz:setValue("Button")cz:setZIndex(5)cz.width=8;cz.bgColor=k.ButtonBG;cz.fgColor=k.ButtonFG;local cA="center"local cB="center"local bZ={getType=function(self)return bM end,setHorizontalAlign=function(self,cC)cA=cC end,setVerticalAlign=function(self,cC)cB=cC end,setText=function(self,au)cz:setValue(au)return self end,draw=function(self)if cz.draw(self)then if self.parent~=nil then local cD,cE=self:getAnchorPosition()local cF=b8(self.height,cB)if self.bgColor~=false then self.parent:drawBackgroundBox(cD,cE,self.width,self.height,self.bgColor)self.parent:drawTextBox(cD,cE,self.width,self.height," ")end;if self.fgColor~=false then self.parent:drawForegroundBox(cD,cE,self.width,self.height,self.fgColor)end;for aj=1,self.height do if aj==cF then self.parent:setText(cD,cE+aj-1,b4(self:getValue(),self.width,cA))end end end;self:setVisualChanged(false)end end}return setmetatable(bZ,cz)end;local function cG(bL)local cz=bK(bL)local bM="Checkbox"cz:setZIndex(5)cz:setValue(false)cz.width=1;cz.height=1;cz.bgColor=k.CheckboxBG;cz.fgColor=k.CheckboxFG;local bZ={symbol="\42",getType=function(self)return bM end,mouseHandler=function(self,aO,ch,as,at)if cz.mouseHandler(self,aO,ch,as,at)then if aO=="mouse_click"and ch==1 or aO=="monitor_touch"then if self:getValue()~=true and self:getValue()~=false then self:setValue(false)else self:setValue(not self:getValue())end end;return true end;return false end,draw=function(self)if cz.draw(self)then if self.parent~=nil then local cD,cE=self:getAnchorPosition()local cF=b8(self.height,"center")if self.bgColor~=false then self.parent:drawBackgroundBox(cD,cE,self.width,self.height,self.bgColor)end;for aj=1,self.height do if aj==cF then if self:getValue()==true then self.parent:writeText(cD,cE+aj-1,b4(self.symbol,self.width,"center"),self.bgColor,self.fgColor)else self.parent:writeText(cD,cE+aj-1,b4(" ",self.width,"center"),self.bgColor,self.fgColor)end end end end;self:setVisualChanged(false)end end}return setmetatable(bZ,cz)end;local function cH(bL)local cz=bK(bL)local bM="Dropdown"cz.width=12;cz.height=1;cz.bgColor=k.dropdownBG;cz.fgColor=k.dropdownFG;cz:setZIndex(6)local cI={}local cJ=k.selectionBG;local cK=k.selectionFG;local cL=true;local cM="left"local cN=0;local cO=16;local cP=6;local cQ="\16"local cR="\31"local cS=false;local bZ={getType=function(self)return bM end,setIndexOffset=function(self,ck)cN=ck;return self end,getIndexOffset=function(self)return cN end,addItem=function(self,au,aE,aF,...)table.insert(cI,{text=au,bgCol=aE or self.bgColor,fgCol=aF or self.fgColor,args={...}})return self end,getAll=function(self)return cI end,removeItem=function(self,aN)table.remove(cI,aN)return self end,getItem=function(self,aN)return cI[aN]end,getItemIndex=function(self)local cT=self:getValue()for bv,aT in pairs(cI)do if aT==cT then return bv end end end,clear=function(self)cI={}self:setValue({})return self end,getItemCount=function(self)return#cI end,editItem=function(self,aN,au,aE,aF,...)table.remove(cI,aN)table.insert(cI,aN,{text=au,bgCol=aE or self.bgColor,fgCol=aF or self.fgColor,args={...}})return self end,selectItem=function(self,aN)self:setValue(cI[aN]or{})return self end,setSelectedItem=function(self,aE,aF,cU)cJ=aE or self.bgColor;cK=aF or self.fgColor;cL=cU;return self end,setDropdownSize=function(self,a9,p)cO,cP=a9,p;return self end,mouseHandler=function(self,aO,ch,as,at)if cS then local cD,cE=self:getAbsolutePosition(self:getAnchorPosition())if aO=="mouse_click"and ch==1 or aO=="monitor_touch"then if#cI>0 then for aj=1,cP do if cI[aj+cN]~=nil then if cD<=as and cD+cO>as and cE+aj==at then self:setValue(cI[aj+cN])return true end end end end end;if aO=="mouse_scroll"then cN=cN+ch;if cN<0 then cN=0 end;if ch==1 then if#cI>cP then if cN>#cI-cP then cN=#cI-cP end else cN=cI-1 end end;return true end;self:setVisualChanged()end;if cz.mouseHandler(self,aO,ch,as,at)then cS=true else cS=false end end,draw=function(self)if cz.draw(self)then local cD,cE=self:getAnchorPosition()if self.parent~=nil then if self.bgColor~=false then self.parent:drawBackgroundBox(cD,cE,self.width,self.height,self.bgColor)end;local aU=self:getValue()local au=b4(aU~=nil and aU.text or"",self.width,cM):sub(1,self.width-1)..(cS and cR or cQ)self.parent:writeText(cD,cE,au,self.bgColor,self.fgColor)if cS then for aj=1,cP do if cI[aj+cN]~=nil then if cI[aj+cN]==aU then if cL then self.parent:writeText(cD,cE+aj,b4(cI[aj+cN].text,cO,cM),cJ,cK)else self.parent:writeText(cD,cE+aj,b4(cI[aj+cN].text,cO,cM),cI[aj+cN].bgCol,cI[aj+cN].fgCol)end else self.parent:writeText(cD,cE+aj,b4(cI[aj+cN].text,cO,cM),cI[aj+cN].bgCol,cI[aj+cN].fgCol)end end end end end;self:setVisualChanged(false)end end}return setmetatable(bZ,cz)end;local function cV(bL)local cz=bK(bL)local bM="Image"cz:setZIndex(2)local cW;local cX;local cY=false;local function bc()local bf={[0]={8,4,3,6,5},{4,14,8,7},{6,10,8,7},{9,11,8,0},{1,14,8,0},{13,12,8,0},{2,10,8,0},{15,8,10,11,12,14},{0,7,1,9,2,13},{3,11,8,7},{2,6,7,15},{9,3,7,15},{13,5,7,15},{5,12,8,7},{1,4,7,15},{7,10,11,12,14}}local bg,bh,bi={},{},{}for r=0,15 do bh[2^r]=r end;do local bj="0123456789abcdef"for r=1,16 do bg[bj:sub(r,r)]=r-1;bg[r-1]=bj:sub(r,r)bi[bj:sub(r,r)]=2^(r-1)bi[2^(r-1)]=bj:sub(r,r)local bk=bf[r-1]for r=1,#bk do bk[r]=2^bk[r]end end end;local function bl(bm)local bn=bf[bh[bm[#bm][1]]]for s=1,#bn do local bo=bn[s]for r=1,#bm-1 do if bm[r][1]==bo then return r end end end;return 1 end;local function bp(bq,br)if not br then local bs={}br={}for r=1,6 do local bt=bq[r]local bu=br[bt]br[bt],bs[r]=bu and bu+1 or 1,bt end;bq=bs end;local bm={}for bv,aT in pairs(br)do bm[#bm+1]={bv,aT}end;if#bm>1 then while#bm>2 do table.sort(bm,function(bw,bx)return bw[2]>bx[2]end)local by,bz=bl(bm),#bm;local bA,bB=bm[bz][1],bm[by][1]for r=1,6 do if bq[r]==bA then bq[r]=bB;bm[by][2]=bm[by][2]+1 end end;bm[bz]=nil end;local bC=128;for r=1,#bq-1 do if bq[r]~=bq[6]then bC=bC+2^(r-1)end end;return string.char(bC),bi[bm[1][1]==bq[6]and bm[2][1]or bm[1][1]],bi[bq[6]]else return"\128",bi[bq[1]],bi[bq[1]]end end;local bD,a9,p,aE={{},{},{}},0,#cW+#cW%3,cz.bgColor or colors.black;for r=1,#cW do if#cW[r]>a9 then a9=#cW[r]end end;for at=0,p-1,3 do local bE,bF,bG,bH={},{},{},1;for as=0,a9-1,2 do local bq,br={},{}for bI=1,3 do for bJ=1,2 do bq[#bq+1]=cW[at+bI]and cW[at+bI][as+bJ]and(cW[at+bI][as+bJ]==0 and aE or cW[at+bI][as+bJ])or aE;br[bq[#bq]]=br[bq[#bq]]and br[bq[#bq]]+1 or 1 end end;bE[bH],bF[bH],bG[bH]=bp(bq,br)bH=bH+1 end;bD[1][#bD[1]+1],bD[2][#bD[2]+1],bD[3][#bD[3]+1]=table.concat(bE),table.concat(bF),table.concat(bG)end;bD.width,bD.height=#bD[1][1],#bD[1]cX=bD end;local bZ={getType=function(self)return bM end,loadImage=function(self,aZ)cW=paintutils.loadImage(aZ)cY=false;return self end,loadBlittleImage=function(self,aZ)return self end,shrink=function(self)bc()cY=true;return self end,draw=function(self)if cz.draw(self)then if self.parent~=nil then if cW~=nil then local cD,cE=self:getAnchorPosition()if cY then local bb,cZ,c_=cX[1],cX[2],cX[3]for r=1,cX.height do local d0=bb[r]if type(d0)=="string"then self.parent:setText(cD,cE+r-1,d0)self.parent:setFG(cD,cE+r-1,cZ[r])self.parent:setBG(cD,cE+r-1,c_[r])elseif type(d0)=="table"then self.parent:setText(cD,cE+r-1,d0[2])self.parent:setFG(cD,cE+r-1,cZ[r])self.parent:setBG(cD,cE+r-1,c_[r])end end else for c3=1,math.min(#cW,self.height)do local d1=cW[c3]for c2=1,math.min(#d1,self.width)do if d1[c2]>0 then self.parent:drawBackgroundBox(cD+c2-1,cE+c3-1,1,1,d1[c2])end end end end end end;self:setVisualChanged(false)end end}return setmetatable(bZ,cz)end;local function d2(bL)local cz=bK(bL)local bM="Input"local d3="text"local d4=0;cz:setZIndex(5)cz:setValue("")cz.width=10;cz.height=1;cz.bgColor=k.InputBG;cz.fgColor=k.InputFG;local d5=1;local d6=1;local d7=""local d8;local d9;local da=d7;local db=false;local bZ={getType=function(self)return bM end,setInputType=function(self,dc)if dc=="password"or dc=="number"or dc=="text"then d3=dc end;return self end,setDefaultText=function(self,au,dd,de)d7=au;d8=de or d8;d9=dd or d9;if self:isFocused()then da=""else da=d7 end;return self end,getInputType=function(self)return d3 end,setValue=function(self,aU)cz.setValue(self,tostring(aU))if not db then d5=tostring(aU):len()+1 end;return self end,getValue=function(self)local aU=cz.getValue(self)return d3=="number"and tonumber(aU)or aU end,setInputLimit=function(self,df)d4=tonumber(df)or d4;return self end,getInputLimit=function(self)return d4 end,getFocusHandler=function(self)cz.getFocusHandler(self)if self.parent~=nil then local cD,cE=self:getAnchorPosition()da=""if self.parent~=nil then self.parent:setCursor(true,cD+d5-d6,cE+math.floor(self.height/2),self.fgColor)end end end,loseFocusHandler=function(self)cz.loseFocusHandler(self)if self.parent~=nil then self.parent:setCursor(false)da=d7 end end,keyHandler=function(self,aO,bv)if cz.keyHandler(self,aO,bv)then db=true;if aO=="key"then if bv==keys.backspace then local au=tostring(cz.getValue())if d5>1 then self:setValue(au:sub(1,d5-2)..au:sub(d5,au:len()))if d5>1 then d5=d5-1 end;if d6>1 then if d5dg then d5=dg+1 end;if d5<1 then d5=1 end;if d5=self.width+d6 then d6=d5-self.width+1 end;if d6<1 then d6=1 end end;if bv==keys.left then d5=d5-1;if d5>=1 then if d5=self.width+d6 then d6=d5 end end;if d5<1 then d5=1 end;if d6<1 then d6=1 end end end;if aO=="char"then local au=cz.getValue()if au:len()=self.width+d6 then d6=d6+1 end end end;local cD,cE=self:getAnchorPosition()local aU=tostring(cz.getValue())local di=(d5<=aU:len()and d5-1 or aU:len())-(d6-1)if di>self.x+self.width-1 then di=self.x+self.width-1 end;if self.parent~=nil then self.parent:setCursor(true,cD+di,cE+math.floor(self.height/2),self.fgColor)end;db=false end end,mouseHandler=function(self,aO,ch,as,at)if cz.mouseHandler(self,aO,ch,as,at)then if aO=="mouse_click"and ch==1 then end;return true end;return false end,draw=function(self)if cz.draw(self)then if self.parent~=nil then local cD,cE=self:getAnchorPosition()local cF=b8(self.height,"center")if self.bgColor~=false then self.parent:drawBackgroundBox(cD,cE,self.width,self.height,self.bgColor)end;for aj=1,self.height do if aj==cF then local aU=tostring(cz.getValue())local de=self.bgColor;local dd=self.fgColor;local au;if aU:len()<=0 then au=da;de=d8 or de;dd=d9 or dd end;au=da;if aU~=""then au=aU end;au=au:sub(d6,self.width+d6-1)local dj=self.width-au:len()if dj<0 then dj=0 end;if d3=="password"and aU~=""then au=string.rep("*",au:len())end;au=au..string.rep(" ",dj)self.parent:writeText(cD,cE+aj-1,au,de,dd)end end end;self:setVisualChanged(false)end end}return setmetatable(bZ,cz)end;local function dk(bL)local cz=bK(bL)local bM="Label"cz:setZIndex(3)cz.fgColor=colors.white;cz.bgcolor=colors.black;local dl=true;cz:setValue("")local cA="left"local cB="top"local dm=0;local bZ={getType=function(self)return bM end,setText=function(self,au)au=tostring(au)cz:setValue(au)if dl then self.width=au:len()end;return self end,setTextAlign=function(self,dn,dp)cA=dn or cA;cB=dp or cB;self:setVisualChanged()return self end,setFontSize=function(self,x)if x>0 and x<=4 then dm=x-1 or 0 end;return self end,getFontSize=function(self)return dm+1 end,setSize=function(self,a9,p)cz.setSize(self,a9,p)dl=false;self:setVisualChanged()return self end,draw=function(self)if cz.draw(self)then if self.parent~=nil then local cD,cE=self:getAnchorPosition()local cF=b8(self.height,cB)if self.bgColor~=false then self.parent:drawBackgroundBox(cD,cE,self.width,self.height,self.bgColor)self.parent:drawTextBox(cD,cE,self.width,self.height," ")end;if self.fgColor~=false then self.parent:drawForegroundBox(cD,cE,self.width,self.height,self.fgColor)end;if dm==0 then for aj=1,self.height do if aj==cF then self.parent:setText(cD,cE+aj-1,b4(self:getValue(),self.width,cA))end end else local dq=N(dm,self:getValue(),self.fgColor,self.bgColor or colors.black)if dl then self.height=#dq[1]-1;self.width=#dq[1][1]end;for aj=1,self.height do if aj==cF then local dr,ds=self.parent:getSize()local dt,du=#dq[1][1],#dq[1]cD=cD or math.floor((dr-dt)/2)+1;cE=cE or math.floor((ds-du)/2)+1;for r=1,du do self.parent:setFG(cD,cE+r+aj-2,b4(dq[2][r],self.width,cA))self.parent:setBG(cD,cE+r+aj-2,b4(dq[3][r],self.width,cA,j[self.bgColor or colors.black]))self.parent:setText(cD,cE+r+aj-2,b4(dq[1][r],self.width,cA))end end end end end;self:setVisualChanged(false)end end}return setmetatable(bZ,cz)end;local function dv(bL)local cz=bK(bL)local bM="List"cz.width=16;cz.height=6;cz.bgColor=k.listBG;cz.fgColor=k.listFG;cz:setZIndex(5)local cI={}local cJ=k.selectionBG;local cK=k.selectionFG;local cL=true;local cM="left"local cN=0;local dw=true;local bZ={getType=function(self)return bM end,addItem=function(self,au,aE,aF,...)table.insert(cI,{text=au,bgCol=aE or self.bgColor,fgCol=aF or self.fgColor,args={...}})if#cI==1 then self:setValue(cI[1])end;return self end,setIndexOffset=function(self,ck)cN=ck;return self end,getIndexOffset=function(self)return cN end,removeItem=function(self,aN)table.remove(cI,aN)return self end,getItem=function(self,aN)return cI[aN]end,getAll=function(self)return cI end,getItemIndex=function(self)local cT=self:getValue()for bv,aT in pairs(cI)do if aT==cT then return bv end end end,clear=function(self)cI={}self:setValue({})return self end,getItemCount=function(self)return#cI end,editItem=function(self,aN,au,aE,aF,...)table.remove(cI,aN)table.insert(cI,aN,{text=au,bgCol=aE or self.bgColor,fgCol=aF or self.fgColor,args={...}})return self end,selectItem=function(self,aN)self:setValue(cI[aN]or{})return self end,setSelectedItem=function(self,aE,aF,cU)cJ=aE or self.bgColor;cK=aF or self.fgColor;cL=cU;return self end,setScrollable=function(self,dx)dw=dx;return self end,mouseHandler=function(self,aO,ch,as,at)local cD,cE=self:getAbsolutePosition(self:getAnchorPosition())if cD<=as and cD+self.width>as and cE<=at and cE+self.height>at and self:isVisible()then if(aO=="mouse_click"or aO=="mouse_drag")and ch==1 or aO=="monitor_touch"then if#cI>0 then for aj=1,self.height do if cI[aj+cN]~=nil then if cD<=as and cD+self.width>as and cE+aj-1==at then self:setValue(cI[aj+cN])self:getEventSystem():sendEvent("mouse_click",self,"mouse_click",0,as,at,cI[aj+cN])end end end end end;if aO=="mouse_scroll"and dw then cN=cN+ch;if cN<0 then cN=0 end;if ch>=1 then if#cI>self.height then if cN>#cI-self.height then cN=#cI-self.height end;if cN>=#cI then cN=#cI-1 end else cN=cN-1 end end end;self:setVisualChanged()return true end end,draw=function(self)if cz.draw(self)then if self.parent~=nil then local cD,cE=self:getAnchorPosition()if self.bgColor~=false then self.parent:drawBackgroundBox(cD,cE,self.width,self.height,self.bgColor)end;for aj=1,self.height do if cI[aj+cN]~=nil then if cI[aj+cN]==self:getValue()then if cL then self.parent:writeText(cD,cE+aj-1,b4(cI[aj+cN].text,self.width,cM),cJ,cK)else self.parent:writeText(cD,cE+aj-1,b4(cI[aj+cN].text,self.width,cM),cI[aj+cN].bgCol,cI[aj+cN].fgCol)end else self.parent:writeText(cD,cE+aj-1,b4(cI[aj+cN].text,self.width,cM),cI[aj+cN].bgCol,cI[aj+cN].fgCol)end end end end;self:setVisualChanged(false)end end}return setmetatable(bZ,cz)end;local function dy(bL)local cz=bK(bL)local bM="Menubar"local bZ={}cz.width=30;cz.height=1;cz.bgColor=colors.gray;cz.fgColor=colors.lightGray;cz:setZIndex(5)local cI={}local cJ=k.selectionBG;local cK=k.selectionFG;local cL=true;local cM="left"local dz=0;local dj=1;local dw=false;local function dA()local dB=0;local c2=0;for aj=1,#cI do if c2+cI[aj].text:len()+dj*2>bZ.width then if c2dB then dz=dB end;return self end,getPositionOffset=function(self)return dz end,setScrollable=function(self,dx)dw=dx;if dx==nil then dw=true end;return self end,removeItem=function(self,aN)table.remove(cI,aN)return self end,getItem=function(self,aN)return cI[aN]end,getItemCount=function(self)return#cI end,editItem=function(self,aN,au,aE,aF,...)table.remove(cI,aN)table.insert(cI,aN,{text=au,bgCol=aE or self.bgColor,fgCol=aF or self.fgColor,args={...}})return self end,selectItem=function(self,aN)self:setValue(cI[aN]or{})return self end,setSelectedItem=function(self,aE,aF,cU)cJ=aE or self.bgColor;cK=aF or self.fgColor;cL=cU;return self end,mouseHandler=function(self,aO,ch,as,at)if cz.mouseHandler(self,aO,ch,as,at)then local ci,cj=self:getAbsolutePosition(self:getAnchorPosition())if ci<=as and ci+self.width>as and cj<=at and cj+self.height>at and self:isVisible()then if self.parent~=nil then self.parent:setFocusedObject(self)end;if aO=="mouse_click"or aO=="monitor_touch"then local c2=0;for aj=1,#cI do if cI[aj]~=nil then if ci+c2<=as+dz and ci+c2+cI[aj].text:len()+dj*2>as+dz and cj==at then self:setValue(cI[aj])self:getEventSystem():sendEvent(aO,self,aO,0,as,at,cI[aj])end;c2=c2+cI[aj].text:len()+dj*2 end end end;if aO=="mouse_scroll"and dw then dz=dz+ch;if dz<0 then dz=0 end;local dB=dA()if dz>dB then dz=dB end end;self:setVisualChanged(true)return true end end;return false end,draw=function(self)if cz.draw(self)then if self.parent~=nil then local cD,cE=self:getAnchorPosition()if self.bgColor~=false then self.parent:drawBackgroundBox(cD,cE,self.width,self.height,self.bgColor)end;local au=""local dD=""local dE=""for aS,c8 in pairs(cI)do local dF=(" "):rep(dj)..c8.text..(" "):rep(dj)au=au..dF;if c8==self:getValue()then dD=dD..j[cJ or c8.bgCol or self.bgColor]:rep(dF:len())dE=dE..j[cK or c8.FgCol or self.fgColor]:rep(dF:len())else dD=dD..j[c8.bgCol or self.bgColor]:rep(dF:len())dE=dE..j[c8.FgCol or self.fgColor]:rep(dF:len())end end;self.parent:setText(cD,cE,au:sub(dz+1,self.width+dz))self.parent:setBG(cD,cE,dD:sub(dz+1,self.width+dz))self.parent:setFG(cD,cE,dE:sub(dz+1,self.width+dz))end;self:setVisualChanged(false)end end}return setmetatable(bZ,cz)end;local function dG(bL)local cz=bK(bL)local bM="Pane"local bZ={getType=function(self)return bM end,draw=function(self)if cz.draw(self)then if self.parent~=nil then local cD,cE=self:getAnchorPosition()self.parent:drawBackgroundBox(cD,cE,self.width,self.height,self.bgColor)self.parent:drawForegroundBox(cD,cE,self.width,self.height,self.bgColor)end;self:setVisualChanged(false)end end}return setmetatable(bZ,cz)end;local function dH(bL)local cz=bK(bL)local bM="Program"cz:setZIndex(5)local bZ;local function dI(as,at,a9,p)local dJ,dK=1,1;local be,dL=colors.black,colors.white;local dM=false;local dN=false;local aa={}local ab={}local ac={}local dO={}local ag;local ah={}for r=0,15 do local dP=2^r;dO[dP]={h.getPaletteColour(dP)}end;local function ai()ag=(" "):rep(a9)for aj=0,15 do local ak=2^aj;local al=j[ak]ah[ak]=al:rep(a9)end end;local function am()ai()local an=ag;local ao=ah[colors.white]local ap=ah[colors.black]for aj=1,p do aa[aj]=i(aa[aj]==nil and an or aa[aj]..an:sub(1,a9-aa[aj]:len()),1,a9)ac[aj]=i(ac[aj]==nil and ao or ac[aj]..ao:sub(1,a9-ac[aj]:len()),1,a9)ab[aj]=i(ab[aj]==nil and ap or ab[aj]..ap:sub(1,a9-ab[aj]:len()),1,a9)end end;am()local function dQ()if dJ>=1 and dK>=1 and dJ<=a9 and dK<=p then else end end;local function dR(dS,dT,dU)local dV=dJ;local ax=dV+#dS-1;if dK>=1 and dK<=p then if dV<=a9 and ax>=1 then if dV==1 and ax==a9 then aa[dK]=dS;ac[dK]=dT;ab[dK]=dU else local dW,dX,dY;if dV<1 then local dZ=1-dV+1;local d_=a9-dV+1;dW=i(dS,dZ,d_)dX=i(dT,dZ,d_)dY=i(dU,dZ,d_)elseif ax>a9 then local d_=a9-dV+1;dW=i(dS,1,d_)dX=i(dT,1,d_)dY=i(dU,1,d_)else dW=dS;dX=dT;dY=dU end;local e0=aa[dK]local e1=ac[dK]local e2=ab[dK]local e3,e4,e5;if dV>1 then local e6=dV-1;e3=i(e0,1,e6)..dW;e4=i(e1,1,e6)..dX;e5=i(e2,1,e6)..dY else e3=dW;e4=dX;e5=dY end;if ax=1 and at<=p then aa[et]=aa[at]ab[et]=ab[at]ac[et]=ac[at]else aa[et]=eq;ac[et]=er;ab[et]=es end end end;if dN then dQ()end end,isColor=function()return h.isColor()end,isColour=function()return h.isColor()end,write=function(au)au=tostring(au)if dN then dR(au,j[dL]:rep(au:len()),j[be]:rep(au:len()))end end,clearLine=function()if dN then ar(1,dK,(" "):rep(a9))aA(1,dK,j[be]:rep(a9))aC(1,dK,j[dL]:rep(a9))end;if dN then dQ()end end,clear=function()for aj=1,p do ar(1,aj,(" "):rep(a9))aA(1,aj,j[be]:rep(a9))aC(1,aj,j[dL]:rep(a9))end;if dN then dQ()end end,blit=function(au,eu,ev)if type(au)~="string"then error("bad argument #1 (expected string, got "..type(au)..")",2)end;if type(eu)~="string"then error("bad argument #2 (expected string, got "..type(eu)..")",2)end;if type(ev)~="string"then error("bad argument #3 (expected string, got "..type(ev)..")",2)end;if#eu~=#au or#ev~=#au then error("Arguments must be the same length",2)end;if dN then dR(au,eu,ev)end end}return el end;cz.width=30;cz.height=12;local ew=dI(1,1,cz.width,cz.height)local ex;local ey=false;local ez={}bZ={getType=function(self)return bM end,show=function(self)cz.show(self)ew.setBackgroundColor(self.bgColor)ew.setTextColor(self.fgColor)ew.basalt_setVisible(true)return self end,hide=function(self)cz.hide(self)ew.basalt_setVisible(false)return self end,setPosition=function(self,as,at,c4)cz.setPosition(self,as,at,c4)ew.basalt_reposition(self:getAnchorPosition())return self end,getBasaltWindow=function()return ew end,getBasaltProcess=function()return ex end,setSize=function(self,a9,p)cz.setSize(self,a9,p)ew.basalt_resize(self.width,self.height)return self end,getStatus=function(self)if ex~=nil then return ex:getStatus()end;return"inactive"end,execute=function(self,aZ,...)ex=aX:new(aZ,ew,...)ew.setBackgroundColor(colors.black)ew.setTextColor(colors.white)ew.clear()ew.setCursorPos(1,1)ex:resume()ey=false;return self end,stop=function(self)if ex~=nil then if not ex:isDead()then ex:resume("terminate")if ex:isDead()then if self.parent~=nil then self.parent:setCursor(false)end end end end;return self end,pause=function(self,eA)ey=eA or not ey;if ex~=nil then if not ex:isDead()then if not ey then self:injectEvents(ez)ez={}end end end;return self end,isPaused=function(self)return ey end,injectEvent=function(self,aO,cl,cm,cn,co,eB)if ex~=nil then if not ex:isDead()then if ey==false or eB then ex:resume(aO,cl,cm,cn,co)else table.insert(ez,{event=aO,args={cl,cm,cn,co}})end end end;return self end,getQueuedEvents=function(self)return ez end,updateQueuedEvents=function(self,aM)ez=aM or ez;return self end,injectEvents=function(self,aM)if ex~=nil then if not ex:isDead()then for aS,aT in pairs(aM)do ex:resume(aT.event,table.unpack(aT.args))end end end;return self end,mouseHandler=function(self,aO,ch,as,at)if cz.mouseHandler(self,aO,ch,as,at)then if ex==nil then return false end;if not ex:isDead()then if not ey then local eC,eD=self:getAbsolutePosition(self:getAnchorPosition(nil,nil,true))ex:resume(aO,ch,as-(eC-1),at-(eD-1))a.debug(aO,ch,as-(eC-1),at-(eD-1))end end;return true end end,keyHandler=function(self,aO,bv)cz.keyHandler(self,aO,bv)if self:isFocused()then if ex==nil then return false end;if not ex:isDead()then if not ey then if self.draw then ex:resume(aO,bv)end end end end end,getFocusHandler=function(self)cz.getFocusHandler(self)if ex~=nil then if not ex:isDead()then if not ey then if self.parent~=nil then local eE,eF=ew.getCursorPos()local cD,cE=self:getAnchorPosition()if self.parent~=nil then if cD+eE-1>=1 and cD+eE-1<=cD+self.width-1 and eF+cE-1>=1 and eF+cE-1<=cE+self.height-1 then self.parent:setCursor(ew.getCursorBlink(),cD+eE-1,eF+cE-1,ew.getTextColor())end end end end end end end,loseFocusHandler=function(self)cz.loseFocusHandler(self)if ex~=nil then if not ex:isDead()then if self.parent~=nil then self.parent:setCursor(false)end end end end,eventHandler=function(self,aO,cl,cm,cn,co)if ex==nil then return end;if not ex:isDead()then if not ey then if aO~="mouse_click"and aO~="monitor_touch"and aO~="mouse_up"and aO~="mouse_scroll"and aO~="mouse_drag"and aO~="key_up"and aO~="key"and aO~="char"and aO~="terminate"then ex:resume(aO,cl,cm,cn,co)end;if self:isFocused()then local cD,cE=self:getAnchorPosition()local eE,eF=ew.getCursorPos()if self.parent~=nil then if cD+eE-1>=1 and cD+eE-1<=cD+self.width-1 and eF+cE-1>=1 and eF+cE-1<=cE+self.height-1 then self.parent:setCursor(ew.getCursorBlink(),cD+eE-1,eF+cE-1,ew.getTextColor())end end;if aO=="terminate"and self:isFocused()then self:stop()end end else if aO~="mouse_click"and aO~="monitor_touch"and aO~="mouse_up"and aO~="mouse_scroll"and aO~="mouse_drag"and aO~="key_up"and aO~="key"and aO~="char"and aO~="terminate"then table.insert(ez,{event=aO,args={cl,cm,cn,co}})end end end end,draw=function(self)if cz.draw(self)then if self.parent~=nil then local cD,cE=self:getAnchorPosition()ew.basalt_reposition(cD,cE)if self.bgColor~=false then self.parent:drawBackgroundBox(cD,cE,self.width,self.height,self.bgColor)end;ew.basalt_update()end;self:setVisualChanged(false)end end}return setmetatable(bZ,cz)end;local function eG(bL)local cz=bK(bL)local bM="Progressbar"local eH=0;cz:setZIndex(5)cz:setValue(false)cz.width=25;cz.height=1;cz.bgColor=k.CheckboxBG;cz.fgColor=k.CheckboxFG;local eI=colors.black;local eJ=""local eK=colors.white;local eL=""local eM=0;local bZ={getType=function(self)return bM end,setDirection=function(self,eN)eM=eN;return self end,setProgressBar=function(self,c6,aG,eO)eI=c6 or eI;eJ=aG or eJ;eK=eO or eK;return self end,setBackgroundSymbol=function(self,aG)eL=aG:sub(1,1)return self end,setProgress=function(self,aT)if aT>=0 and aT<=100 and eH~=aT then eH=aT;self:setValue(eH)if eH==100 then self:progressDoneHandler()end end;return self end,getProgress=function(self)return eH end,onProgressDone=function(self,A)self:registerEvent("progress_done",A)return self end,progressDoneHandler=function(self)self:sendEvent("progress_done",self)end,draw=function(self)if cz.draw(self)then if self.parent~=nil then local cD,cE=self:getAnchorPosition()self.parent:drawBackgroundBox(cD,cE,self.width,self.height,self.bgColor)self.parent:drawForegroundBox(cD,cE,self.width,self.height,self.fgColor)self.parent:drawTextBox(cD,cE,self.width,self.height,eL)if eM==1 then self.parent:drawBackgroundBox(cD,cE,self.width,self.height/100*eH,eI)self.parent:drawForegroundBox(cD,cE,self.width,self.height/100*eH,eK)self.parent:drawTextBox(cD,cE,self.width,self.height/100*eH,eJ)elseif eM==2 then self.parent:drawBackgroundBox(cD,cE+math.ceil(self.height-self.height/100*eH),self.width,self.height/100*eH,eI)self.parent:drawForegroundBox(cD,cE+math.ceil(self.height-self.height/100*eH),self.width,self.height/100*eH,eK)self.parent:drawTextBox(cD,cE+math.ceil(self.height-self.height/100*eH),self.width,self.height/100*eH,eJ)elseif eM==3 then self.parent:drawBackgroundBox(cD+math.ceil(self.width-self.width/100*eH),cE,self.width/100*eH,self.height,eI)self.parent:drawForegroundBox(cD+math.ceil(self.width-self.width/100*eH),cE,self.width/100*eH,self.height,eK)self.parent:drawTextBox(cD+math.ceil(self.width-self.width/100*eH),cE,self.width/100*eH,self.height,eJ)else self.parent:drawBackgroundBox(cD,cE,self.width/100*eH,self.height,eI)self.parent:drawForegroundBox(cD,cE,self.width/100*eH,self.height,eK)self.parent:drawTextBox(cD,cE,self.width/100*eH,self.height,eJ)end end;self:setVisualChanged(false)end end}return setmetatable(bZ,cz)end;local function eP(bL)local cz=bK(bL)local bM="Radio"cz.width=8;cz.bgColor=k.listBG;cz.fgColor=k.listFG;cz:setZIndex(5)local cI={}local cJ=k.selectionBG;local cK=k.selectionFG;local eQ=cz.bgColor;local eR=cz.fgColor;local cL=true;local aG="\7"local cM="left"local bZ={getType=function(self)return bM end,addItem=function(self,au,as,at,aE,aF,...)table.insert(cI,{x=as or 1,y=at or 1,text=au,bgCol=aE or self.bgColor,fgCol=aF or self.fgColor,args={...}})if#cI==1 then self:setValue(cI[1])end;return self end,getAll=function(self)return cI end,removeItem=function(self,aN)table.remove(cI,aN)return self end,getItem=function(self,aN)return cI[aN]end,getItemIndex=function(self)local cT=self:getValue()for bv,aT in pairs(cI)do if aT==cT then return bv end end end,clear=function(self)cI={}self:setValue({})return self end,getItemCount=function(self)return#cI end,editItem=function(self,aN,au,as,at,aE,aF,...)table.remove(cI,aN)table.insert(cI,aN,{x=as or 1,y=at or 1,text=au,bgCol=aE or self.bgColor,fgCol=aF or self.fgColor,args={...}})return self end,selectItem=function(self,aN)self:setValue(cI[aN]or{})return self end,setSelectedItem=function(self,aE,aF,eS,eT,cU)cJ=aE or cJ;cK=aF or cK;eQ=eS or eQ;eR=eT or eR;cL=cU;return self end,mouseHandler=function(self,aO,ch,as,at)local cD,cE=self:getAbsolutePosition(self:getAnchorPosition())if aO=="mouse_click"and ch==1 or aO=="monitor_touch"then if#cI>0 then for aS,aT in pairs(cI)do if cD+aT.x-1<=as and cD+aT.x-1+aT.text:len()+2>=as and cE+aT.y-1==at then self:setValue(aT)if self.parent~=nil then self.parent:setFocusedObject(self)end;self:setVisualChanged()return true end end end end;return false end,draw=function(self)if cz.draw(self)then if self.parent~=nil then local cD,cE=self:getAnchorPosition()for aS,aT in pairs(cI)do if aT==self:getValue()then if cM=="left"then self.parent:writeText(aT.x+cD-1,aT.y+cE-1,aG,eQ,eR)self.parent:writeText(aT.x+2+cD-1,aT.y+cE-1,aT.text,cJ,cK)end else self.parent:drawBackgroundBox(aT.x+cD-1,aT.y+cE-1,1,1,self.bgColor)self.parent:writeText(aT.x+2+cD-1,aT.y+cE-1,aT.text,aT.bgCol,aT.fgCol)end end end;self:setVisualChanged(false)end end}return setmetatable(bZ,cz)end;local function eU(bL)local cz=bK(bL)local bM="Scrollbar"cz.width=1;cz.height=8;cz.bgColor=colors.lightGray;cz.fgColor=colors.gray;cz:setValue(1)cz:setZIndex(2)local eV="vertical"local aG=" "local eW=colors.black;local eX="\127"local eY=cz.height;local aN=1;local eZ=1;local bZ={getType=function(self)return bM end,setSymbol=function(self,e_)aG=e_:sub(1,1)self:setVisualChanged()return self end,setSymbolSize=function(self,x)eZ=tonumber(x)or 1;if eV=="vertical"then self:setValue(aN-1*eY/(self.height-(eZ-1))-eY/(self.height-(eZ-1)))elseif eV=="horizontal"then self:setValue(aN-1*eY/(self.width-(eZ-1))-eY/(self.width-(eZ-1)))end;self:setVisualChanged()return self end,setMaxValue=function(self,aU)eY=aU;return self end,setBackgroundSymbol=function(self,f0)eX=string.sub(f0,1,1)self:setVisualChanged()return self end,setSymbolColor=function(self,f1)eW=f1;self:setVisualChanged()return self end,setBarType=function(self,f2)eV=f2:lower()return self end,mouseHandler=function(self,aO,ch,as,at)if cz.mouseHandler(self,aO,ch,as,at)then local cD,cE=self:getAbsolutePosition(self:getAnchorPosition())if(aO=="mouse_click"or aO=="mouse_drag")and ch==1 or aO=="monitor_touch"then if eV=="horizontal"then for f3=0,self.width do if cD+f3==as and cE<=at and cE+self.height>at then aN=math.min(f3+1,self.width-(eZ-1))self:setValue(eY/self.width*aN)self:setVisualChanged()end end end;if eV=="vertical"then for f3=0,self.height do if cE+f3==at and cD<=as and cD+self.width>as then aN=math.min(f3+1,self.height-(eZ-1))self:setValue(eY/self.height*aN)self:setVisualChanged()end end end end;if aO=="mouse_scroll"then aN=aN+ch;if aN<1 then aN=1 end;aN=math.min(aN,(eV=="vertical"and self.height or self.width)-(eZ-1))self:setValue(eY/(eV=="vertical"and self.height or self.width)*aN)end;return true end end,draw=function(self)if cz.draw(self)then if self.parent~=nil then local cD,cE=self:getAnchorPosition()if eV=="horizontal"then self.parent:writeText(cD,cE,eX:rep(aN-1),self.bgColor,self.fgColor)self.parent:writeText(cD+aN-1,cE,aG:rep(eZ),eW,eW)self.parent:writeText(cD+aN+eZ-1,cE,eX:rep(self.width-(aN+eZ-1)),self.bgColor,self.fgColor)end;if eV=="vertical"then for aj=0,self.height-1 do if aN==aj+1 then for f4=0,math.min(eZ-1,self.height)do self.parent:writeText(cD,cE+aj+f4,aG,eW,eW)end else if aj+1aN-1+eZ then self.parent:writeText(cD,cE+aj,eX,self.bgColor,self.fgColor)end end end end end;self:setVisualChanged(false)end end}return setmetatable(bZ,cz)end;local function f5(bL)local cz=bK(bL)local bM="Slider"cz.width=8;cz.height=1;cz.bgColor=colors.lightGray;cz.fgColor=colors.gray;cz:setValue(1)local eV="horizontal"local aG=" "local eW=colors.black;local eX="\140"local eY=cz.width;local aN=1;local eZ=1;local bZ={getType=function(self)return bM end,setSymbol=function(self,e_)aG=e_:sub(1,1)self:setVisualChanged()return self end,setSymbolSize=function(self,x)eZ=tonumber(x)or 1;if eV=="vertical"then self:setValue(aN-1*eY/(self.height-(eZ-1))-eY/(self.height-(eZ-1)))elseif eV=="horizontal"then self:setValue(aN-1*eY/(self.width-(eZ-1))-eY/(self.width-(eZ-1)))end;self:setVisualChanged()return self end,setMaxValue=function(self,aU)eY=aU;return self end,setBackgroundSymbol=function(self,f0)eX=string.sub(f0,1,1)self:setVisualChanged()return self end,setSymbolColor=function(self,f1)eW=f1;self:setVisualChanged()return self end,setBarType=function(self,f2)eV=f2:lower()return self end,mouseHandler=function(self,aO,ch,as,at)if cz.mouseHandler(self,aO,ch,as,at)then local cD,cE=self:getAbsolutePosition(self:getAnchorPosition())if(aO=="mouse_click"or aO=="mouse_drag")and ch==1 or aO=="monitor_touch"then if eV=="horizontal"then for f3=0,self.width do if cD+f3==as and cE<=at and cE+self.height>at then aN=math.min(f3+1,self.width-(eZ-1))self:setValue(eY/self.width*aN)self:setVisualChanged()end end end;if eV=="vertical"then for f3=0,self.height do if cE+f3==at and cD<=as and cD+self.width>as then aN=math.min(f3+1,self.height-(eZ-1))self:setValue(eY/self.height*aN)self:setVisualChanged()end end end end;if aO=="mouse_scroll"then aN=aN+ch;if aN<1 then aN=1 end;aN=math.min(aN,(eV=="vertical"and self.height or self.width)-(eZ-1))self:setValue(eY/(eV=="vertical"and self.height or self.width)*aN)end;return true end end,draw=function(self)if cz.draw(self)then if self.parent~=nil then local cD,cE=self:getAnchorPosition()if eV=="horizontal"then self.parent:writeText(cD,cE,eX:rep(aN-1),self.bgColor,self.fgColor)self.parent:writeText(cD+aN-1,cE,aG:rep(eZ),eW,eW)self.parent:writeText(cD+aN+eZ-1,cE,eX:rep(self.width-(aN+eZ-1)),self.bgColor,self.fgColor)end;if eV=="vertical"then for aj=0,self.height-1 do if aN==aj+1 then for f4=0,math.min(eZ-1,self.height)do self.parent:writeText(cD,cE+aj+f4,aG,eW,eW)end else if aj+1aN-1+eZ then self.parent:writeText(cD,cE+aj,eX,self.bgColor,self.fgColor)end end end end end;self:setVisualChanged(false)end end}return setmetatable(bZ,cz)end;local function f6(bL)local cz=bK(bL)local bM="Switch"cz.width=2;cz.height=1;cz.bgColor=colors.lightGray;cz.fgColor=colors.gray;cz:setValue(false)cz:setZIndex(5)local eX=colors.black;local f7=colors.red;local f8=colors.green;local bZ={getType=function(self)return bM end,setSymbolColor=function(self,eW)eX=eW;self:setVisualChanged()return self end,setActiveBackground=function(self,ev)f8=ev;self:setVisualChanged()return self end,setInactiveBackground=function(self,ev)f7=ev;self:setVisualChanged()return self end,mouseHandler=function(self,aO,ch,as,at)if cz.mouseHandler(self,aO,ch,as,at)then local cD,cE=self:getAbsolutePosition(self:getAnchorPosition())if aO=="mouse_click"and ch==1 or aO=="monitor_touch"then self:setValue(not self:getValue())end;return true end end,draw=function(self)if cz.draw(self)then if self.parent~=nil then local cD,cE=self:getAnchorPosition()self.parent:drawBackgroundBox(cD,cE,self.width,self.height,self.bgColor)if self:getValue()then self.parent:drawBackgroundBox(cD,cE,1,self.height,f8)self.parent:drawBackgroundBox(cD+1,cE,1,self.height,eX)else self.parent:drawBackgroundBox(cD,cE,1,self.height,eX)self.parent:drawBackgroundBox(cD+1,cE,1,self.height,f7)end end;self:setVisualChanged(false)end end}return setmetatable(bZ,cz)end;local function f9(bL)local cz=bK(bL)local bM="Textfield"local fa,d6,d5,fb=1,1,1,1;local fc={""}local fd={[colors.purple]={"break"}}cz.width=20;cz.height=8;cz.bgColor=k.textfieldBG;cz.fgColor=k.textfieldFG;cz:setZIndex(5)local bZ={getType=function(self)return bM end,getLines=function(self)return fc end,getLine=function(self,aN)return fc[aN]or""end,editLine=function(self,aN,au)fc[aN]=au or fc[aN]return self end,addLine=function(self,au,aN)if aN~=nil then table.insert(fc,aN,au)else table.insert(fc,au)end;return self end,addKeyword=function(self,fe,c6)end,removeLine=function(self,aN)table.remove(fc,aN or#fc)if#fc<=0 then table.insert(fc,"")end;return self end,getTextCursor=function(self)return d5,fb end,getFocusHandler=function(self)cz.getFocusHandler(self)if self.parent~=nil then local cD,cE=self:getAnchorPosition()if self.parent~=nil then self.parent:setCursor(true,cD+d5-d6,cE+fb-fa,self.fgColor)end end end,loseFocusHandler=function(self)cz.loseFocusHandler(self)if self.parent~=nil then self.parent:setCursor(false)end end,keyHandler=function(self,aO,bv)if cz.keyHandler(self,aO,bv)then local cD,cE=self:getAnchorPosition()if aO=="key"then if bv==keys.backspace then if fc[fb]==""then if fb>1 then table.remove(fc,fb)d5=fc[fb-1]:len()+1;d6=d5-self.width+1;if d6<1 then d6=1 end;fb=fb-1 end elseif d5<=1 then if fb>1 then d5=fc[fb-1]:len()+1;d6=d5-self.width+1;if d6<1 then d6=1 end;fc[fb-1]=fc[fb-1]..fc[fb]table.remove(fc,fb)fb=fb-1 end else fc[fb]=fc[fb]:sub(1,d5-2)..fc[fb]:sub(d5,fc[fb]:len())if d5>1 then d5=d5-1 end;if d6>1 then if d5fc[fb]:len()then if fc[fb+1]~=nil then fc[fb]=fc[fb]..fc[fb+1]table.remove(fc,fb+1)end else fc[fb]=fc[fb]:sub(1,d5-1)..fc[fb]:sub(d5+1,fc[fb]:len())end end;if bv==keys.enter then table.insert(fc,fb+1,fc[fb]:sub(d5,fc[fb]:len()))fc[fb]=fc[fb]:sub(1,d5-1)fb=fb+1;d5=1;d6=1;if fb-fa>=self.height then fa=fa+1 end;self:setValue("")end;if bv==keys.up then if fb>1 then fb=fb-1;if d5>fc[fb]:len()+1 then d5=fc[fb]:len()+1 end;if d6>1 then if d51 then if fbfc[fb]:len()+1 then d5=fc[fb]:len()+1 end;if fb>=fa+self.height then fa=fa+1 end end end;if bv==keys.right then d5=d5+1;if fb<#fc then if d5>fc[fb]:len()+1 then d5=1;fb=fb+1 end elseif d5>fc[fb]:len()then d5=fc[fb]:len()+1 end;if d5<1 then d5=1 end;if d5=self.width+d6 then d6=d5-self.width+1 end;if d6<1 then d6=1 end end;if bv==keys.left then d5=d5-1;if d5>=1 then if d5=self.width+d6 then d6=d5 end end;if fb>1 then if d5<1 then fb=fb-1;d5=fc[fb]:len()+1;d6=d5-self.width+1 end end;if d5<1 then d5=1 end;if d6<1 then d6=1 end end end;if aO=="char"then fc[fb]=fc[fb]:sub(1,d5-1)..bv..fc[fb]:sub(d5,fc[fb]:len())d5=d5+1;if d5>=self.width+d6 then d6=d6+1 end;self:setValue("")end;local di=(d5<=fc[fb]:len()and d5-1 or fc[fb]:len())-(d6-1)if di>self.x+self.width-1 then di=self.x+self.width-1 end;local ff=fb-fafc[fb]:len()then d5=fc[fb]:len()+1 end;if d5fc[fb]:len()then d5=fc[fb]:len()+1 end;if d5#fc-(self.height-1)then fa=#fc-(self.height-1)end;if fa<1 then fa=1 end;if self.parent~=nil then if cD+d5-d6>=cD and cD+d5-d6<=cD+self.width and(cE+fb-fa>=cE and cE+fb-fa<=cE+self.height)then self.parent:setCursor(true,fg+d5-d6,fh+fb-fa,self.fgColor)else self.parent:setCursor(false)end end end;self:setVisualChanged()return true end end,draw=function(self)if cz.draw(self)then if self.parent~=nil then local cD,cE=self:getAnchorPosition()if self.bgColor~=false then self.parent:drawBackgroundBox(cD,cE,self.width,self.height,self.bgColor)end;if self.fgColor~=false then self.parent:drawForegroundBox(cD,cE,self.width,self.height,self.fgColor)end;for aj=1,self.height do local au=""if fc[aj+fa-1]~=nil then au=fc[aj+fa-1]end;au=au:sub(d6,self.width+d6-1)local dj=self.width-au:len()if dj<0 then dj=0 end;au=au..string.rep(" ",dj)self.parent:setText(cD,cE+aj-1,au)end end;self:setVisualChanged(false)end end}return setmetatable(bZ,cz)end;local function fi(bL)local bZ;local bM="Thread"local aQ;local fj;local fk=false;bZ={name=bL,getType=function(self)return bM end,getZIndex=function(self)return 1 end,getName=function(self)return self.name end,start=function(self,A)if A==nil then error("Function provided to thread is nil")end;aQ=A;fj=coroutine.create(aQ)fk=true;local b2,b3=coroutine.resume(fj)if not b2 then if b3~="Terminated"then error("Thread Error Occurred - "..b3)end end;return self end,getStatus=function(self,A)if fj~=nil then return coroutine.status(fj)end;return nil end,stop=function(self,A)fk=false;return self end,eventHandler=function(self,aO,cl,cm,cn)if fk then if coroutine.status(fj)~="dead"then local b2,b3=coroutine.resume(fj,aO,cl,cm,cn)if not b2 then if b3~="Terminated"then error("Thread Error Occurred - "..b3)end end else fk=false end end end}bZ.__index=bZ;return bZ end;local function fl(bL)local bM="Timer"local fm=0;local fn=0;local fo=0;local cq;local aV=aL()local fp=false;local bZ={name=bL,getType=function(self)return bM end,getZIndex=function(self)return 1 end,getName=function(self)return self.name end,setTime=function(self,fq,fr)fm=fq or 0;fn=fr or 1;return self end,start=function(self)if fp then os.cancelTimer(cq)end;fo=fn;cq=os.startTimer(fm)fp=true;return self end,isActive=function(self)return fp end,cancel=function(self)if cq~=nil then os.cancelTimer(cq)end;fp=false;return self end,onCall=function(self,aQ)aV:registerEvent("timed_event",aQ)return self end,eventHandler=function(self,aO,cx)if aO=="timer"and cx==cq and fp then aV:sendEvent("timed_event",self)if fo>=1 then fo=fo-1;if fo>=1 then cq=os.startTimer(fm)end elseif fo==-1 then cq=os.startTimer(fm)end end end}bZ.__index=bZ;return bZ end;local function fs(bL,ft)local cz=bK(bL)local bM="Frame"local fu={}local fv={}local bZ={}local fw=h;local fx=""local fy=false;local fz=false;local fA=0;local fB=0;cz:setZIndex(10)local aD=a6(fw)local dM=false;local dJ=1;local dK=1;local fC=colors.white;local fD,cN=0,0;if ft~=nil then cz.parent=ft;cz.width,cz.height=ft:getSize()cz.bgColor=k.FrameBG;cz.fgColor=k.FrameFG else cz.width,cz.height=fw.getSize()cz.bgColor=k.basaltBG;cz.fgColor=k.basaltFG end;local function fE(bL)for aS,aT in pairs(fu)do for aS,bx in pairs(aT)do if bx.name==bL then return aT end end end end;local function fF(fG)local bN=fG:getZIndex()if fE(fG.name)~=nil then return nil end;if fu[bN]==nil then for as=1,#fv+1 do if fv[as]~=nil then if bN==fv[as]then break end;if bN>fv[as]then table.insert(fv,as,bN)break end else table.insert(fv,bN)end end;if#fv<=0 then table.insert(fv,bN)end;fu[bN]={}end;fG.parent=bZ;table.insert(fu[bN],fG)return fG end;local function fH(fG)for bw,bx in pairs(fu)do for bv,aT in pairs(bx)do if aT==fG then table.remove(fu[bw],bv)return true end end end;return false end;bZ={barActive=false,barBackground=colors.gray,barTextcolor=colors.black,barText="New Frame",barTextAlign="left",isMoveable=false,getType=function(self)return bM end,setFocusedObject=function(self,fG)if c~=nil then c:loseFocusHandler()c=nil end;if fG~=nil then c=fG;fG:getFocusHandler()end;return self end,setSize=function(self,fI,b9)cz.setSize(self,fI,b9)for aS,aN in pairs(fv)do if fu[aN]~=nil then for aS,aT in pairs(fu[aN])do if aT.eventHandler~=nil then aT:sendEvent("basalt_resize",aT,self)end end end end;return self end,setOffset=function(self,cd,ce)fD=cd~=nil and math.floor(cd<0 and math.abs(cd)or-cd)or fD;cN=ce~=nil and math.floor(ce<0 and math.abs(ce)or-ce)or cN;return self end,getFrameOffset=function(self)return fD,cN end,removeFocusedObject=function(self)if c~=nil then c:loseFocusHandler()end;c=nil;return self end,getFocusedObject=function(self)return c end,setCursor=function(self,fJ,fK,fL,c6)if self.parent~=nil then local cD,cE=self:getAnchorPosition()self.parent:setCursor(fJ or false,(fK or 0)+cD-1,(fL or 0)+cE-1,c6 or fC)else local cD,cE=self:getAbsolutePosition(self:getAnchorPosition())dM=fJ or false;if fK~=nil then dJ=cD+fK-1 end;if fL~=nil then dK=cE+fL-1 end;fC=c6 or fC;self:setVisualChanged()end;return self end,setMoveable=function(self,fM)self.isMoveable=fM or not self.isMoveable;self:setVisualChanged()return self end,show=function(self)cz.show(self)if self.parent==nil then e=self;if fy then g[fx]=self else f=self end end;return self end,hide=function(self)cz.hide(self)if self.parent==nil then if e==self then e=nil end;if fy then if g[fx]==self then g[fx]=nil end else if f==self then f=nil end end end;return self end,showBar=function(self,fN)self.barActive=fN or not self.barActive;self:setVisualChanged()return self end,setBar=function(self,au,aE,aF)self.barText=au or""self.barBackground=aE or self.barBackground;self.barTextcolor=aF or self.barTextcolor;self:setVisualChanged()return self end,setBarTextAlign=function(self,cM)self.barTextAlign=cM or"left"self:setVisualChanged()return self end,setMonitor=function(self,c9)if c9~=nil and c9~=false then if peripheral.getType(c9)=="monitor"then fw=peripheral.wrap(c9)fz=true end;fy=true else fw=h;fy=false;if g[fx]==self then g[fx]=nil end end;aD=a6(fw)fx=c9 or nil;return self end,getVisualChanged=function(self)local fO=cz.getVisualChanged(self)for aS,aN in pairs(fv)do if fu[aN]~=nil then for aS,aT in pairs(fu[aN])do if aT.getVisualChanged~=nil and aT:getVisualChanged()then fO=true end end end end;return fO end,loseFocusHandler=function(self)cz.loseFocusHandler(self)end,getFocusHandler=function(self)cz.getFocusHandler(self)if self.parent~=nil then self.parent:removeObject(self)self.parent:addObject(self)end end,keyHandler=function(self,aO,bv)if c~=nil then if c~=self then if c.keyHandler~=nil then if c:keyHandler(aO,bv)then return true end end else cz.keyHandler(self,aO,bv)end end;return false end,backgroundKeyHandler=function(self,aO,bv)cz.backgroundKeyHandler(self,aO,bv)for aS,aN in pairs(fv)do if fu[aN]~=nil then for aS,aT in pairs(fu[aN])do if aT.backgroundKeyHandler~=nil then aT:backgroundKeyHandler(aO,bv)end end end end end,eventHandler=function(self,aO,cl,cm,cn,co)cz.eventHandler(self,aO,cl,cm,cn,co)for aS,aN in pairs(fv)do if fu[aN]~=nil then for aS,aT in pairs(fu[aN])do if aT.eventHandler~=nil then aT:eventHandler(aO,cl,cm,cn,co)end end end end;if fy then if aO=="peripheral"and cl==fx then if peripheral.getType(fx)=="monitor"then fz=true;fw=peripheral.wrap(fx)aD=a6(fw)end end;if aO=="peripheral_detach"and cl==fx then fz=false end end;if aO=="terminate"then fw.clear()fw.setCursorPos(1,1)a.stop()end end,mouseHandler=function(self,aO,ch,as,at)local cd,ce=self:getOffset()cd=cd<0 and math.abs(cd)or-cd;ce=ce<0 and math.abs(ce)or-ce;if self.drag then if aO=="mouse_drag"then local fP=1;local fQ=1;if self.parent~=nil then fP,fQ=self.parent:getAbsolutePosition(self.parent:getAnchorPosition())end;self:setPosition(as+fA-(fP-1)+cd,at+fB-(fQ-1)+ce)end;if aO=="mouse_up"then self.drag=false end;return true end;local ci,cj=self:getAbsolutePosition(self:getAnchorPosition())local ck=false;if cj-1==at and self:getBorder("top")then at=at+1;ck=true end;if cz.mouseHandler(self,aO,ch,as,at)then local ca,cb=self:getAbsolutePosition(self:getAnchorPosition())ca=ca+fD;cb=cb+cN;for aS,aN in pairs(fv)do if fu[aN]~=nil then for aS,aT in ba(fu[aN])do if aT.mouseHandler~=nil then if aT:mouseHandler(aO,ch,as,at)then return true end end end end end;if self.isMoveable then local ca,cb=self:getAbsolutePosition(self:getAnchorPosition())if as>=ca and as<=ca+self.width-1 and at==cb and aO=="mouse_click"then self.drag=true;fA=ca-as;fB=ck and 1 or 0 end end;if c~=nil then c:loseFocusHandler()c=nil end;return true end;return false end,setText=function(self,as,at,au)local cD,cE=self:getAbsolutePosition(self:getAnchorPosition())if at>=1 and at<=self.height then if self.parent~=nil then local fP,fQ=self.parent:getAnchorPosition()self.parent:setText(math.max(as+cD-1,cD)-(fP-1),cE+at-1-(fQ-1),i(au,math.max(1-as+1,1),math.max(self.width-as+1,1)))else aD.setText(math.max(as+cD-1,cD),cE+at-1,i(au,math.max(1-as+1,1),math.max(self.width-as+1,1)))end end end,setBG=function(self,as,at,aE)local cD,cE=self:getAbsolutePosition(self:getAnchorPosition())if at>=1 and at<=self.height then if self.parent~=nil then local fP,fQ=self.parent:getAnchorPosition()self.parent:setBG(math.max(as+cD-1,cD)-(fP-1),cE+at-1-(fQ-1),i(aE,math.max(1-as+1,1),math.max(self.width-as+1,1)))else aD.setBG(math.max(as+cD-1,cD),cE+at-1,i(aE,math.max(1-as+1,1),math.max(self.width-as+1,1)))end end end,setFG=function(self,as,at,aF)local cD,cE=self:getAbsolutePosition(self:getAnchorPosition())if at>=1 and at<=self.height then if self.parent~=nil then local fP,fQ=self.parent:getAnchorPosition()self.parent:setFG(math.max(as+cD-1,cD)-(fP-1),cE+at-1-(fQ-1),i(aF,math.max(1-as+1,1),math.max(self.width-as+1,1)))else aD.setFG(math.max(as+cD-1,cD),cE+at-1,i(aF,math.max(1-as+1,1),math.max(self.width-as+1,1)))end end end,writeText=function(self,as,at,au,aE,aF)local cD,cE=self:getAbsolutePosition(self:getAnchorPosition())if at>=1 and at<=self.height then if self.parent~=nil then local fP,fQ=self.parent:getAnchorPosition()self.parent:writeText(math.max(as+cD-1,cD)-(fP-1),cE+at-1-(fQ-1),i(au,math.max(1-as+1,1),self.width-as+1),aE,aF)else aD.writeText(math.max(as+cD-1,cD),cE+at-1,i(au,math.max(1-as+1,1),math.max(self.width-as+1,1)),aE,aF)end end end,drawBackgroundBox=function(self,as,at,a9,p,aE)local cD,cE=self:getAbsolutePosition(self:getAnchorPosition())p=at<1 and(p+at>self.height and self.height or p+at-1)or(p+at>self.height and self.height-at+1 or p)a9=as<1 and(a9+as>self.width and self.width or a9+as-1)or(a9+as>self.width and self.width-as+1 or a9)if self.parent~=nil then local fP,fQ=self.parent:getAnchorPosition()self.parent:drawBackgroundBox(math.max(as+cD-1,cD)-(fP-1),math.max(at+cE-1,cE)-(fQ-1),a9,p,aE)else aD.drawBackgroundBox(math.max(as+cD-1,cD),math.max(at+cE-1,cE),a9,p,aE)end end,drawTextBox=function(self,as,at,a9,p,aG)local cD,cE=self:getAbsolutePosition(self:getAnchorPosition())p=at<1 and(p+at>self.height and self.height or p+at-1)or(p+at>self.height and self.height-at+1 or p)a9=as<1 and(a9+as>self.width and self.width or a9+as-1)or(a9+as>self.width and self.width-as+1 or a9)if self.parent~=nil then local fP,fQ=self.parent:getAnchorPosition()self.parent:drawTextBox(math.max(as+cD-1,cD)-(fP-1),math.max(at+cE-1,cE)-(fQ-1),a9,p,aG:sub(1,1))else aD.drawTextBox(math.max(as+cD-1,cD),math.max(at+cE-1,cE),a9,p,aG:sub(1,1))end end,drawForegroundBox=function(self,as,at,a9,p,aF)local cD,cE=self:getAbsolutePosition(self:getAnchorPosition())p=at<1 and(p+at>self.height and self.height or p+at-1)or(p+at>self.height and self.height-at+1 or p)a9=as<1 and(a9+as>self.width and self.width or a9+as-1)or(a9+as>self.width and self.width-as+1 or a9)if self.parent~=nil then local fP,fQ=self.parent:getAnchorPosition()self.parent:drawForegroundBox(math.max(as+cD-1,cD)-(fP-1),math.max(at+cE-1,cE)-(fQ-1),a9,p,aF)else aD.drawForegroundBox(math.max(as+cD-1,cD),math.max(at+cE-1,cE),a9,p,aF)end end,draw=function(self)if fy and not fz then return false end;if self:getVisualChanged()then if cz.draw(self)then local cD,cE=self:getAbsolutePosition(self:getAnchorPosition())local fg,fh=self:getAnchorPosition()if self.parent~=nil then if self.bgColor~=false then self.parent:drawBackgroundBox(fg,fh,self.width,self.height,self.bgColor)self.parent:drawTextBox(fg,fh,self.width,self.height," ")end;if self.bgColor~=false then self.parent:drawForegroundBox(fg,fh,self.width,self.height,self.fgColor)end else if self.bgColor~=false then aD.drawBackgroundBox(cD,cE,self.width,self.height,self.bgColor)aD.drawTextBox(cD,cE,self.width,self.height," ")end;if self.fgColor~=false then aD.drawForegroundBox(cD,cE,self.width,self.height,self.fgColor)end end;fw.setCursorBlink(false)if self.barActive then if self.parent~=nil then self.parent:writeText(fg,fh,b4(self.barText,self.width,self.barTextAlign),self.barBackground,self.barTextcolor)else aD.writeText(cD,cE,b4(self.barText,self.width,self.barTextAlign),self.barBackground,self.barTextcolor)end;if self:getBorder("left")then if self.parent~=nil then self.parent:drawBackgroundBox(fg-1,fh,1,1,self.barBackground)if self.bgColor~=false then self.parent:drawBackgroundBox(fg-1,fh+1,1,self.height-1,self.bgColor)end end end;if self:getBorder("top")then if self.parent~=nil then self.parent:drawBackgroundBox(fg-1,fh-1,self.width+1,1,self.barBackground)end end end;for aS,aN in ba(fv)do if fu[aN]~=nil then for aS,aT in pairs(fu[aN])do if aT.draw~=nil then aT:draw()end end end end;if dM then fw.setTextColor(fC)fw.setCursorPos(dJ,dK)if self.parent~=nil then fw.setCursorBlink(self:isFocused())else fw.setCursorBlink(dM)end end;self:setVisualChanged(false)end end end,drawUpdate=function(self)if fy and not fz then return false end;aD.update()end,addObject=function(self,fG)return fF(fG)end,removeObject=function(self,fG)return fH(fG)end,getObject=function(self,fG)return fE(fG)end,addButton=function(self,bL)local fG=cy(bL)fG.name=bL;return fF(fG)end,addLabel=function(self,bL)local fG=dk(bL)fG.bgColor=self.bgColor;fG.fgColor=self.fgColor;return fF(fG)end,addCheckbox=function(self,bL)local fG=cG(bL)return fF(fG)end,addInput=function(self,bL)local fG=d2(bL)return fF(fG)end,addProgram=function(self,bL)local fG=dH(bL)return fF(fG)end,addTextfield=function(self,bL)local fG=f9(bL)return fF(fG)end,addList=function(self,bL)local fG=dv(bL)fG.name=nam;return fF(fG)end,addDropdown=function(self,bL)local fG=cH(bL)return fF(fG)end,addRadio=function(self,bL)local fG=eP(bL)return fF(fG)end,addTimer=function(self,bL)local fG=fl(bL)return fF(fG)end,addAnimation=function(self,bL)local fG=cp(bL)return fF(fG)end,addSlider=function(self,bL)local fG=f5(bL)return fF(fG)end,addScrollbar=function(self,bL)local fG=eU(bL)return fF(fG)end,addMenubar=function(self,bL)local fG=dy(bL)return fF(fG)end,addThread=function(self,bL)local fG=fi(bL)return fF(fG)end,addPane=function(self,bL)local fG=dG(bL)return fF(fG)end,addImage=function(self,bL)local fG=cV(bL)return fF(fG)end,addProgressbar=function(self,bL)local fG=eG(bL)return fF(fG)end,addSwitch=function(self,bL)local fG=f6(bL)return fF(fG)end,addFrame=function(self,bL)local fG=fs(bL,self)return fF(fG)end}setmetatable(bZ,cz)return bZ end;local function fR()f:draw()f:drawUpdate()for aS,c8 in pairs(g)do c8:draw()c8:drawUpdate()end end;local fS=false;local function fT(aO,cl,cm,cn,co)if aV:sendEvent("basaltEventCycle",aO,cl,cm,cn,co)==false then return end;if f~=nil then if aO=="mouse_click"then f:mouseHandler(aO,cl,cm,cn,co)e=f elseif aO=="mouse_drag"then f:mouseHandler(aO,cl,cm,cn,co)e=f elseif aO=="mouse_up"then f:mouseHandler(aO,cl,cm,cn,co)e=f elseif aO=="mouse_scroll"then f:mouseHandler(aO,cl,cm,cn,co)e=f elseif aO=="monitor_touch"then if g[cl]~=nil then g[cl]:mouseHandler(aO,cl,cm,cn,co)e=g[cl]end end end;if aO=="key"or aO=="char"then e:keyHandler(aO,cl)e:backgroundKeyHandler(aO,cl)end;if aO=="key"then b[cl]=true end;if aO=="key_up"then b[cl]=false end;for aS,c8 in pairs(d)do c8:eventHandler(aO,cl,cm,cn,co)end;fR()end;function a.autoUpdate(fk)fS=fk;if fk==nil then fS=true end;fR()while fS do local aO,cl,cm,cn,co=os.pullEventRaw()fT(aO,cl,cm,cn,co)end end;function a.update(aO,cl,cm,cn,co)if aO~=nil then fT(aO,cl,cm,cn,co)end end;function a.stop()fS=false end;function a.isKeyDown(bv)if b[bv]==nil then return false end;return b[bv]end;function a.getFrame(bL)for aS,aT in pairs(d)do if aT.name==bL then return aT end end end;function a.getActiveFrame()return e end;function a.setActiveFrame(b_)if b_:getType()=="Frame"then e=b_;return true end;return false end;function a.onEvent(...)for aS,c8 in pairs(table.pack(...))do if type(c8)=="function"then aV:registerEvent("basaltEventCycle",c8)end end end;function a.createFrame(bL)for aS,c8 in pairs(d)do if c8.name==bL then return nil end end;local fU=fs(bL)table.insert(d,fU)return fU end;function a.removeFrame(bL)d[bL]=nil end;if a.debugger then a.debugFrame=a.createFrame("basaltDebuggingFrame"):showBar():setBackground(colors.lightGray):setBar("Debug",colors.black,colors.gray)a.debugList=a.debugFrame:addList("debugList"):setSize(a.debugFrame.width-2,a.debugFrame.height-3):setPosition(2,3):setScrollable(true):show()a.debugFrame:addButton("back"):setAnchor("topRight"):setSize(1,1):setText("\22"):onClick(function()a.oldFrame:show()end):setBackground(colors.red):show()a.debugLabel=a.debugFrame:addLabel("debugLabel"):onClick(function()a.oldFrame=f;a.debugFrame:show()end):setBackground(colors.black):setForeground(colors.white):setAnchor("bottomLeft"):ignoreOffset():setZIndex(20):show()end;if a.debugger then function a.debug(...)local b0={...}if f.name~="basaltDebuggingFrame"then if f~=a.debugFrame then a.debugLabel:setParent(f)end end;local fV=""for bv,aT in pairs(b0)do fV=fV..tostring(aT)..(#b0~=bv and", "or"")end;a.debugLabel:setText("[Debug] "..fV)a.debugList:addItem(fV)if a.debugList:getItemCount()>50 then a.debugList:removeItem(1)end;a.debugList:setValue(a.debugList:getItem(a.debugList:getItemCount()))if a.debugList.getItemCount()>a.debugList:getHeight()then a.debugList:setIndexOffset(a.debugList:getItemCount()-a.debugList:getHeight())end;a.debugLabel:show()end end;return a \ No newline at end of file diff --git a/oldVersions/lastVersion/source/compiler.lua b/oldVersions/lastVersion/source/compiler.lua deleted file mode 100644 index 383ca6b..0000000 --- a/oldVersions/lastVersion/source/compiler.lua +++ /dev/null @@ -1,7 +0,0 @@ -local basaltFileName = "basalt-source.lua" -local absolutePath = "source" -local basalt = dofile(fs.combine(absolutePath, "packager.lua")) -- path to packager - -local b = fs.open(fs.combine(absolutePath, basaltFileName), "w") -b.write(basalt) -b.close() \ No newline at end of file diff --git a/oldVersions/lastVersion/source/loader.lua b/oldVersions/lastVersion/source/loader.lua deleted file mode 100644 index 8036ccb..0000000 --- a/oldVersions/lastVersion/source/loader.lua +++ /dev/null @@ -1,4 +0,0 @@ -local absolutePath = "source" -local basalt = dofile(fs.combine(absolutePath, "packager.lua")) - -return (load(basalt, "t")()) \ No newline at end of file diff --git a/oldVersions/lastVersion/source/packager.lua b/oldVersions/lastVersion/source/packager.lua deleted file mode 100644 index 0be5f59..0000000 --- a/oldVersions/lastVersion/source/packager.lua +++ /dev/null @@ -1,68 +0,0 @@ -local basaltFileName = "basalt.lua" -local absoluteFilePath = "source/project" - -local requiredFiles = { - "mainTop.lua", - "mainBottom.lua", - "Frame.lua", - "Object.lua", - "defaultTheme.lua", - "lib/drawHelper.lua", - "lib/eventSystem.lua", - "lib/process.lua", - "lib/utils.lua", -} - -local basalt = "" - -for k,v in pairs(requiredFiles)do - assert(fs.exists(fs.combine(absoluteFilePath, v)), "File "..v.." doesn't exists!") -end - -local lib = fs.list(fs.combine(absoluteFilePath, "lib")) -local objects = fs.list(fs.combine(absoluteFilePath, "objects")) - -local file = fs.open(fs.combine(absoluteFilePath, "mainTop.lua"), "r") -basalt = basalt..file.readAll().."\n" -file.close() - -local file = fs.open(fs.combine(absoluteFilePath, "defaultTheme.lua"), "r") -basalt = basalt..file.readAll().."\n" -file.close() - -for _,v in pairs(lib)do - local path = fs.combine(fs.combine(absoluteFilePath, "lib"), v) - if not(fs.isDir(path))then - local file = fs.open(path, "r") - basalt = basalt..file.readAll().."\n" - file.close() - end -end - -local file = fs.open(fs.combine(absoluteFilePath, "Object.lua"), "r") -basalt = basalt..file.readAll().."\n" -file.close() - -for _,v in pairs(objects)do - if(v~="example.lua")then - local path = fs.combine(fs.combine(absoluteFilePath, "objects"), v) - if not(fs.isDir(path))then - local file = fs.open(path, "r") - basalt = basalt..file.readAll().."\n" - file.close() - end - end -end - -local file = fs.open(fs.combine(absoluteFilePath, "Frame.lua"), "r") -basalt = basalt..file.readAll().."\n" -file.close() - -local file = fs.open(fs.combine(absoluteFilePath, "mainBottom.lua"), "r") -basalt = basalt..file.readAll().."\n" -file.close() - ---local b = fs.open(fs.combine(absoluteFilePath, "basalt.lua"), "w") ---b.write(basalt) ---b.close() -return basalt \ No newline at end of file diff --git a/oldVersions/lastVersion/source/project/Frame.lua b/oldVersions/lastVersion/source/project/Frame.lua deleted file mode 100644 index d397c07..0000000 --- a/oldVersions/lastVersion/source/project/Frame.lua +++ /dev/null @@ -1,657 +0,0 @@ -local function Frame(name, parent) - -- Frame - local base = Object(name) - local objectType = "Frame" - local objects = {} - local objZIndex = {} - local object = {} - local termObject = parentTerminal - - local monSide = "" - local isMonitor = false - local monitorAttached = false - local dragXOffset = 0 - local dragYOffset = 0 - - base:setZIndex(10) - - local drawHelper = basaltDrawHelper(termObject) - - local cursorBlink = false - local xCursor = 1 - local yCursor = 1 - local cursorColor = colors.white - - local xOffset, yOffset = 0, 0 - - if (parent ~= nil) then - base.parent = parent - base.width, base.height = parent:getSize() - base.bgColor = theme.FrameBG - base.fgColor = theme.FrameFG - else - base.width, base.height = termObject.getSize() - base.bgColor = theme.basaltBG - base.fgColor = theme.basaltFG - end - - local function getObject(name) - for _, value in pairs(objects) do - for _, b in pairs(value) do - if (b.name == name) then - return value - end - end - end - end - - local function addObject(obj) - local zIndex = obj:getZIndex() - if (getObject(obj.name) ~= nil) then - return nil - end - if (objects[zIndex] == nil) then - for x = 1, #objZIndex + 1 do - if (objZIndex[x] ~= nil) then - if (zIndex == objZIndex[x]) then - break - end - if (zIndex > objZIndex[x]) then - table.insert(objZIndex, x, zIndex) - break - end - else - table.insert(objZIndex, zIndex) - end - end - if (#objZIndex <= 0) then - table.insert(objZIndex, zIndex) - end - objects[zIndex] = {} - end - obj.parent = object - table.insert(objects[zIndex], obj) - return obj - end - - local function removeObject(obj) - for a, b in pairs(objects) do - for key, value in pairs(b) do - if (value == obj) then - table.remove(objects[a], key) - return true; - end - end - end - return false - end - - object = { - barActive = false, - barBackground = colors.gray, - barTextcolor = colors.black, - barText = "New Frame", - barTextAlign = "left", - isMoveable = false, - - getType = function(self) - return objectType - end; - - setFocusedObject = function(self, obj) - if (focusedObject ~= nil) then - focusedObject:loseFocusHandler() - focusedObject = nil - end - if(obj~=nil)then - focusedObject = obj - obj:getFocusHandler() - end - return self - end; - - setSize = function(self, w, h) - base.setSize(self, w, h) - for _, index in pairs(objZIndex) do - if (objects[index] ~= nil) then - for _, value in pairs(objects[index]) do - if (value.eventHandler ~= nil) then - value:sendEvent("basalt_resize", value, self) - end - end - end - end - return self - end; - - setOffset = function(self, xO, yO) - xOffset = xO ~= nil and math.floor(xO < 0 and math.abs(xO) or -xO) or xOffset - yOffset = yO ~= nil and math.floor(yO < 0 and math.abs(yO) or -yO) or yOffset - return self - end; - - getFrameOffset = function(self) -- internal - return xOffset, yOffset - end; - - removeFocusedObject = function(self) - if (focusedObject ~= nil) then - focusedObject:loseFocusHandler() - end - focusedObject = nil - return self - end; - - getFocusedObject = function(self) - return focusedObject - end; - - setCursor = function(self, _blink, _xCursor, _yCursor, color) - if(self.parent~=nil)then - local obx, oby = self:getAnchorPosition() - self.parent:setCursor(_blink or false, (_xCursor or 0)+obx-1, (_yCursor or 0)+oby-1, color or cursorColor) - else - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - cursorBlink = _blink or false - if (_xCursor ~= nil) then - xCursor = obx + _xCursor - 1 - end - if (_yCursor ~= nil) then - yCursor = oby + _yCursor - 1 - end - cursorColor = color or cursorColor - self:setVisualChanged() - end - return self - end; - - setMoveable = function(self, moveable) - self.isMoveable = moveable or not self.isMoveable - self:setVisualChanged() - return self; - end; - - show = function(self) - base.show(self) - if(self.parent==nil)then - activeFrame = self; - if(isMonitor)then - monFrames[monSide] = self; - else - mainFrame = self; - end - end - return self; - end; - - hide = function (self) - base.hide(self) - if(self.parent==nil)then - if(activeFrame == self)then activeFrame = nil end - if(isMonitor)then - if(monFrames[monSide] == self)then - monFrames[monSide] = nil; - end - else - if(mainFrame == self)then - mainFrame = nil; - end - end - end - return self - end; - - - showBar = function(self, showIt) - self.barActive = showIt or not self.barActive - self:setVisualChanged() - return self - end; - - setBar = function(self, text, bgCol, fgCol) - self.barText = text or "" - self.barBackground = bgCol or self.barBackground - self.barTextcolor = fgCol or self.barTextcolor - self:setVisualChanged() - return self - end; - - setBarTextAlign = function(self, align) - self.barTextAlign = align or "left" - self:setVisualChanged() - return self - end; - - setMonitor = function(self, side) - if(side~=nil)and(side~=false)then - if(peripheral.getType(side)=="monitor")then - termObject = peripheral.wrap(side) - monitorAttached = true - end - isMonitor = true - else - termObject = parentTerminal - isMonitor = false - if(monFrames[monSide]==self)then - monFrames[monSide] = nil - end - end - drawHelper = basaltDrawHelper(termObject) - monSide = side or nil - return self; - end; - - getVisualChanged = function(self) - local changed = base.getVisualChanged(self) - for _, index in pairs(objZIndex) do - if (objects[index] ~= nil) then - for _, value in pairs(objects[index]) do - if (value.getVisualChanged ~= nil and value:getVisualChanged()) then - changed = true - end - end - end - end - return changed - end; - - loseFocusHandler = function(self) - base.loseFocusHandler(self) - end; - - getFocusHandler = function(self) - base.getFocusHandler(self) - if (self.parent ~= nil) then - self.parent:removeObject(self) - self.parent:addObject(self) - end - end; - - keyHandler = function(self, event, key) - if (focusedObject ~= nil) then - if(focusedObject~=self)then - if (focusedObject.keyHandler ~= nil) then - if (focusedObject:keyHandler(event, key)) then - return true - end - end - else - base.keyHandler(self, event, key) - end - end - return false - end; - - backgroundKeyHandler = function(self, event, key) - base.backgroundKeyHandler(self, event, key) - for _, index in pairs(objZIndex) do - if (objects[index] ~= nil) then - for _, value in pairs(objects[index]) do - if (value.backgroundKeyHandler ~= nil) then - value:backgroundKeyHandler(event, key) - end - end - end - end - end; - - eventHandler = function(self, event, p1, p2, p3, p4) - base.eventHandler(self, event, p1, p2, p3, p4) - for _, index in pairs(objZIndex) do - if (objects[index] ~= nil) then - for _, value in pairs(objects[index]) do - if (value.eventHandler ~= nil) then - value:eventHandler(event, p1, p2, p3, p4) - end - end - end - end - if(isMonitor)then - if(event == "peripheral")and(p1==monSide)then - if(peripheral.getType(monSide)=="monitor")then - monitorAttached = true - termObject = peripheral.wrap(monSide) - drawHelper = basaltDrawHelper(termObject) - end - end - if(event == "peripheral_detach")and(p1==monSide)then - monitorAttached = false - end - end - if (event == "terminate") then - termObject.clear() - termObject.setCursorPos(1, 1) - basalt.stop() - end - end; - - mouseHandler = function(self, event, button, x, y) - local xO, yO = self:getOffset() - xO = xO < 0 and math.abs(xO) or -xO - yO = yO < 0 and math.abs(yO) or -yO - if (self.drag) then - if (event == "mouse_drag") then - local parentX = 1; - local parentY = 1 - if (self.parent ~= nil) then - parentX, parentY = self.parent:getAbsolutePosition(self.parent:getAnchorPosition()) - end - self:setPosition(x + dragXOffset - (parentX - 1) + xO, y + dragYOffset - (parentY - 1) + yO) - end - if (event == "mouse_up") then - self.drag = false - end - return true - end - - local objX, objY = self:getAbsolutePosition(self:getAnchorPosition()) - local yOff = false - if(objY-1 == y)and(self:getBorder("top"))then - y = y+1 - yOff = true - end - - if (base.mouseHandler(self, event, button, x, y)) then - local fx, fy = self:getAbsolutePosition(self:getAnchorPosition()) - fx = fx + xOffset;fy = fy + yOffset; - for _, index in pairs(objZIndex) do - if (objects[index] ~= nil) then - for _, value in rpairs(objects[index]) do - if (value.mouseHandler ~= nil) then - if (value:mouseHandler(event, button, x, y)) then - return true - end - end - end - end - end - if (self.isMoveable) then - local fx, fy = self:getAbsolutePosition(self:getAnchorPosition()) - if (x >= fx) and (x <= fx + self.width - 1) and (y == fy) and (event == "mouse_click") then - self.drag = true - dragXOffset = fx - x - dragYOffset = yOff and 1 or 0 - end - end - if (focusedObject ~= nil) then - focusedObject:loseFocusHandler() - focusedObject = nil - end - return true - end - return false - end; - - setText = function(self, x, y, text) - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - if (y >= 1) and (y <= self.height) then - if (self.parent ~= nil) then - local parentX, parentY = self.parent:getAnchorPosition() - self.parent:setText(math.max(x + (obx - 1), obx) - (parentX - 1), oby + y - 1 - (parentY - 1), sub(text, math.max(1 - x + 1, 1), math.max(self.width - x + 1,1))) - else - drawHelper.setText(math.max(x + (obx - 1), obx), oby + y - 1, sub(text, math.max(1 - x + 1, 1), math.max(self.width - x + 1,1))) -- math.max(self.width - x + 1,1) now, before: self.width - x + 1 - end - end - end; - - setBG = function(self, x, y, bgCol) - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - if (y >= 1) and (y <= self.height) then - if (self.parent ~= nil) then - local parentX, parentY = self.parent:getAnchorPosition() - self.parent:setBG(math.max(x + (obx - 1), obx) - (parentX - 1), oby + y - 1 - (parentY - 1), sub(bgCol, math.max(1 - x + 1, 1), math.max(self.width - x + 1,1))) - else - drawHelper.setBG(math.max(x + (obx - 1), obx), oby + y - 1, sub(bgCol, math.max(1 - x + 1, 1), math.max(self.width - x + 1,1))) - end - end - end; - - setFG = function(self, x, y, fgCol) - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - if (y >= 1) and (y <= self.height) then - if (self.parent ~= nil) then - local parentX, parentY = self.parent:getAnchorPosition() - self.parent:setFG(math.max(x + (obx - 1), obx) - (parentX - 1), oby + y - 1 - (parentY - 1), sub(fgCol, math.max(1 - x + 1, 1), math.max(self.width - x + 1,1))) - else - drawHelper.setFG(math.max(x + (obx - 1), obx), oby + y - 1, sub(fgCol, math.max(1 - x + 1, 1), math.max(self.width - x + 1,1))) - end - end - end; - - writeText = function(self, x, y, text, bgCol, fgCol) - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - if (y >= 1) and (y <= self.height) then - if (self.parent ~= nil) then - local parentX, parentY = self.parent:getAnchorPosition() - self.parent:writeText(math.max(x + (obx - 1), obx) - (parentX - 1), oby + y - 1 - (parentY - 1), sub(text, math.max(1 - x + 1, 1), self.width - x + 1), bgCol, fgCol) - else - drawHelper.writeText(math.max(x + (obx - 1), obx), oby + y - 1, sub(text, math.max(1 - x + 1, 1), math.max(self.width - x + 1,1)), bgCol, fgCol) - end - end - end; - - drawBackgroundBox = function(self, x, y, width, height, bgCol) - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - height = (y < 1 and (height + y > self.height and self.height or height + y - 1) or (height + y > self.height and self.height - y + 1 or height)) - width = (x < 1 and (width + x > self.width and self.width or width + x - 1) or (width + x > self.width and self.width - x + 1 or width)) - if (self.parent ~= nil) then - local parentX, parentY = self.parent:getAnchorPosition() - self.parent:drawBackgroundBox(math.max(x + (obx - 1), obx) - (parentX - 1), math.max(y + (oby - 1), oby) - (parentY - 1), width, height, bgCol) - else - drawHelper.drawBackgroundBox(math.max(x + (obx - 1), obx), math.max(y + (oby - 1), oby), width, height, bgCol) - end - end; - - drawTextBox = function(self, x, y, width, height, symbol) - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - height = (y < 1 and (height + y > self.height and self.height or height + y - 1) or (height + y > self.height and self.height - y + 1 or height)) - width = (x < 1 and (width + x > self.width and self.width or width + x - 1) or (width + x > self.width and self.width - x + 1 or width)) - if (self.parent ~= nil) then - local parentX, parentY = self.parent:getAnchorPosition() - self.parent:drawTextBox(math.max(x + (obx - 1), obx) - (parentX - 1), math.max(y + (oby - 1), oby) - (parentY - 1), width, height, symbol:sub(1, 1)) - else - drawHelper.drawTextBox(math.max(x + (obx - 1), obx), math.max(y + (oby - 1), oby), width, height, symbol:sub(1, 1)) - end - end; - - drawForegroundBox = function(self, x, y, width, height, fgCol) - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - height = (y < 1 and (height + y > self.height and self.height or height + y - 1) or (height + y > self.height and self.height - y + 1 or height)) - width = (x < 1 and (width + x > self.width and self.width or width + x - 1) or (width + x > self.width and self.width - x + 1 or width)) - if (self.parent ~= nil) then - local parentX, parentY = self.parent:getAnchorPosition() - self.parent:drawForegroundBox(math.max(x + (obx - 1), obx) - (parentX - 1), math.max(y + (oby - 1), oby) - (parentY - 1), width, height, fgCol) - else - drawHelper.drawForegroundBox(math.max(x + (obx - 1), obx), math.max(y + (oby - 1), oby), width, height, fgCol) - end - end; - - draw = function(self) - if(isMonitor)and not(monitorAttached)then return false end; - if (self:getVisualChanged()) then - if (base.draw(self)) then - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - local anchx, anchy = self:getAnchorPosition() - if (self.parent ~= nil) then - if(self.bgColor~=false)then - self.parent:drawBackgroundBox(anchx, anchy, self.width, self.height, self.bgColor) - self.parent:drawTextBox(anchx, anchy, self.width, self.height, " ") - end - if(self.bgColor~=false)then self.parent:drawForegroundBox(anchx, anchy, self.width, self.height, self.fgColor) end - else - if(self.bgColor~=false)then - drawHelper.drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - drawHelper.drawTextBox(obx, oby, self.width, self.height, " ") - end - if(self.fgColor~=false)then drawHelper.drawForegroundBox(obx, oby, self.width, self.height, self.fgColor) end - end - termObject.setCursorBlink(false) - if (self.barActive) then - if (self.parent ~= nil) then - self.parent:writeText(anchx, anchy, getTextHorizontalAlign(self.barText, self.width, self.barTextAlign), self.barBackground, self.barTextcolor) - else - drawHelper.writeText(obx, oby, getTextHorizontalAlign(self.barText, self.width, self.barTextAlign), self.barBackground, self.barTextcolor) - end - if(self:getBorder("left"))then - if (self.parent ~= nil) then - self.parent:drawBackgroundBox(anchx-1, anchy, 1, 1, self.barBackground) - if(self.bgColor~=false)then - self.parent:drawBackgroundBox(anchx-1, anchy+1, 1, self.height-1, self.bgColor) - end - end - end - if(self:getBorder("top"))then - if (self.parent ~= nil) then - self.parent:drawBackgroundBox(anchx-1, anchy-1, self.width+1, 1, self.barBackground) - end - end - end - - for _, index in rpairs(objZIndex) do - if (objects[index] ~= nil) then - for _, value in pairs(objects[index]) do - if (value.draw ~= nil) then - value:draw() - end - end - end - end - - if (cursorBlink) then - termObject.setTextColor(cursorColor) - termObject.setCursorPos(xCursor, yCursor) - if (self.parent ~= nil) then - termObject.setCursorBlink(self:isFocused()) - else - termObject.setCursorBlink(cursorBlink) - end - end - self:setVisualChanged(false) - end - end - end; - - drawUpdate = function(self) - if(isMonitor)and not(monitorAttached)then return false end; - drawHelper.update() - end; - - addObject = function(self, obj) - return addObject(obj) - end; - - removeObject = function(self, obj) - return removeObject(obj) - end; - - getObject = function(self, obj) - return getObject(obj) - end; - - addButton = function(self, name) - local obj = Button(name) - obj.name = name - return addObject(obj) - end; - - addLabel = function(self, name) - local obj = Label(name) - obj.bgColor = self.bgColor - obj.fgColor = self.fgColor - return addObject(obj) - end; - - addCheckbox = function(self, name) - local obj = Checkbox(name) - return addObject(obj) - end; - - addInput = function(self, name) - local obj = Input(name) - return addObject(obj) - end; - - addProgram = function(self, name) - local obj = Program(name) - return addObject(obj) - end; - - addTextfield = function(self, name) - local obj = Textfield(name) - return addObject(obj) - end; - - addList = function(self, name) - local obj = List(name) - obj.name = nam - return addObject(obj) - end; - - addDropdown = function(self, name) - local obj = Dropdown(name) - return addObject(obj) - end; - - addRadio = function(self, name) - local obj = Radio(name) - return addObject(obj) - end; - - addTimer = function(self, name) - local obj = Timer(name) - return addObject(obj) - end; - - addAnimation = function(self, name) - local obj = Animation(name) - return addObject(obj) - end; - - addSlider = function(self, name) - local obj = Slider(name) - return addObject(obj) - end; - - addScrollbar = function(self, name) - local obj = Scrollbar(name) - return addObject(obj) - end; - - addMenubar = function(self, name) - local obj = Menubar(name) - return addObject(obj) - end; - - addThread = function(self, name) - local obj = Thread(name) - return addObject(obj) - end; - - addPane = function(self, name) - local obj = Pane(name) - return addObject(obj) - end; - - addImage = function(self, name) - local obj = Image(name) - return addObject(obj) - end; - - addProgressbar = function(self, name) - local obj = Progressbar(name) - return addObject(obj) - end; - - addSwitch = function(self, name) - local obj = Switch(name) - return addObject(obj) - end; - - addFrame = function(self, name) - local obj = Frame(name, self) - return addObject(obj) - end; - } - setmetatable(object, base) - return object -end \ No newline at end of file diff --git a/oldVersions/lastVersion/source/project/Object.lua b/oldVersions/lastVersion/source/project/Object.lua deleted file mode 100644 index a895e43..0000000 --- a/oldVersions/lastVersion/source/project/Object.lua +++ /dev/null @@ -1,573 +0,0 @@ -local function Object(name) - -- Base object - local objectType = "Object" -- not changeable - local value - local zIndex = 1 - local anchor = "topLeft" - local ignOffset = false - local isVisible = false - - local shadow = false - local borderLeft = false - local borderTop = false - local borderRight = false - local borderBottom = false - - local shadowColor = colors.black - local borderColor = colors.black - - local visualsChanged = true - - local eventSystem = BasaltEvents() - - local object = { - x = 1, - y = 1, - width = 1, - height = 1, - bgColor = colors.black, - fgColor = colors.white, - name = name or "Object", - parent = nil, - - show = function(self) - isVisible = true - visualsChanged = true - return self - end; - - hide = function(self) - isVisible = false - visualsChanged = true - return self - end; - - isVisible = function(self) - return isVisible - end; - - setFocus = function(self) - if (self.parent ~= nil) then - self.parent:setFocusedObject(self) - end - return self - end; - - setZIndex = function(self, index) - zIndex = index - if (self.parent ~= nil) then - self.parent:removeObject(self) - self.parent:addObject(self) - end - return self - end; - - getZIndex = function(self) - return zIndex; - end; - - getType = function(self) - return objectType - end; - - getName = function(self) - return self.name - end; - - remove = function(self) - if (self.parent ~= nil) then - self.parent:removeObject(self) - end - return self - end; - - setParent = function(self, frame) - if (frame.getType ~= nil and frame:getType() == "Frame") then - self:remove() - frame:addObject(self) - if (self.draw) then - self:show() - end - end - return self - end; - - setValue = function(self, _value) - if (value ~= _value) then - value = _value - visualsChanged = true - self:valueChangedHandler() - end - return self - end; - - getValue = function(self) - return value - end; - - getVisualChanged = function(self) - return visualsChanged - end; - - setVisualChanged = function(self, change) - visualsChanged = change or true - if(change == nil)then visualsChanged = true end - return self - end; - - - getEventSystem = function(self) - return eventSystem - end; - - - getParent = function(self) - return self.parent - end; - - setPosition = function(self, xPos, yPos, rel) - if (rel) then - self.x, self.y = math.floor(self.x + xPos), math.floor(self.y + yPos) - else - self.x, self.y = math.floor(xPos), math.floor(yPos) - end - visualsChanged = true - return self - end; - - getPosition = function(self) - return self.x, self.y - end; - - getVisibility = function(self) - return isVisible - end; - - setVisibility = function(self, _isVisible) - isVisible = _isVisible or not isVisible - visualsChanged = true - return self - end; - - setSize = function(self, width, height) - self.width, self.height = width, height - eventSystem:sendEvent("basalt_resize", self) - visualsChanged = true - return self - end; - - getHeight = function(self) - return self.height - end; - - getWidth = function(self) - return self.width - end; - - getSize = function(self) - return self.width, self.height - end; - - setBackground = function(self, color) - self.bgColor = color - visualsChanged = true - return self - end; - - getBackground = function(self) - return self.bgColor - end; - - setForeground = function(self, color) - self.fgColor = color - visualsChanged = true - return self - end; - - getForeground = function(self) - return self.fgColor - end; - - showShadow = function(self, show) - shadow = show or (not shadow) - return self - end; - - setShadow = function(self, color) - shadowColor = color - return self - end; - - isShadowActive = function(self) - return shadow; - end; - - showBorder = function(self, ...) - for _,v in pairs(table.pack(...))do - if(v=="left")then - borderLeft = true - end - if(v=="top")then - borderTop = true - end - if(v=="right")then - borderRight = true - end - if(v=="bottom")then - borderBottom = true - end - end - return self - end; - - setBorder = function(self, color) - shadowColor = color - return self - end; - - getBorder = function(self, side) - if(side=="left")then - return borderLeft; - end - if(side=="top")then - return borderTop; - end - if(side=="right")then - return borderRight; - end - if(side=="bottom")then - return borderBottom; - end - end; - - draw = function(self) - if (isVisible) then - if(self.parent~=nil)then - local x, y = self:getAnchorPosition() - if(shadow)then - self.parent:drawBackgroundBox(x+1, y+self.height, self.width, 1, shadowColor) - self.parent:drawBackgroundBox(x+self.width, y+1, 1, self.height, shadowColor) - self.parent:drawForegroundBox(x+1, y+self.height, self.width, 1, shadowColor) - self.parent:drawForegroundBox(x+self.width, y+1, 1, self.height, shadowColor) - end - if(borderLeft)then - self.parent:drawTextBox(x-1, y, 1, self.height, "\149") - self.parent:drawForegroundBox(x-1, y, 1, self.height, borderColor) - if(self.bgColor~=false)then self.parent:drawBackgroundBox(x-1, y, 1, self.height, self.bgColor) end - end - if(borderLeft)and(borderTop)then - self.parent:drawTextBox(x-1, y-1, 1, 1, "\151") - self.parent:drawForegroundBox(x-1, y-1, 1, 1, borderColor) - if(self.bgColor~=false)then self.parent:drawBackgroundBox(x-1, y-1, 1, 1, self.bgColor) end - end - if(borderTop)then - self.parent:drawTextBox(x, y-1, self.width, 1, "\131") - self.parent:drawForegroundBox(x, y-1, self.width, 1, borderColor) - if(self.bgColor~=false)then self.parent:drawBackgroundBox(x, y-1, self.width, 1, self.bgColor) end - end - if(borderTop)and(borderRight)then - self.parent:drawTextBox(x+self.width, y-1, 1, 1, "\149") - self.parent:drawForegroundBox(x+self.width, y-1, 1, 1, borderColor) - end - if(borderRight)then - self.parent:drawTextBox(x+self.width, y, 1, self.height, "\149") - self.parent:drawForegroundBox(x+self.width, y, 1, self.height, borderColor) - end - if(borderRight)and(borderBottom)then - self.parent:drawTextBox(x+self.width, y+self.height, 1, 1, "\129") - self.parent:drawForegroundBox(x+self.width, y+self.height, 1, 1, borderColor) - end - if(borderBottom)then - self.parent:drawTextBox(x, y+self.height, self.width, 1, "\131") - self.parent:drawForegroundBox(x, y+self.height, self.width, 1, borderColor) - end - if(borderBottom)and(borderLeft)then - self.parent:drawTextBox(x-1, y+self.height, 1, 1, "\131") - self.parent:drawForegroundBox(x-1, y+self.height, 1, 1, borderColor) - end - end - return true - end - return false - end; - - - getAbsolutePosition = function(self, x, y) - -- relative position to absolute position - if (x == nil) or (y == nil) then - x, y = self:getAnchorPosition() - end - - if (self.parent ~= nil) then - local fx, fy = self.parent:getAbsolutePosition(self.parent:getAnchorPosition()) - x = fx + x - 1 - y = fy + y - 1 - end - return x, y - end; - - getAnchorPosition = function(self, x, y, ignOff) - if (x == nil) then - x = self.x - end - if (y == nil) then - y = self.y - end - if (anchor == "top") then - x = math.floor(self.parent.width/2) + x - 1 - elseif(anchor == "topRight") then - x = self.parent.width + x - 1 - elseif(anchor == "right") then - x = self.parent.width + x - 1 - y = math.floor(self.parent.height/2) + y - 1 - elseif(anchor == "bottomRight") then - x = self.parent.width + x - 1 - y = self.parent.height + y - 1 - elseif(anchor == "bottom") then - x = math.floor(self.parent.width/2) + x - 1 - y = self.parent.height + y - 1 - elseif(anchor == "bottomLeft") then - y = self.parent.height + y - 1 - elseif(anchor == "left") then - y = math.floor(self.parent.height/2) + y - 1 - elseif(anchor == "center") then - x = math.floor(self.parent.width/2) + x - 1 - y = math.floor(self.parent.height/2) + y - 1 - end - local xO, yO = self:getOffset() - if not(ignOffset or ignOff) then - return x+xO, y+yO - end - return x, y - end; - - getOffset = function(self) - if (self.parent ~= nil) then - return self.parent:getFrameOffset() - end - return 0, 0 - end; - - ignoreOffset = function(self, ignore) - ignOffset = ignore - if(ignore==nil)then ignOffset = true end - return self - end; - - getBaseFrame = function(self) - if(self.parent~=nil)then - return self.parent:getBaseFrame() - end - return self - end; - - setAnchor = function(self, newAnchor) - anchor = newAnchor - visualsChanged = true - return self - end; - - getAnchor = function(self) - return anchor - end; - - onChange = function(self, ...) - for _,v in pairs(table.pack(...))do - if(type(v)=="function")then - self:registerEvent("value_changed", v) - end - end - return self - end; - - onClick = function(self, ...) - for _,v in pairs(table.pack(...))do - if(type(v)=="function")then - self:registerEvent("mouse_click", v) - self:registerEvent("monitor_touch", v) - end - end - return self - end; - - onClickUp = function(self, ...) - for _,v in pairs(table.pack(...))do - if(type(v)=="function")then - self:registerEvent("mouse_up", v) - end - end - return self - end; - - - onScroll = function(self, ...) - for _,v in pairs(table.pack(...))do - if(type(v)=="function")then - self:registerEvent("mouse_scroll", v) - end - end - return self - end; - - onDrag = function(self, ...) - for _,v in pairs(table.pack(...))do - if(type(v)=="function")then - self:registerEvent("mouse_drag", v) - end - end - return self - end; - - onEvent = function(self, ...) - for _,v in pairs(table.pack(...))do - if(type(v)=="function")then - self:registerEvent("custom_event_handler", v) - end - end - return self - end; - - onKey = function(self, ...) - for _,v in pairs(table.pack(...))do - if(type(v)=="function")then - self:registerEvent("key", v) - self:registerEvent("char", v) - end - end - return self - end; - - onResize = function(self, ...) - for _,v in pairs(table.pack(...))do - if(type(v)=="function")then - self:registerEvent("basalt_resize", v) - end - end - return self - end; - - onKeyUp = function(self, ...) - for _,v in pairs(table.pack(...))do - if(type(v)=="function")then - self:registerEvent("key_up", v) - end - end - return self - end; - - onBackgroundKey = function(self, ...) - for _,v in pairs(table.pack(...))do - if(type(v)=="function")then - self:registerEvent("background_key", v) - self:registerEvent("background_char", v) - end - end - return self - end; - - onBackgroundKeyUp = function(self, ...) - for _,v in pairs(table.pack(...))do - if(type(v)=="function")then - self:registerEvent("background_key_up", v) - end - end - return self - end; - - isFocused = function(self) - if (self.parent ~= nil) then - return self.parent:getFocusedObject() == self - end - return false - end; - - onGetFocus = function(self, ...) - for _,v in pairs(table.pack(...))do - if(type(v)=="function")then - self:registerEvent("get_focus", v) - end - end - return self - end; - - onLoseFocus = function(self, ...) - for _,v in pairs(table.pack(...))do - if(type(v)=="function")then - self:registerEvent("lose_focus", v) - end - end - return self - end; - - registerEvent = function(self, event, func) - return eventSystem:registerEvent(event, func) - end; - - removeEvent = function(self, event, index) - return eventSystem:removeEvent(event, index) - end; - - sendEvent = function(self, event, ...) - return eventSystem:sendEvent(event, self, ...) - end; - - mouseHandler = function(self, event, button, x, y) - local objX, objY = self:getAbsolutePosition(self:getAnchorPosition()) - local yOff = false - if(objY-1 == y)and(self:getBorder("top"))then - y = y+1 - yOff = true - end - - if (objX <= x) and (objX + self.width > x) and (objY <= y) and (objY + self.height > y) and (isVisible) then - if (self.parent ~= nil) then - self.parent:setFocusedObject(self) - end - local val = eventSystem:sendEvent(event, self, event, button, x, y) - if(val~=nil)then return val end - return true - end - return false - end; - - keyHandler = function(self, event, key) - if (self:isFocused()) then - local val = eventSystem:sendEvent(event, self, event, key) - if(val~=nil)then return val end - return true - end - return false - end; - - backgroundKeyHandler = function(self, event, key) - local val = eventSystem:sendEvent("background_"..event, self, event, key) - if(val~=nil)then return val end - return true - end; - - valueChangedHandler = function(self) - eventSystem:sendEvent("value_changed", self) - end; - - eventHandler = function(self, event, p1, p2, p3, p4) - eventSystem:sendEvent("custom_event_handler", self, event, p1, p2, p3, p4) - end; - - getFocusHandler = function(self) - local val = eventSystem:sendEvent("get_focus", self) - if(val~=nil)then return val end - return true - end; - - loseFocusHandler = function(self) - local val = eventSystem:sendEvent("lose_focus", self) - if(val~=nil)then return val end - return true - end; - - - } - - object.__index = object - return object -end \ No newline at end of file diff --git a/oldVersions/lastVersion/source/project/defaultTheme.lua b/oldVersions/lastVersion/source/project/defaultTheme.lua deleted file mode 100644 index 309c060..0000000 --- a/oldVersions/lastVersion/source/project/defaultTheme.lua +++ /dev/null @@ -1,23 +0,0 @@ --- current version 1 -local theme = { - basaltBG = colors.lightGray, - basaltFG = colors.black, - FrameBG = colors.gray, - FrameFG = colors.black, - ButtonBG = colors.gray, - ButtonFG = colors.black, - CheckboxBG = colors.gray, - CheckboxFG = colors.black, - InputBG = colors.gray, - InputFG = colors.black, - textfieldBG = colors.gray, - textfieldFG = colors.black, - listBG = colors.gray, - listFG = colors.black, - dropdownBG = colors.gray, - dropdownFG = colors.black, - radioBG = colors.gray, - radioFG = colors.black, - selectionBG = colors.black, - selectionFG = colors.lightGray, -} \ No newline at end of file diff --git a/oldVersions/lastVersion/source/project/lib/bigfont.lua b/oldVersions/lastVersion/source/project/lib/bigfont.lua deleted file mode 100644 index 7ce3fe5..0000000 --- a/oldVersions/lastVersion/source/project/lib/bigfont.lua +++ /dev/null @@ -1,135 +0,0 @@ -------------------------------------------------------------------------------------- --- Wojbies API 5.0 - Bigfont - functions to write bigger font using drawing sybols -- -------------------------------------------------------------------------------------- --- Copyright (c) 2015-2022 Wojbie (wojbie@wojbie.net) --- Redistribution and use in source and binary forms, with or without modification, are permitted (subject to the limitations in the disclaimer below) provided that the following conditions are met: --- 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. --- 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. --- 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. --- 4. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. --- 5. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. --- NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. YOU ACKNOWLEDGE THAT THIS SOFTWARE IS NOT DESIGNED, LICENSED OR INTENDED FOR USE IN THE DESIGN, CONSTRUCTION, OPERATION OR MAINTENANCE OF ANY NUCLEAR FACILITY. - -local rawFont = {{"\32\32\32\137\156\148\158\159\148\135\135\144\159\139\32\136\157\32\159\139\32\32\143\32\32\143\32\32\32\32\32\32\32\32\147\148\150\131\148\32\32\32\151\140\148\151\140\147", "\32\32\32\149\132\149\136\156\149\144\32\133\139\159\129\143\159\133\143\159\133\138\32\133\138\32\133\32\32\32\32\32\32\150\150\129\137\156\129\32\32\32\133\131\129\133\131\132", "\32\32\32\130\131\32\130\131\32\32\129\32\32\32\32\130\131\32\130\131\32\32\32\32\143\143\143\32\32\32\32\32\32\130\129\32\130\135\32\32\32\32\131\32\32\131\32\131", "\139\144\32\32\143\148\135\130\144\149\32\149\150\151\149\158\140\129\32\32\32\135\130\144\135\130\144\32\149\32\32\139\32\159\148\32\32\32\32\159\32\144\32\148\32\147\131\132", "\159\135\129\131\143\149\143\138\144\138\32\133\130\149\149\137\155\149\159\143\144\147\130\132\32\149\32\147\130\132\131\159\129\139\151\129\148\32\32\139\131\135\133\32\144\130\151\32", "\32\32\32\32\32\32\130\135\32\130\32\129\32\129\129\131\131\32\130\131\129\140\141\132\32\129\32\32\129\32\32\32\32\32\32\32\131\131\129\32\32\32\32\32\32\32\32\32", "\32\32\32\32\149\32\159\154\133\133\133\144\152\141\132\133\151\129\136\153\32\32\154\32\159\134\129\130\137\144\159\32\144\32\148\32\32\32\32\32\32\32\32\32\32\32\151\129", "\32\32\32\32\133\32\32\32\32\145\145\132\141\140\132\151\129\144\150\146\129\32\32\32\138\144\32\32\159\133\136\131\132\131\151\129\32\144\32\131\131\129\32\144\32\151\129\32", "\32\32\32\32\129\32\32\32\32\130\130\32\32\129\32\129\32\129\130\129\129\32\32\32\32\130\129\130\129\32\32\32\32\32\32\32\32\133\32\32\32\32\32\129\32\129\32\32", "\150\156\148\136\149\32\134\131\148\134\131\148\159\134\149\136\140\129\152\131\32\135\131\149\150\131\148\150\131\148\32\148\32\32\148\32\32\152\129\143\143\144\130\155\32\134\131\148", "\157\129\149\32\149\32\152\131\144\144\131\148\141\140\149\144\32\149\151\131\148\32\150\32\150\131\148\130\156\133\32\144\32\32\144\32\130\155\32\143\143\144\32\152\129\32\134\32", "\130\131\32\131\131\129\131\131\129\130\131\32\32\32\129\130\131\32\130\131\32\32\129\32\130\131\32\130\129\32\32\129\32\32\133\32\32\32\129\32\32\32\130\32\32\32\129\32", "\150\140\150\137\140\148\136\140\132\150\131\132\151\131\148\136\147\129\136\147\129\150\156\145\138\143\149\130\151\32\32\32\149\138\152\129\149\32\32\157\152\149\157\144\149\150\131\148", "\149\143\142\149\32\149\149\32\149\149\32\144\149\32\149\149\32\32\149\32\32\149\32\149\149\32\149\32\149\32\144\32\149\149\130\148\149\32\32\149\32\149\149\130\149\149\32\149", "\130\131\129\129\32\129\131\131\32\130\131\32\131\131\32\131\131\129\129\32\32\130\131\32\129\32\129\130\131\32\130\131\32\129\32\129\131\131\129\129\32\129\129\32\129\130\131\32", "\136\140\132\150\131\148\136\140\132\153\140\129\131\151\129\149\32\149\149\32\149\149\32\149\137\152\129\137\152\129\131\156\133\149\131\32\150\32\32\130\148\32\152\137\144\32\32\32", "\149\32\32\149\159\133\149\32\149\144\32\149\32\149\32\149\32\149\150\151\129\138\155\149\150\130\148\32\149\32\152\129\32\149\32\32\32\150\32\32\149\32\32\32\32\32\32\32", "\129\32\32\130\129\129\129\32\129\130\131\32\32\129\32\130\131\32\32\129\32\129\32\129\129\32\129\32\129\32\131\131\129\130\131\32\32\32\129\130\131\32\32\32\32\140\140\132", "\32\154\32\159\143\32\149\143\32\159\143\32\159\144\149\159\143\32\159\137\145\159\143\144\149\143\32\32\145\32\32\32\145\149\32\144\32\149\32\143\159\32\143\143\32\159\143\32", "\32\32\32\152\140\149\151\32\149\149\32\145\149\130\149\157\140\133\32\149\32\154\143\149\151\32\149\32\149\32\144\32\149\149\153\32\32\149\32\149\133\149\149\32\149\149\32\149", "\32\32\32\130\131\129\131\131\32\130\131\32\130\131\129\130\131\129\32\129\32\140\140\129\129\32\129\32\129\32\137\140\129\130\32\129\32\130\32\129\32\129\129\32\129\130\131\32", "\144\143\32\159\144\144\144\143\32\159\143\144\159\138\32\144\32\144\144\32\144\144\32\144\144\32\144\144\32\144\143\143\144\32\150\129\32\149\32\130\150\32\134\137\134\134\131\148", "\136\143\133\154\141\149\151\32\129\137\140\144\32\149\32\149\32\149\154\159\133\149\148\149\157\153\32\154\143\149\159\134\32\130\148\32\32\149\32\32\151\129\32\32\32\32\134\32", "\133\32\32\32\32\133\129\32\32\131\131\32\32\130\32\130\131\129\32\129\32\130\131\129\129\32\129\140\140\129\131\131\129\32\130\129\32\129\32\130\129\32\32\32\32\32\129\32", "\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32", "\32\32\32\32\32\32\32\32\32\32\32\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\32\32\32\32\32\32\32\32\32\32\32", "\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32", "\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32", "\32\32\32\32\32\32\32\32\32\32\32\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\32\32\32\32\32\32\32\32\32\32\32", "\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32", "\32\32\32\32\145\32\159\139\32\151\131\132\155\143\132\134\135\145\32\149\32\158\140\129\130\130\32\152\147\155\157\134\32\32\144\144\32\32\32\32\32\32\152\131\155\131\131\129", "\32\32\32\32\149\32\149\32\145\148\131\32\149\32\149\140\157\132\32\148\32\137\155\149\32\32\32\149\154\149\137\142\32\153\153\32\131\131\149\131\131\129\149\135\145\32\32\32", "\32\32\32\32\129\32\130\135\32\131\131\129\134\131\132\32\129\32\32\129\32\131\131\32\32\32\32\130\131\129\32\32\32\32\129\129\32\32\32\32\32\32\130\131\129\32\32\32", "\150\150\32\32\148\32\134\32\32\132\32\32\134\32\32\144\32\144\150\151\149\32\32\32\32\32\32\145\32\32\152\140\144\144\144\32\133\151\129\133\151\129\132\151\129\32\145\32", "\130\129\32\131\151\129\141\32\32\142\32\32\32\32\32\149\32\149\130\149\149\32\143\32\32\32\32\142\132\32\154\143\133\157\153\132\151\150\148\151\158\132\151\150\148\144\130\148", "\32\32\32\140\140\132\32\32\32\32\32\32\32\32\32\151\131\32\32\129\129\32\32\32\32\134\32\32\32\32\32\32\32\129\129\32\129\32\129\129\130\129\129\32\129\130\131\32", "\156\143\32\159\141\129\153\140\132\153\137\32\157\141\32\159\142\32\150\151\129\150\131\132\140\143\144\143\141\145\137\140\148\141\141\144\157\142\32\159\140\32\151\134\32\157\141\32", "\157\140\149\157\140\149\157\140\149\157\140\149\157\140\149\157\140\149\151\151\32\154\143\132\157\140\32\157\140\32\157\140\32\157\140\32\32\149\32\32\149\32\32\149\32\32\149\32", "\129\32\129\129\32\129\129\32\129\129\32\129\129\32\129\129\32\129\129\131\129\32\134\32\131\131\129\131\131\129\131\131\129\131\131\129\130\131\32\130\131\32\130\131\32\130\131\32", "\151\131\148\152\137\145\155\140\144\152\142\145\153\140\132\153\137\32\154\142\144\155\159\132\150\156\148\147\32\144\144\130\145\136\137\32\146\130\144\144\130\145\130\136\32\151\140\132", "\151\32\149\151\155\149\149\32\149\149\32\149\149\32\149\149\32\149\149\32\149\152\137\144\157\129\149\149\32\149\149\32\149\149\32\149\149\32\149\130\150\32\32\157\129\149\32\149", "\131\131\32\129\32\129\130\131\32\130\131\32\130\131\32\130\131\32\130\131\32\32\32\32\130\131\32\130\131\32\130\131\32\130\131\32\130\131\32\32\129\32\130\131\32\133\131\32", "\156\143\32\159\141\129\153\140\132\153\137\32\157\141\32\159\142\32\159\159\144\152\140\144\156\143\32\159\141\129\153\140\132\157\141\32\130\145\32\32\147\32\136\153\32\130\146\32", "\152\140\149\152\140\149\152\140\149\152\140\149\152\140\149\152\140\149\149\157\134\154\143\132\157\140\133\157\140\133\157\140\133\157\140\133\32\149\32\32\149\32\32\149\32\32\149\32", "\130\131\129\130\131\129\130\131\129\130\131\129\130\131\129\130\131\129\130\130\131\32\134\32\130\131\129\130\131\129\130\131\129\130\131\129\32\129\32\32\129\32\32\129\32\32\129\32", "\159\134\144\137\137\32\156\143\32\159\141\129\153\140\132\153\137\32\157\141\32\32\132\32\159\143\32\147\32\144\144\130\145\136\137\32\146\130\144\144\130\145\130\138\32\146\130\144", "\149\32\149\149\32\149\149\32\149\149\32\149\149\32\149\149\32\149\149\32\149\131\147\129\138\134\149\149\32\149\149\32\149\149\32\149\149\32\149\154\143\149\32\157\129\154\143\149", "\130\131\32\129\32\129\130\131\32\130\131\32\130\131\32\130\131\32\130\131\32\32\32\32\130\131\32\130\131\129\130\131\129\130\131\129\130\131\129\140\140\129\130\131\32\140\140\129" }, {[[000110000110110000110010101000000010000000100101]], [[000000110110000000000010101000000010000000100101]], [[000000000000000000000000000000000000000000000000]], [[100010110100000010000110110000010100000100000110]], [[000000110000000010110110000110000000000000110000]], [[000000000000000000000000000000000000000000000000]], [[000000110110000010000000100000100000000000000010]], [[000000000110110100010000000010000000000000000100]], [[000000000000000000000000000000000000000000000000]], [[010000000000100110000000000000000000000110010000]], [[000000000000000000000000000010000000010110000000]], [[000000000000000000000000000000000000000000000000]], [[011110110000000100100010110000000100000000000000]], [[000000000000000000000000000000000000000000000000]], [[000000000000000000000000000000000000000000000000]], [[110000110110000000000000000000010100100010000000]], [[000010000000000000110110000000000100010010000000]], [[000000000000000000000000000000000000000000000000]], [[010110010110100110110110010000000100000110110110]], [[000000000000000000000110000000000110000000000000]], [[000000000000000000000000000000000000000000000000]], [[010100010110110000000000000000110000000010000000]], [[110110000000000000110000110110100000000010000000]], [[000000000000000000000000000000000000000000000000]], [[000100011111000100011111000100011111000100011111]], [[000000000000100100100100011011011011111111111111]], [[000000000000000000000000000000000000000000000000]], [[000100011111000100011111000100011111000100011111]], [[000000000000100100100100011011011011111111111111]], [[100100100100100100100100100100100100100100100100]], [[000000110100110110000010000011110000000000011000]], [[000000000100000000000010000011000110000000001000]], [[000000000000000000000000000000000000000000000000]], [[010000100100000000000000000100000000010010110000]], [[000000000000000000000000000000110110110110110000]], [[000000000000000000000000000000000000000000000000]], [[110110110110110110000000110110110110110110110110]], [[000000000000000000000110000000000000000000000000]], [[000000000000000000000000000000000000000000000000]], [[000000000000110110000110010000000000000000010010]], [[000010000000000000000000000000000000000000000000]], [[000000000000000000000000000000000000000000000000]], [[110110110110110110110000110110110110000000000000]], [[000000000000000000000110000000000000000000000000]], [[000000000000000000000000000000000000000000000000]], [[110110110110110110110000110000000000000000010000]], [[000000000000000000000000100000000000000110000110]], [[000000000000000000000000000000000000000000000000]] }} - ---### Genarate fonts using 3x3 chars per a character. (1 character is 6x9 pixels) -local fonts = {} -local firstFont = {} -do - local char = 0 - local height = #rawFont[1] - local length = #rawFont[1][1] - for i = 1, height, 3 do - for j = 1, length, 3 do - local thisChar = string.char(char) - - local temp = {} - temp[1] = rawFont[1][i]:sub(j, j + 2) - temp[2] = rawFont[1][i + 1]:sub(j, j + 2) - temp[3] = rawFont[1][i + 2]:sub(j, j + 2) - - local temp2 = {} - temp2[1] = rawFont[2][i]:sub(j, j + 2) - temp2[2] = rawFont[2][i + 1]:sub(j, j + 2) - temp2[3] = rawFont[2][i + 2]:sub(j, j + 2) - - firstFont[thisChar] = {temp, temp2} - char = char + 1 - end - end - fonts[1] = firstFont -end - -local function generateFontSize(size,yeld) - local inverter = {["0"] = "1", ["1"] = "0"} --:gsub("[01]",inverter) - if size<= #fonts then return true end - for f = #fonts+1, size do - --automagicly make bigger fonts using firstFont and fonts[f-1]. - local nextFont = {} - local lastFont = fonts[f - 1] - for char = 0, 255 do - local thisChar = string.char(char) - --sleep(0) print(f,thisChar) - - local temp = {} - local temp2 = {} - - local templateChar = lastFont[thisChar][1] - local templateBack = lastFont[thisChar][2] - for i = 1, #templateChar do - local line1, line2, line3, back1, back2, back3 = {}, {}, {}, {}, {}, {} - for j = 1, #templateChar[1] do - local currentChar = firstFont[templateChar[i]:sub(j, j)][1] - table.insert(line1, currentChar[1]) - table.insert(line2, currentChar[2]) - table.insert(line3, currentChar[3]) - - local currentBack = firstFont[templateChar[i]:sub(j, j)][2] - if templateBack[i]:sub(j, j) == "1" then - table.insert(back1, (currentBack[1]:gsub("[01]", inverter))) - table.insert(back2, (currentBack[2]:gsub("[01]", inverter))) - table.insert(back3, (currentBack[3]:gsub("[01]", inverter))) - else - table.insert(back1, currentBack[1]) - table.insert(back2, currentBack[2]) - table.insert(back3, currentBack[3]) - end - end - table.insert(temp, table.concat(line1)) - table.insert(temp, table.concat(line2)) - table.insert(temp, table.concat(line3)) - table.insert(temp2, table.concat(back1)) - table.insert(temp2, table.concat(back2)) - table.insert(temp2, table.concat(back3)) - end - - nextFont[thisChar] = {temp, temp2} - if yeld then yeld = "Font"..f.."Yeld"..char os.queueEvent(yeld) os.pullEvent(yeld) end - end - fonts[f] = nextFont - end - return true -end - -local function makeText(nSize, sString, nFC, nBC, bBlit) - if not type(sString) == "string" then error("Not a String",3) end --this should never happend with expects in place. - local cFC = type(nFC) == "string" and nFC:sub(1, 1) or tHex[nFC] or error("Wrong Front Color",3) - local cBC = type(nBC) == "string" and nBC:sub(1, 1) or tHex[nBC] or error("Wrong Back Color",3) - if(fonts[nSize]==nil)then generateFontSize(3,false) end - local font = fonts[nSize] or error("Wrong font size selected",3) - if sString == "" then return {{""}, {""}, {""}} end - - local input = {} - for i in sString:gmatch('.') do table.insert(input, i) end - - local tText = {} - local height = #font[input[1]][1] - - - for nLine = 1, height do - local outLine = {} - for i = 1, #input do - outLine[i] = font[input[i]] and font[input[i]][1][nLine] or "" - end - tText[nLine] = table.concat(outLine) - end - - local tFront = {} - local tBack = {} - local tFrontSub = {["0"] = cFC, ["1"] = cBC} - local tBackSub = {["0"] = cBC, ["1"] = cFC} - - for nLine = 1, height do - local front = {} - local back = {} - for i = 1, #input do - local template = font[input[i]] and font[input[i]][2][nLine] or "" - front[i] = template:gsub("[01]", bBlit and {["0"] = nFC:sub(i, i), ["1"] = nBC:sub(i, i)} or tFrontSub) - back[i] = template:gsub("[01]", bBlit and {["0"] = nBC:sub(i, i), ["1"] = nFC:sub(i, i)} or tBackSub) - end - tFront[nLine] = table.concat(front) - tBack[nLine] = table.concat(back) - end - - return {tText, tFront, tBack} -end \ No newline at end of file diff --git a/oldVersions/lastVersion/source/project/lib/drawHelper.lua b/oldVersions/lastVersion/source/project/lib/drawHelper.lua deleted file mode 100644 index 13b6bbb..0000000 --- a/oldVersions/lastVersion/source/project/lib/drawHelper.lua +++ /dev/null @@ -1,181 +0,0 @@ -local function basaltDrawHelper(drawTerm) - local terminal = drawTerm - local width, height = terminal.getSize() - local cacheT = {} - local cacheBG = {} - local cacheFG = {} - - local _cacheT = {} - local _cacheBG = {} - local _cacheFG = {} - - local emptySpaceLine - local emptyColorLines = {} - - local function createEmptyLines() - emptySpaceLine = (" "):rep(width) - for n = 0, 15 do - local nColor = 2 ^ n - local sHex = tHex[nColor] - emptyColorLines[nColor] = sHex:rep(width) - end - end - ---- - createEmptyLines() - - local function recreateWindowArray() - local emptyText = emptySpaceLine - local emptyFG = emptyColorLines[colors.white] - local emptyBG = emptyColorLines[colors.black] - for currentY = 1, height do - cacheT[currentY] = sub(cacheT[currentY] == nil and emptyText or cacheT[currentY] .. emptyText:sub(1, width - cacheT[currentY]:len()), 1, width) - cacheFG[currentY] = sub(cacheFG[currentY] == nil and emptyFG or cacheFG[currentY] .. emptyFG:sub(1, width - cacheFG[currentY]:len()), 1, width) - cacheBG[currentY] = sub(cacheBG[currentY] == nil and emptyBG or cacheBG[currentY] .. emptyBG:sub(1, width - cacheBG[currentY]:len()), 1, width) - end - end - recreateWindowArray() - - local function setText(x, y, text) - if (y >= 1) and (y <= height) then - if (x + text:len() > 0) and (x <= width) then - local oldCache = cacheT[y] - local newCache - local nEnd = x + #text - 1 - - if (x < 1) then - local startN = 1 - x + 1 - local endN = width - x + 1 - text = sub(text, startN, endN) - elseif (nEnd > width) then - local endN = width - x + 1 - text = sub(text, 1, endN) - end - - if (x > 1) then - local endN = x - 1 - newCache = sub(oldCache, 1, endN) .. text - else - newCache = text - end - if nEnd < width then - newCache = newCache .. sub(oldCache, nEnd + 1, width) - end - cacheT[y] = newCache - end - end - end - - local function setBG(x, y, colorStr) - if (y >= 1) and (y <= height) then - if (x + colorStr:len() > 0) and (x <= width) then - local oldCache = cacheBG[y] - local newCache - local nEnd = x + #colorStr - 1 - - if (x < 1) then - colorStr = sub(colorStr, 1 - x + 1, width - x + 1) - elseif (nEnd > width) then - colorStr = sub(colorStr, 1, width - x + 1) - end - - if (x > 1) then - newCache = sub(oldCache, 1, x - 1) .. colorStr - else - newCache = colorStr - end - if nEnd < width then - newCache = newCache .. sub(oldCache, nEnd + 1, width) - end - cacheBG[y] = newCache - end - end - end - - local function setFG(x, y, colorStr) - if (y >= 1) and (y <= height) then - if (x + colorStr:len() > 0) and (x <= width) then - local oldCache = cacheFG[y] - local newCache - local nEnd = x + #colorStr - 1 - - if (x < 1) then - local startN = 1 - x + 1 - local endN = width - x + 1 - colorStr = sub(colorStr, startN, endN) - elseif (nEnd > width) then - local endN = width - x + 1 - colorStr = sub(colorStr, 1, endN) - end - - if (x > 1) then - local endN = x - 1 - newCache = sub(oldCache, 1, endN) .. colorStr - else - newCache = colorStr - end - if nEnd < width then - newCache = newCache .. sub(oldCache, nEnd + 1, width) - end - cacheFG[y] = newCache - end - end - end - - local drawHelper = { - setBG = function(x, y, colorStr) - setBG(x, y, colorStr) - end; - - setText = function(x, y, text) - setText(x, y, text) - end; - - setFG = function(x, y, colorStr) - setFG(x, y, colorStr) - end; - - drawBackgroundBox = function(x, y, width, height, bgCol) - for n = 1, height do - setBG(x, y + (n - 1), tHex[bgCol]:rep(width)) - end - end; - drawForegroundBox = function(x, y, width, height, fgCol) - for n = 1, height do - setFG(x, y + (n - 1), tHex[fgCol]:rep(width)) - end - end; - drawTextBox = function(x, y, width, height, symbol) - for n = 1, height do - setText(x, y + (n - 1), symbol:rep(width)) - end - end; - writeText = function(x, y, text, bgCol, fgCol) - bgCol = bgCol or terminal.getBackgroundColor() - fgCol = fgCol or terminal.getTextColor() - setText(x, y, text) - setBG(x, y, tHex[bgCol]:rep(text:len())) - setFG(x, y, tHex[fgCol]:rep(text:len())) - end; - - update = function() - local xC, yC = terminal.getCursorPos() - local isBlinking = false - if (terminal.getCursorBlink ~= nil) then - isBlinking = terminal.getCursorBlink() - end - terminal.setCursorBlink(false) - for n = 1, height do - terminal.setCursorPos(1, n) - terminal.blit(cacheT[n], cacheFG[n], cacheBG[n]) - end - terminal.setBackgroundColor(colors.black) - terminal.setCursorBlink(isBlinking) - terminal.setCursorPos(xC, yC) - end; - - setTerm = function(newTerm) - terminal = newTerm; - end; - } - return drawHelper -end \ No newline at end of file diff --git a/oldVersions/lastVersion/source/project/lib/eventSystem.lua b/oldVersions/lastVersion/source/project/lib/eventSystem.lua deleted file mode 100644 index 84f6421..0000000 --- a/oldVersions/lastVersion/source/project/lib/eventSystem.lua +++ /dev/null @@ -1,37 +0,0 @@ -local function BasaltEvents() - - local events = {} - local index = {} - - local event = { - registerEvent = function(self, _event, func) - if (events[_event] == nil) then - events[_event] = {} - index[_event] = 1 - end - events[_event][index[_event]] = func - index[_event] = index[_event] + 1 - return index[_event] - 1 - end; - - removeEvent = function(self, _event, index) - events[_event][index[_event]] = nil - end; - - sendEvent = function(self, _event, ...) - local returnValue - if (events[_event] ~= nil) then - for _, value in pairs(events[_event]) do - local val = value(...) - if(val==false)then - returnValue = val - end - end - end - return returnValue - end; - } - event.__index = event - return event -end -local eventSystem = BasaltEvents() \ No newline at end of file diff --git a/oldVersions/lastVersion/source/project/lib/process.lua b/oldVersions/lastVersion/source/project/lib/process.lua deleted file mode 100644 index fc9ae9c..0000000 --- a/oldVersions/lastVersion/source/project/lib/process.lua +++ /dev/null @@ -1,50 +0,0 @@ -local processes = {} -local process = {} -local processId = 0 - -function process:new(path, window, ...) - local args = table.pack(...) - local newP = setmetatable({ path = path }, { __index = self }) - newP.window = window - newP.processId = processId - newP.coroutine = coroutine.create(function() - os.run({ }, path, table.unpack(args)) - end) - processes[processId] = newP - processId = processId + 1 - return newP -end - -function process:resume(event, ...) - term.redirect(self.window) - local ok, result = coroutine.resume(self.coroutine, event, ...) - self.window = term.current() - if ok then - self.filter = result - else - basalt.debug(result) - end -end - -function process:isDead() - if (self.coroutine ~= nil) then - if (coroutine.status(self.coroutine) == "dead") then - table.remove(processes, self.processId) - return true - end - else - return true - end - return false -end - -function process:getStatus() - if (self.coroutine ~= nil) then - return coroutine.status(self.coroutine) - end - return nil -end - -function process:start() - coroutine.resume(self.coroutine) -end \ No newline at end of file diff --git a/oldVersions/lastVersion/source/project/lib/utils.lua b/oldVersions/lastVersion/source/project/lib/utils.lua deleted file mode 100644 index ad2fb7e..0000000 --- a/oldVersions/lastVersion/source/project/lib/utils.lua +++ /dev/null @@ -1,158 +0,0 @@ -local function getTextHorizontalAlign(text, width, textAlign, replaceChar) - text = string.sub(text, 1, width) - local offset = width - string.len(text) - if (textAlign == "right") then - text = string.rep(replaceChar or " ", offset) .. text - elseif (textAlign == "center") then - text = string.rep(replaceChar or " ", math.floor(offset / 2)) .. text .. string.rep(replaceChar or " ", math.floor(offset / 2)) - text = text .. (string.len(text) < width and (replaceChar or " ") or "") - else - text = text .. string.rep(replaceChar or " ", offset) - end - return text -end - -local function getTextVerticalAlign(h, textAlign) - local offset = 0 - if (textAlign == "center") then - offset = math.ceil(h / 2) - if (offset < 1) then - offset = 1 - end - end - if (textAlign == "bottom") then - offset = h - end - if(offset<1)then offset=1 end - return offset -end - -local function rpairs(t) - return function(t, i) - i = i - 1 - if i ~= 0 then - return i, t[i] - end - end, t, #t + 1 -end - --- shrink system is copy pasted (and slightly changed) from blittle by Bomb Bloke: http://www.computercraft.info/forums2/index.php?/topic/25354-cc-176-blittle-api/ -local function shrink(bLittleData, bgColor) - local relations = { [0] = { 8, 4, 3, 6, 5 }, { 4, 14, 8, 7 }, { 6, 10, 8, 7 }, { 9, 11, 8, 0 }, { 1, 14, 8, 0 }, { 13, 12, 8, 0 }, { 2, 10, 8, 0 }, { 15, 8, 10, 11, 12, 14 }, - { 0, 7, 1, 9, 2, 13 }, { 3, 11, 8, 7 }, { 2, 6, 7, 15 }, { 9, 3, 7, 15 }, { 13, 5, 7, 15 }, { 5, 12, 8, 7 }, { 1, 4, 7, 15 }, { 7, 10, 11, 12, 14 } } - - local colourNum, exponents, colourChar = {}, {}, {} - for i = 0, 15 do - exponents[2 ^ i] = i - end - do - local hex = "0123456789abcdef" - for i = 1, 16 do - colourNum[hex:sub(i, i)] = i - 1 - colourNum[i - 1] = hex:sub(i, i) - colourChar[hex:sub(i, i)] = 2 ^ (i - 1) - colourChar[2 ^ (i - 1)] = hex:sub(i, i) - - local thisRel = relations[i - 1] - for i = 1, #thisRel do - thisRel[i] = 2 ^ thisRel[i] - end - end - end - - local function getBestColourMatch(usage) - local lastCol = relations[exponents[usage[#usage][1]]] - if(lastCol~=nil)then - for j = 1, #lastCol do - local thisRelation = lastCol[j] - for i = 1, #usage - 1 do - if usage[i][1] == thisRelation then - return i - end - end - end - end - return 1 - end - - local function colsToChar(pattern, totals) - if not totals then - local newPattern = {} - totals = {} - for i = 1, 6 do - local thisVal = pattern[i] - local thisTot = totals[thisVal] - totals[thisVal], newPattern[i] = thisTot and (thisTot + 1) or 1, thisVal - end - pattern = newPattern - end - - local usage = {} - for key, value in pairs(totals) do - usage[#usage + 1] = { key, value } - end - - if #usage > 1 then - -- Reduce the chunk to two colours: - while #usage > 2 do - table.sort(usage, function(a, b) - return a[2] > b[2] - end) - local matchToInd, usageLen = getBestColourMatch(usage), #usage - local matchFrom, matchTo = usage[usageLen][1], usage[matchToInd][1] - for i = 1, 6 do - if pattern[i] == matchFrom then - pattern[i] = matchTo - usage[matchToInd][2] = usage[matchToInd][2] + 1 - end - end - usage[usageLen] = nil - end - - -- Convert to character. Adapted from oli414's function: - -- http://www.computercraft.info/forums2/index.php?/topic/25340-cc-176-easy-drawing-characters/ - local data = 128 - for i = 1, #pattern - 1 do - if pattern[i] ~= pattern[6] then - data = data + 2 ^ (i - 1) - end - end - return string.char(data), colourChar[usage[1][1] == pattern[6] and usage[2][1] or usage[1][1]], colourChar[pattern[6]] - else - -- Solid colour character: - return "\128", colourChar[pattern[1]], colourChar[pattern[1]] - end - end - - local results, width, height, bgCol = { {}, {}, {} }, 0, #bLittleData + #bLittleData % 3, bgColor or colors.black - for i = 1, #bLittleData do - if #bLittleData[i] > width then - width = #bLittleData[i] - end - end - - for y = 0, height - 1, 3 do - local cRow, tRow, bRow, counter = {}, {}, {}, 1 - - for x = 0, width - 1, 2 do - -- Grab a 2x3 chunk: - local pattern, totals = {}, {} - - for yy = 1, 3 do - for xx = 1, 2 do - pattern[#pattern + 1] = (bLittleData[y + yy] and bLittleData[y + yy][x + xx]) and (bLittleData[y + yy][x + xx] == 0 and bgCol or bLittleData[y + yy][x + xx]) or bgCol - totals[pattern[#pattern]] = totals[pattern[#pattern]] and (totals[pattern[#pattern]] + 1) or 1 - end - end - - cRow[counter], tRow[counter], bRow[counter] = colsToChar(pattern, totals) - counter = counter + 1 - end - - results[1][#results[1] + 1], results[2][#results[2] + 1], results[3][#results[3] + 1] = table.concat(cRow), table.concat(tRow), table.concat(bRow) - end - - results.width, results.height = #results[1][1], #results[1] - - return results -end \ No newline at end of file diff --git a/oldVersions/lastVersion/source/project/mainBottom.lua b/oldVersions/lastVersion/source/project/mainBottom.lua deleted file mode 100644 index ccac3c9..0000000 --- a/oldVersions/lastVersion/source/project/mainBottom.lua +++ /dev/null @@ -1,154 +0,0 @@ -local function drawFrames() - mainFrame:draw() - mainFrame:drawUpdate() - for _,v in pairs(monFrames)do - v:draw() - v:drawUpdate() - end -end - -local updaterActive = false -local function basaltUpdateEvent(event, p1, p2, p3, p4) - if(eventSystem:sendEvent("basaltEventCycle", event, p1, p2, p3, p4)==false)then return end - if(mainFrame~=nil)then - if (event == "mouse_click") then - mainFrame:mouseHandler(event, p1, p2, p3, p4) - activeFrame = mainFrame - elseif (event == "mouse_drag") then - mainFrame:mouseHandler(event, p1, p2, p3, p4) - activeFrame = mainFrame - elseif (event == "mouse_up") then - mainFrame:mouseHandler(event, p1, p2, p3, p4) - activeFrame = mainFrame - elseif (event == "mouse_scroll") then - mainFrame:mouseHandler(event, p1, p2, p3, p4) - activeFrame = mainFrame - elseif (event == "monitor_touch") then - if(monFrames[p1]~=nil)then - monFrames[p1]:mouseHandler(event, p1, p2, p3, p4) - activeFrame = monFrames[p1] - end - end - end - - if(event == "key") or (event == "char") then - activeFrame:keyHandler(event, p1) - activeFrame:backgroundKeyHandler(event, p1) - end - - if(event == "key")then - keyActive[p1] = true - end - - if(event == "key_up")then - keyActive[p1] = false - end - - for _, v in pairs(frames) do - v:eventHandler(event, p1, p2, p3, p4) - end - drawFrames() -end - -function basalt.autoUpdate(isActive) - updaterActive = isActive - if(isActive==nil)then updaterActive = true end - drawFrames() - while updaterActive do - local event, p1, p2, p3, p4 = os.pullEventRaw() -- change to raw later - basaltUpdateEvent(event, p1, p2, p3, p4) - end -end - -function basalt.update(event, p1, p2, p3, p4) - if (event ~= nil) then - basaltUpdateEvent(event, p1, p2, p3, p4) - end -end - -function basalt.stop() - updaterActive = false -end - -function basalt.isKeyDown(key) - if(keyActive[key]==nil)then return false end - return keyActive[key]; -end - -function basalt.getFrame(name) - for _, value in pairs(frames) do - if (value.name == name) then - return value - end - end -end - -function basalt.getActiveFrame() - return activeFrame -end - -function basalt.setActiveFrame(frame) - if (frame:getType() == "Frame") then - activeFrame = frame - return true - end - return false -end - -function basalt.onEvent(...) - for _,v in pairs(table.pack(...))do - if(type(v)=="function")then - eventSystem:registerEvent("basaltEventCycle", v) - end - end -end - -function basalt.createFrame(name) - for _, v in pairs(frames) do - if (v.name == name) then - return nil - end - end - local newFrame = Frame(name) - table.insert(frames, newFrame) - return newFrame -end - -function basalt.removeFrame(name) - frames[name] = nil -end - - -if (basalt.debugger) then - basalt.debugFrame = basalt.createFrame("basaltDebuggingFrame"):showBar():setBackground(colors.lightGray):setBar("Debug", colors.black, colors.gray) - basalt.debugList = basalt.debugFrame:addList("debugList"):setSize(basalt.debugFrame.width - 2, basalt.debugFrame.height - 3):setPosition(2, 3):setScrollable(true):show() - basalt.debugFrame:addButton("back"):setAnchor("topRight"):setSize(1, 1):setText("\22"):onClick(function() basalt.oldFrame:show() end):setBackground(colors.red):show() - basalt.debugLabel = basalt.debugFrame:addLabel("debugLabel"):onClick(function() basalt.oldFrame = mainFrame basalt.debugFrame:show() end):setBackground(colors.black):setForeground(colors.white):setAnchor("bottomLeft"):ignoreOffset():setZIndex(20):show() -end - -if (basalt.debugger) then - function basalt.debug(...) - local args = { ... } - if (mainFrame.name ~= "basaltDebuggingFrame") then - if (mainFrame ~= basalt.debugFrame) then - basalt.debugLabel:setParent(mainFrame) - end - end - local str = "" - for key, value in pairs(args) do - str = str .. tostring(value) .. (#args ~= key and ", " or "") - end - basalt.debugLabel:setText("[Debug] " .. str) - basalt.debugList:addItem(str) - if (basalt.debugList:getItemCount() > 50) then - basalt.debugList:removeItem(1) - end - basalt.debugList:setValue(basalt.debugList:getItem(basalt.debugList:getItemCount())) - if(basalt.debugList.getItemCount() > basalt.debugList:getHeight())then - basalt.debugList:setIndexOffset(basalt.debugList:getItemCount() - basalt.debugList:getHeight()) - end - basalt.debugLabel:show() - end -end - -return basalt \ No newline at end of file diff --git a/oldVersions/lastVersion/source/project/mainTop.lua b/oldVersions/lastVersion/source/project/mainTop.lua deleted file mode 100644 index 327456c..0000000 --- a/oldVersions/lastVersion/source/project/mainTop.lua +++ /dev/null @@ -1,31 +0,0 @@ -local basalt = { debugger = true, version = 1 } -local keyActive = {} -local focusedObject -local frames = {} -local activeFrame - -local mainFrame -local monFrames = {} - -local parentTerminal = term.current() - -local sub = string.sub - -local tHex = { -- copy paste is a very important feature - [colors.white] = "0", - [colors.orange] = "1", - [colors.magenta] = "2", - [colors.lightBlue] = "3", - [colors.yellow] = "4", - [colors.lime] = "5", - [colors.pink] = "6", - [colors.gray] = "7", - [colors.lightGray] = "8", - [colors.cyan] = "9", - [colors.purple] = "a", - [colors.blue] = "b", - [colors.brown] = "c", - [colors.green] = "d", - [colors.red] = "e", - [colors.black] = "f", -} \ No newline at end of file diff --git a/oldVersions/lastVersion/source/project/objects/Animation.lua b/oldVersions/lastVersion/source/project/objects/Animation.lua deleted file mode 100644 index c8dc953..0000000 --- a/oldVersions/lastVersion/source/project/objects/Animation.lua +++ /dev/null @@ -1,95 +0,0 @@ -local function Animation(name) - local object = {} - local objectType = "Animation" - - local timerObj - - local animations = {} - local index = 1 - - local nextWaitTimer = 0 - local lastFunc - - local function onPlay() - if (animations[index] ~= nil) then - animations[index].f(object, index) - end - index = index + 1 - if (animations[index] ~= nil) then - if (animations[index].t > 0) then - timerObj = os.startTimer(animations[index].t) - else - onPlay() - end - end - end - - object = { - name = name, - getType = function(self) - return objectType - end; - - getZIndex = function(self) - return 1 - end; - - getName = function(self) - return self.name - end; - - add = function(self, func, wait) - lastFunc = func - table.insert(animations, { f = func, t = wait or nextWaitTimer }) - return self - end; - - wait = function(self, wait) - nextWaitTimer = wait - return self - end; - - rep = function(self, reps) - for x = 1, reps do - table.insert(animations, { f = lastFunc, t = nextWaitTimer }) - end - return self - end; - - clear = function(self) - animations = {} - lastFunc = nil - nextWaitTimer = 0 - index = 1 - return self - end; - - play = function(self) - index = 1 - if (animations[index] ~= nil) then - if (animations[index].t > 0) then - timerObj = os.startTimer(animations[index].t) - else - onPlay() - end - end - return self - end; - - cancel = function(self) - os.cancelTimer(timerObj) - return self - end; - - eventHandler = function(self, event, tObj) - if (event == "timer") and (tObj == timerObj) then - if (animations[index] ~= nil) then - onPlay() - end - end - end; - } - object.__index = object - - return object -end \ No newline at end of file diff --git a/oldVersions/lastVersion/source/project/objects/Button.lua b/oldVersions/lastVersion/source/project/objects/Button.lua deleted file mode 100644 index c6ab3f7..0000000 --- a/oldVersions/lastVersion/source/project/objects/Button.lua +++ /dev/null @@ -1,55 +0,0 @@ -local function Button(name) - -- Button - local base = Object(name) - local objectType = "Button" - - base:setValue("Button") - base:setZIndex(5) - base.width = 8 - base.bgColor = theme.ButtonBG - base.fgColor = theme.ButtonFG - - local textHorizontalAlign = "center" - local textVerticalAlign = "center" - - local object = { - getType = function(self) - return objectType - end; - setHorizontalAlign = function(self, pos) - textHorizontalAlign = pos - end; - - setVerticalAlign = function(self, pos) - textVerticalAlign = pos - end; - - setText = function(self, text) - base:setValue(text) - return self - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - local verticalAlign = getTextVerticalAlign(self.height, textVerticalAlign) - - if(self.bgColor~=false)then - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - self.parent:drawTextBox(obx, oby, self.width, self.height, " ") - end - if(self.fgColor~=false)then self.parent:drawForegroundBox(obx, oby, self.width, self.height, self.fgColor) end - for n = 1, self.height do - if (n == verticalAlign) then - self.parent:setText(obx, oby + (n - 1), getTextHorizontalAlign(self:getValue(), self.width, textHorizontalAlign)) - end - end - end - self:setVisualChanged(false) - end - end; - - } - return setmetatable(object, base) -end \ No newline at end of file diff --git a/oldVersions/lastVersion/source/project/objects/Checkbox.lua b/oldVersions/lastVersion/source/project/objects/Checkbox.lua deleted file mode 100644 index 41e9b9d..0000000 --- a/oldVersions/lastVersion/source/project/objects/Checkbox.lua +++ /dev/null @@ -1,58 +0,0 @@ -local function Checkbox(name) - -- Checkbox - local base = Object(name) - local objectType = "Checkbox" - - base:setZIndex(5) - base:setValue(false) - base.width = 1 - base.height = 1 - base.bgColor = theme.CheckboxBG - base.fgColor = theme.CheckboxFG - - local object = { - symbol = "\42", - - getType = function(self) - return objectType - end; - - mouseHandler = function(self, event, button, x, y) - if (base.mouseHandler(self, event, button, x, y)) then - if ((event == "mouse_click") and (button == 1)) or (event == "monitor_touch") then - if (self:getValue() ~= true) and (self:getValue() ~= false) then - self:setValue(false) - else - self:setValue(not self:getValue()) - end - end - return true - end - return false - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - local verticalAlign = getTextVerticalAlign(self.height, "center") - - if(self.bgColor~=false)then self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) end - for n = 1, self.height do - if (n == verticalAlign) then - if (self:getValue() == true) then - self.parent:writeText(obx, oby + (n - 1), getTextHorizontalAlign(self.symbol, self.width, "center"), self.bgColor, self.fgColor) - else - self.parent:writeText(obx, oby + (n - 1), getTextHorizontalAlign(" ", self.width, "center"), self.bgColor, self.fgColor) - end - end - end - end - self:setVisualChanged(false) - end - end; - - } - - return setmetatable(object, base) -end \ No newline at end of file diff --git a/oldVersions/lastVersion/source/project/objects/Dropdown.lua b/oldVersions/lastVersion/source/project/objects/Dropdown.lua deleted file mode 100644 index 1cac811..0000000 --- a/oldVersions/lastVersion/source/project/objects/Dropdown.lua +++ /dev/null @@ -1,170 +0,0 @@ -local function Dropdown(name) - local base = Object(name) - local objectType = "Dropdown" - base.width = 12 - base.height = 1 - base.bgColor = theme.dropdownBG - base.fgColor = theme.dropdownFG - base:setZIndex(6) - - local list = {} - local itemSelectedBG = theme.selectionBG - local itemSelectedFG = theme.selectionFG - local selectionColorActive = true - local align = "left" - local yOffset = 0 - - local dropdownW = 16 - local dropdownH = 6 - local closedSymbol = "\16" - local openedSymbol = "\31" - local isOpened = false - - local object = { - getType = function(self) - return objectType - end; - - setIndexOffset = function(self, yOff) - yOffset = yOff - return self - end; - - getIndexOffset = function(self) - return yOffset - end; - - addItem = function(self, text, bgCol, fgCol, ...) - table.insert(list, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } }) - return self - end; - - getAll = function(self) - return list - end; - - removeItem = function(self, index) - table.remove(list, index) - return self - end; - - getItem = function(self, index) - return list[index] - end; - - getItemIndex = function(self) - local selected = self:getValue() - for key, value in pairs(list) do - if (value == selected) then - return key - end - end - end; - - clear = function(self) - list = {} - self:setValue({}) - return self - end; - - getItemCount = function(self) - return #list - end; - - editItem = function(self, index, text, bgCol, fgCol, ...) - table.remove(list, index) - table.insert(list, index, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } }) - return self - end; - - selectItem = function(self, index) - self:setValue(list[index] or {}) - return self - end; - - setSelectedItem = function(self, bgCol, fgCol, active) - itemSelectedBG = bgCol or self.bgColor - itemSelectedFG = fgCol or self.fgColor - selectionColorActive = active - return self - end; - - setDropdownSize = function(self, width, height) - dropdownW, dropdownH = width, height - return self - end; - - mouseHandler = function(self, event, button, x, y) - if (isOpened) then - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - if ((event == "mouse_click") and (button == 1)) or (event == "monitor_touch") then - - if (#list > 0) then - for n = 1, dropdownH do - if (list[n + yOffset] ~= nil) then - if (obx <= x) and (obx + dropdownW > x) and (oby + n == y) then - self:setValue(list[n + yOffset]) - return true - end - end - end - end - end - - if (event == "mouse_scroll") then - yOffset = yOffset + button - if (yOffset < 0) then - yOffset = 0 - end - if (button == 1) then - if (#list > dropdownH) then - if (yOffset > #list - dropdownH) then - yOffset = #list - dropdownH - end - else - yOffset = list - 1 - end - end - return true - end - self:setVisualChanged() - end - if (base.mouseHandler(self, event, button, x, y)) then - isOpened = true - else - isOpened = false - end - end; - - draw = function(self) - if (base.draw(self)) then - local obx, oby = self:getAnchorPosition() - if (self.parent ~= nil) then - if(self.bgColor~=false)then self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) end - local val = self:getValue() - local text = getTextHorizontalAlign((val~=nil and val.text or ""), self.width, align):sub(1, self.width - 1) .. (isOpened and openedSymbol or closedSymbol) - self.parent:writeText(obx, oby, text, self.bgColor, self.fgColor) - - if (isOpened) then - for n = 1, dropdownH do - if (list[n + yOffset] ~= nil) then - if (list[n + yOffset] == val) then - if (selectionColorActive) then - self.parent:writeText(obx, oby + n, getTextHorizontalAlign(list[n + yOffset].text, dropdownW, align), itemSelectedBG, itemSelectedFG) - else - self.parent:writeText(obx, oby + n, getTextHorizontalAlign(list[n + yOffset].text, dropdownW, align), list[n + yOffset].bgCol, list[n + yOffset].fgCol) - end - else - self.parent:writeText(obx, oby + n, getTextHorizontalAlign(list[n + yOffset].text, dropdownW, align), list[n + yOffset].bgCol, list[n + yOffset].fgCol) - end - end - end - end - end - self:setVisualChanged(false) - end - end; - } - - return setmetatable(object, base) -end \ No newline at end of file diff --git a/oldVersions/lastVersion/source/project/objects/Image.lua b/oldVersions/lastVersion/source/project/objects/Image.lua deleted file mode 100644 index 2c05f65..0000000 --- a/oldVersions/lastVersion/source/project/objects/Image.lua +++ /dev/null @@ -1,193 +0,0 @@ -local function Image(name) - -- Pane - local base = Object(name) - local objectType = "Image" - base:setZIndex(2) - local image - local shrinkedImage - local imageGotShrinked = false - - local function shrink() - - -- shrinkSystem is copy pasted (and slightly changed) from blittle by Bomb Bloke: http://www.computercraft.info/forums2/index.php?/topic/25354-cc-176-blittle-api/ - local relations = { [0] = { 8, 4, 3, 6, 5 }, { 4, 14, 8, 7 }, { 6, 10, 8, 7 }, { 9, 11, 8, 0 }, { 1, 14, 8, 0 }, { 13, 12, 8, 0 }, { 2, 10, 8, 0 }, { 15, 8, 10, 11, 12, 14 }, - { 0, 7, 1, 9, 2, 13 }, { 3, 11, 8, 7 }, { 2, 6, 7, 15 }, { 9, 3, 7, 15 }, { 13, 5, 7, 15 }, { 5, 12, 8, 7 }, { 1, 4, 7, 15 }, { 7, 10, 11, 12, 14 } } - - local colourNum, exponents, colourChar = {}, {}, {} - for i = 0, 15 do - exponents[2 ^ i] = i - end - do - local hex = "0123456789abcdef" - for i = 1, 16 do - colourNum[hex:sub(i, i)] = i - 1 - colourNum[i - 1] = hex:sub(i, i) - colourChar[hex:sub(i, i)] = 2 ^ (i - 1) - colourChar[2 ^ (i - 1)] = hex:sub(i, i) - - local thisRel = relations[i - 1] - for i = 1, #thisRel do - thisRel[i] = 2 ^ thisRel[i] - end - end - end - - local function getBestColourMatch(usage) - local lastCol = relations[exponents[usage[#usage][1]]] - - for j = 1, #lastCol do - local thisRelation = lastCol[j] - for i = 1, #usage - 1 do - if usage[i][1] == thisRelation then - return i - end - end - end - - return 1 - end - - local function colsToChar(pattern, totals) - if not totals then - local newPattern = {} - totals = {} - for i = 1, 6 do - local thisVal = pattern[i] - local thisTot = totals[thisVal] - totals[thisVal], newPattern[i] = thisTot and (thisTot + 1) or 1, thisVal - end - pattern = newPattern - end - - local usage = {} - for key, value in pairs(totals) do - usage[#usage + 1] = { key, value } - end - - if #usage > 1 then - -- Reduce the chunk to two colours: - while #usage > 2 do - table.sort(usage, function(a, b) - return a[2] > b[2] - end) - local matchToInd, usageLen = getBestColourMatch(usage), #usage - local matchFrom, matchTo = usage[usageLen][1], usage[matchToInd][1] - for i = 1, 6 do - if pattern[i] == matchFrom then - pattern[i] = matchTo - usage[matchToInd][2] = usage[matchToInd][2] + 1 - end - end - usage[usageLen] = nil - end - - -- Convert to character. Adapted from oli414's function: - -- http://www.computercraft.info/forums2/index.php?/topic/25340-cc-176-easy-drawing-characters/ - local data = 128 - for i = 1, #pattern - 1 do - if pattern[i] ~= pattern[6] then - data = data + 2 ^ (i - 1) - end - end - return string.char(data), colourChar[usage[1][1] == pattern[6] and usage[2][1] or usage[1][1]], colourChar[pattern[6]] - else - -- Solid colour character: - return "\128", colourChar[pattern[1]], colourChar[pattern[1]] - end - end - - local results, width, height, bgCol = { {}, {}, {} }, 0, #image + #image % 3, base.bgColor or colors.black - for i = 1, #image do - if #image[i] > width then - width = #image[i] - end - end - - for y = 0, height - 1, 3 do - local cRow, tRow, bRow, counter = {}, {}, {}, 1 - - for x = 0, width - 1, 2 do - -- Grab a 2x3 chunk: - local pattern, totals = {}, {} - - for yy = 1, 3 do - for xx = 1, 2 do - pattern[#pattern + 1] = (image[y + yy] and image[y + yy][x + xx]) and (image[y + yy][x + xx] == 0 and bgCol or image[y + yy][x + xx]) or bgCol - totals[pattern[#pattern]] = totals[pattern[#pattern]] and (totals[pattern[#pattern]] + 1) or 1 - end - end - - cRow[counter], tRow[counter], bRow[counter] = colsToChar(pattern, totals) - counter = counter + 1 - end - - results[1][#results[1] + 1], results[2][#results[2] + 1], results[3][#results[3] + 1] = table.concat(cRow), table.concat(tRow), table.concat(bRow) - end - - results.width, results.height = #results[1][1], #results[1] - - shrinkedImage = results - end - - local object = { - getType = function(self) - return objectType - end; - - loadImage = function(self, path) - image = paintutils.loadImage(path) - imageGotShrinked = false - return self - end; - - loadBlittleImage = function(self, path) -- not done yet - --image = paintutils.loadImage(path) - --imageGotShrinked = true - return self - end; - - shrink = function(self) - shrink() - imageGotShrinked = true - return self - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - if (image ~= nil) then - local obx, oby = self:getAnchorPosition() - if (imageGotShrinked) then - -- this is copy pasted (and slightly changed) from blittle by Bomb Bloke: http://www.computercraft.info/forums2/index.php?/topic/25354-cc-176-blittle-api/ - local t, tC, bC = shrinkedImage[1], shrinkedImage[2], shrinkedImage[3] - for i = 1, shrinkedImage.height do - local tI = t[i] - if type(tI) == "string" then - self.parent:setText(obx, oby + i - 1, tI) - self.parent:setFG(obx, oby + i - 1, tC[i]) - self.parent:setBG(obx, oby + i - 1, bC[i]) - elseif type(tI) == "table" then - self.parent:setText(obx, oby + i - 1, tI[2]) - self.parent:setFG(obx, oby + i - 1, tC[i]) - self.parent:setBG(obx, oby + i - 1, bC[i]) - end - end - else - for yPos = 1, math.min(#image, self.height) do - local line = image[yPos] - for xPos = 1, math.min(#line, self.width) do - if line[xPos] > 0 then - self.parent:drawBackgroundBox(obx + xPos - 1, oby + yPos - 1, 1, 1, line[xPos]) - end - end - end - end - end - end - self:setVisualChanged(false) - end - end; - } - - return setmetatable(object, base) -end \ No newline at end of file diff --git a/oldVersions/lastVersion/source/project/objects/Input.lua b/oldVersions/lastVersion/source/project/objects/Input.lua deleted file mode 100644 index 748d848..0000000 --- a/oldVersions/lastVersion/source/project/objects/Input.lua +++ /dev/null @@ -1,242 +0,0 @@ -local function Input(name) - -- Input - local base = Object(name) - local objectType = "Input" - - local inputType = "text" - local inputLimit = 0 - base:setZIndex(5) - base:setValue("") - base.width = 10 - base.height = 1 - base.bgColor = theme.InputBG - base.fgColor = theme.InputFG - - local textX = 1 - local wIndex = 1 - - local defaultText = "" - local defaultBGCol - local defaultFGCol - local showingText = defaultText - local internalValueChange = false - - local object = { - - getType = function(self) - return objectType - end; - - setInputType = function(self, iType) - if (iType == "password") or (iType == "number") or (iType == "text") then - inputType = iType - end - return self - end; - - setDefaultText = function(self, text, fCol, bCol) - defaultText = text - defaultBGCol = bCol or defaultBGCol - defaultFGCol = fCol or defaultFGCol - if (self:isFocused()) then - showingText = "" - else - showingText = defaultText - end - return self - end; - - getInputType = function(self) - return inputType - end; - - setValue = function(self, val) - base.setValue(self, tostring(val)) - if not (internalValueChange) then - textX = tostring(val):len() + 1 - end - return self - end; - - getValue = function(self) - local val = base.getValue(self) - return inputType == "number" and tonumber(val) or val - end; - - setInputLimit = function(self, limit) - inputLimit = tonumber(limit) or inputLimit - return self - end; - - getInputLimit = function(self) - return inputLimit - end; - - getFocusHandler = function(self) - base.getFocusHandler(self) - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - showingText = "" - if (self.parent ~= nil) then - self.parent:setCursor(true, obx + textX - wIndex, oby+math.floor(self.height/2), self.fgColor) - end - end - end; - - loseFocusHandler = function(self) - base.loseFocusHandler(self) - if (self.parent ~= nil) then - self.parent:setCursor(false) - showingText = defaultText - end - end; - - keyHandler = function(self, event, key) - if (base.keyHandler(self, event, key)) then - internalValueChange = true - if (event == "key") then - if (key == keys.backspace) then - -- on backspace - local text = tostring(base.getValue()) - if (textX > 1) then - self:setValue(text:sub(1, textX - 2) .. text:sub(textX, text:len())) - if (textX > 1) then - textX = textX - 1 - end - if (wIndex > 1) then - if (textX < wIndex) then - wIndex = wIndex - 1 - end - end - end - end - if (key == keys.enter) then - -- on enter - if (self.parent ~= nil) then - --self.parent:removeFocusedObject(self) - end - end - if (key == keys.right) then - -- right arrow - local tLength = tostring(base.getValue()):len() - textX = textX + 1 - - if (textX > tLength) then - textX = tLength + 1 - end - if (textX < 1) then - textX = 1 - end - if (textX < wIndex) or (textX >= self.width + wIndex) then - wIndex = textX - self.width + 1 - end - if (wIndex < 1) then - wIndex = 1 - end - end - - if (key == keys.left) then - -- left arrow - textX = textX - 1 - if (textX >= 1) then - if (textX < wIndex) or (textX >= self.width + wIndex) then - wIndex = textX - end - end - if (textX < 1) then - textX = 1 - end - if (wIndex < 1) then - wIndex = 1 - end - end - end - - if (event == "char") then - local text = base.getValue() - if (text:len() < inputLimit or inputLimit <= 0) then - if (inputType == "number") then - local cache = text - if (key == ".") or (tonumber(key) ~= nil) then - self:setValue(text:sub(1, textX - 1) .. key .. text:sub(textX, text:len())) - textX = textX + 1 - end - if (tonumber(base.getValue()) == nil) then - self:setValue(cache) - end - else - self:setValue(text:sub(1, textX - 1) .. key .. text:sub(textX, text:len())) - textX = textX + 1 - end - if (textX >= self.width + wIndex) then - wIndex = wIndex + 1 - end - end - end - local obx, oby = self:getAnchorPosition() - local val = tostring(base.getValue()) - local cursorX = (textX <= val:len() and textX - 1 or val:len()) - (wIndex - 1) - - if (cursorX > self.x + self.width - 1) then - cursorX = self.x + self.width - 1 - end - if (self.parent ~= nil) then - self.parent:setCursor(true, obx + cursorX, oby+math.floor(self.height/2), self.fgColor) - end - internalValueChange = false - end - end; - - mouseHandler = function(self, event, button, x, y) - if (base.mouseHandler(self, event, button, x, y)) then - if (event == "mouse_click") and (button == 1) then - - end - return true - end - return false - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - local verticalAlign = getTextVerticalAlign(self.height, "center") - - if(self.bgColor~=false)then self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) end - for n = 1, self.height do - if (n == verticalAlign) then - local val = tostring(base.getValue()) - local bCol = self.bgColor - local fCol = self.fgColor - local text - if (val:len() <= 0) then - text = showingText - bCol = defaultBGCol or bCol - fCol = defaultFGCol or fCol - end - - text = showingText - if (val ~= "") then - text = val - end - text = text:sub(wIndex, self.width + wIndex - 1) - local space = self.width - text:len() - if (space < 0) then - space = 0 - end - if (inputType == "password") and (val ~= "") then - text = string.rep("*", text:len()) - end - text = text .. string.rep(" ", space) - self.parent:writeText(obx, oby + (n - 1), text, bCol, fCol) - end - end - end - self:setVisualChanged(false) - end - end; - } - - return setmetatable(object, base) -end \ No newline at end of file diff --git a/oldVersions/lastVersion/source/project/objects/Label.lua b/oldVersions/lastVersion/source/project/objects/Label.lua deleted file mode 100644 index 76495ba..0000000 --- a/oldVersions/lastVersion/source/project/objects/Label.lua +++ /dev/null @@ -1,99 +0,0 @@ -local function Label(name) - -- Label - local base = Object(name) - local objectType = "Label" - - base:setZIndex(3) - base.fgColor = colors.white - base.bgcolor = colors.black - - local autoSize = true - base:setValue("") - - local textHorizontalAlign = "left" - local textVerticalAlign = "top" - local fontsize = 0 - - local object = { - getType = function(self) - return objectType - end; - setText = function(self, text) - text = tostring(text) - base:setValue(text) - if (autoSize) then - self.width = text:len() - end - return self - end; - - setTextAlign = function(self, hor, vert) - textHorizontalAlign = hor or textHorizontalAlign - textVerticalAlign = vert or textVerticalAlign - self:setVisualChanged() - return self - end; - - setFontSize = function(self, size) - if(size>0)and(size<=4)then - fontsize = size-1 or 0 - end - return self - end; - - getFontSize = function(self) - return fontsize+1 - end; - - setSize = function(self, width, height) - base.setSize(self, width, height) - autoSize = false - self:setVisualChanged() - return self - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - local verticalAlign = getTextVerticalAlign(self.height, textVerticalAlign) - if(self.bgColor~=false)then - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - self.parent:drawTextBox(obx, oby, self.width, self.height, " ") end - if(self.fgColor~=false)then self.parent:drawForegroundBox(obx, oby, self.width, self.height, self.fgColor) end - if(fontsize==0)then - for n = 1, self.height do - if (n == verticalAlign) then - self.parent:setText(obx, oby + (n - 1), getTextHorizontalAlign(self:getValue(), self.width, textHorizontalAlign)) - end - end - else - local tData = makeText(fontsize, self:getValue(), self.fgColor, self.bgColor or colors.black) - if(autoSize)then - self.height = #tData[1]-1 - self.width = #tData[1][1] - end - for n = 1, self.height do - if (n == verticalAlign) then - local oX, oY = self.parent:getSize() - local cX, cY = #tData[1][1], #tData[1] - obx = obx or math.floor((oX - cX) / 2) + 1 - oby = oby or math.floor((oY - cY) / 2) + 1 - - for i = 1, cY do - self.parent:setFG(obx, oby + i + n - 2, getTextHorizontalAlign(tData[2][i], self.width, textHorizontalAlign)) - self.parent:setBG(obx, oby + i + n - 2, getTextHorizontalAlign(tData[3][i], self.width, textHorizontalAlign, tHex[self.bgColor or colors.black])) - self.parent:setText(obx, oby + i + n - 2, getTextHorizontalAlign(tData[1][i], self.width, textHorizontalAlign)) - end - end - end - end - end - self:setVisualChanged(false) - end - end; - - } - - return setmetatable(object, base) -end \ No newline at end of file diff --git a/oldVersions/lastVersion/source/project/objects/List.lua b/oldVersions/lastVersion/source/project/objects/List.lua deleted file mode 100644 index 3c13521..0000000 --- a/oldVersions/lastVersion/source/project/objects/List.lua +++ /dev/null @@ -1,161 +0,0 @@ -local function List(name) - local base = Object(name) - local objectType = "List" - base.width = 16 - base.height = 6 - base.bgColor = theme.listBG - base.fgColor = theme.listFG - base:setZIndex(5) - - local list = {} - local itemSelectedBG = theme.selectionBG - local itemSelectedFG = theme.selectionFG - local selectionColorActive = true - local align = "left" - local yOffset = 0 - local scrollable = true - - local object = { - getType = function(self) - return objectType - end; - - addItem = function(self, text, bgCol, fgCol, ...) - table.insert(list, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } }) - if (#list == 1) then - self:setValue(list[1]) - end - return self - end; - - setIndexOffset = function(self, yOff) - yOffset = yOff - return self - end; - - getIndexOffset = function(self) - return yOffset - end; - - removeItem = function(self, index) - table.remove(list, index) - return self - end; - - getItem = function(self, index) - return list[index] - end; - - getAll = function(self) - return list - end; - - getItemIndex = function(self) - local selected = self:getValue() - for key, value in pairs(list) do - if (value == selected) then - return key - end - end - end; - - clear = function(self) - list = {} - self:setValue({}) - return self - end; - - getItemCount = function(self) - return #list - end; - - editItem = function(self, index, text, bgCol, fgCol, ...) - table.remove(list, index) - table.insert(list, index, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } }) - return self - end; - - selectItem = function(self, index) - self:setValue(list[index] or {}) - return self - end; - - setSelectedItem = function(self, bgCol, fgCol, active) - itemSelectedBG = bgCol or self.bgColor - itemSelectedFG = fgCol or self.fgColor - selectionColorActive = active - return self - end; - - setScrollable = function(self, scroll) - scrollable = scroll - return self - end; - - mouseHandler = function(self, event, button, x, y) - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - if (obx <= x) and (obx + self.width > x) and (oby <= y) and (oby + self.height > y) and (self:isVisible()) then - if (((event == "mouse_click") or (event == "mouse_drag"))and(button==1))or(event=="monitor_touch") then - if (#list > 0) then - for n = 1, self.height do - if (list[n + yOffset] ~= nil) then - if (obx <= x) and (obx + self.width > x) and (oby + n - 1 == y) then - self:setValue(list[n + yOffset]) - self:getEventSystem():sendEvent("mouse_click", self, "mouse_click", 0, x, y, list[n + yOffset]) - end - end - end - end - end - - if (event == "mouse_scroll") and (scrollable) then - yOffset = yOffset + button - if (yOffset < 0) then - yOffset = 0 - end - if (button >= 1) then - if (#list > self.height) then - if (yOffset > #list - self.height) then - yOffset = #list - self.height - end - if (yOffset >= #list) then - yOffset = #list - 1 - end - else - yOffset = yOffset - 1 - end - end - end - self:setVisualChanged() - return true - end - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - if(self.bgColor~=false)then - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - end - for n = 1, self.height do - if (list[n + yOffset] ~= nil) then - if (list[n + yOffset] == self:getValue()) then - if (selectionColorActive) then - self.parent:writeText(obx, oby + n - 1, getTextHorizontalAlign(list[n + yOffset].text, self.width, align), itemSelectedBG, itemSelectedFG) - else - self.parent:writeText(obx, oby + n - 1, getTextHorizontalAlign(list[n + yOffset].text, self.width, align), list[n + yOffset].bgCol, list[n + yOffset].fgCol) - end - else - self.parent:writeText(obx, oby + n - 1, getTextHorizontalAlign(list[n + yOffset].text, self.width, align), list[n + yOffset].bgCol, list[n + yOffset].fgCol) - end - end - end - end - self:setVisualChanged(false) - end - end; - } - - return setmetatable(object, base) -end \ No newline at end of file diff --git a/oldVersions/lastVersion/source/project/objects/Menubar.lua b/oldVersions/lastVersion/source/project/objects/Menubar.lua deleted file mode 100644 index 464ab97..0000000 --- a/oldVersions/lastVersion/source/project/objects/Menubar.lua +++ /dev/null @@ -1,201 +0,0 @@ -local function Menubar(name) - local base = Object(name) - local objectType = "Menubar" - local object = {} - - base.width = 30 - base.height = 1 - base.bgColor = colors.gray - base.fgColor = colors.lightGray - base:setZIndex(5) - - local list = {} - local itemSelectedBG = theme.selectionBG - local itemSelectedFG = theme.selectionFG - local selectionColorActive = true - local align = "left" - local itemOffset = 0 - local space = 1 - local scrollable = false - - local function maxScroll() - local mScroll = 0 - local xPos = 0 - for n = 1, #list do - if (xPos + list[n].text:len() + space * 2 > object.width) then - if(xPos < object.width)then - mScroll = mScroll + (list[n].text:len() + space * 2-(object.width - xPos)) - else - mScroll = mScroll + list[n].text:len() + space * 2 - end - end - xPos = xPos + list[n].text:len() + space * 2 - - end - return mScroll - end - - object = { - getType = function(self) - return objectType - end; - - addItem = function(self, text, bgCol, fgCol, ...) - table.insert(list, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } }) - if (#list == 1) then - self:setValue(list[1]) - end - return self - end; - - getAll = function(self) - return list - end; - - getItemIndex = function(self) - local selected = self:getValue() - for key, value in pairs(list) do - if (value == selected) then - return key - end - end - end; - - clear = function(self) - list = {} - self:setValue({}) - return self - end; - - setSpace = function(self, _space) - space = _space or space - return self - end; - - setPositionOffset = function(self, offset) - itemOffset = offset or 0 - if (itemOffset < 0) then - itemOffset = 0 - end - - local mScroll = maxScroll() - if (itemOffset > mScroll) then - itemOffset = mScroll - end - return self - end; - - getPositionOffset = function(self) - return itemOffset - end; - - setScrollable = function(self, scroll) - scrollable = scroll - if(scroll==nil)then scrollable = true end - return self - end; - - removeItem = function(self, index) - table.remove(list, index) - return self - end; - - getItem = function(self, index) - return list[index] - end; - - getItemCount = function(self) - return #list - end; - - editItem = function(self, index, text, bgCol, fgCol, ...) - table.remove(list, index) - table.insert(list, index, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } }) - return self - end; - - selectItem = function(self, index) - self:setValue(list[index] or {}) - return self - end; - - setSelectedItem = function(self, bgCol, fgCol, active) - itemSelectedBG = bgCol or self.bgColor - itemSelectedFG = fgCol or self.fgColor - selectionColorActive = active - return self - end; - - mouseHandler = function(self, event, button, x, y) - if(base.mouseHandler(self, event, button, x, y))then - local objX, objY = self:getAbsolutePosition(self:getAnchorPosition()) - if (objX <= x) and (objX + self.width > x) and (objY <= y) and (objY + self.height > y) and (self:isVisible()) then - if (self.parent ~= nil) then - self.parent:setFocusedObject(self) - end - if (event == "mouse_click") or (event == "monitor_touch") then - local xPos = 0 - for n = 1, #list do - if (list[n] ~= nil) then - --if (xPos-1 + list[n].text:len() + space * 2 <= self.width) then - if (objX + xPos <= x + itemOffset) and (objX + xPos + list[n].text:len() + (space*2) > x + itemOffset) and (objY == y) then - self:setValue(list[n]) - self:getEventSystem():sendEvent(event, self, event, 0, x, y, list[n]) - end - xPos = xPos + list[n].text:len() + space * 2 - end - end - - end - if (event == "mouse_scroll") and (scrollable) then - itemOffset = itemOffset + button - if (itemOffset < 0) then - itemOffset = 0 - end - - local mScroll = maxScroll() - - if (itemOffset > mScroll) then - itemOffset = mScroll - end - end - self:setVisualChanged(true) - return true - end - end - return false - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - if(self.bgColor~=false)then - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - end - local text = "" - local textBGCol = "" - local textFGCol = "" - for _, v in pairs(list) do - local newItem = (" "):rep(space) .. v.text .. (" "):rep(space) - text = text .. newItem - if(v == self:getValue())then - textBGCol = textBGCol .. tHex[itemSelectedBG or v.bgCol or self.bgColor]:rep(newItem:len()) - textFGCol = textFGCol .. tHex[itemSelectedFG or v.FgCol or self.fgColor]:rep(newItem:len()) - else - textBGCol = textBGCol .. tHex[v.bgCol or self.bgColor]:rep(newItem:len()) - textFGCol = textFGCol .. tHex[v.FgCol or self.fgColor]:rep(newItem:len()) - end - end - - self.parent:setText(obx, oby, text:sub(itemOffset+1, self.width+itemOffset)) - self.parent:setBG(obx, oby, textBGCol:sub(itemOffset+1, self.width+itemOffset)) - self.parent:setFG(obx, oby, textFGCol:sub(itemOffset+1, self.width+itemOffset)) - end - self:setVisualChanged(false) - end - end; - } - - return setmetatable(object, base) -end \ No newline at end of file diff --git a/oldVersions/lastVersion/source/project/objects/Pane.lua b/oldVersions/lastVersion/source/project/objects/Pane.lua deleted file mode 100644 index e154118..0000000 --- a/oldVersions/lastVersion/source/project/objects/Pane.lua +++ /dev/null @@ -1,25 +0,0 @@ -local function Pane(name) - -- Pane - local base = Object(name) - local objectType = "Pane" - - local object = { - getType = function(self) - return objectType - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - self.parent:drawForegroundBox(obx, oby, self.width, self.height, self.bgColor) - end - self:setVisualChanged(false) - end - end; - - } - - return setmetatable(object, base) -end \ No newline at end of file diff --git a/oldVersions/lastVersion/source/project/objects/Program.lua b/oldVersions/lastVersion/source/project/objects/Program.lua deleted file mode 100644 index d0c5acc..0000000 --- a/oldVersions/lastVersion/source/project/objects/Program.lua +++ /dev/null @@ -1,646 +0,0 @@ -local function Program(name) - local base = Object(name) - local objectType = "Program" - base:setZIndex(5) - local object - - local function createBasaltWindow(x, y, width, height) - local xCursor, yCursor = 1, 1 - local bgColor, fgColor = colors.black, colors.white - local cursorBlink = false - local visible = false - - local cacheT = {} - local cacheBG = {} - local cacheFG = {} - - local tPalette = {} - - local emptySpaceLine - local emptyColorLines = {} - - for i = 0, 15 do - local c = 2 ^ i - tPalette[c] = { parentTerminal.getPaletteColour(c) } - end - - local function createEmptyLines() - emptySpaceLine = (" "):rep(width) - for n = 0, 15 do - local nColor = 2 ^ n - local sHex = tHex[nColor] - emptyColorLines[nColor] = sHex:rep(width) - end - end - - local function recreateWindowArray() - createEmptyLines() - local emptyText = emptySpaceLine - local emptyFG = emptyColorLines[colors.white] - local emptyBG = emptyColorLines[colors.black] - for n = 1, height do - cacheT[n] = sub(cacheT[n] == nil and emptyText or cacheT[n] .. emptyText:sub(1, width - cacheT[n]:len()), 1, width) - cacheFG[n] = sub(cacheFG[n] == nil and emptyFG or cacheFG[n] .. emptyFG:sub(1, width - cacheFG[n]:len()), 1, width) - cacheBG[n] = sub(cacheBG[n] == nil and emptyBG or cacheBG[n] .. emptyBG:sub(1, width - cacheBG[n]:len()), 1, width) - end - end - recreateWindowArray() - - local function updateCursor() - if xCursor >= 1 and yCursor >= 1 and xCursor <= width and yCursor <= height then - --parentTerminal.setCursorPos(xCursor + x - 1, yCursor + y - 1) - else - --parentTerminal.setCursorPos(0, 0) - end - --parentTerminal.setTextColor(fgColor) - end - - local function internalBlit(sText, sTextColor, sBackgroundColor) - -- copy pasti strikes again (cc: window.lua) - local nStart = xCursor - local nEnd = nStart + #sText - 1 - if yCursor >= 1 and yCursor <= height then - if nStart <= width and nEnd >= 1 then - -- Modify line - if nStart == 1 and nEnd == width then - cacheT[yCursor] = sText - cacheFG[yCursor] = sTextColor - cacheBG[yCursor] = sBackgroundColor - else - local sClippedText, sClippedTextColor, sClippedBackgroundColor - if nStart < 1 then - local nClipStart = 1 - nStart + 1 - local nClipEnd = width - nStart + 1 - sClippedText = sub(sText, nClipStart, nClipEnd) - sClippedTextColor = sub(sTextColor, nClipStart, nClipEnd) - sClippedBackgroundColor = sub(sBackgroundColor, nClipStart, nClipEnd) - elseif nEnd > width then - local nClipEnd = width - nStart + 1 - sClippedText = sub(sText, 1, nClipEnd) - sClippedTextColor = sub(sTextColor, 1, nClipEnd) - sClippedBackgroundColor = sub(sBackgroundColor, 1, nClipEnd) - else - sClippedText = sText - sClippedTextColor = sTextColor - sClippedBackgroundColor = sBackgroundColor - end - - local sOldText = cacheT[yCursor] - local sOldTextColor = cacheFG[yCursor] - local sOldBackgroundColor = cacheBG[yCursor] - local sNewText, sNewTextColor, sNewBackgroundColor - if nStart > 1 then - local nOldEnd = nStart - 1 - sNewText = sub(sOldText, 1, nOldEnd) .. sClippedText - sNewTextColor = sub(sOldTextColor, 1, nOldEnd) .. sClippedTextColor - sNewBackgroundColor = sub(sOldBackgroundColor, 1, nOldEnd) .. sClippedBackgroundColor - else - sNewText = sClippedText - sNewTextColor = sClippedTextColor - sNewBackgroundColor = sClippedBackgroundColor - end - if nEnd < width then - local nOldStart = nEnd + 1 - sNewText = sNewText .. sub(sOldText, nOldStart, width) - sNewTextColor = sNewTextColor .. sub(sOldTextColor, nOldStart, width) - sNewBackgroundColor = sNewBackgroundColor .. sub(sOldBackgroundColor, nOldStart, width) - end - - cacheT[yCursor] = sNewText - cacheFG[yCursor] = sNewTextColor - cacheBG[yCursor] = sNewBackgroundColor - end - end - xCursor = nEnd + 1 - if (visible) then - updateCursor() - end - end - end - - local function setText(_x, _y, text) - if (text ~= nil) then - local gText = cacheT[_y] - if (gText ~= nil) then - cacheT[_y] = sub(gText:sub(1, _x - 1) .. text .. gText:sub(_x + (text:len()), width), 1, width) - end - end - end - - local function setBG(_x, _y, colorStr) - if (colorStr ~= nil) then - local gBG = cacheBG[_y] - if (gBG ~= nil) then - cacheBG[_y] = sub(gBG:sub(1, _x - 1) .. colorStr .. gBG:sub(_x + (colorStr:len()), width), 1, width) - end - end - end - - local function setFG(_x, _y, colorStr) - if (colorStr ~= nil) then - local gFG = cacheFG[_y] - if (gFG ~= nil) then - cacheFG[_y] = sub(gFG:sub(1, _x - 1) .. colorStr .. gFG:sub(_x + (colorStr:len()), width), 1, width) - end - end - end - - local setTextColor = function(color) - if type(color) ~= "number" then - error("bad argument #1 (expected number, got " .. type(color) .. ")", 2) - elseif tHex[color] == nil then - error("Invalid color (got " .. color .. ")", 2) - end - fgColor = color - end - - local setBackgroundColor = function(color) - if type(color) ~= "number" then - error("bad argument #1 (expected number, got " .. type(color) .. ")", 2) - elseif tHex[color] == nil then - error("Invalid color (got " .. color .. ")", 2) - end - bgColor = color - end - - local setPaletteColor = function(colour, r, g, b) - -- have to work on - if type(colour) ~= "number" then - error("bad argument #1 (expected number, got " .. type(colour) .. ")", 2) - end - - if tHex[colour] == nil then - error("Invalid color (got " .. colour .. ")", 2) - end - - local tCol - if type(r) == "number" and g == nil and b == nil then - tCol = { colours.rgb8(r) } - tPalette[colour] = tCol - else - if type(r) ~= "number" then - error("bad argument #2 (expected number, got " .. type(r) .. ")", 2) - end - if type(g) ~= "number" then - error("bad argument #3 (expected number, got " .. type(g) .. ")", 2) - end - if type(b) ~= "number" then - error("bad argument #4 (expected number, got " .. type(b) .. ")", 2) - end - - tCol = tPalette[colour] - tCol[1] = r - tCol[2] = g - tCol[3] = b - end - end - - local getPaletteColor = function(colour) - if type(colour) ~= "number" then - error("bad argument #1 (expected number, got " .. type(colour) .. ")", 2) - end - if tHex[colour] == nil then - error("Invalid color (got " .. colour .. ")", 2) - end - local tCol = tPalette[colour] - return tCol[1], tCol[2], tCol[3] - end - - local basaltwindow = { - setCursorPos = function(_x, _y) - if type(_x) ~= "number" then - error("bad argument #1 (expected number, got " .. type(_x) .. ")", 2) - end - if type(_y) ~= "number" then - error("bad argument #2 (expected number, got " .. type(_y) .. ")", 2) - end - xCursor = math.floor(_x) - yCursor = math.floor(_y) - if (visible) then - updateCursor() - end - end; - - getCursorPos = function() - return xCursor, yCursor - end; - - setCursorBlink = function(blink) - if type(blink) ~= "boolean" then - error("bad argument #1 (expected boolean, got " .. type(blink) .. ")", 2) - end - cursorBlink = blink - end; - - getCursorBlink = function() - return cursorBlink - end; - - - getPaletteColor = getPaletteColor, - getPaletteColour = getPaletteColor, - - setBackgroundColor = setBackgroundColor, - setBackgroundColour = setBackgroundColor, - - setTextColor = setTextColor, - setTextColour = setTextColor, - - setPaletteColor = setPaletteColor, - setPaletteColour = setPaletteColor, - - getBackgroundColor = function() - return bgColor - end; - getBackgroundColour = function() - return bgColor - end; - - getSize = function() - return width, height - end; - - getTextColor = function() - return fgColor - end; - getTextColour = function() - return fgColor - end; - - basalt_resize = function(_width, _height) - width, height = _width, _height - recreateWindowArray() - end; - - basalt_reposition = function(_x, _y) - x, y = _x, _y - end; - - basalt_setVisible = function(vis) - visible = vis - end; - - drawBackgroundBox = function(_x, _y, _width, _height, bgCol) - for n = 1, _height do - setBG(_x, _y + (n - 1), tHex[bgCol]:rep(_width)) - end - end; - drawForegroundBox = function(_x, _y, _width, _height, fgCol) - for n = 1, _height do - setFG(_x, _y + (n - 1), tHex[fgCol]:rep(_width)) - end - end; - drawTextBox = function(_x, _y, _width, _height, symbol) - for n = 1, _height do - setText(_x, _y + (n - 1), symbol:rep(_width)) - end - end; - - writeText = function(_x, _y, text, bgCol, fgCol) - bgCol = bgCol or bgColor - fgCol = fgCol or fgColor - setText(x, _y, text) - setBG(_x, _y, tHex[bgCol]:rep(text:len())) - setFG(_x, _y, tHex[fgCol]:rep(text:len())) - end; - - basalt_update = function() - if (object.parent ~= nil) then - for n = 1, height do - object.parent:setText(x, y + (n - 1), cacheT[n]) - object.parent:setBG(x, y + (n - 1), cacheBG[n]) - object.parent:setFG(x, y + (n - 1), cacheFG[n]) - end - end - end; - - scroll = function(offset) - if type(offset) ~= "number" then - error("bad argument #1 (expected number, got " .. type(offset) .. ")", 2) - end - if offset ~= 0 then - local sEmptyText = emptySpaceLine - local sEmptyTextColor = emptyColorLines[fgColor] - local sEmptyBackgroundColor = emptyColorLines[bgColor] - for newY = 1, height do - local y = newY + offset - if y >= 1 and y <= height then - cacheT[newY] = cacheT[y] - cacheBG[newY] = cacheBG[y] - cacheFG[newY] = cacheFG[y] - else - cacheT[newY] = sEmptyText - cacheFG[newY] = sEmptyTextColor - cacheBG[newY] = sEmptyBackgroundColor - end - end - end - if (visible) then - updateCursor() - end - end; - - - isColor = function() - return parentTerminal.isColor() - end; - - isColour = function() - return parentTerminal.isColor() - end; - - write = function(text) - text = tostring(text) - if (visible) then - internalBlit(text, tHex[fgColor]:rep(text:len()), tHex[bgColor]:rep(text:len())) - end - end; - - clearLine = function() - if (visible) then - setText(1, yCursor, (" "):rep(width)) - setBG(1, yCursor, tHex[bgColor]:rep(width)) - setFG(1, yCursor, tHex[fgColor]:rep(width)) - end - if (visible) then - updateCursor() - end - end; - - clear = function() - for n = 1, height do - setText(1, n, (" "):rep(width)) - setBG(1, n, tHex[bgColor]:rep(width)) - setFG(1, n, tHex[fgColor]:rep(width)) - end - if (visible) then - updateCursor() - end - end; - - blit = function(text, fgcol, bgcol) - if type(text) ~= "string" then - error("bad argument #1 (expected string, got " .. type(text) .. ")", 2) - end - if type(fgcol) ~= "string" then - error("bad argument #2 (expected string, got " .. type(fgcol) .. ")", 2) - end - if type(bgcol) ~= "string" then - error("bad argument #3 (expected string, got " .. type(bgcol) .. ")", 2) - end - if #fgcol ~= #text or #bgcol ~= #text then - error("Arguments must be the same length", 2) - end - if (visible) then - --setText(xCursor, yCursor, text) - --setBG(xCursor, yCursor, bgcol) - --setFG(xCursor, yCursor, fgcol) - --xCursor = xCursor+text:len() - internalBlit(text, fgcol, bgcol) - end - end - - - } - - return basaltwindow - end - - base.width = 30 - base.height = 12 - local pWindow = createBasaltWindow(1, 1, base.width, base.height) - local curProcess - local paused = false - local queuedEvent = {} - - object = { - getType = function(self) - return objectType - end; - - show = function(self) - base.show(self) - pWindow.setBackgroundColor(self.bgColor) - pWindow.setTextColor(self.fgColor) - pWindow.basalt_setVisible(true) - return self - end; - - hide = function(self) - base.hide(self) - pWindow.basalt_setVisible(false) - return self - end; - - setPosition = function(self, x, y, rel) - base.setPosition(self, x, y, rel) - pWindow.basalt_reposition(self:getAnchorPosition()) - return self - end; - - getBasaltWindow = function() - return pWindow - end; - - getBasaltProcess = function() - return curProcess - end; - - setSize = function(self, width, height) - base.setSize(self, width, height) - pWindow.basalt_resize(self.width, self.height) - return self - end; - - getStatus = function(self) - if (curProcess ~= nil) then - return curProcess:getStatus() - end - return "inactive" - end; - - execute = function(self, path, ...) - curProcess = process:new(path, pWindow, ...) - pWindow.setBackgroundColor(colors.black) - pWindow.setTextColor(colors.white) - pWindow.clear() - pWindow.setCursorPos(1, 1) - curProcess:resume() - paused = false - return self - end; - - stop = function(self) - if (curProcess ~= nil) then - if not (curProcess:isDead()) then - curProcess:resume("terminate") - if (curProcess:isDead()) then - if (self.parent ~= nil) then - self.parent:setCursor(false) - end - end - end - end - return self - end; - - pause = function(self, p) - paused = p or (not paused) - if (curProcess ~= nil) then - if not (curProcess:isDead()) then - if not (paused) then - self:injectEvents(queuedEvent) - queuedEvent = {} - end - end - end - return self - end; - - isPaused = function(self) - return paused - end; - - injectEvent = function(self, event, p1, p2, p3, p4, ign) - if (curProcess ~= nil) then - if not (curProcess:isDead()) then - if (paused == false) or (ign) then - curProcess:resume(event, p1, p2, p3, p4) - else - table.insert(queuedEvent, { event = event, args = { p1, p2, p3, p4 } }) - end - end - end - return self - end; - - getQueuedEvents = function(self) - return queuedEvent - end; - - updateQueuedEvents = function(self, events) - queuedEvent = events or queuedEvent - return self - end; - - injectEvents = function(self, events) - if (curProcess ~= nil) then - if not (curProcess:isDead()) then - for _, value in pairs(events) do - curProcess:resume(value.event, table.unpack(value.args)) - end - end - end - return self - end; - - mouseHandler = function(self, event, button, x, y) - if (base.mouseHandler(self, event, button, x, y)) then - if (curProcess == nil) then - return false - end - if not (curProcess:isDead()) then - if not (paused) then - local absX, absY = self:getAbsolutePosition(self:getAnchorPosition(nil, nil, true)) - curProcess:resume(event, button, x - (absX - 1), y - (absY - 1)) - basalt.debug(event, button, x - (absX - 1), y - (absY - 1)) - end - end - return true - end - end; - - keyHandler = function(self, event, key) - base.keyHandler(self, event, key) - if (self:isFocused()) then - if (curProcess == nil) then - return false - end - if not (curProcess:isDead()) then - if not (paused) then - if (self.draw) then - curProcess:resume(event, key) - end - end - end - end - end; - - getFocusHandler = function(self) - base.getFocusHandler(self) - if (curProcess ~= nil) then - if not (curProcess:isDead()) then - if not (paused) then - if (self.parent ~= nil) then - local xCur, yCur = pWindow.getCursorPos() - local obx, oby = self:getAnchorPosition() - if (self.parent ~= nil) then - if (obx + xCur - 1 >= 1 and obx + xCur - 1 <= obx + self.width - 1 and yCur + oby - 1 >= 1 and yCur + oby - 1 <= oby + self.height - 1) then - self.parent:setCursor(pWindow.getCursorBlink(), obx + xCur - 1, yCur + oby - 1, pWindow.getTextColor()) - end - end - end - end - end - end - end; - - loseFocusHandler = function(self) - base.loseFocusHandler(self) - if (curProcess ~= nil) then - if not (curProcess:isDead()) then - if (self.parent ~= nil) then - self.parent:setCursor(false) - end - end - end - end; - - eventHandler = function(self, event, p1, p2, p3, p4) - if (curProcess == nil) then - return - end - if not (curProcess:isDead()) then - if not (paused) then - if (event ~= "mouse_click") and (event ~= "monitor_touch") and (event ~= "mouse_up") and (event ~= "mouse_scroll") and (event ~= "mouse_drag") and (event ~= "key_up") and (event ~= "key") and (event ~= "char") and (event ~= "terminate") then - curProcess:resume(event, p1, p2, p3, p4) - end - if (self:isFocused()) then - local obx, oby = self:getAnchorPosition() - local xCur, yCur = pWindow.getCursorPos() - if (self.parent ~= nil) then - if (obx + xCur - 1 >= 1 and obx + xCur - 1 <= obx + self.width - 1 and yCur + oby - 1 >= 1 and yCur + oby - 1 <= oby + self.height - 1) then - self.parent:setCursor(pWindow.getCursorBlink(), obx + xCur - 1, yCur + oby - 1, pWindow.getTextColor()) - end - end - - if (event == "terminate") and (self:isFocused()) then - self:stop() - end - end - else - if (event ~= "mouse_click") and (event ~= "monitor_touch") and (event ~= "mouse_up") and (event ~= "mouse_scroll") and (event ~= "mouse_drag") and (event ~= "key_up") and (event ~= "key") and (event ~= "char") and (event ~= "terminate") then - table.insert(queuedEvent, { event = event, args = { p1, p2, p3, p4 } }) - end - end - end - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - pWindow.basalt_reposition(obx, oby) - if(self.bgColor~=false)then - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - end - pWindow.basalt_update() - end - self:setVisualChanged(false) - end - end; - - } - - return setmetatable(object, base) -end \ No newline at end of file diff --git a/oldVersions/lastVersion/source/project/objects/Progressbar.lua b/oldVersions/lastVersion/source/project/objects/Progressbar.lua deleted file mode 100644 index 9ed1d0c..0000000 --- a/oldVersions/lastVersion/source/project/objects/Progressbar.lua +++ /dev/null @@ -1,100 +0,0 @@ -local function Progressbar(name) - -- Checkbox - local base = Object(name) - local objectType = "Progressbar" - - local progress = 0 - - base:setZIndex(5) - base:setValue(false) - base.width = 25 - base.height = 1 - base.bgColor = theme.CheckboxBG - base.fgColor = theme.CheckboxFG - - local activeBarColor = colors.black - local activeBarSymbol = "" - local activeBarSymbolCol = colors.white - local bgBarSymbol = "" - local direction = 0 - - local object = { - - getType = function(self) - return objectType - end; - - setDirection = function(self, dir) - direction = dir - return self - end; - - setProgressBar = function(self, color, symbol, symbolcolor) - activeBarColor = color or activeBarColor - activeBarSymbol = symbol or activeBarSymbol - activeBarSymbolCol = symbolcolor or activeBarSymbolCol - return self - end; - - setBackgroundSymbol = function(self, symbol) - bgBarSymbol = symbol:sub(1, 1) - return self - end; - - setProgress = function(self, value) - if (value >= 0) and (value <= 100) and (progress ~= value) then - progress = value - self:setValue(progress) - if (progress == 100) then - self:progressDoneHandler() - end - end - return self - end; - - getProgress = function(self) - return progress - end; - - onProgressDone = function(self, f) - self:registerEvent("progress_done", f) - return self - end; - - progressDoneHandler = function(self) - self:sendEvent("progress_done", self) - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - self.parent:drawForegroundBox(obx, oby, self.width, self.height, self.fgColor) - self.parent:drawTextBox(obx, oby, self.width, self.height, bgBarSymbol) - if (direction == 1) then - self.parent:drawBackgroundBox(obx, oby, self.width, self.height / 100 * progress, activeBarColor) - self.parent:drawForegroundBox(obx, oby, self.width, self.height / 100 * progress, activeBarSymbolCol) - self.parent:drawTextBox(obx, oby, self.width, self.height / 100 * progress, activeBarSymbol) - elseif (direction == 2) then - self.parent:drawBackgroundBox(obx, oby + math.ceil(self.height - self.height / 100 * progress), self.width, self.height / 100 * progress, activeBarColor) - self.parent:drawForegroundBox(obx, oby + math.ceil(self.height - self.height / 100 * progress), self.width, self.height / 100 * progress, activeBarSymbolCol) - self.parent:drawTextBox(obx, oby + math.ceil(self.height - self.height / 100 * progress), self.width, self.height / 100 * progress, activeBarSymbol) - elseif (direction == 3) then - self.parent:drawBackgroundBox(obx + math.ceil(self.width - self.width / 100 * progress), oby, self.width / 100 * progress, self.height, activeBarColor) - self.parent:drawForegroundBox(obx + math.ceil(self.width - self.width / 100 * progress), oby, self.width / 100 * progress, self.height, activeBarSymbolCol) - self.parent:drawTextBox(obx + math.ceil(self.width - self.width / 100 * progress), oby, self.width / 100 * progress, self.height, activeBarSymbol) - else - self.parent:drawBackgroundBox(obx, oby, self.width / 100 * progress, self.height, activeBarColor) - self.parent:drawForegroundBox(obx, oby, self.width / 100 * progress, self.height, activeBarSymbolCol) - self.parent:drawTextBox(obx, oby, self.width / 100 * progress, self.height, activeBarSymbol) - end - end - self:setVisualChanged(false) - end - end; - - } - - return setmetatable(object, base) -end \ No newline at end of file diff --git a/oldVersions/lastVersion/source/project/objects/Radio.lua b/oldVersions/lastVersion/source/project/objects/Radio.lua deleted file mode 100644 index 7a32766..0000000 --- a/oldVersions/lastVersion/source/project/objects/Radio.lua +++ /dev/null @@ -1,125 +0,0 @@ -local function Radio(name) - local base = Object(name) - local objectType = "Radio" - base.width = 8 - base.bgColor = theme.listBG - base.fgColor = theme.listFG - base:setZIndex(5) - - local list = {} - local itemSelectedBG = theme.selectionBG - local itemSelectedFG = theme.selectionFG - local boxSelectedBG = base.bgColor - local boxSelectedFG = base.fgColor - local selectionColorActive = true - local symbol = "\7" - local align = "left" - - local object = { - getType = function(self) - return objectType - end; - - addItem = function(self, text, x, y, bgCol, fgCol, ...) - table.insert(list, { x = x or 1, y = y or 1, text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } }) - if (#list == 1) then - self:setValue(list[1]) - end - return self - end; - - getAll = function(self) - return list - end; - - removeItem = function(self, index) - table.remove(list, index) - return self - end; - - getItem = function(self, index) - return list[index] - end; - - getItemIndex = function(self) - local selected = self:getValue() - for key, value in pairs(list) do - if (value == selected) then - return key - end - end - end; - - clear = function(self) - list = {} - self:setValue({}) - return self - end; - - getItemCount = function(self) - return #list - end; - - editItem = function(self, index, text, x, y, bgCol, fgCol, ...) - table.remove(list, index) - table.insert(list, index, { x = x or 1, y = y or 1, text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } }) - return self - end; - - selectItem = function(self, index) - self:setValue(list[index] or {}) - return self - end; - - setSelectedItem = function(self, bgCol, fgCol, boxBG, boxFG, active) - itemSelectedBG = bgCol or itemSelectedBG - itemSelectedFG = fgCol or itemSelectedFG - boxSelectedBG = boxBG or boxSelectedBG - boxSelectedFG = boxFG or boxSelectedFG - selectionColorActive = active - return self - end; - - mouseHandler = function(self, event, button, x, y) - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - if ((event == "mouse_click")and(button==1))or(event=="monitor_touch") then - if (#list > 0) then - for _, value in pairs(list) do - if (obx + value.x - 1 <= x) and (obx + value.x - 1 + value.text:len() + 2 >= x) and (oby + value.y - 1 == y) then - self:setValue(value) - if (self.parent ~= nil) then - self.parent:setFocusedObject(self) - end - --eventSystem:sendEvent(event, self, event, button, x, y) - self:setVisualChanged() - return true - end - end - end - end - return false - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - for _, value in pairs(list) do - if (value == self:getValue()) then - if (align == "left") then - self.parent:writeText(value.x + obx - 1, value.y + oby - 1, symbol, boxSelectedBG, boxSelectedFG) - self.parent:writeText(value.x + 2 + obx - 1, value.y + oby - 1, value.text, itemSelectedBG, itemSelectedFG) - end - else - self.parent:drawBackgroundBox(value.x + obx - 1, value.y + oby - 1, 1, 1, self.bgColor) - self.parent:writeText(value.x + 2 + obx - 1, value.y + oby - 1, value.text, value.bgCol, value.fgCol) - end - end - end - self:setVisualChanged(false) - end - end; - } - - return setmetatable(object, base) -end \ No newline at end of file diff --git a/oldVersions/lastVersion/source/project/objects/Scrollbar.lua b/oldVersions/lastVersion/source/project/objects/Scrollbar.lua deleted file mode 100644 index 2928547..0000000 --- a/oldVersions/lastVersion/source/project/objects/Scrollbar.lua +++ /dev/null @@ -1,130 +0,0 @@ -local function Scrollbar(name) - local base = Object(name) - local objectType = "Scrollbar" - - base.width = 1 - base.height = 8 - base.bgColor = colors.lightGray - base.fgColor = colors.gray - base:setValue(1) - base:setZIndex(2) - - local barType = "vertical" - local symbol = " " - local symbolColor = colors.black - local bgSymbol = "\127" - local maxValue = base.height - local index = 1 - local symbolSize = 1 - - local object = { - getType = function(self) - return objectType - end; - - setSymbol = function(self, _symbol) - symbol = _symbol:sub(1, 1) - self:setVisualChanged() - return self - end; - - setSymbolSize = function(self, size) - symbolSize = tonumber(size) or 1 - if (barType == "vertical") then - self:setValue(index - 1 * (maxValue / (self.height - (symbolSize - 1))) - (maxValue / (self.height - (symbolSize - 1)))) - elseif (barType == "horizontal") then - self:setValue(index - 1 * (maxValue / (self.width - (symbolSize - 1))) - (maxValue / (self.width - (symbolSize - 1)))) - end - self:setVisualChanged() - return self - end; - - setMaxValue = function(self, val) - maxValue = val - return self - end; - - setBackgroundSymbol = function(self, _bgSymbol) - bgSymbol = string.sub(_bgSymbol, 1, 1) - self:setVisualChanged() - return self - end; - - setSymbolColor = function(self, col) - symbolColor = col - self:setVisualChanged() - return self - end; - - setBarType = function(self, _typ) - barType = _typ:lower() - return self - end; - - mouseHandler = function(self, event, button, x, y) - if (base.mouseHandler(self, event, button, x, y)) then - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - if (((event == "mouse_click") or (event == "mouse_drag")) and (button == 1))or(event=="monitor_touch") then - if (barType == "horizontal") then - for _index = 0, self.width do - if (obx + _index == x) and (oby <= y) and (oby + self.height > y) then - index = math.min(_index + 1, self.width - (symbolSize - 1)) - self:setValue(maxValue / self.width * (index)) - self:setVisualChanged() - end - end - end - if (barType == "vertical") then - for _index = 0, self.height do - if (oby + _index == y) and (obx <= x) and (obx + self.width > x) then - index = math.min(_index + 1, self.height - (symbolSize - 1)) - self:setValue(maxValue / self.height * (index)) - self:setVisualChanged() - end - end - end - end - if (event == "mouse_scroll") then - index = index + button - if (index < 1) then - index = 1 - end - index = math.min(index, (barType == "vertical" and self.height or self.width) - (symbolSize - 1)) - self:setValue(maxValue / (barType == "vertical" and self.height or self.width) * index) - end - return true - end - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - if (barType == "horizontal") then - self.parent:writeText(obx, oby, bgSymbol:rep(index - 1), self.bgColor, self.fgColor) - self.parent:writeText(obx + index - 1, oby, symbol:rep(symbolSize), symbolColor, symbolColor) - self.parent:writeText(obx + index + symbolSize - 1, oby, bgSymbol:rep(self.width - (index + symbolSize - 1)), self.bgColor, self.fgColor) - end - - if (barType == "vertical") then - for n = 0, self.height - 1 do - - if (index == n + 1) then - for curIndexOffset = 0, math.min(symbolSize - 1, self.height) do - self.parent:writeText(obx, oby + n + curIndexOffset, symbol, symbolColor, symbolColor) - end - else - if (n + 1 < index) or (n + 1 > index - 1 + symbolSize) then - self.parent:writeText(obx, oby + n, bgSymbol, self.bgColor, self.fgColor) - end - end - end - end - end - self:setVisualChanged(false) - end - end; - } - - return setmetatable(object, base) -end \ No newline at end of file diff --git a/oldVersions/lastVersion/source/project/objects/Slider.lua b/oldVersions/lastVersion/source/project/objects/Slider.lua deleted file mode 100644 index 0227cf2..0000000 --- a/oldVersions/lastVersion/source/project/objects/Slider.lua +++ /dev/null @@ -1,129 +0,0 @@ -local function Slider(name) - local base = Object(name) - local objectType = "Slider" - - base.width = 8 - base.height = 1 - base.bgColor = colors.lightGray - base.fgColor = colors.gray - base:setValue(1) - - local barType = "horizontal" - local symbol = " " - local symbolColor = colors.black - local bgSymbol = "\140" - local maxValue = base.width - local index = 1 - local symbolSize = 1 - - local object = { - getType = function(self) - return objectType - end; - - setSymbol = function(self, _symbol) - symbol = _symbol:sub(1, 1) - self:setVisualChanged() - return self - end; - - setSymbolSize = function(self, size) - symbolSize = tonumber(size) or 1 - if (barType == "vertical") then - self:setValue(index - 1 * (maxValue / (self.height - (symbolSize - 1))) - (maxValue / (self.height - (symbolSize - 1)))) - elseif (barType == "horizontal") then - self:setValue(index - 1 * (maxValue / (self.width - (symbolSize - 1))) - (maxValue / (self.width - (symbolSize - 1)))) - end - self:setVisualChanged() - return self - end; - - setMaxValue = function(self, val) - maxValue = val - return self - end; - - setBackgroundSymbol = function(self, _bgSymbol) - bgSymbol = string.sub(_bgSymbol, 1, 1) - self:setVisualChanged() - return self - end; - - setSymbolColor = function(self, col) - symbolColor = col - self:setVisualChanged() - return self - end; - - setBarType = function(self, _typ) - barType = _typ:lower() - return self - end; - - mouseHandler = function(self, event, button, x, y) - if (base.mouseHandler(self, event, button, x, y)) then - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - if (((event == "mouse_click") or (event == "mouse_drag")) and (button == 1))or(event=="monitor_touch") then - if (barType == "horizontal") then - for _index = 0, self.width do - if (obx + _index == x) and (oby <= y) and (oby + self.height > y) then - index = math.min(_index + 1, self.width - (symbolSize - 1)) - self:setValue(maxValue / self.width * (index)) - self:setVisualChanged() - end - end - end - if (barType == "vertical") then - for _index = 0, self.height do - if (oby + _index == y) and (obx <= x) and (obx + self.width > x) then - index = math.min(_index + 1, self.height - (symbolSize - 1)) - self:setValue(maxValue / self.height * (index)) - self:setVisualChanged() - end - end - end - end - if (event == "mouse_scroll") then - index = index + button - if (index < 1) then - index = 1 - end - index = math.min(index, (barType == "vertical" and self.height or self.width) - (symbolSize - 1)) - self:setValue(maxValue / (barType == "vertical" and self.height or self.width) * index) - end - return true - end - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - if (barType == "horizontal") then - self.parent:writeText(obx, oby, bgSymbol:rep(index - 1), self.bgColor, self.fgColor) - self.parent:writeText(obx + index - 1, oby, symbol:rep(symbolSize), symbolColor, symbolColor) - self.parent:writeText(obx + index + symbolSize - 1, oby, bgSymbol:rep(self.width - (index + symbolSize - 1)), self.bgColor, self.fgColor) - end - - if (barType == "vertical") then - for n = 0, self.height - 1 do - - if (index == n + 1) then - for curIndexOffset = 0, math.min(symbolSize - 1, self.height) do - self.parent:writeText(obx, oby + n + curIndexOffset, symbol, symbolColor, symbolColor) - end - else - if (n + 1 < index) or (n + 1 > index - 1 + symbolSize) then - self.parent:writeText(obx, oby + n, bgSymbol, self.bgColor, self.fgColor) - end - end - end - end - end - self:setVisualChanged(false) - end - end; - } - - return setmetatable(object, base) -end \ No newline at end of file diff --git a/oldVersions/lastVersion/source/project/objects/Switch.lua b/oldVersions/lastVersion/source/project/objects/Switch.lua deleted file mode 100644 index 826f059..0000000 --- a/oldVersions/lastVersion/source/project/objects/Switch.lua +++ /dev/null @@ -1,68 +0,0 @@ -local function Switch(name) - local base = Object(name) - local objectType = "Switch" - - base.width = 2 - base.height = 1 - base.bgColor = colors.lightGray - base.fgColor = colors.gray - base:setValue(false) - base:setZIndex(5) - - local bgSymbol = colors.black - local inactiveBG = colors.red - local activeBG = colors.green - - local object = { - getType = function(self) - return objectType - end; - - setSymbolColor = function(self, symbolColor) - bgSymbol = symbolColor - self:setVisualChanged() - return self - end; - - setActiveBackground = function(self, bgcol) - activeBG = bgcol - self:setVisualChanged() - return self - end; - - setInactiveBackground = function(self, bgcol) - inactiveBG = bgcol - self:setVisualChanged() - return self - end; - - mouseHandler = function(self, event, button, x, y) - if (base.mouseHandler(self, event, button, x, y)) then - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - if ((event == "mouse_click") and (button == 1))or(event=="monitor_touch") then - self:setValue(not self:getValue()) - end - return true - end - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - if(self:getValue())then - self.parent:drawBackgroundBox(obx, oby, 1, self.height, activeBG) - self.parent:drawBackgroundBox(obx+1, oby, 1, self.height, bgSymbol) - else - self.parent:drawBackgroundBox(obx, oby, 1, self.height, bgSymbol) - self.parent:drawBackgroundBox(obx+1, oby, 1, self.height, inactiveBG) - end - end - self:setVisualChanged(false) - end - end; - } - - return setmetatable(object, base) -end \ No newline at end of file diff --git a/oldVersions/lastVersion/source/project/objects/Textfield.lua b/oldVersions/lastVersion/source/project/objects/Textfield.lua deleted file mode 100644 index 8225e1e..0000000 --- a/oldVersions/lastVersion/source/project/objects/Textfield.lua +++ /dev/null @@ -1,341 +0,0 @@ -local function Textfield(name) - local base = Object(name) - local objectType = "Textfield" - local hIndex, wIndex, textX, textY = 1, 1, 1, 1 - - local lines = { "" } - local keyWords = { [colors.purple] = { "break" } } - - base.width = 20 - base.height = 8 - base.bgColor = theme.textfieldBG - base.fgColor = theme.textfieldFG - base:setZIndex(5) - - local object = { - getType = function(self) - return objectType - end; - - getLines = function(self) - return lines - end; - - getLine = function(self, index) - return lines[index] or "" - end; - - editLine = function(self, index, text) - lines[index] = text or lines[index] - return self - end; - - addLine = function(self, text, index) - if (index ~= nil) then - table.insert(lines, index, text) - else - table.insert(lines, text) - end - return self - end; - - addKeyword = function(self, keyword, color) - - end; - - removeLine = function(self, index) - table.remove(lines, index or #lines) - if (#lines <= 0) then - table.insert(lines, "") - end - return self - end; - - getTextCursor = function(self) - return textX, textY - end; - - getFocusHandler = function(self) - base.getFocusHandler(self) - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - if (self.parent ~= nil) then - self.parent:setCursor(true, obx + textX - wIndex, oby + textY - hIndex, self.fgColor) - end - end - end; - - loseFocusHandler = function(self) - base.loseFocusHandler(self) - if (self.parent ~= nil) then - self.parent:setCursor(false) - end - end; - - keyHandler = function(self, event, key) - if (base.keyHandler(self, event, key)) then - local obx, oby = self:getAnchorPosition() - if (event == "key") then - if (key == keys.backspace) then - -- on backspace - if (lines[textY] == "") then - if (textY > 1) then - table.remove(lines, textY) - textX = lines[textY - 1]:len() + 1 - wIndex = textX - self.width + 1 - if (wIndex < 1) then - wIndex = 1 - end - textY = textY - 1 - end - elseif (textX <= 1) then - if (textY > 1) then - textX = lines[textY - 1]:len() + 1 - wIndex = textX - self.width + 1 - if (wIndex < 1) then - wIndex = 1 - end - lines[textY - 1] = lines[textY - 1] .. lines[textY] - table.remove(lines, textY) - textY = textY - 1 - end - else - lines[textY] = lines[textY]:sub(1, textX - 2) .. lines[textY]:sub(textX, lines[textY]:len()) - if (textX > 1) then - textX = textX - 1 - end - if (wIndex > 1) then - if (textX < wIndex) then - wIndex = wIndex - 1 - end - end - end - if (textY < hIndex) then - hIndex = hIndex - 1 - end - self:setValue("") - end - - if (key == keys.delete) then - -- on delete - if (textX > lines[textY]:len()) then - if (lines[textY + 1] ~= nil) then - lines[textY] = lines[textY] .. lines[textY + 1] - table.remove(lines, textY + 1) - end - else - lines[textY] = lines[textY]:sub(1, textX - 1) .. lines[textY]:sub(textX + 1, lines[textY]:len()) - end - end - - if (key == keys.enter) then - -- on enter - table.insert(lines, textY + 1, lines[textY]:sub(textX, lines[textY]:len())) - lines[textY] = lines[textY]:sub(1, textX - 1) - textY = textY + 1 - textX = 1 - wIndex = 1 - if (textY - hIndex >= self.height) then - hIndex = hIndex + 1 - end - self:setValue("") - end - - if (key == keys.up) then - -- arrow up - if (textY > 1) then - textY = textY - 1 - if (textX > lines[textY]:len() + 1) then - textX = lines[textY]:len() + 1 - end - if (wIndex > 1) then - if (textX < wIndex) then - wIndex = textX - self.width + 1 - if (wIndex < 1) then - wIndex = 1 - end - end - end - if (hIndex > 1) then - if (textY < hIndex) then - hIndex = hIndex - 1 - end - end - end - end - if (key == keys.down) then - -- arrow down - if (textY < #lines) then - textY = textY + 1 - if (textX > lines[textY]:len() + 1) then - textX = lines[textY]:len() + 1 - end - - if (textY >= hIndex + self.height) then - hIndex = hIndex + 1 - end - end - end - if (key == keys.right) then - -- arrow right - textX = textX + 1 - if (textY < #lines) then - if (textX > lines[textY]:len() + 1) then - textX = 1 - textY = textY + 1 - end - elseif (textX > lines[textY]:len()) then - textX = lines[textY]:len() + 1 - end - if (textX < 1) then - textX = 1 - end - if (textX < wIndex) or (textX >= self.width + wIndex) then - wIndex = textX - self.width + 1 - end - if (wIndex < 1) then - wIndex = 1 - end - - end - if (key == keys.left) then - -- arrow left - textX = textX - 1 - if (textX >= 1) then - if (textX < wIndex) or (textX >= self.width + wIndex) then - wIndex = textX - end - end - if (textY > 1) then - if (textX < 1) then - textY = textY - 1 - textX = lines[textY]:len() + 1 - wIndex = textX - self.width + 1 - end - end - if (textX < 1) then - textX = 1 - end - if (wIndex < 1) then - wIndex = 1 - end - end - end - - if (event == "char") then - lines[textY] = lines[textY]:sub(1, textX - 1) .. key .. lines[textY]:sub(textX, lines[textY]:len()) - textX = textX + 1 - if (textX >= self.width + wIndex) then - wIndex = wIndex + 1 - end - self:setValue("") - end - - local cursorX = (textX <= lines[textY]:len() and textX - 1 or lines[textY]:len()) - (wIndex - 1) - if (cursorX > self.x + self.width - 1) then - cursorX = self.x + self.width - 1 - end - local cursorY = (textY - hIndex < self.height and textY - hIndex or textY - hIndex - 1) - if (cursorX < 1) then - cursorX = 0 - end - self.parent:setCursor(true, obx + cursorX, oby + cursorY, self.fgColor) - return true - end - end; - - mouseHandler = function(self, event, button, x, y) - if (base.mouseHandler(self, event, button, x, y)) then - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - local anchx, anchy = self:getAnchorPosition() - if (event == "mouse_click")or(event=="monitor_touch") then - if (lines[y - oby + hIndex] ~= nil) then - textX = x - obx + wIndex - textY = y - oby + hIndex - if (textX > lines[textY]:len()) then - textX = lines[textY]:len() + 1 - end - if (textX < wIndex) then - wIndex = textX - 1 - if (wIndex < 1) then - wIndex = 1 - end - end - if (self.parent ~= nil) then - self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self.fgColor) - end - end - end - if (event == "mouse_drag") then - if (lines[y - oby + hIndex] ~= nil) then - textX = x - obx + wIndex - textY = y - oby + hIndex - if (textX > lines[textY]:len()) then - textX = lines[textY]:len() + 1 - end - if (textX < wIndex) then - wIndex = textX - 1 - if (wIndex < 1) then - wIndex = 1 - end - end - if (self.parent ~= nil) then - self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self.fgColor) - end - end - end - - if (event == "mouse_scroll") then - hIndex = hIndex + button - if (hIndex > #lines - (self.height - 1)) then - hIndex = #lines - (self.height - 1) - end - - if (hIndex < 1) then - hIndex = 1 - end - - if (self.parent ~= nil) then - if (obx + textX - wIndex >= obx and obx + textX - wIndex <= obx + self.width) and (oby + textY - hIndex >= oby and oby + textY - hIndex <= oby + self.height) then - self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self.fgColor) - else - self.parent:setCursor(false) - end - end - end - self:setVisualChanged() - return true - end - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - if(self.bgColor~=false)then - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - end - if(self.fgColor~=false)then - self.parent:drawForegroundBox(obx, oby, self.width, self.height, self.fgColor) - end - for n = 1, self.height do - local text = "" - if (lines[n + hIndex - 1] ~= nil) then - text = lines[n + hIndex - 1] - end - text = text:sub(wIndex, self.width + wIndex - 1) - local space = self.width - text:len() - if (space < 0) then - space = 0 - end - text = text .. string.rep(" ", space) - self.parent:setText(obx, oby + n - 1, text) - end - end - self:setVisualChanged(false) - end - end; - } - - return setmetatable(object, base) -end \ No newline at end of file diff --git a/oldVersions/lastVersion/source/project/objects/Thread.lua b/oldVersions/lastVersion/source/project/objects/Thread.lua deleted file mode 100644 index 41f9e5c..0000000 --- a/oldVersions/lastVersion/source/project/objects/Thread.lua +++ /dev/null @@ -1,69 +0,0 @@ -local function Thread(name) - local object - local objectType = "Thread" - - local func - local cRoutine - local isActive = false - - object = { - name = name, - getType = function(self) - return objectType - end; - getZIndex = function(self) - return 1 - end; - getName = function(self) - return self.name - end; - - start = function(self, f) - if (f == nil) then - error("Function provided to thread is nil") - end - func = f - cRoutine = coroutine.create(func) - isActive = true - local ok, result = coroutine.resume(cRoutine) - if not (ok) then - if (result ~= "Terminated") then - error("Thread Error Occurred - " .. result) - end - end - return self - end; - - getStatus = function(self, f) - if (cRoutine ~= nil) then - return coroutine.status(cRoutine) - end - return nil - end; - - stop = function(self, f) - isActive = false - return self - end; - - eventHandler = function(self, event, p1, p2, p3) - if (isActive) then - if (coroutine.status(cRoutine) ~= "dead") then - local ok, result = coroutine.resume(cRoutine, event, p1, p2, p3) - if not (ok) then - if (result ~= "Terminated") then - error("Thread Error Occurred - " .. result) - end - end - else - isActive = false - end - end - end; - - } - - object.__index = object - - return object -end \ No newline at end of file diff --git a/oldVersions/lastVersion/source/project/objects/Timer.lua b/oldVersions/lastVersion/source/project/objects/Timer.lua deleted file mode 100644 index 0f5e9b8..0000000 --- a/oldVersions/lastVersion/source/project/objects/Timer.lua +++ /dev/null @@ -1,75 +0,0 @@ -local function Timer(name) - local objectType = "Timer" - - local timer = 0 - local savedRepeats = 0 - local repeats = 0 - local timerObj - local eventSystem = BasaltEvents() - local timerIsActive = false - - local object = { - name = name, - getType = function(self) - return objectType - end; - - getZIndex = function(self) - return 1 - end; - - getName = function(self) - return self.name - end; - - setTime = function(self, _timer, _repeats) - timer = _timer or 0 - savedRepeats = _repeats or 1 - return self - end; - - start = function(self) - if(timerIsActive)then - os.cancelTimer(timerObj) - end - repeats = savedRepeats - timerObj = os.startTimer(timer) - timerIsActive = true - return self - end; - - isActive = function(self) - return timerIsActive - end; - - cancel = function(self) - if (timerObj ~= nil) then - os.cancelTimer(timerObj) - end - timerIsActive = false - return self - end; - - onCall = function(self, func) - eventSystem:registerEvent("timed_event", func) - return self - end; - - eventHandler = function(self, event, tObj) - if event == "timer" and tObj == timerObj and timerIsActive then - eventSystem:sendEvent("timed_event", self) - if (repeats >= 1) then - repeats = repeats - 1 - if (repeats >= 1) then - timerObj = os.startTimer(timer) - end - elseif (repeats == -1) then - timerObj = os.startTimer(timer) - end - end - end; - } - object.__index = object - - return object -end \ No newline at end of file diff --git a/oldVersions/lastVersion/source/project/objects/example.lua b/oldVersions/lastVersion/source/project/objects/example.lua deleted file mode 100644 index 288b904..0000000 --- a/oldVersions/lastVersion/source/project/objects/example.lua +++ /dev/null @@ -1,45 +0,0 @@ -local function Example(name) -- you can call this function how you want, doesn't matter - local base = Object(name) -- this will load the base object class, it is necessary if you want to make a visual object, otherwise you dont need that. - local objectType = "Example" -- here is the object type, make sure it is the same as the file name - this way you can also make sure its unique - - -- here you could set some default values, but its not necessary, it doesn't matter if you call the functions or change the values directly, maybe i should change that - --i guess its better if you call functions base:setBackground, base:setSize and so on. - base.width = 12 - base.height = 1 - base.bgColor = colors.lightGray - base.fgColor = colors.gray - base:setValue(false) - base:setZIndex(5) -- if you want to change the zIndex always use the function - - local object = { -- here you start your unique object class, please always make sure a getType exists! - getType = function(self) - return objectType - end; - - - mouseClickHandler = function(self, event, button, x, y) -- this is your extended mouseClickHandler, if you want something to happen if the user clicks on that - if (base.mouseClickHandler(self, event, button, x, y)) then -- here you access the base class mouseClickHandler it will return true if the user really clicks on the object - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) --getAnchorPosition is obviously for returning the x and y coords changed by the anchor system, absolute position explains itself i guess - if ((event == "mouse_click") or (event == "mouse_drag")) and (button == 1) then - --here you can create your logic - end - return true -- please always return true if base.mouseClickHandler also returns true, otherwise your object wont get focused. - end - end; - - draw = function(self) -- if your object is visual, you will need a draw function - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - --self.parent:drawBackgroundbox(obx, oby, self.width, self.height, self.bgColor) -- changes the background color of that object - --self.parent:drawForegroundbox(obx, oby, self.width, self.height, self.fgColor) -- changes the foreground (textcolor) color of that object - --self.parent:writeText(obx, oby, "Some Text", self.bgColor, self.fgColor) -- writes something on the screen, also able to change its bgcolor and fgcolor - - --the draw functions always gets called after something got visually changed. I am always redrawing the entire screen, but only if something has changed. - end - end - end; - } - - return setmetatable(object, base) -- required -end \ No newline at end of file diff --git a/oldVersions/lastVersion/source/readme.md b/oldVersions/lastVersion/source/readme.md deleted file mode 100644 index b371661..0000000 --- a/oldVersions/lastVersion/source/readme.md +++ /dev/null @@ -1,23 +0,0 @@ -# How to use the source code - -The source code is for people who want to change something directly in basalt. You can add/remove objects, add/remove libs or change the drawsystem, eventsystem or whatever you want. For example, you can remove objects you just dont use for a more compact (smaller) basalt. Or you want to create your own objects and add it to the project. - -My goal is to make basalt for end users very very easy to use, this is why i want basalt to be in one single file. But this also makes working on it, especially if multiple people working on basalt, very very hard. Because of that i did split the project into multiple file. - -## Project - -The project folder is the actual source code of basalt. Objects are in project/objects and libraries are in project/lib - -## compiler.lua - -The compiler will create a basalt.lua file based off of the project's content. It will automatically minify the result. To use the compiler.lua just execute it (make sure the paths are correct, just edit the file and change the absolutepath variable on the top - -## loader.lua - -The loader file will load the source project into your program, where you can immediately work with the source code instead of always having to compile the code before you can see the changes. Just use local basalt = dofile("source/loader.lua") instead of basalt = dofile("basalt.lua") - -## Important - -- The source project is still in developement and some things might not work as intended. -- The minify feature is still not implemented. -- The project folder's content could be completly changed, because i am not fully happy on how it looks like diff --git a/oldVersions/old/basalt.lua b/oldVersions/old/basalt.lua deleted file mode 100644 index 1b42a78..0000000 --- a/oldVersions/old/basalt.lua +++ /dev/null @@ -1 +0,0 @@ -local a={basaltBG=colors.lightGray,basaltFG=colors.black,FrameBG=colors.gray,FrameFG=colors.black,ButtonBG=colors.gray,ButtonFG=colors.black,CheckboxBG=colors.gray,CheckboxFG=colors.black,InputBG=colors.gray,InputFG=colors.black,textfieldBG=colors.gray,textfieldFG=colors.black,listBG=colors.gray,listFG=colors.black,dropdownBG=colors.gray,dropdownFG=colors.black,radioBG=colors.gray,radioFG=colors.black,selectionBG=colors.black,selectionFG=colors.lightGray}local b={debugger=true,version=1}local c;local d={}local e={}local f=term.current()local g=string.sub;local function h(i,j,k)i=string.sub(i,1,j)local l=j-string.len(i)if k=="right"then i=string.rep(" ",l)..i elseif k=="center"then i=string.rep(" ",math.floor(l/2))..i..string.rep(" ",math.floor(l/2))i=i..(string.len(i)=1 and O<=u then if N+i:len()>0 and N<=j then local P=v[O]local Q;local R=N+#i-1;if N<1 then local S=1-N+1;local T=j-N+1;i=g(i,S,T)elseif R>j then local T=j-N+1;i=g(i,1,T)end;if N>1 then local T=N-1;Q=g(P,1,T)..i else Q=i end;if R=1 and O<=u then if N+V:len()>0 and N<=j then local P=w[O]local Q;local R=N+#V-1;if N<1 then V=g(V,1-N+1,j-N+1)elseif R>j then V=g(V,1,j-N+1)end;if N>1 then Q=g(P,1,N-1)..V else Q=V end;if R=1 and O<=u then if N+V:len()>0 and N<=j then local P=x[O]local Q;local R=N+#V-1;if N<1 then local S=1-N+1;local T=j-N+1;V=g(V,S,T)elseif R>j then local T=j-N+1;V=g(V,1,T)end;if N>1 then local T=N-1;Q=g(P,1,T)..V else Q=V end;if RN and aM<=O and aM+self.height>O and as then if self.parent~=nil then self.parent:setFocusedObject(self)end;au:sendEvent(a7,self,a7,aK,N,O)return true end;return false end,keyHandler=function(self,a7,aN)if self:isFocused()then au:sendEvent(a7,self,a7,aN)return true end;return false end,backgroundKeyHandler=function(self,a7,aN)au:sendEvent("background_"..a7,self,a7,aN)end,valueChangedHandler=function(self)au:sendEvent("value_changed",self)end,eventHandler=function(self,a7,aO,aP,aQ,aR)au:sendEvent("custom_event_handler",self,a7,aO,aP,aQ,aR)end,getFocusHandler=function(self)au:sendEvent("get_focus",self)end,loseFocusHandler=function(self)au:sendEvent("lose_focus",self)end}av.__index=av;return av end;local function aS(am)local aT=al(am)local an="Button"aT:setValue("Button")aT:setZIndex(5)aT.width=8;aT.bgColor=a.ButtonBG;aT.fgColor=a.ButtonFG;local aU="center"local aV="center"local av={getType=function(self)return an end,setHorizontalAlign=function(self,aW)aU=aW end,setVerticalAlign=function(self,aW)aV=aW end,setText=function(self,i)aT:setValue(i)return self end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()local aZ=m(self.height,aV)self.parent:drawBackgroundBox(aX,aY,self.width,self.height,self.bgColor)self.parent:drawForegroundBox(aX,aY,self.width,self.height,self.fgColor)self.parent:drawTextBox(aX,aY,self.width,self.height," ")for E=1,self.height do if E==aZ then self.parent:setText(aX,aY+E-1,h(self:getValue(),self.width,aU))end end end end end}return setmetatable(av,aT)end;local function a_(am)local aT=al(am)local an="Program"aT:setZIndex(5)local av;local function b0(N,O,j,u)local b1,b2=1,1;local b3,b4=colors.black,colors.white;local b5=false;local b6=false;local v={}local w={}local x={}local b7={}local B;local C={}for q=0,15 do local b8=2^q;b7[b8]={f.getPaletteColour(b8)}end;local function D()B=(" "):rep(j)for E=0,15 do local F=2^E;local G=r[F]C[F]=G:rep(j)end end;local function H()D()local I=B;local J=C[colors.white]local K=C[colors.black]for E=1,u do v[E]=g(v[E]==nil and I or v[E]..I:sub(1,j-v[E]:len()),1,j)x[E]=g(x[E]==nil and J or x[E]..J:sub(1,j-x[E]:len()),1,j)w[E]=g(w[E]==nil and K or w[E]..K:sub(1,j-w[E]:len()),1,j)end end;H()local function b9()if b1>=1 and b2>=1 and b1<=j and b2<=u then else end end;local function ba(bb,bc,bd)local be=b1;local R=be+#bb-1;if b2>=1 and b2<=u then if be<=j and R>=1 then if be==1 and R==j then v[b2]=bb;x[b2]=bc;w[b2]=bd else local bf,bg,bh;if be<1 then local bi=1-be+1;local bj=j-be+1;bf=g(bb,bi,bj)bg=g(bc,bi,bj)bh=g(bd,bi,bj)elseif R>j then local bj=j-be+1;bf=g(bb,1,bj)bg=g(bc,1,bj)bh=g(bd,1,bj)else bf=bb;bg=bc;bh=bd end;local bk=v[b2]local bl=x[b2]local bm=w[b2]local bn,bo,bp;if be>1 then local bq=be-1;bn=g(bk,1,bq)..bf;bo=g(bl,1,bq)..bg;bp=g(bm,1,bq)..bh else bn=bf;bo=bg;bp=bh end;if R=1 and O<=u then v[bO]=v[O]w[bO]=w[O]x[bO]=x[O]else v[bO]=bL;x[bO]=bM;w[bO]=bN end end end;if b6 then b9()end end,isColor=function()return f.isColor()end,isColour=function()return f.isColor()end,write=function(i)i=tostring(i)if b6 then ba(i,r[b4]:rep(i:len()),r[b3]:rep(i:len()))end end,clearLine=function()if b6 then M(1,b2,(" "):rep(j))U(1,b2,r[b3]:rep(j))W(1,b2,r[b4]:rep(j))end;if b6 then b9()end end,clear=function()for E=1,u do M(1,E,(" "):rep(j))U(1,E,r[b3]:rep(j))W(1,E,r[b4]:rep(j))end;if b6 then b9()end end,blit=function(i,bP,bQ)if type(i)~="string"then error("bad argument #1 (expected string, got "..type(i)..")",2)end;if type(bP)~="string"then error("bad argument #2 (expected string, got "..type(bP)..")",2)end;if type(bQ)~="string"then error("bad argument #3 (expected string, got "..type(bQ)..")",2)end;if#bP~=#i or#bQ~=#i then error("Arguments must be the same length",2)end;if b6 then ba(i,bP,bQ)end end}return bG end;aT.width=30;aT.height=12;local bR=b0(1,1,aT.width,aT.height)local bS;local bT=false;local bU={}av={getType=function(self)return an end,show=function(self)aT.show(self)bR.setBackgroundColor(self.bgColor)bR.setTextColor(self.fgColor)bR.basalt_setVisible(true)return self end,hide=function(self)aT.hide(self)bR.basalt_setVisible(false)return self end,setPosition=function(self,N,O,aB)aT.setPosition(self,N,O,aB)bR.basalt_reposition(self:getAnchorPosition())return self end,getBasaltWindow=function()return bR end,getBasaltProcess=function()return bS end,setSize=function(self,j,u)aT.setSize(self,j,u)bR.basalt_resize(self.width,self.height)return self end,getStatus=function(self)if bS~=nil then return bS:getStatus()end;return"inactive"end,execute=function(self,af,...)bS=ad:new(af,bR,...)bR.setBackgroundColor(colors.black)bR.setTextColor(colors.white)bR.clear()bR.setCursorPos(1,1)bS:resume()bT=false;return self end,stop=function(self)if bS~=nil then if not bS:isDead()then bS:resume("terminate")if bS:isDead()then if self.parent~=nil then self.parent:setCursor(false)end end end end;return self end,pause=function(self,bV)bT=bV or not bT;if bS~=nil then if not bS:isDead()then if not bT then self:injectEvents(bU)bU={}end end end;return self end,isPaused=function(self)return bT end,injectEvent=function(self,a7,aO,aP,aQ,aR,bW)if bS~=nil then if not bS:isDead()then if bT==false or bW then bS:resume(a7,aO,aP,aQ,aR)else table.insert(bU,{event=a7,args={aO,aP,aQ,aR}})end end end;return self end,getQueuedEvents=function(self)return bU end,updateQueuedEvents=function(self,a5)bU=a5 or bU;return self end,injectEvents=function(self,a5)if bS~=nil then if not bS:isDead()then for aa,ab in pairs(a5)do bS:resume(ab.event,table.unpack(ab.args))end end end;return self end,mouseClickHandler=function(self,a7,aK,N,O)if aT.mouseClickHandler(self,a7,aK,N,O)then if bS==nil then return false end;if not bS:isDead()then if not bT then local bX,bY=self:getAbsolutePosition(self:getAnchorPosition(nil,nil,true))bS:resume(a7,aK,N-bX+1,O-bY+1)end end;return true end end,keyHandler=function(self,a7,aN)aT.keyHandler(self,a7,aN)if self:isFocused()then if bS==nil then return false end;if not bS:isDead()then if not bT then if self.draw then bS:resume(a7,aN)end end end end end,getFocusHandler=function(self)aT.getFocusHandler(self)if bS~=nil then if not bS:isDead()then if not bT then if self.parent~=nil then local bZ,b_=bR.getCursorPos()local aX,aY=self:getAnchorPosition()if self.parent~=nil then if aX+bZ-1>=1 and aX+bZ-1<=aX+self.width-1 and b_+aY-1>=1 and b_+aY-1<=aY+self.height-1 then self.parent:setCursor(bR.getCursorBlink(),aX+bZ-1,b_+aY-1,bR.getTextColor())end end end end end end end,loseFocusHandler=function(self)aT.loseFocusHandler(self)if bS~=nil then if not bS:isDead()then if self.parent~=nil then self.parent:setCursor(false)end end end end,eventHandler=function(self,a7,aO,aP,aQ,aR)if bS==nil then return end;if not bS:isDead()then if not bT then if a7~="mouse_click"and a7~="mouse_up"and a7~="mouse_scroll"and a7~="mouse_drag"and a7~="key_up"and a7~="key"and a7~="char"and a7~="terminate"then bS:resume(a7,aO,aP,aQ,aR)end;if self:isFocused()then local aX,aY=self:getAnchorPosition()local bZ,b_=bR.getCursorPos()if self.parent~=nil then if aX+bZ-1>=1 and aX+bZ-1<=aX+self.width-1 and b_+aY-1>=1 and b_+aY-1<=aY+self.height-1 then self.parent:setCursor(bR.getCursorBlink(),aX+bZ-1,b_+aY-1,bR.getTextColor())end end;if a7=="terminate"and self:isFocused()then self:stop()end end else if a7~="mouse_click"and a7~="mouse_up"and a7~="mouse_scroll"and a7~="mouse_drag"and a7~="key_up"and a7~="key"and a7~="char"and a7~="terminate"then table.insert(bU,{event=a7,args={aO,aP,aQ,aR}})end end end end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()bR.basalt_reposition(aX,aY)self.parent:drawBackgroundBox(aX,aY,self.width,self.height,self.bgColor)bR.basalt_update()end end end}return setmetatable(av,aT)end;local function c0(am)local aT=al(am)local an="Label"aT:setZIndex(3)local c1=true;aT:setValue("")local av={getType=function(self)return an end,setText=function(self,i)i=tostring(i)aT:setValue(i)if c1 then self.width=i:len()end;return self end,setSize=function(self,j,n)self.width,self.height=j,n;c1=false;return self end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()self.parent:writeText(aX,aY,self:getValue(),self.bgColor,self.fgColor)end end end}return setmetatable(av,aT)end;local function c2(am)local aT=al(am)local an="Pane"local av={getType=function(self)return an end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()self.parent:drawBackgroundBox(aX,aY,self.width,self.height,self.bgColor)self.parent:drawForegroundBox(aX,aY,self.width,self.height,self.bgColor)end end end}return setmetatable(av,aT)end;local function c3(am)local aT=al(am)local an="Image"aT:setZIndex(2)local c4;local c5;local c6=false;local function c7()local c8={[0]={8,4,3,6,5},{4,14,8,7},{6,10,8,7},{9,11,8,0},{1,14,8,0},{13,12,8,0},{2,10,8,0},{15,8,10,11,12,14},{0,7,1,9,2,13},{3,11,8,7},{2,6,7,15},{9,3,7,15},{13,5,7,15},{5,12,8,7},{1,4,7,15},{7,10,11,12,14}}local c9,ca,cb={},{},{}for q=0,15 do ca[2^q]=q end;do local cc="0123456789abcdef"for q=1,16 do c9[cc:sub(q,q)]=q-1;c9[q-1]=cc:sub(q,q)cb[cc:sub(q,q)]=2^(q-1)cb[2^(q-1)]=cc:sub(q,q)local cd=c8[q-1]for q=1,#cd do cd[q]=2^cd[q]end end end;local function ce(cf)local cg=c8[ca[cf[#cf][1]]]for ch=1,#cg do local ci=cg[ch]for q=1,#cf-1 do if cf[q][1]==ci then return q end end end;return 1 end;local function cj(ck,cl)if not cl then local cm={}cl={}for q=1,6 do local cn=ck[q]local co=cl[cn]cl[cn],cm[q]=co and co+1 or 1,cn end;ck=cm end;local cf={}for aN,ab in pairs(cl)do cf[#cf+1]={aN,ab}end;if#cf>1 then while#cf>2 do table.sort(cf,function(cp,bD)return cp[2]>bD[2]end)local cq,cr=ce(cf),#cf;local cs,ct=cf[cr][1],cf[cq][1]for q=1,6 do if ck[q]==cs then ck[q]=ct;cf[cq][2]=cf[cq][2]+1 end end;cf[cr]=nil end;local cu=128;for q=1,#ck-1 do if ck[q]~=ck[6]then cu=cu+2^(q-1)end end;return string.char(cu),cb[cf[1][1]==ck[6]and cf[2][1]or cf[1][1]],cb[ck[6]]else return"\128",cb[ck[1]],cb[ck[1]]end end;local cv,j,u,Y={{},{},{}},0,#c4+#c4%3,aT.bgColor or colors.black;for q=1,#c4 do if#c4[q]>j then j=#c4[q]end end;for O=0,u-1,3 do local cw,cx,cy,cz={},{},{},1;for N=0,j-1,2 do local ck,cl={},{}for cA=1,3 do for cB=1,2 do ck[#ck+1]=c4[O+cA]and c4[O+cA][N+cB]and(c4[O+cA][N+cB]==0 and Y or c4[O+cA][N+cB])or Y;cl[ck[#ck]]=cl[ck[#ck]]and cl[ck[#ck]]+1 or 1 end end;cw[cz],cx[cz],cy[cz]=cj(ck,cl)cz=cz+1 end;cv[1][#cv[1]+1],cv[2][#cv[2]+1],cv[3][#cv[3]+1]=table.concat(cw),table.concat(cx),table.concat(cy)end;cv.width,cv.height=#cv[1][1],#cv[1]c5=cv end;local av={getType=function(self)return an end,loadImage=function(self,af)c4=paintutils.loadImage(af)c6=false;return self end,loadBlittleImage=function(self,af)c6=true;return self end,shrinkImage=function(self)c7()c6=true;return self end,draw=function(self)if aT.draw(self)then if self.parent~=nil then if c4~=nil then local aX,aY=self:getAnchorPosition()if c6 then local p,cC,cD=c5[1],c5[2],c5[3]for q=1,c5.height do local cE=p[q]if type(cE)=="string"then self.parent:setText(aX,aY+q-1,cE)self.parent:setFG(aX,aY+q-1,cC[q])self.parent:setBG(aX,aY+q-1,cD[q])elseif type(cE)=="table"then self.parent:setText(aX,aY+q-1,cE[2])self.parent:setFG(aX,aY+q-1,cC[q])self.parent:setBG(aX,aY+q-1,cD[q])end end else for aA=1,math.min(#c4,self.height)do local cF=c4[aA]for az=1,math.min(#cF,self.width)do if cF[az]>0 then self.parent:drawBackgroundBox(aX+az-1,aY+aA-1,1,1,cF[az])end end end end end end end end}return setmetatable(av,aT)end;local function cG(am)local aT=al(am)local an="Checkbox"aT:setZIndex(5)aT:setValue(false)aT.width=1;aT.height=1;aT.bgColor=a.CheckboxBG;aT.fgColor=a.CheckboxFG;local av={symbol="\42",getType=function(self)return an end,mouseClickHandler=function(self,a7,aK,N,O)if aT.mouseClickHandler(self,a7,aK,N,O)then if a7=="mouse_click"and aK==1 then if self:getValue()~=true and self:getValue()~=false then self:setValue(false)else self:setValue(not self:getValue())end end;return true end;return false end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()local aZ=m(self.height,"center")self.parent:drawBackgroundBox(aX,aY,self.width,self.height,self.bgColor)for E=1,self.height do if E==aZ then if self:getValue()==true then self.parent:writeText(aX,aY+E-1,h(self.symbol,self.width,"center"),self.bgColor,self.fgColor)else self.parent:writeText(aX,aY+E-1,h(" ",self.width,"center"),self.bgColor,self.fgColor)end end end end end end}return setmetatable(av,aT)end;local function cH(am)local aT=al(am)local an="Progressbar"local cI=0;aT:setZIndex(5)aT:setValue(false)aT.width=25;aT.height=1;aT.bgColor=a.CheckboxBG;aT.fgColor=a.CheckboxFG;local cJ=colors.black;local cK=""local cL=colors.white;local cM=""local cN=0;local av={getType=function(self)return an end,setDirection=function(self,cO)cN=cO;return self end,setProgressBar=function(self,aD,_,cP)cJ=aD or cJ;cK=_ or cK;cL=cP or cL;return self end,setBackgroundSymbol=function(self,_)cM=_:sub(1,1)return self end,setProgress=function(self,ab)if ab>=0 and ab<=100 and cI~=ab then cI=ab;self:setValue(cI)if cI==100 then self:progressDoneHandler()end end;return self end,getProgress=function(self)return cI end,onProgressDone=function(self,cQ)self:registerEvent("progress_done",cQ)return self end,progressDoneHandler=function(self)self:sendEvent("progress_done")end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()self.parent:drawBackgroundBox(aX,aY,self.width,self.height,self.bgColor)self.parent:drawForegroundBox(aX,aY,self.width,self.height,self.fgColor)self.parent:drawTextBox(aX,aY,self.width,self.height,cM)if cN==1 then self.parent:drawBackgroundBox(aX,aY,self.width,self.height/100*cI,cJ)self.parent:drawForegroundBox(aX,aY,self.width,self.height/100*cI,cL)self.parent:drawTextBox(aX,aY,self.width,self.height/100*cI,cK)elseif cN==2 then self.parent:drawBackgroundBox(aX,aY+math.ceil(self.height-self.height/100*cI),self.width,self.height/100*cI,cJ)self.parent:drawForegroundBox(aX,aY+math.ceil(self.height-self.height/100*cI),self.width,self.height/100*cI,cL)self.parent:drawTextBox(aX,aY+math.ceil(self.height-self.height/100*cI),self.width,self.height/100*cI,cK)elseif cN==3 then self.parent:drawBackgroundBox(aX+math.ceil(self.width-self.width/100*cI),aY,self.width/100*cI,self.height,cJ)self.parent:drawForegroundBox(aX+math.ceil(self.width-self.width/100*cI),aY,self.width/100*cI,self.height,cL)self.parent:drawTextBox(aX+math.ceil(self.width-self.width/100*cI),aY,self.width/100*cI,self.height,cK)else self.parent:drawBackgroundBox(aX,aY,self.width/100*cI,self.height,cJ)self.parent:drawForegroundBox(aX,aY,self.width/100*cI,self.height,cL)self.parent:drawTextBox(aX,aY,self.width/100*cI,self.height,cK)end end end end}return setmetatable(av,aT)end;local function cR(am)local aT=al(am)local an="Input"local cS="text"local cT=0;aT:setZIndex(5)aT:setValue("")aT.width=10;aT.height=1;aT.bgColor=a.InputBG;aT.fgColor=a.InputFG;local cU=1;local cV=1;local cW=""local cX;local cY;local cZ=cW;local c_=false;local av={getType=function(self)return an end,setInputType=function(self,d0)if d0=="password"or d0=="number"or d0=="text"then cS=d0 end;return self end,setDefaultText=function(self,i,d1,d2)cW=i;cX=d2 or cX;cY=d1 or cY;if self:isFocused()then cZ=""else cZ=cW end;return self end,getInputType=function(self)return cS end,setValue=function(self,d3)aT.setValue(self,tostring(d3))if not c_ then cU=tostring(d3):len()+1 end;return self end,getValue=function(self)local d3=aT.getValue(self)return cS=="number"and tonumber(d3)or d3 end,setInputLimit=function(self,d4)cT=tonumber(d4)or cT;return self end,getInputLimit=function(self)return cT end,getFocusHandler=function(self)aT.getFocusHandler(self)if self.parent~=nil then local aX,aY=self:getAnchorPosition()cZ=""if self.parent~=nil then self.parent:setCursor(true,aX+cU-cV,aY,self.fgColor)end end end,loseFocusHandler=function(self)aT.loseFocusHandler(self)if self.parent~=nil then self.parent:setCursor(false)cZ=cW end end,keyHandler=function(self,a7,aN)if aT.keyHandler(self,a7,aN)then c_=true;if a7=="key"then if aN==keys.backspace then local i=tostring(aT.getValue())if cU>1 then self:setValue(i:sub(1,cU-2)..i:sub(cU,i:len()))if cU>1 then cU=cU-1 end;if cV>1 then if cUd5 then cU=d5+1 end;if cU<1 then cU=1 end;if cU=self.width+cV then cV=cU-self.width+1 end;if cV<1 then cV=1 end end;if aN==keys.left then cU=cU-1;if cU>=1 then if cU=self.width+cV then cV=cU end end;if cU<1 then cU=1 end;if cV<1 then cV=1 end end end;if a7=="char"then local i=aT.getValue()if i:len()=self.width+cV then cV=cV+1 end end end;local aX,aY=self:getAnchorPosition()local d3=tostring(aT.getValue())local d7=(cU<=d3:len()and cU-1 or d3:len())-(cV-1)if d7>self.x+self.width-1 then d7=self.x+self.width-1 end;if self.parent~=nil then self.parent:setCursor(true,aX+d7,aY,self.fgColor)end;c_=false end end,mouseClickHandler=function(self,a7,aK,N,O)if aT.mouseClickHandler(self,a7,aK,N,O)then if a7=="mouse_click"and aK==1 then end;return true end;return false end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()local aZ=m(self.height,"center")self.parent:drawBackgroundBox(aX,aY,self.width,self.height,self.bgColor)for E=1,self.height do if E==aZ then local d3=tostring(aT.getValue())local d2=self.bgColor;local d1=self.fgColor;local i;if d3:len()<=0 then i=cZ;d2=cX or d2;d1=cY or d1 end;i=cZ;if d3~=""then i=d3 end;i=i:sub(cV,self.width+cV-1)local d8=self.width-i:len()if d8<0 then d8=0 end;if cS=="password"and d3~=""then i=string.rep("*",i:len())end;i=i..string.rep(" ",d8)self.parent:writeText(aX,aY+E-1,i,d2,d1)end end end end end}return setmetatable(av,aT)end;local function d9(am)local aT=al(am)local an="Textfield"local da,cV,cU,db=1,1,1,1;local dc={""}local dd={[colors.purple]={"break"}}aT.width=20;aT.height=8;aT.bgColor=a.textfieldBG;aT.fgColor=a.textfieldFG;aT:setZIndex(5)local av={getType=function(self)return an end,getLines=function(self)return dc end,getLine=function(self,a6)return dc[a6]or""end,editLine=function(self,a6,i)dc[a6]=i or dc[a6]return self end,addLine=function(self,i,a6)if a6~=nil then table.insert(dc,a6,i)else table.insert(dc,i)end;return self end,addKeyword=function(self,de,aD)end,removeLine=function(self,a6)table.remove(dc,a6 or#dc)if#dc<=0 then table.insert(dc,"")end;return self end,getTextCursor=function(self)return cU,db end,getFocusHandler=function(self)aT.getFocusHandler(self)if self.parent~=nil then local aX,aY=self:getAnchorPosition()if self.parent~=nil then self.parent:setCursor(true,aX+cU-cV,aY+db-da,self.fgColor)end end end,loseFocusHandler=function(self)aT.loseFocusHandler(self)if self.parent~=nil then self.parent:setCursor(false)end end,keyHandler=function(self,a7,aN)if aT.keyHandler(self,a7,aN)then local aX,aY=self:getAnchorPosition()if a7=="key"then if aN==keys.backspace then if dc[db]==""then if db>1 then table.remove(dc,db)cU=dc[db-1]:len()+1;cV=cU-self.width+1;if cV<1 then cV=1 end;db=db-1 end elseif cU<=1 then if db>1 then cU=dc[db-1]:len()+1;cV=cU-self.width+1;if cV<1 then cV=1 end;dc[db-1]=dc[db-1]..dc[db]table.remove(dc,db)db=db-1 end else dc[db]=dc[db]:sub(1,cU-2)..dc[db]:sub(cU,dc[db]:len())if cU>1 then cU=cU-1 end;if cV>1 then if cUdc[db]:len()then if dc[db+1]~=nil then dc[db]=dc[db]..dc[db+1]table.remove(dc,db+1)end else dc[db]=dc[db]:sub(1,cU-1)..dc[db]:sub(cU+1,dc[db]:len())end end;if aN==keys.enter then table.insert(dc,db+1,dc[db]:sub(cU,dc[db]:len()))dc[db]=dc[db]:sub(1,cU-1)db=db+1;cU=1;cV=1;if db-da>=self.height then da=da+1 end;self:setValue("")end;if aN==keys.up then if db>1 then db=db-1;if cU>dc[db]:len()+1 then cU=dc[db]:len()+1 end;if cV>1 then if cU1 then if dbdc[db]:len()+1 then cU=dc[db]:len()+1 end;if db>=da+self.height then da=da+1 end end end;if aN==keys.right then cU=cU+1;if db<#dc then if cU>dc[db]:len()+1 then cU=1;db=db+1 end elseif cU>dc[db]:len()then cU=dc[db]:len()+1 end;if cU<1 then cU=1 end;if cU=self.width+cV then cV=cU-self.width+1 end;if cV<1 then cV=1 end end;if aN==keys.left then cU=cU-1;if cU>=1 then if cU=self.width+cV then cV=cU end end;if db>1 then if cU<1 then db=db-1;cU=dc[db]:len()+1;cV=cU-self.width+1 end end;if cU<1 then cU=1 end;if cV<1 then cV=1 end end end;if a7=="char"then dc[db]=dc[db]:sub(1,cU-1)..aN..dc[db]:sub(cU,dc[db]:len())cU=cU+1;if cU>=self.width+cV then cV=cV+1 end;self:setValue("")end;local d7=(cU<=dc[db]:len()and cU-1 or dc[db]:len())-(cV-1)if d7>self.x+self.width-1 then d7=self.x+self.width-1 end;local df=db-dadc[db]:len()then cU=dc[db]:len()+1 end;if cUdc[db]:len()then cU=dc[db]:len()+1 end;if cU#dc-(self.height-1)then da=#dc-(self.height-1)end;if da<1 then da=1 end;if self.parent~=nil then if aX+cU-cV>=aX and aX+cU-cV<=aX+self.width and(aY+db-da>=aY and aY+db-da<=aY+self.height)then self.parent:setCursor(true,dg+cU-cV,dh+db-da)else self.parent:setCursor(false)end end end;self:setVisualChanged()return true end end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()self.parent:drawBackgroundBox(aX,aY,self.width,self.height,self.bgColor)self.parent:drawForegroundBox(aX,aY,self.width,self.height,self.fgColor)for E=1,self.height do local i=""if dc[E+da-1]~=nil then i=dc[E+da-1]end;i=i:sub(cV,self.width+cV-1)local d8=self.width-i:len()if d8<0 then d8=0 end;i=i..string.rep(" ",d8)self.parent:setText(aX,aY+E-1,i)end end end end}return setmetatable(av,aT)end;local function di(am)local aT=al(am)local an="List"aT.width=16;aT.height=6;aT.bgColor=a.listBG;aT.fgColor=a.listFG;aT:setZIndex(5)local dj={}local dk=a.selectionBG;local dl=a.selectionFG;local dm=true;local dn="left"local dp=0;local dq=true;local av={getType=function(self)return an end,addItem=function(self,i,Y,Z,...)table.insert(dj,{text=i,bgCol=Y or self.bgColor,fgCol=Z or self.fgColor,args={...}})if#dj==1 then self:setValue(dj[1])end;return self end,setIndexOffset=function(self,dr)dp=dr;return self end,getIndexOffset=function(self)return dp end,removeItem=function(self,a6)table.remove(dj,a6)return self end,getItem=function(self,a6)return dj[a6]end,getItemIndex=function(self)local ds=self:getValue()for aN,ab in pairs(dj)do if ab==ds then return aN end end end,clear=function(self)dj={}self:setValue({})return self end,getItemCount=function(self)return#dj end,editItem=function(self,a6,i,Y,Z,...)table.remove(dj,a6)table.insert(dj,a6,{text=i,bgCol=Y or self.bgColor,fgCol=Z or self.fgColor,args={...}})return self end,selectItem=function(self,a6)self:setValue(dj[a6]or{})return self end,setSelectedItem=function(self,Y,Z,dt)dk=Y or self.bgColor;dl=Z or self.fgColor;dm=dt;return self end,setScrollable=function(self,du)dq=du;return self end,mouseClickHandler=function(self,a7,aK,N,O)local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())if aX<=N and aX+self.width>N and aY<=O and aY+self.height>O and self:isVisible()then if a7=="mouse_click"or a7=="mouse_drag"then if aK==1 then if#dj>0 then for E=1,self.height do if dj[E+dp]~=nil then if aX<=N and aX+self.width>N and aY+E-1==O then self:setValue(dj[E+dp])self:getEventSystem():sendEvent("mouse_click",self,"mouse_click",0,N,O,dj[E+dp])end end end end end end;if a7=="mouse_scroll"and dq then dp=dp+aK;if dp<0 then dp=0 end;if aK>=1 then if#dj>self.height then if dp>#dj-self.height then dp=#dj-self.height end;if dp>=#dj then dp=#dj-1 end else dp=dp-1 end end end;self:setVisualChanged()return true end end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()self.parent:drawBackgroundBox(aX,aY,self.width,self.height,self.bgColor)for E=1,self.height do if dj[E+dp]~=nil then if dj[E+dp]==self:getValue()then if dm then self.parent:writeText(aX,aY+E-1,h(dj[E+dp].text,self.width,dn),dk,dl)else self.parent:writeText(aX,aY+E-1,h(dj[E+dp].text,self.width,dn),dj[E+dp].bgCol,dj[E+dp].fgCol)end else self.parent:writeText(aX,aY+E-1,h(dj[E+dp].text,self.width,dn),dj[E+dp].bgCol,dj[E+dp].fgCol)end end end end end end}return setmetatable(av,aT)end;local function dv(am)local aT=al(am)local an="Menubar"local av={}aT.width=30;aT.height=1;aT.bgColor=colors.gray;aT.fgColor=colors.lightGray;aT:setZIndex(5)local dj={}local dk=a.selectionBG;local dl=a.selectionFG;local dm=true;local dn="left"local dw=0;local d8=2;local dq=false;local function dx()local dy=0;local az=1;for E=1,#dj do if az+dj[E].text:len()+d8*2>av.w then dy=dy+dj[E].text:len()+d8*2 end;az=az+dj[E].text:len()+d8*2 end;return dy end;av={getType=function(self)return an end,addItem=function(self,i,Y,Z,...)table.insert(dj,{text=i,bgCol=Y or self.bgColor,fgCol=Z or self.fgColor,args={...}})if#dj==1 then self:setValue(dj[1])end;return self end,getItemIndex=function(self)local ds=self:getValue()for aN,ab in pairs(dj)do if ab==ds then return aN end end end,clear=function(self)dj={}self:setValue({})return self end,setSpace=function(self,dz)d8=dz or d8;return self end,setButtonOffset=function(self,l)dw=l or 0;if dw<0 then dw=0 end;local dy=dx()if dw>dy then dw=dy end;return self end,setScrollable=function(self,du)dq=du;return self end,removeItem=function(self,a6)table.remove(dj,a6)return self end,getItem=function(self,a6)return dj[a6]end,getItemCount=function(self)return#dj end,editItem=function(self,a6,i,Y,Z,...)table.remove(dj,a6)table.insert(dj,a6,{text=i,bgCol=Y or self.bgColor,fgCol=Z or self.fgColor,args={...}})return self end,selectItem=function(self,a6)self:setValue(dj[a6]or{})return self end,setSelectedItem=function(self,Y,Z,dt)dk=Y or self.bgColor;dl=Z or self.fgColor;dm=dt;return self end,mouseClickHandler=function(self,a7,aK,N,O)local aL,aM=self:getAbsolutePosition(self:getAnchorPosition())if aL<=N and aL+self.width>N and aM<=O and aM+self.height>O and self:isVisible()then if self.parent~=nil then self.parent:setFocusedObject(self)end;if a7=="mouse_click"then local az=1;for E=1+dw,#dj do if dj[E]~=nil then if az+dj[E].text:len()+d8*2<=self.width then if aL+az-1<=N and aL+az-1+dj[E].text:len()+d8*2>N and aM==O then self:setValue(dj[E])self:getEventSystem():sendEvent("mouse_click",self,"mouse_click",0,N,O,dj[E])end;az=az+dj[E].text:len()+d8*2 else break end end end end;if a7=="mouse_scroll"and dq then dw=dw+aK;if dw<0 then dw=0 end;local dy=dx()if dw>dy then dw=dy end end;return true end;return false end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()self.parent:drawBackgroundBox(aX,aY,self.width,self.height,self.bgColor)local az=0;for aa,ab in pairs(dj)do if az+ab.text:len()+d8*2<=self.width then if ab==self:getValue()then self.parent:writeText(aX+az-1+-dw,aY,h((" "):rep(d8)..ab.text..(" "):rep(d8),ab.text:len()+d8*2,dn),dk or ab.bgCol,dl or ab.fgCol)else self.parent:writeText(aX+az-1+-dw,aY,h((" "):rep(d8)..ab.text..(" "):rep(d8),ab.text:len()+d8*2,dn),ab.bgCol,ab.fgCol)end;az=az+ab.text:len()+d8*2 else if az0 then for E=1,dC do if dj[E+dp]~=nil then if aX<=N and aX+dB>N and aY+E==O then self:setValue(dj[E+dp])return true end end end end end end;if a7=="mouse_scroll"then dp=dp+aK;if dp<0 then dp=0 end;if aK==1 then if#dj>dC then if dp>#dj-dC then dp=#dj-dC end else dp=dj-1 end end;return true end;self:setVisualChanged()end;if aT.mouseClickHandler(self,a7,aK,N,O)then dF=2 else dF=1 end end,draw=function(self)if aT.draw(self)then local aX,aY=self:getAnchorPosition()if self.parent~=nil then self.parent:drawBackgroundBox(aX,aY,self.width,self.height,self.bgColor)if#dj>=1 then if self:getValue()~=nil then if self:getValue().text~=nil then if dF==1 then self.parent:writeText(aX,aY,h(self:getValue().text,self.width,dn):sub(1,self.width-1)..dD,self.bgColor,self.fgColor)else self.parent:writeText(aX,aY,h(self:getValue().text,self.width,dn):sub(1,self.width-1)..dE,self.bgColor,self.fgColor)end end end;if dF==2 then for E=1,dC do if dj[E+dp]~=nil then if dj[E+dp]==self:getValue()then if dm then self.parent:writeText(aX,aY+E,h(dj[E+dp].text,dB,dn),dk,dl)else self.parent:writeText(aX,aY+E,h(dj[E+dp].text,dB,dn),dj[E+dp].bgCol,dj[E+dp].fgCol)end else self.parent:writeText(aX,aY+E,h(dj[E+dp].text,dB,dn),dj[E+dp].bgCol,dj[E+dp].fgCol)end end end end end end end end}return setmetatable(av,aT)end;local function dG(am)local aT=al(am)local an="Radio"aT.width=8;aT.bgColor=a.listBG;aT.fgColor=a.listFG;aT:setZIndex(5)local dj={}local dk=a.selectionBG;local dl=a.selectionFG;local dH=aT.bgColor;local dI=aT.fgColor;local dm=true;local _="\7"local dn="left"local av={getType=function(self)return an end,addItem=function(self,i,N,O,Y,Z,...)table.insert(dj,{x=N or 1,y=O or 1,text=i,bgCol=Y or self.bgColor,fgCol=Z or self.fgColor,args={...}})if#dj==1 then self:setValue(dj[1])end;return self end,removeItem=function(self,a6)table.remove(dj,a6)return self end,getItem=function(self,a6)return dj[a6]end,getItemIndex=function(self)local ds=self:getValue()for aN,ab in pairs(dj)do if ab==ds then return aN end end end,clear=function(self)dj={}self:setValue({})return self end,getItemCount=function(self)return#dj end,editItem=function(self,a6,i,N,O,Y,Z,...)table.remove(dj,a6)table.insert(dj,a6,{x=N or 1,y=O or 1,text=i,bgCol=Y or self.bgColor,fgCol=Z or self.fgColor,args={...}})return self end,selectItem=function(self,a6)self:setValue(dj[a6]or{})return self end,setSelectedItem=function(self,Y,Z,dJ,dK,dt)dk=Y or dk;dl=Z or dl;dH=dJ or dH;dI=dK or dI;dm=dt;return self end,mouseClickHandler=function(self,a7,aK,N,O)local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())if a7=="mouse_click"then if aK==1 then if#dj>0 then for aa,ab in pairs(dj)do if aX+ab.x-1<=N and aX+ab.x-1+ab.text:len()+2>=N and aY+ab.y-1==O then self:setValue(ab)if self.parent~=nil then self.parent:setFocusedObject(self)end;self:setVisualChanged()return true end end end end end;return false end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()for aa,ab in pairs(dj)do if ab==self:getValue()then if dn=="left"then self.parent:writeText(ab.x+aX-1,ab.y+aY-1,_,dH,dI)self.parent:writeText(ab.x+2+aX-1,ab.y+aY-1,ab.text,dk,dl)end else self.parent:drawBackgroundBox(ab.x+aX-1,ab.y+aY-1,1,1,self.bgColor)self.parent:writeText(ab.x+2+aX-1,ab.y+aY-1,ab.text,ab.bgCol,ab.fgCol)end end end end end}return setmetatable(av,aT)end;local function dL(am)local an="Timer"local dM=0;local dN=0;local dO=0;local dP;local au=a4()local av={name=am,getType=function(self)return an end,getZIndex=function(self)return 1 end,getName=function(self)return self.name end,setTime=function(self,dQ,dR)dM=dQ or 0;dN=dR or 1;return self end,start=function(self)dO=dN;dP=os.startTimer(dM)return self end,cancel=function(self)if dP~=nil then os.cancelTimer(dP)end;return self end,onCall=function(self,a9)au:registerEvent("timed_event",a9)return self end,eventHandler=function(self,a7,dS)if a7=="timer"and dS==dP then au:sendEvent("timed_event",self)if dO>=1 then dO=dO-1;if dO>=1 then dP=os.startTimer(dM)end elseif dO==-1 then dP=os.startTimer(dM)end end end}av.__index=av;return av end;local function dT(am)local av;local an="Thread"local a9;local dU;local dV=false;av={name=am,getType=function(self)return an end,getZIndex=function(self)return 1 end,getName=function(self)return self.name end,start=function(self,cQ)if cQ==nil then error("function is nil")end;a9=cQ;dU=coroutine.create(a9)dV=true;local aj,ak=coroutine.resume(dU)if not aj then if ak~="Terminated"then error("Threaderror - "..ak)end end;return self end,getStatus=function(self,cQ)if dU~=nil then return coroutine.status(dU)end;return nil end,stop=function(self,cQ)dV=false;return self end,eventHandler=function(self,a7,aO,aP,aQ)if dV then if coroutine.status(dU)~="dead"then local aj,ak=coroutine.resume(dU,a7,aO,aP,aQ)if not aj then if ak~="Terminated"then error("Threaderror - "..ak)end end else dV=false end end end}av.__index=av;return av end;local function dW(am)local av={}local an="Animation"local dP;local dX={}local a6=1;local dY=0;local dZ;local function d_()if dX[a6]~=nil then dX[a6].f(av,a6)end;a6=a6+1;if dX[a6]~=nil then if dX[a6].t>0 then dP=os.startTimer(dX[a6].t)else d_()end end end;av={name=am,getType=function(self)return an end,getZIndex=function(self)return 1 end,getName=function(self)return self.name end,add=function(self,a9,e0)dZ=a9;table.insert(dX,{f=a9,t=e0 or dY})return self end,wait=function(self,e0)dY=e0;return self end,rep=function(self,e1)for N=1,e1 do table.insert(dX,{f=dZ,t=dY})end;return self end,clear=function(self)dX={}dZ=nil;dY=0;a6=1;return self end,play=function(self)a6=1;if dX[a6]~=nil then if dX[a6].t>0 then dP=os.startTimer(dX[a6].t)else d_()end end;return self end,cancel=function(self)os.cancelTimer(dP)return self end,eventHandler=function(self,a7,dS)if a7=="timer"and dS==dP then if dX[a6]~=nil then d_()end end end}av.__index=av;return av end;local function e2(am)local aT=al(am)local an="Slider"aT.width=8;aT.bgColor=colors.lightGray;aT.fgColor=colors.gray;aT:setValue(1)local e3="horizontal"local _=" "local e4=colors.black;local e5="\140"local e6=aT.width;local a6=1;local av={getType=function(self)return an end,setSymbol=function(self,e7)_=e7:sub(1,1)self:setVisualChanged()return self end,setBackgroundSymbol=function(self,e8)e5=string.sub(e8,1,1)self:setVisualChanged()return self end,setSymbolColor=function(self,e9)e4=e9;self:setVisualChanged()return self end,setBarType=function(self,ea)e3=ea:lower()return self end,mouseClickHandler=function(self,a7,aK,N,O)if aT.mouseClickHandler(self,a7,aK,N,O)then local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())if e3=="horizontal"then for eb=0,self.width-1 do if aX+eb==N and aY<=O and aY+self.height>O then a6=eb+1;self:setValue(e6/self.width*a6)self:setVisualChanged()end end end;if e3=="vertical"then for eb=0,self.height-1 do if aY+eb==O and aX<=N and aX+self.width>N then a6=eb+1;self:setValue(e6/self.height*a6)self:setVisualChanged()end end end end end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()if e3=="horizontal"then self.parent:writeText(aX,aY,e5:rep(a6-1),self.bgColor,self.fgColor)self.parent:writeText(aX+a6-1,aY,_,e4,e4)self.parent:writeText(aX+a6,aY,e5:rep(self.width-a6),self.bgColor,self.fgColor)end;if e3=="vertical"then for E=0,self.height-1 do if E+1==a6 then self.parent:writeText(aX,aY+E,_,e4,e4)else self.parent:writeText(aX,aY+E,e5,self.bgColor,self.fgColor)end end end end end end}return setmetatable(av,aT)end;local function ec(am)local aT=al(am)local an="Scrollbar"aT.width=1;aT.height=8;aT.bgColor=colors.lightGray;aT.fgColor=colors.gray;aT:setValue(1)aT:setZIndex(2)local e3="vertical"local _=" "local e4=colors.black;local e5="\127"local e6=aT.height;local a6=1;local ed=1;local av={getType=function(self)return an end,setSymbol=function(self,e7)_=e7:sub(1,1)self:setVisualChanged()return self end,setSymbolSize=function(self,ee)ed=tonumber(ee)or 1;if e3=="vertical"then self:setValue(a6-1*e6/(self.height-(ed-1))-e6/(self.height-(ed-1)))elseif e3=="horizontal"then self:setValue(a6-1*e6/(self.width-(ed-1))-e6/(self.width-(ed-1)))end;self:setVisualChanged()return self end,setMaxValue=function(self,d3)e6=d3;return self end,setBackgroundSymbol=function(self,e8)e5=string.sub(e8,1,1)self:setVisualChanged()return self end,setSymbolColor=function(self,e9)e4=e9;self:setVisualChanged()return self end,setBarType=function(self,ea)e3=ea:lower()return self end,mouseClickHandler=function(self,a7,aK,N,O)if aT.mouseClickHandler(self,a7,aK,N,O)then local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())if(a7=="mouse_click"or a7=="mouse_drag")and aK==1 then if e3=="horizontal"then for eb=0,self.width do if aX+eb==N and aY<=O and aY+self.height>O then a6=math.min(eb+1,self.width-(ed-1))self:setValue(e6/self.width*a6)self:setVisualChanged()end end end;if e3=="vertical"then for eb=0,self.height do if aY+eb==O and aX<=N and aX+self.width>N then a6=math.min(eb+1,self.height-(ed-1))self:setValue(e6/self.height*a6)self:setVisualChanged()end end end end;if a7=="mouse_scroll"then a6=a6+aK;if a6<1 then a6=1 end;a6=math.min(a6,(e3=="vertical"and self.height or self.width)-(ed-1))self:setValue(e6/(e3=="vertical"and self.height or self.width)*a6)end;return true end end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()if e3=="horizontal"then self.parent:writeText(aX,aY,e5:rep(a6-1),self.bgColor,self.fgColor)self.parent:writeText(aX+a6-1,aY,_:rep(ed),e4,e4)self.parent:writeText(aX+a6+ed-1,aY,e5:rep(self.width-(a6+ed-1)),self.bgColor,self.fgColor)end;if e3=="vertical"then for E=0,self.height-1 do if a6==E+1 then for ef=0,math.min(ed-1,self.height)do self.parent:writeText(aX,aY+E+ef,_,e4,e4)end else if E+1a6-1+ed then self.parent:writeText(aX,aY+E,e5,self.bgColor,self.fgColor)end end end end end end end}return setmetatable(av,aT)end;local function eg(am)local aT=al(am)local an="Switch"aT.width=3;aT.height=1;aT.bgColor=colors.lightGray;aT.fgColor=colors.gray;aT:setValue(false)aT:setZIndex(5)local av={getType=function(self)return an end,mouseClickHandler=function(self,a7,aK,N,O)if aT.mouseClickHandler(self,a7,aK,N,O)then local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())if(a7=="mouse_click"or a7=="mouse_drag")and aK==1 then end;return true end end,draw=function(self)if aT.draw(self)then if self.parent~=nil then local aX,aY=self:getAnchorPosition()end end end}return setmetatable(av,aT)end;local function eh(am,ei)local aT=al(am)local an="Frame"local ej={}local ek={}local av={}local el;aT:setZIndex(10)local b5=false;local b1=1;local b2=1;local em=colors.white;local en,dp=0,0;if ei~=nil then aT.parent=ei;aT.width,aT.height=ei.w,ei.h;aT.bgColor=a.FrameBG;aT.fgColor=a.FrameFG else local eo,ep=f.getSize()aT.width,aT.height=eo,ep;aT.bgColor=a.basaltBG;aT.fgColor=a.basaltFG end;local function eq(am)for aa,ab in pairs(ej)do for aa,bD in pairs(ab)do if bD.name==am then return ab end end end end;local function er(es)local ao=es:getZIndex()if eq(es.name)~=nil then return nil end;if ej[ao]==nil then for N=1,#ek+1 do if ek[N]~=nil then if ao==ek[N]then break end;if ao>ek[N]then table.insert(ek,N,ao)break end else table.insert(ek,ao)end end;if#ek<=0 then table.insert(ek,ao)end;ej[ao]={}end;es.parent=av;table.insert(ej[ao],es)return es end;local function et(es)for cp,bD in pairs(ej)do for aN,ab in pairs(bD)do if ab==es then table.remove(ej[cp],aN)return true end end end;return false end;av={barActive=false,barBackground=colors.gray,barTextcolor=colors.black,barText="New Frame",barTextAlign="left",isMoveable=false,getType=function(self)return an end,setFocusedObject=function(self,es)for aa,a6 in pairs(ek)do for aa,ab in pairs(ej[a6])do if ab==es then if el~=nil then el:loseFocusHandler()end;el=es;el:getFocusHandler()end end end;return self end,setOffset=function(self,aH,aI)en=aH~=nil and math.floor(aH<0 and math.abs(aH)or-aH)or en;dp=aI~=nil and math.floor(aI<0 and math.abs(aI)or-aI)or dp;return self end,getFrameOffset=function(self)return en,dp end,removeFocusedObject=function(self)if el~=nil then el:loseFocusHandler()end;el=nil;return self end,getFocusedObject=function(self)return el end,show=function(self)aT:show()if self.parent==nil then c=self end;return self end,setCursor=function(self,eu,ev,ew,aD)local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())b5=eu or false;if ev~=nil then b1=aX+ev-1 end;if ew~=nil then b2=aY+ew-1 end;em=aD or em;self:setVisualChanged()return self end,setMoveable=function(self,ex)self.isMoveable=ex or not self.isMoveable;self:setVisualChanged()return self end,showBar=function(self,ey)self.barActive=ey or not self.barActive;self:setVisualChanged()return self end,setBar=function(self,i,Y,Z)self.barText=i or""self.barBackground=Y or self.barBackground;self.barTextcolor=Z or self.barTextcolor;self:setVisualChanged()return self end,setBarTextAlign=function(self,dn)self.barTextAlign=dn or"left"self:setVisualChanged()return self end,getVisualChanged=function(self)local ez=aT.getVisualChanged(self)for aa,a6 in pairs(ek)do if ej[a6]~=nil then for aa,ab in pairs(ej[a6])do if ab.getVisualChanged~=nil and ab:getVisualChanged()then ez=true end end end end;return ez end,loseFocusHandler=function(self)aT.loseFocusHandler(self)end,getFocusHandler=function(self)aT.getFocusHandler(self)if self.parent~=nil then self.parent:removeObject(self)self.parent:addObject(self)end end,keyHandler=function(self,a7,aN)if el~=nil then if el.keyHandler~=nil then if el:keyHandler(a7,aN)then return true end end end;return false end,backgroundKeyHandler=function(self,a7,aN)aT.backgroundKeyHandler(self,a7,aN)for aa,a6 in pairs(ek)do if ej[a6]~=nil then for aa,ab in pairs(ej[a6])do if ab.backgroundKeyHandler~=nil then ab:backgroundKeyHandler(a7,aN)end end end end end,eventHandler=function(self,a7,aO,aP,aQ,aR)aT.eventHandler(self,a7,aO,aP,aQ,aR)for aa,a6 in pairs(ek)do if ej[a6]~=nil then for aa,ab in pairs(ej[a6])do if ab.eventHandler~=nil then ab:eventHandler(a7,aO,aP,aQ,aR)end end end end;if a7=="terminate"then f.clear()f.setCursorPos(1,1)b.stop()end end,mouseClickHandler=function(self,a7,aK,N,O)local aH,aI=self:getOffset()aH=aH<0 and math.abs(aH)or-aH;aI=aI<0 and math.abs(aI)or-aI;if self.drag then if a7=="mouse_drag"then local eA=1;local eB=1;if self.parent~=nil then eA,eB=self.parent:getAbsolutePosition(self.parent:getAnchorPosition())end;self:setPosition(N+self.xToRem-(eA-1)+aH,O-(eB-1)+aI)end;if a7=="mouse_up"then self.drag=false end;return true end;if aT.mouseClickHandler(self,a7,aK,N,O)then local aE,aF=self:getAbsolutePosition(self:getAnchorPosition())for aa,a6 in pairs(ek)do if ej[a6]~=nil then for aa,ab in o(ej[a6])do if ab.mouseClickHandler~=nil then if ab:mouseClickHandler(a7,aK,N+aH,O+aI)then return true end end end end end;if self.isMoveable then if N>=aE and N<=aE+self.width-1 and O==aF and a7=="mouse_click"then self.drag=true;self.xToRem=aE-N end end;if el~=nil then el:loseFocusHandler()el=nil end;return true end;return false end,setText=function(self,N,O,i)local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())if O>=1 and O<=self.height then if self.parent~=nil then self.parent:setText(math.max(N+aX-1,aX)-(self.parent.x-1),aY+O-1-(self.parent.y-1),g(i,math.max(1-N+1,1),self.width-N+1))else X.setText(math.max(N+aX-1,aX),aY+O-1,g(i,math.max(1-N+1,1),self.width-N+1))end end end,setBG=function(self,N,O,Y)local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())if O>=1 and O<=self.height then if self.parent~=nil then self.parent:setBG(math.max(N+aX-1,aX)-(self.parent.x-1),aY+O-1-(self.parent.y-1),g(Y,math.max(1-N+1,1),self.width-N+1))else X.setBG(math.max(N+aX-1,aX),aY+O-1,g(Y,math.max(1-N+1,1),self.width-N+1))end end end,setFG=function(self,N,O,Z)local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())if O>=1 and O<=self.height then if self.parent~=nil then self.parent:setFG(math.max(N+aX-1,aX)-(self.parent.x-1),aY+O-1-(self.parent.y-1),g(Z,math.max(1-N+1,1),self.width-N+1))else X.setFG(math.max(N+aX-1,aX),aY+O-1,g(Z,math.max(1-N+1,1),self.width-N+1))end end end,writeText=function(self,N,O,i,Y,Z)local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())if O>=1 and O<=self.height then if self.parent~=nil then self.parent:writeText(math.max(N+aX-1,aX)-(self.parent.x-1),aY+O-1-(self.parent.y-1),g(i,math.max(1-N+1,1),self.width-N+1),Y,Z)else X.writeText(math.max(N+aX-1,aX),aY+O-1,g(i,math.max(1-N+1,1),self.width-N+1),Y,Z)end end end,drawBackgroundBox=function(self,N,O,j,u,Y)local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())u=O<1 and(u+O>self.height and self.height or u+O-1)or(u+O>self.height and self.height-O+1 or u)j=N<1 and(j+N>self.width and self.width or j+N-1)or(j+N>self.width and self.width-N+1 or j)if self.parent~=nil then self.parent:drawBackgroundBox(math.max(N+aX-1,aX)-(self.parent.x-1),math.max(O+aY-1,aY)-(self.parent.y-1),j,u,Y)else X.drawBackgroundBox(math.max(N+aX-1,aX),math.max(O+aY-1,aY),j,u,Y)end end,drawTextBox=function(self,N,O,j,u,_)local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())u=O<1 and(u+O>self.height and self.height or u+O-1)or(u+O>self.height and self.height-O+1 or u)j=N<1 and(j+N>self.width and self.width or j+N-1)or(j+N>self.width and self.width-N+1 or j)if self.parent~=nil then self.parent:drawTextBox(math.max(N+aX-1,aX)-(self.parent.x-1),math.max(O+aY-1,aY)-(self.parent.y-1),j,u,_:sub(1,1))else X.drawTextBox(math.max(N+aX-1,aX),math.max(O+aY-1,aY),j,u,_:sub(1,1))end end,drawForegroundBox=function(self,N,O,j,u,Z)local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())u=O<1 and(u+O>self.height and self.height or u+O-1)or(u+O>self.height and self.height-O+1 or u)j=N<1 and(j+N>self.width and self.width or j+N-1)or(j+N>self.width and self.width-N+1 or j)if self.parent~=nil then self.parent:drawForegroundBox(math.max(N+aX-1,aX)-(self.parent.x-1),math.max(O+aY-1,aY)-(self.parent.y-1),j,u,Z)else X.drawForegroundBox(math.max(N+aX-1,aX),math.max(O+aY-1,aY),j,u,Z)end end,draw=function(self)if self:getVisualChanged()then if aT.draw(self)then local aX,aY=self:getAbsolutePosition(self:getAnchorPosition())local dg,dh=self:getAnchorPosition()if self.parent~=nil then self.parent:drawBackgroundBox(dg,dh,self.width,self.height,self.bgColor)self.parent:drawForegroundBox(dg,dh,self.width,self.height,self.fgColor)self.parent:drawTextBox(dg,dh,self.width,self.height," ")else X.drawBackgroundBox(aX,aY,self.width,self.height,self.bgColor)X.drawForegroundBox(aX,aY,self.width,self.height,self.fgColor)X.drawTextBox(aX,aY,self.width,self.height," ")end;f.setCursorBlink(false)if self.barActive then if self.parent~=nil then self.parent:writeText(dg,dh,h(self.barText,self.width,self.barTextAlign),self.barBackground,self.barTextcolor)else X.writeText(aX,aY,h(self.barText,self.width,self.barTextAlign),self.barBackground,self.barTextcolor)end end;for aa,a6 in o(ek)do if ej[a6]~=nil then for aa,ab in pairs(ej[a6])do if ab.draw~=nil then ab:draw()end end end end;if b5 then f.setTextColor(em)f.setCursorPos(b1,b2)if self.parent~=nil then f.setCursorBlink(self:isFocused())else f.setCursorBlink(b5)end end;self:setVisualChanged(false)end end end,addObject=function(self,es)return er(es)end,removeObject=function(self,es)return et(es)end,getObject=function(self,es)return eq(es)end,addButton=function(self,am)local es=aS(am)es.name=am;return er(es)end,addLabel=function(self,am)local es=c0(am)es.name=am;es.bgColor=self.bgColor;es.fgColor=self.fgColor;return er(es)end,addCheckbox=function(self,am)local es=cG(am)es.name=am;return er(es)end,addInput=function(self,am)local es=cR(am)es.name=am;return er(es)end,addProgram=function(self,am)local es=a_(am)es.name=am;return er(es)end,addTextfield=function(self,am)local es=d9(am)es.name=am;return er(es)end,addList=function(self,am)local es=di(am)es.name=am;return er(es)end,addDropdown=function(self,am)local es=dA(am)es.name=am;return er(es)end,addRadio=function(self,am)local es=dG(am)es.name=am;return er(es)end,addTimer=function(self,am)local es=dL(am)es.name=am;return er(es)end,addAnimation=function(self,am)local es=dW(am)es.name=am;return er(es)end,addSlider=function(self,am)local es=e2(am)es.name=am;return er(es)end,addScrollbar=function(self,am)local es=ec(am)es.name=am;return er(es)end,addMenubar=function(self,am)local es=dv(am)es.name=am;return er(es)end,addThread=function(self,am)local es=dT(am)es.name=am;return er(es)end,addPane=function(self,am)local es=c2(am)es.name=am;return er(es)end,addImage=function(self,am)local es=c3(am)es.name=am;return er(es)end,addProgressbar=function(self,am)local es=cH(am)es.name=am;return er(es)end,addFrame=function(self,am)local es=eh(am,self)es.name=am;return er(es)end}setmetatable(av,aT)if ei==nil then table.insert(d,av)end;return av end;local eC=false;local function eD(a7,aO,aP,aQ,aR)if a7=="mouse_click"then c:mouseClickHandler(a7,aO,aP,aQ,aR)end;if a7=="mouse_drag"then c:mouseClickHandler(a7,aO,aP,aQ,aR)end;if a7=="mouse_up"then c:mouseClickHandler(a7,aO,aP,aQ,aR)end;if a7=="mouse_scroll"then c:mouseClickHandler(a7,aO,aP,aQ,aR)end;if a7=="key"or a7=="char"then c:keyHandler(a7,aO)c:backgroundKeyHandler(a7,aO)end;for aa,ab in pairs(d)do ab:eventHandler(a7,aO,aP,aQ,aR)end;if eC then c:draw()X.update()end end;function b.autoUpdate(dV)f.clear()eC=dV or true;c:draw()X.update()while eC do local a7,aO,aP,aQ,aR=os.pullEventRaw()eD(a7,aO,aP,aQ,aR)end end;function b.update(a7,aO,aP,aQ,aR)if a7~="nil"then eD(a7,aO,aP,aQ,aR)else c:draw()X.update()end end;function b.stop()eC=false end;function b.getFrame(am)for aa,ab in pairs(d)do if ab.name==am then return ab end end end;function b.getActiveFrame()return c end;function b.setActiveFrame(aw)if aw:getType()=="Frame"then c=aw;return true end;return false end;function b.createFrame(am)local aw=eh(am)return aw end;function b.removeFrame(am)for aN,ab in pairs(d)do if ab.name==am then d[aN]=nil;return true end end;return false end;if b.debugger then b.debugFrame=b.createFrame("basaltDebuggingFrame"):showBar():setBackground(colors.lightGray):setBar("Debug",colors.black,colors.gray)b.debugList=b.debugFrame:addList("debugList"):setSize(b.debugFrame.width-2,b.debugFrame.height-3):setPosition(2,3):setScrollable(true):show()b.debugFrame:addButton("back"):setAnchor("right"):setSize(1,1):setText("\22"):onClick(function()b.oldFrame:show()end):setBackground(colors.red):show()b.debugLabel=b.debugFrame:addLabel("debugLabel"):onClick(function()b.oldFrame=c;b.debugFrame:show()end):setBackground(colors.black):setForeground(colors.white):setAnchor("bottom"):setZIndex(20):show()end;if b.debugger then function b.debug(...)local ah={...}if c.name~="basaltDebuggingFrame"then if c~=b.debugLabel.frame then b.debugLabel:setParent(c)end end;local eE=""for aN,ab in pairs(ah)do eE=eE..tostring(ab)..(#ah~=aN and", "or"")end;b.debugLabel:setText("[Debug] "..eE)b.debugList:addItem(eE)if b.debugList:getItemCount()>50 then b.debugList:removeItem(1)end;b.debugList:setValue(b.debugList:getItem(b.debugList:getItemCount()))b.debugLabel:show()end end;return b \ No newline at end of file diff --git a/oldVersions/old/v1.0/basalt.lua b/oldVersions/old/v1.0/basalt.lua deleted file mode 100644 index 4a51f8c..0000000 --- a/oldVersions/old/v1.0/basalt.lua +++ /dev/null @@ -1,4246 +0,0 @@ --- current version 1 -local theme = { - basaltBG = colors.lightGray, - basaltFG = colors.black, - FrameBG = colors.gray, - FrameFG = colors.black, - ButtonBG = colors.gray, - ButtonFG = colors.black, - CheckboxBG = colors.gray, - CheckboxFG = colors.black, - InputBG = colors.gray, - InputFG = colors.black, - textfieldBG = colors.gray, - textfieldFG = colors.black, - listBG = colors.gray, - listFG = colors.black, - dropdownBG = colors.gray, - dropdownFG = colors.black, - radioBG = colors.gray, - radioFG = colors.black, - selectionBG = colors.black, - selectionFG = colors.lightGray, -} - -local basalt = { debugger = true, version = 1 } -local activeFrame -local frames = {} - -local keyModifier = {} -local parentTerminal = term.current() - -local sub = string.sub - -local function getTextHorizontalAlign(text, width, textAlign) - text = string.sub(text, 1, width) - local offset = width - string.len(text) - if (textAlign == "right") then - text = string.rep(" ", offset) .. text - elseif (textAlign == "center") then - text = string.rep(" ", math.floor(offset / 2)) .. text .. string.rep(" ", math.floor(offset / 2)) - text = text .. (string.len(text) < width and " " or "") - else - text = text .. string.rep(" ", offset) - end - return text -end - -local function getTextVerticalAlign(h, textAlign) - local offset = 0 - if (textAlign == "center") then - offset = math.ceil(h / 2) - if (offset < 1) then - offset = 1 - end - end - if (textAlign == "bottom") then - offset = h - end - return offset -end - -local function rpairs(t) - return function(t, i) - i = i - 1 - if i ~= 0 then - return i, t[i] - end - end, t, #t + 1 -end - -local tHex = { -- copy paste is a very important feature - [colors.white] = "0", - [colors.orange] = "1", - [colors.magenta] = "2", - [colors.lightBlue] = "3", - [colors.yellow] = "4", - [colors.lime] = "5", - [colors.pink] = "6", - [colors.gray] = "7", - [colors.lightGray] = "8", - [colors.cyan] = "9", - [colors.purple] = "a", - [colors.blue] = "b", - [colors.brown] = "c", - [colors.green] = "d", - [colors.red] = "e", - [colors.black] = "f", -} - -local function basaltDrawHelper() - local terminal = parentTerminal - local width, height = terminal.getSize() - local cacheT = {} - local cacheBG = {} - local cacheFG = {} - - local _cacheT = {} - local _cacheBG = {} - local _cacheFG = {} - - local emptySpaceLine - local emptyColorLines = {} - - local function createEmptyLines() - emptySpaceLine = (" "):rep(width) - for n = 0, 15 do - local nColor = 2 ^ n - local sHex = tHex[nColor] - emptyColorLines[nColor] = sHex:rep(width) - end - end - ---- - createEmptyLines() - - local function recreateWindowArray() - local emptyText = emptySpaceLine - local emptyFG = emptyColorLines[colors.white] - local emptyBG = emptyColorLines[colors.black] - for currentY = 1, height do - cacheT[currentY] = sub(cacheT[currentY] == nil and emptyText or cacheT[currentY] .. emptyText:sub(1, width - cacheT[currentY]:len()), 1, width) - cacheFG[currentY] = sub(cacheFG[currentY] == nil and emptyFG or cacheFG[currentY] .. emptyFG:sub(1, width - cacheFG[currentY]:len()), 1, width) - cacheBG[currentY] = sub(cacheBG[currentY] == nil and emptyBG or cacheBG[currentY] .. emptyBG:sub(1, width - cacheBG[currentY]:len()), 1, width) - end - end - recreateWindowArray() - - local function setText(x, y, text) - if (y >= 1) and (y <= height) then - if (x + text:len() > 0) and (x <= width) then - local oldCache = cacheT[y] - local newCache - local nEnd = x + #text - 1 - - if (x < 1) then - local startN = 1 - x + 1 - local endN = width - x + 1 - text = sub(text, startN, endN) - elseif (nEnd > width) then - local endN = width - x + 1 - text = sub(text, 1, endN) - end - - if (x > 1) then - local endN = x - 1 - newCache = sub(oldCache, 1, endN) .. text - else - newCache = text - end - if nEnd < width then - newCache = newCache .. sub(oldCache, nEnd + 1, width) - end - cacheT[y] = newCache - end - end - end - - local function setBG(x, y, colorStr) - if (y >= 1) and (y <= height) then - if (x + colorStr:len() > 0) and (x <= width) then - local oldCache = cacheBG[y] - local newCache - local nEnd = x + #colorStr - 1 - - if (x < 1) then - colorStr = sub(colorStr, 1 - x + 1, width - x + 1) - elseif (nEnd > width) then - colorStr = sub(colorStr, 1, width - x + 1) - end - - if (x > 1) then - newCache = sub(oldCache, 1, x - 1) .. colorStr - else - newCache = colorStr - end - if nEnd < width then - newCache = newCache .. sub(oldCache, nEnd + 1, width) - end - cacheBG[y] = newCache - end - end - end - - local function setFG(x, y, colorStr) - if (y >= 1) and (y <= height) then - if (x + colorStr:len() > 0) and (x <= width) then - local oldCache = cacheFG[y] - local newCache - local nEnd = x + #colorStr - 1 - - if (x < 1) then - local startN = 1 - x + 1 - local endN = width - x + 1 - colorStr = sub(colorStr, startN, endN) - elseif (nEnd > width) then - local endN = width - x + 1 - colorStr = sub(colorStr, 1, endN) - end - - if (x > 1) then - local endN = x - 1 - newCache = sub(oldCache, 1, endN) .. colorStr - else - newCache = colorStr - end - if nEnd < width then - newCache = newCache .. sub(oldCache, nEnd + 1, width) - end - cacheFG[y] = newCache - end - end - end - - local drawHelper = { - setBG = function(x, y, colorStr) - setBG(x, y, colorStr) - end; - - setText = function(x, y, text) - setText(x, y, text) - end; - - setFG = function(x, y, colorStr) - setFG(x, y, colorStr) - end; - - drawBackgroundBox = function(x, y, width, height, bgCol) - for n = 1, height do - setBG(x, y + (n - 1), tHex[bgCol]:rep(width)) - end - end; - drawForegroundBox = function(x, y, width, height, fgCol) - for n = 1, height do - setFG(x, y + (n - 1), tHex[fgCol]:rep(width)) - end - end; - drawTextBox = function(x, y, width, height, symbol) - for n = 1, height do - setText(x, y + (n - 1), symbol:rep(width)) - end - end; - writeText = function(x, y, text, bgCol, fgCol) - bgCol = bgCol or terminal.getBackgroundColor() - fgCol = fgCol or terminal.getTextColor() - setText(x, y, text) - setBG(x, y, tHex[bgCol]:rep(text:len())) - setFG(x, y, tHex[fgCol]:rep(text:len())) - end; - - update = function() - local xC, yC = terminal.getCursorPos() - local isBlinking = false - if (terminal.getCursorBlink ~= nil) then - isBlinking = terminal.getCursorBlink() - end - terminal.setCursorBlink(false) - for n = 1, height do - terminal.setCursorPos(1, n) - terminal.blit(cacheT[n], cacheFG[n], cacheBG[n]) - end - terminal.setCursorBlink(isBlinking) - terminal.setCursorPos(xC, yC) - end; - - setTerm = function(newTerm) - terminal = newTerm; - end; - } - return drawHelper -end -local drawHelper = basaltDrawHelper() - -local function BasaltEvents() - - local events = {} - local index = {} - - local event = { - registerEvent = function(self, _event, func) - if (events[_event] == nil) then - events[_event] = {} - index[_event] = 1 - end - events[_event][index[_event]] = func - index[_event] = index[_event] + 1 - return index[_event] - 1 - end; - - removeEvent = function(self, _event, index) - events[_event][index[_event]] = nil - end; - - sendEvent = function(self, _event, ...) - if (events[_event] ~= nil) then - for _, value in pairs(events[_event]) do - value(...) - end - end - end; - } - event.__index = event - return event -end - -local processes = {} -local process = {} -local processId = 0 - -function process:new(path, window, ...) - local args = table.pack(...) - local newP = setmetatable({ path = path }, { __index = self }) - newP.window = window - newP.processId = processId - newP.coroutine = coroutine.create(function() - os.run({ basalt = basalt }, path, table.unpack(args)) - end) - processes[processId] = newP - processId = processId + 1 - return newP -end - -function process:resume(event, ...) - term.redirect(self.window) - local ok, result = coroutine.resume(self.coroutine, event, ...) - self.window = term.current() - if ok then - self.filter = result - else - basalt.debug(result) - end -end - -function process:isDead() - if (self.coroutine ~= nil) then - if (coroutine.status(self.coroutine) == "dead") then - table.remove(processes, self.processId) - return true - end - else - return true - end - return false -end - -function process:getStatus() - if (self.coroutine ~= nil) then - return coroutine.status(self.coroutine) - end - return nil -end - -function process:start() - coroutine.resume(self.coroutine) -end - -local function Object(name) - -- Base object - local objectType = "Object" -- not changeable - --[[ - local horizontalAnchor = "left" - local verticalAnchor = "top" - local ignYOffset = false - local ignXOffset = false ]] - local value - local zIndex = 1 - local hanchor = "left" - local vanchor = "top" - local ignOffset = false - local isVisible = false - - local visualsChanged = true - - local eventSystem = BasaltEvents() - - local object = { - x = 1, - y = 1, - width = 1, - height = 1, - bgColor = colors.black, - fgColor = colors.white, - name = name or "Object", - parent = nil, - - show = function(self) - isVisible = true - visualsChanged = true - return self - end; - - hide = function(self) - isVisible = false - visualsChanged = true - return self - end; - - isVisible = function(self) - return isVisible - end; - - getZIndex = function(self) - return zIndex; - end; - - setFocus = function(self) - if (self.parent ~= nil) then - self.parent:setFocusedObject(self) - end - return self - end; - - setZIndex = function(self, index) - zIndex = index - if (self.parent ~= nil) then - self.parent:removeObject(self) - self.parent:addObject(self) - end - return self - end; - - getType = function(self) - return objectType - end; - - getName = function(self) - return self.name - end; - - remove = function(self) - if (self.parent ~= nil) then - self.parent:removeObject(self) - end - return self - end; - - setParent = function(self, frame) - if (frame.getType ~= nil and frame:getType() == "Frame") then - self:remove() - frame:addObject(self) - if (self.draw) then - self:show() - end - end - return self - end; - - setValue = function(self, _value) - if (value ~= _value) then - value = _value - visualsChanged = true - self:valueChangedHandler() - end - return self - end; - - getValue = function(self) - return value - end; - - getVisualChanged = function(self) - return visualsChanged - end; - - setVisualChanged = function(self, change) - visualsChanged = change or true - return self - end; - - - getEventSystem = function(self) - return eventSystem - end; - - - getParent = function(self) - return self.parent - end; - - setPosition = function(self, xPos, yPos, rel) - if (rel) then - self.x, self.y = self.x + xPos, self.y + yPos - else - self.x, self.y = xPos, yPos - end - visualsChanged = true - return self - end; - - getPosition = function(self) - return self.x, self.y - end; - - getVisibility = function(self) - return isVisible - end; - - setVisibility = function(self, _isVisible) - isVisible = _isVisible or not isVisible - visualsChanged = true - return self - end; - - setSize = function(self, width, height) - self.width, self.height = width, height - visualsChanged = true - return self - end; - - getHeight = function(self) - return self.height - end; - - getWidth = function(self) - return self.w - end; - - setBackground = function(self, color) - self.bgColor = color - visualsChanged = true - return self - end; - - getBackground = function(self) - return self.bgColor - end; - - setForeground = function(self, color) - self.fgColor = color - visualsChanged = true - return self - end; - - getForeground = function(self) - return self.fgColor - end; - - draw = function(self) - if (isVisible) then - return true - end - return false - end; - - - getAbsolutePosition = function(self, x, y) - -- relative position to absolute position - if (x == nil) then - x = self.x - end - if (y == nil) then - y = self.y - end - - if (self.parent ~= nil) then - local fx, fy = self.parent:getAbsolutePosition(self.parent:getAnchorPosition()) - x = fx + x - 1 - y = fy + y - 1 - end - return x, y - end; - - getAnchorPosition = function(self, x, y, ignOff) - if (x == nil) then - x = self.x - end - if (y == nil) then - y = self.y - end - if (hanchor == "right") then - x = self.parent.width - x - self.width + 2 - end - if (vanchor == "bottom") then - y = self.parent.height - y - self.height + 2 - end - local xO, yO = self:getOffset() - if (ignOffset or ignOff) then - return x, y - end - return x + xO, y + yO - end; - - getOffset = function(self) - if (self.parent ~= nil) and (ignOffset == false) then - return self.parent:getFrameOffset() - end - return 0, 0 - end; - - ignoreOffset = function(self, ignore) - ignOffset = ignore or true - return self - end; - - setAnchor = function(self, ...) - for _, value in pairs(table.pack(...)) do - if (value == "right") or (value == "left") then - hanchor = value - end - if (value == "top") or (value == "bottom") then - vanchor = value - end - end - visualsChanged = true - return self - end; - - getAnchor = function(self) - return hanchor, vanchor - end; - - onChange = function(self, func) - self:registerEvent("value_changed", func) - return self - end; - - onClick = function(self, func) - self:registerEvent("mouse_click", func) - return self - end; - - onEvent = function(self, func) - self:registerEvent("custom_event_handler", func) - return self - end; - - onClickUp = function(self, func) - self:registerEvent("mouse_up", func) - return self - end; - - onKey = function(self, func) - self:registerEvent("key", func) - self:registerEvent("char", func) - return self - end; - - onKeyUp = function(self, func) - self:registerEvent("key_up", func) - return self - end; - - onBackgroundKey = function(self, func) - self:registerEvent("background_key", func) - self:registerEvent("background_char", func) - return self - end; - - onBackgroundKeyUp = function(self, func) - self:registerEvent("background_key_up", func) - return self - end; - - isFocused = function(self) - if (self.parent ~= nil) then - return self.parent:getFocusedObject() == self - end - return false - end; - - onGetFocus = function(self, func) - self:registerEvent("get_focus", func) - return self - end; - - onLoseFocus = function(self, func) - self:registerEvent("lose_focus", func) - return self - end; - - registerEvent = function(self, event, func) - return eventSystem:registerEvent(event, func) - end; - - removeEvent = function(self, event, index) - return eventSystem:removeEvent(event, index) - end; - - sendEvent = function(self, event, ...) - return eventSystem:sendEvent(event, self, ...) - end; - - mouseClickHandler = function(self, event, button, x, y) - local objX, objY = self:getAbsolutePosition(self:getAnchorPosition()) - if (objX <= x) and (objX + self.width > x) and (objY <= y) and (objY + self.height > y) and (isVisible) then - if (self.parent ~= nil) then - self.parent:setFocusedObject(self) - end - eventSystem:sendEvent(event, self, event, button, x, y) - return true - end - return false - end; - - keyHandler = function(self, event, key) - if (self:isFocused()) then - eventSystem:sendEvent(event, self, event, key) - return true - end - return false - end; - - backgroundKeyHandler = function(self, event, key) - eventSystem:sendEvent("background_" .. event, self, event, key) - end; - - valueChangedHandler = function(self) - eventSystem:sendEvent("value_changed", self) - end; - - eventHandler = function(self, event, p1, p2, p3, p4) - eventSystem:sendEvent("custom_event_handler", self, event, p1, p2, p3, p4) - end; - - getFocusHandler = function(self) - eventSystem:sendEvent("get_focus", self) - end; - - loseFocusHandler = function(self) - eventSystem:sendEvent("lose_focus", self) - end; - - - } - - object.__index = object - return object -end - -local function Button(name) - -- Button - local base = Object(name) - local objectType = "Button" - - base:setValue("Button") - base:setZIndex(5) - base.width = 8 - base.bgColor = theme.ButtonBG - base.fgColor = theme.ButtonFG - - local textHorizontalAlign = "center" - local textVerticalAlign = "center" - - local object = { - getType = function(self) - return objectType - end; - setHorizontalAlign = function(self, pos) - textHorizontalAlign = pos - end; - - setVerticalAlign = function(self, pos) - textVerticalAlign = pos - end; - - setText = function(self, text) - base:setValue(text) - return self - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - local verticalAlign = getTextVerticalAlign(self.height, textVerticalAlign) - - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - self.parent:drawForegroundBox(obx, oby, self.width, self.height, self.fgColor) - self.parent:drawTextBox(obx, oby, self.width, self.height, " ") - for n = 1, self.height do - if (n == verticalAlign) then - self.parent:setText(obx, oby + (n - 1), getTextHorizontalAlign(self:getValue(), self.width, textHorizontalAlign)) - end - end - end - end - end; - - } - return setmetatable(object, base) -end - -local function Program(name) - local base = Object(name) - local objectType = "Program" - base:setZIndex(5) - local object - - local function createBasaltWindow(x, y, width, height) - local xCursor, yCursor = 1, 1 - local bgColor, fgColor = colors.black, colors.white - local cursorBlink = false - local visible = false - - local cacheT = {} - local cacheBG = {} - local cacheFG = {} - - local tPalette = {} - - local emptySpaceLine - local emptyColorLines = {} - - for i = 0, 15 do - local c = 2 ^ i - tPalette[c] = { parentTerminal.getPaletteColour(c) } - end - - local function createEmptyLines() - emptySpaceLine = (" "):rep(width) - for n = 0, 15 do - local nColor = 2 ^ n - local sHex = tHex[nColor] - emptyColorLines[nColor] = sHex:rep(width) - end - end - - local function recreateWindowArray() - createEmptyLines() - local emptyText = emptySpaceLine - local emptyFG = emptyColorLines[colors.white] - local emptyBG = emptyColorLines[colors.black] - for n = 1, height do - cacheT[n] = sub(cacheT[n] == nil and emptyText or cacheT[n] .. emptyText:sub(1, width - cacheT[n]:len()), 1, width) - cacheFG[n] = sub(cacheFG[n] == nil and emptyFG or cacheFG[n] .. emptyFG:sub(1, width - cacheFG[n]:len()), 1, width) - cacheBG[n] = sub(cacheBG[n] == nil and emptyBG or cacheBG[n] .. emptyBG:sub(1, width - cacheBG[n]:len()), 1, width) - end - end - recreateWindowArray() - - local function updateCursor() - if xCursor >= 1 and yCursor >= 1 and xCursor <= width and yCursor <= height then - --parentTerminal.setCursorPos(xCursor + x - 1, yCursor + y - 1) - else - --parentTerminal.setCursorPos(0, 0) - end - --parentTerminal.setTextColor(fgColor) - end - - local function internalBlit(sText, sTextColor, sBackgroundColor) - -- copy pasti strikes again (cc: window.lua) - local nStart = xCursor - local nEnd = nStart + #sText - 1 - if yCursor >= 1 and yCursor <= height then - if nStart <= width and nEnd >= 1 then - -- Modify line - if nStart == 1 and nEnd == width then - cacheT[yCursor] = sText - cacheFG[yCursor] = sTextColor - cacheBG[yCursor] = sBackgroundColor - else - local sClippedText, sClippedTextColor, sClippedBackgroundColor - if nStart < 1 then - local nClipStart = 1 - nStart + 1 - local nClipEnd = width - nStart + 1 - sClippedText = sub(sText, nClipStart, nClipEnd) - sClippedTextColor = sub(sTextColor, nClipStart, nClipEnd) - sClippedBackgroundColor = sub(sBackgroundColor, nClipStart, nClipEnd) - elseif nEnd > width then - local nClipEnd = width - nStart + 1 - sClippedText = sub(sText, 1, nClipEnd) - sClippedTextColor = sub(sTextColor, 1, nClipEnd) - sClippedBackgroundColor = sub(sBackgroundColor, 1, nClipEnd) - else - sClippedText = sText - sClippedTextColor = sTextColor - sClippedBackgroundColor = sBackgroundColor - end - - local sOldText = cacheT[yCursor] - local sOldTextColor = cacheFG[yCursor] - local sOldBackgroundColor = cacheBG[yCursor] - local sNewText, sNewTextColor, sNewBackgroundColor - if nStart > 1 then - local nOldEnd = nStart - 1 - sNewText = sub(sOldText, 1, nOldEnd) .. sClippedText - sNewTextColor = sub(sOldTextColor, 1, nOldEnd) .. sClippedTextColor - sNewBackgroundColor = sub(sOldBackgroundColor, 1, nOldEnd) .. sClippedBackgroundColor - else - sNewText = sClippedText - sNewTextColor = sClippedTextColor - sNewBackgroundColor = sClippedBackgroundColor - end - if nEnd < width then - local nOldStart = nEnd + 1 - sNewText = sNewText .. sub(sOldText, nOldStart, width) - sNewTextColor = sNewTextColor .. sub(sOldTextColor, nOldStart, width) - sNewBackgroundColor = sNewBackgroundColor .. sub(sOldBackgroundColor, nOldStart, width) - end - - cacheT[yCursor] = sNewText - cacheFG[yCursor] = sNewTextColor - cacheBG[yCursor] = sNewBackgroundColor - end - end - xCursor = nEnd + 1 - if (visible) then - updateCursor() - end - end - end - - local function setText(_x, _y, text) - if (text ~= nil) then - local gText = cacheT[_y] - if (gText ~= nil) then - cacheT[_y] = sub(gText:sub(1, _x - 1) .. text .. gText:sub(_x + (text:len()), width), 1, width) - end - end - end - - local function setBG(_x, _y, colorStr) - if (colorStr ~= nil) then - local gBG = cacheBG[_y] - if (gBG ~= nil) then - cacheBG[_y] = sub(gBG:sub(1, _x - 1) .. colorStr .. gBG:sub(_x + (colorStr:len()), width), 1, width) - end - end - end - - local function setFG(_x, _y, colorStr) - if (colorStr ~= nil) then - local gFG = cacheFG[_y] - if (gFG ~= nil) then - cacheFG[_y] = sub(gFG:sub(1, _x - 1) .. colorStr .. gFG:sub(_x + (colorStr:len()), width), 1, width) - end - end - end - - local setTextColor = function(color) - if type(color) ~= "number" then - error("bad argument #1 (expected number, got " .. type(color) .. ")", 2) - elseif tHex[color] == nil then - error("Invalid color (got " .. color .. ")", 2) - end - fgColor = color - end - - local setBackgroundColor = function(color) - if type(color) ~= "number" then - error("bad argument #1 (expected number, got " .. type(color) .. ")", 2) - elseif tHex[color] == nil then - error("Invalid color (got " .. color .. ")", 2) - end - bgColor = color - end - - local setPaletteColor = function(colour, r, g, b) - -- have to work on - if type(colour) ~= "number" then - error("bad argument #1 (expected number, got " .. type(colour) .. ")", 2) - end - - if tHex[colour] == nil then - error("Invalid color (got " .. colour .. ")", 2) - end - - local tCol - if type(r) == "number" and g == nil and b == nil then - tCol = { colours.rgb8(r) } - tPalette[colour] = tCol - else - if type(r) ~= "number" then - error("bad argument #2 (expected number, got " .. type(r) .. ")", 2) - end - if type(g) ~= "number" then - error("bad argument #3 (expected number, got " .. type(g) .. ")", 2) - end - if type(b) ~= "number" then - error("bad argument #4 (expected number, got " .. type(b) .. ")", 2) - end - - tCol = tPalette[colour] - tCol[1] = r - tCol[2] = g - tCol[3] = b - end - end - - local getPaletteColor = function(colour) - if type(colour) ~= "number" then - error("bad argument #1 (expected number, got " .. type(colour) .. ")", 2) - end - if tHex[colour] == nil then - error("Invalid color (got " .. colour .. ")", 2) - end - local tCol = tPalette[colour] - return tCol[1], tCol[2], tCol[3] - end - - local basaltwindow = { - setCursorPos = function(_x, _y) - if type(_x) ~= "number" then - error("bad argument #1 (expected number, got " .. type(_x) .. ")", 2) - end - if type(_y) ~= "number" then - error("bad argument #2 (expected number, got " .. type(_y) .. ")", 2) - end - xCursor = math.floor(_x) - yCursor = math.floor(_y) - if (visible) then - updateCursor() - end - end; - - getCursorPos = function() - return xCursor, yCursor - end; - - setCursorBlink = function(blink) - if type(blink) ~= "boolean" then - error("bad argument #1 (expected boolean, got " .. type(blink) .. ")", 2) - end - cursorBlink = blink - end; - - getCursorBlink = function() - return cursorBlink - end; - - - getPaletteColor = getPaletteColor, - getPaletteColour = getPaletteColor, - - setBackgroundColor = setBackgroundColor, - setBackgroundColour = setBackgroundColor, - - setTextColor = setTextColor, - setTextColour = setTextColor, - - setPaletteColor = setPaletteColor, - setPaletteColour = setPaletteColor, - - getBackgroundColor = function() - return bgColor - end; - getBackgroundColour = function() - return bgColor - end; - - getSize = function() - return width, height - end; - - getTextColor = function() - return fgColor - end; - getTextColour = function() - return fgColor - end; - - basalt_resize = function(_width, _height) - width, height = _width, _height - recreateWindowArray() - end; - - basalt_reposition = function(_x, _y) - x, y = _x, _y - end; - - basalt_setVisible = function(vis) - visible = vis - end; - - drawBackgroundBox = function(_x, _y, _width, _height, bgCol) - for n = 1, _height do - setBG(_x, _y + (n - 1), tHex[bgCol]:rep(_width)) - end - end; - drawForegroundBox = function(_x, _y, _width, _height, fgCol) - for n = 1, _height do - setFG(_x, _y + (n - 1), tHex[fgCol]:rep(_width)) - end - end; - drawTextBox = function(_x, _y, _width, _height, symbol) - for n = 1, _height do - setText(_x, _y + (n - 1), symbol:rep(_width)) - end - end; - - writeText = function(_x, _y, text, bgCol, fgCol) - bgCol = bgCol or bgColor - fgCol = fgCol or fgColor - setText(x, _y, text) - setBG(_x, _y, tHex[bgCol]:rep(text:len())) - setFG(_x, _y, tHex[fgCol]:rep(text:len())) - end; - - basalt_update = function() - if (object.parent ~= nil) then - for n = 1, height do - object.parent:setText(x, y + (n - 1), cacheT[n]) - object.parent:setBG(x, y + (n - 1), cacheBG[n]) - object.parent:setFG(x, y + (n - 1), cacheFG[n]) - end - end - end; - - scroll = function(offset) - if type(offset) ~= "number" then - error("bad argument #1 (expected number, got " .. type(offset) .. ")", 2) - end - if offset ~= 0 then - local sEmptyText = emptySpaceLine - local sEmptyTextColor = emptyColorLines[fgColor] - local sEmptyBackgroundColor = emptyColorLines[bgColor] - for newY = 1, height do - local y = newY + offset - if y >= 1 and y <= height then - cacheT[newY] = cacheT[y] - cacheBG[newY] = cacheBG[y] - cacheFG[newY] = cacheFG[y] - else - cacheT[newY] = sEmptyText - cacheFG[newY] = sEmptyTextColor - cacheBG[newY] = sEmptyBackgroundColor - end - end - end - if (visible) then - updateCursor() - end - end; - - - isColor = function() - return parentTerminal.isColor() - end; - - isColour = function() - return parentTerminal.isColor() - end; - - write = function(text) - text = tostring(text) - if (visible) then - internalBlit(text, tHex[fgColor]:rep(text:len()), tHex[bgColor]:rep(text:len())) - end - end; - - clearLine = function() - if (visible) then - setText(1, yCursor, (" "):rep(width)) - setBG(1, yCursor, tHex[bgColor]:rep(width)) - setFG(1, yCursor, tHex[fgColor]:rep(width)) - end - if (visible) then - updateCursor() - end - end; - - clear = function() - for n = 1, height do - setText(1, n, (" "):rep(width)) - setBG(1, n, tHex[bgColor]:rep(width)) - setFG(1, n, tHex[fgColor]:rep(width)) - end - if (visible) then - updateCursor() - end - end; - - blit = function(text, fgcol, bgcol) - if type(text) ~= "string" then - error("bad argument #1 (expected string, got " .. type(text) .. ")", 2) - end - if type(fgcol) ~= "string" then - error("bad argument #2 (expected string, got " .. type(fgcol) .. ")", 2) - end - if type(bgcol) ~= "string" then - error("bad argument #3 (expected string, got " .. type(bgcol) .. ")", 2) - end - if #fgcol ~= #text or #bgcol ~= #text then - error("Arguments must be the same length", 2) - end - if (visible) then - --setText(xCursor, yCursor, text) - --setBG(xCursor, yCursor, bgcol) - --setFG(xCursor, yCursor, fgcol) - --xCursor = xCursor+text:len() - internalBlit(text, fgcol, bgcol) - end - end - - - } - - return basaltwindow - end - - base.width = 30 - base.height = 12 - local pWindow = createBasaltWindow(1, 1, base.width, base.height) - local curProcess - local paused = false - local queuedEvent = {} - - object = { - getType = function(self) - return objectType - end; - - show = function(self) - base.show(self) - pWindow.setBackgroundColor(self.bgColor) - pWindow.setTextColor(self.fgColor) - pWindow.basalt_setVisible(true) - return self - end; - - hide = function(self) - base.hide(self) - pWindow.basalt_setVisible(false) - return self - end; - - setPosition = function(self, x, y, rel) - base.setPosition(self, x, y, rel) - pWindow.basalt_reposition(self:getAnchorPosition()) - return self - end; - - getBasaltWindow = function() - return pWindow - end; - - getBasaltProcess = function() - return curProcess - end; - - setSize = function(self, width, height) - base.setSize(self, width, height) - pWindow.basalt_resize(self.width, self.height) - return self - end; - - getStatus = function(self) - if (curProcess ~= nil) then - return curProcess:getStatus() - end - return "inactive" - end; - - execute = function(self, path, ...) - curProcess = process:new(path, pWindow, ...) - pWindow.setBackgroundColor(colors.black) - pWindow.setTextColor(colors.white) - pWindow.clear() - pWindow.setCursorPos(1, 1) - curProcess:resume() - paused = false - return self - end; - - stop = function(self) - if (curProcess ~= nil) then - if not (curProcess:isDead()) then - curProcess:resume("terminate") - if (curProcess:isDead()) then - if (self.parent ~= nil) then - self.parent:setCursor(false) - end - end - end - end - return self - end; - - pause = function(self, p) - paused = p or (not paused) - if (curProcess ~= nil) then - if not (curProcess:isDead()) then - if not (paused) then - self:injectEvents(queuedEvent) - queuedEvent = {} - end - end - end - return self - end; - - isPaused = function(self) - return paused - end; - - injectEvent = function(self, event, p1, p2, p3, p4, ign) - if (curProcess ~= nil) then - if not (curProcess:isDead()) then - if (paused == false) or (ign) then - curProcess:resume(event, p1, p2, p3, p4) - else - table.insert(queuedEvent, { event = event, args = { p1, p2, p3, p4 } }) - end - end - end - return self - end; - - getQueuedEvents = function(self) - return queuedEvent - end; - - updateQueuedEvents = function(self, events) - queuedEvent = events or queuedEvent - return self - end; - - injectEvents = function(self, events) - if (curProcess ~= nil) then - if not (curProcess:isDead()) then - for _, value in pairs(events) do - curProcess:resume(value.event, table.unpack(value.args)) - end - end - end - return self - end; - - mouseClickHandler = function(self, event, button, x, y) - if (base.mouseClickHandler(self, event, button, x, y)) then - if (curProcess == nil) then - return false - end - if not (curProcess:isDead()) then - if not (paused) then - local absX, absY = self:getAbsolutePosition(self:getAnchorPosition(nil, nil, true)) - curProcess:resume(event, button, x - absX + 1, y - absY + 1) - end - end - return true - end - end; - - keyHandler = function(self, event, key) - base.keyHandler(self, event, key) - if (self:isFocused()) then - if (curProcess == nil) then - return false - end - if not (curProcess:isDead()) then - if not (paused) then - if (self.draw) then - curProcess:resume(event, key) - end - end - end - end - end; - - getFocusHandler = function(self) - base.getFocusHandler(self) - if (curProcess ~= nil) then - if not (curProcess:isDead()) then - if not (paused) then - if (self.parent ~= nil) then - local xCur, yCur = pWindow.getCursorPos() - local obx, oby = self:getAnchorPosition() - if (self.parent ~= nil) then - if (obx + xCur - 1 >= 1 and obx + xCur - 1 <= obx + self.width - 1 and yCur + oby - 1 >= 1 and yCur + oby - 1 <= oby + self.height - 1) then - self.parent:setCursor(pWindow.getCursorBlink(), obx + xCur - 1, yCur + oby - 1, pWindow.getTextColor()) - end - end - end - end - end - end - end; - - loseFocusHandler = function(self) - base.loseFocusHandler(self) - if (curProcess ~= nil) then - if not (curProcess:isDead()) then - if (self.parent ~= nil) then - self.parent:setCursor(false) - end - end - end - end; - - eventHandler = function(self, event, p1, p2, p3, p4) - if (curProcess == nil) then - return - end - if not (curProcess:isDead()) then - if not (paused) then - if (event ~= "mouse_click") and (event ~= "mouse_up") and (event ~= "mouse_scroll") and (event ~= "mouse_drag") and (event ~= "key_up") and (event ~= "key") and (event ~= "char") and (event ~= "terminate") then - curProcess:resume(event, p1, p2, p3, p4) - end - if (self:isFocused()) then - local obx, oby = self:getAnchorPosition() - local xCur, yCur = pWindow.getCursorPos() - if (self.parent ~= nil) then - if (obx + xCur - 1 >= 1 and obx + xCur - 1 <= obx + self.width - 1 and yCur + oby - 1 >= 1 and yCur + oby - 1 <= oby + self.height - 1) then - self.parent:setCursor(pWindow.getCursorBlink(), obx + xCur - 1, yCur + oby - 1, pWindow.getTextColor()) - end - end - - if (event == "terminate") and (self:isFocused()) then - self:stop() - end - end - else - if (event ~= "mouse_click") and (event ~= "mouse_up") and (event ~= "mouse_scroll") and (event ~= "mouse_drag") and (event ~= "key_up") and (event ~= "key") and (event ~= "char") and (event ~= "terminate") then - table.insert(queuedEvent, { event = event, args = { p1, p2, p3, p4 } }) - end - end - end - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - pWindow.basalt_reposition(obx, oby) - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - pWindow.basalt_update() - end - end - end; - - } - - return setmetatable(object, base) -end - -local function Label(name) - -- Label - local base = Object(name) - local objectType = "Label" - - base:setZIndex(3) - - local autoWidth = true - base:setValue("") - - local object = { - getType = function(self) - return objectType - end; - setText = function(self, text) - text = tostring(text) - base:setValue(text) - if (autoWidth) then - self.width = text:len() - end - return self - end; - - setSize = function(self, width, h) - self.width, self.height = width, h - autoWidth = false - return self - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - self.parent:writeText(obx, oby, self:getValue(), self.bgColor, self.fgColor) - end - end - end; - - } - - return setmetatable(object, base) -end - -local function Pane(name) - -- Pane - local base = Object(name) - local objectType = "Pane" - - local object = { - getType = function(self) - return objectType - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - self.parent:drawForegroundBox(obx, oby, self.width, self.height, self.bgColor) - end - end - end; - - } - - return setmetatable(object, base) -end - -local function Image(name) - -- Pane - local base = Object(name) - local objectType = "Image" - base:setZIndex(2) - local image - local shrinkedImage - local imageGotShrinked = false - - local function shrink() - - -- shrinkSystem is copy pasted (and slightly changed) from blittle by Bomb Bloke: http://www.computercraft.info/forums2/index.php?/topic/25354-cc-176-blittle-api/ - local relations = { [0] = { 8, 4, 3, 6, 5 }, { 4, 14, 8, 7 }, { 6, 10, 8, 7 }, { 9, 11, 8, 0 }, { 1, 14, 8, 0 }, { 13, 12, 8, 0 }, { 2, 10, 8, 0 }, { 15, 8, 10, 11, 12, 14 }, - { 0, 7, 1, 9, 2, 13 }, { 3, 11, 8, 7 }, { 2, 6, 7, 15 }, { 9, 3, 7, 15 }, { 13, 5, 7, 15 }, { 5, 12, 8, 7 }, { 1, 4, 7, 15 }, { 7, 10, 11, 12, 14 } } - - local colourNum, exponents, colourChar = {}, {}, {} - for i = 0, 15 do - exponents[2 ^ i] = i - end - do - local hex = "0123456789abcdef" - for i = 1, 16 do - colourNum[hex:sub(i, i)] = i - 1 - colourNum[i - 1] = hex:sub(i, i) - colourChar[hex:sub(i, i)] = 2 ^ (i - 1) - colourChar[2 ^ (i - 1)] = hex:sub(i, i) - - local thisRel = relations[i - 1] - for i = 1, #thisRel do - thisRel[i] = 2 ^ thisRel[i] - end - end - end - - local function getBestColourMatch(usage) - local lastCol = relations[exponents[usage[#usage][1]]] - - for j = 1, #lastCol do - local thisRelation = lastCol[j] - for i = 1, #usage - 1 do - if usage[i][1] == thisRelation then - return i - end - end - end - - return 1 - end - - local function colsToChar(pattern, totals) - if not totals then - local newPattern = {} - totals = {} - for i = 1, 6 do - local thisVal = pattern[i] - local thisTot = totals[thisVal] - totals[thisVal], newPattern[i] = thisTot and (thisTot + 1) or 1, thisVal - end - pattern = newPattern - end - - local usage = {} - for key, value in pairs(totals) do - usage[#usage + 1] = { key, value } - end - - if #usage > 1 then - -- Reduce the chunk to two colours: - while #usage > 2 do - table.sort(usage, function(a, b) - return a[2] > b[2] - end) - local matchToInd, usageLen = getBestColourMatch(usage), #usage - local matchFrom, matchTo = usage[usageLen][1], usage[matchToInd][1] - for i = 1, 6 do - if pattern[i] == matchFrom then - pattern[i] = matchTo - usage[matchToInd][2] = usage[matchToInd][2] + 1 - end - end - usage[usageLen] = nil - end - - -- Convert to character. Adapted from oli414's function: - -- http://www.computercraft.info/forums2/index.php?/topic/25340-cc-176-easy-drawing-characters/ - local data = 128 - for i = 1, #pattern - 1 do - if pattern[i] ~= pattern[6] then - data = data + 2 ^ (i - 1) - end - end - return string.char(data), colourChar[usage[1][1] == pattern[6] and usage[2][1] or usage[1][1]], colourChar[pattern[6]] - else - -- Solid colour character: - return "\128", colourChar[pattern[1]], colourChar[pattern[1]] - end - end - - local results, width, height, bgCol = { {}, {}, {} }, 0, #image + #image % 3, base.bgColor or colors.black - for i = 1, #image do - if #image[i] > width then - width = #image[i] - end - end - - for y = 0, height - 1, 3 do - local cRow, tRow, bRow, counter = {}, {}, {}, 1 - - for x = 0, width - 1, 2 do - -- Grab a 2x3 chunk: - local pattern, totals = {}, {} - - for yy = 1, 3 do - for xx = 1, 2 do - pattern[#pattern + 1] = (image[y + yy] and image[y + yy][x + xx]) and (image[y + yy][x + xx] == 0 and bgCol or image[y + yy][x + xx]) or bgCol - totals[pattern[#pattern]] = totals[pattern[#pattern]] and (totals[pattern[#pattern]] + 1) or 1 - end - end - - cRow[counter], tRow[counter], bRow[counter] = colsToChar(pattern, totals) - counter = counter + 1 - end - - results[1][#results[1] + 1], results[2][#results[2] + 1], results[3][#results[3] + 1] = table.concat(cRow), table.concat(tRow), table.concat(bRow) - end - - results.width, results.height = #results[1][1], #results[1] - - shrinkedImage = results - end - - local object = { - getType = function(self) - return objectType - end; - - loadImage = function(self, path) - image = paintutils.loadImage(path) - imageGotShrinked = false - return self - end; - - loadBlittleImage = function(self, path) - --image = paintutils.loadImage(path) - imageGotShrinked = true - return self - end; - - shrinkImage = function(self) - shrink() - imageGotShrinked = true - return self - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - if (image ~= nil) then - local obx, oby = self:getAnchorPosition() - if (imageGotShrinked) then - -- this is copy pasted (and slightly changed) from blittle by Bomb Bloke: http://www.computercraft.info/forums2/index.php?/topic/25354-cc-176-blittle-api/ - local t, tC, bC = shrinkedImage[1], shrinkedImage[2], shrinkedImage[3] - for i = 1, shrinkedImage.height do - local tI = t[i] - if type(tI) == "string" then - self.parent:setText(obx, oby + i - 1, tI) - self.parent:setFG(obx, oby + i - 1, tC[i]) - self.parent:setBG(obx, oby + i - 1, bC[i]) - elseif type(tI) == "table" then - self.parent:setText(obx, oby + i - 1, tI[2]) - self.parent:setFG(obx, oby + i - 1, tC[i]) - self.parent:setBG(obx, oby + i - 1, bC[i]) - end - end - else - for yPos = 1, math.min(#image, self.height) do - local line = image[yPos] - for xPos = 1, math.min(#line, self.width) do - if line[xPos] > 0 then - self.parent:drawBackgroundBox(obx + xPos - 1, oby + yPos - 1, 1, 1, line[xPos]) - end - end - end - end - end - end - end - end; - } - - return setmetatable(object, base) -end - -local function Checkbox(name) - -- Checkbox - local base = Object(name) - local objectType = "Checkbox" - - base:setZIndex(5) - base:setValue(false) - base.width = 1 - base.height = 1 - base.bgColor = theme.CheckboxBG - base.fgColor = theme.CheckboxFG - - local object = { - symbol = "\42", - - getType = function(self) - return objectType - end; - - mouseClickHandler = function(self, event, button, x, y) - if (base.mouseClickHandler(self, event, button, x, y)) then - if (event == "mouse_click") and (button == 1) then - if (self:getValue() ~= true) and (self:getValue() ~= false) then - self:setValue(false) - else - self:setValue(not self:getValue()) - end - end - return true - end - return false - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - local verticalAlign = getTextVerticalAlign(self.height, "center") - - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - for n = 1, self.height do - if (n == verticalAlign) then - if (self:getValue() == true) then - self.parent:writeText(obx, oby + (n - 1), getTextHorizontalAlign(self.symbol, self.width, "center"), self.bgColor, self.fgColor) - else - self.parent:writeText(obx, oby + (n - 1), getTextHorizontalAlign(" ", self.width, "center"), self.bgColor, self.fgColor) - end - end - end - end - end - end; - - } - - return setmetatable(object, base) -end - -local function Progressbar(name) - -- Checkbox - local base = Object(name) - local objectType = "Progressbar" - - local progress = 0 - - base:setZIndex(5) - base:setValue(false) - base.width = 25 - base.height = 1 - base.bgColor = theme.CheckboxBG - base.fgColor = theme.CheckboxFG - - local activeBarColor = colors.black - local activeBarSymbol = "" - local activeBarSymbolCol = colors.white - local bgBarSymbol = "" - local direction = 0 - - local object = { - - getType = function(self) - return objectType - end; - - setDirection = function(self, dir) - direction = dir - return self - end; - - setProgressBar = function(self, color, symbol, symbolcolor) - activeBarColor = color or activeBarColor - activeBarSymbol = symbol or activeBarSymbol - activeBarSymbolCol = symbolcolor or activeBarSymbolCol - return self - end; - - setBackgroundSymbol = function(self, symbol) - bgBarSymbol = symbol:sub(1, 1) - return self - end; - - setProgress = function(self, value) - if (value >= 0) and (value <= 100) and (progress ~= value) then - progress = value - self:setValue(progress) - if (progress == 100) then - self:progressDoneHandler() - end - end - return self - end; - - getProgress = function(self) - return progress - end; - - onProgressDone = function(self, f) - self:registerEvent("progress_done", f) - return self - end; - - progressDoneHandler = function(self) - self:sendEvent("progress_done") - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - self.parent:drawForegroundBox(obx, oby, self.width, self.height, self.fgColor) - self.parent:drawTextBox(obx, oby, self.width, self.height, bgBarSymbol) - if (direction == 1) then - self.parent:drawBackgroundBox(obx, oby, self.width, self.height / 100 * progress, activeBarColor) - self.parent:drawForegroundBox(obx, oby, self.width, self.height / 100 * progress, activeBarSymbolCol) - self.parent:drawTextBox(obx, oby, self.width, self.height / 100 * progress, activeBarSymbol) - elseif (direction == 2) then - self.parent:drawBackgroundBox(obx, oby + math.ceil(self.height - self.height / 100 * progress), self.width, self.height / 100 * progress, activeBarColor) - self.parent:drawForegroundBox(obx, oby + math.ceil(self.height - self.height / 100 * progress), self.width, self.height / 100 * progress, activeBarSymbolCol) - self.parent:drawTextBox(obx, oby + math.ceil(self.height - self.height / 100 * progress), self.width, self.height / 100 * progress, activeBarSymbol) - elseif (direction == 3) then - self.parent:drawBackgroundBox(obx + math.ceil(self.width - self.width / 100 * progress), oby, self.width / 100 * progress, self.height, activeBarColor) - self.parent:drawForegroundBox(obx + math.ceil(self.width - self.width / 100 * progress), oby, self.width / 100 * progress, self.height, activeBarSymbolCol) - self.parent:drawTextBox(obx + math.ceil(self.width - self.width / 100 * progress), oby, self.width / 100 * progress, self.height, activeBarSymbol) - else - self.parent:drawBackgroundBox(obx, oby, self.width / 100 * progress, self.height, activeBarColor) - self.parent:drawForegroundBox(obx, oby, self.width / 100 * progress, self.height, activeBarSymbolCol) - self.parent:drawTextBox(obx, oby, self.width / 100 * progress, self.height, activeBarSymbol) - end - end - end - end; - - } - - return setmetatable(object, base) -end - -local function Input(name) - -- Input - local base = Object(name) - local objectType = "Input" - - local inputType = "text" - local inputLimit = 0 - base:setZIndex(5) - base:setValue("") - base.width = 10 - base.height = 1 - base.bgColor = theme.InputBG - base.fgColor = theme.InputFG - - local textX = 1 - local wIndex = 1 - - local defaultText = "" - local defaultBGCol - local defaultFGCol - local showingText = defaultText - local internalValueChange = false - - local object = { - - getType = function(self) - return objectType - end; - - setInputType = function(self, iType) - if (iType == "password") or (iType == "number") or (iType == "text") then - inputType = iType - end - return self - end; - - setDefaultText = function(self, text, fCol, bCol) - defaultText = text - defaultBGCol = bCol or defaultBGCol - defaultFGCol = fCol or defaultFGCol - if (self:isFocused()) then - showingText = "" - else - showingText = defaultText - end - return self - end; - - getInputType = function(self) - return inputType - end; - - setValue = function(self, val) - base.setValue(self, tostring(val)) - if not (internalValueChange) then - textX = tostring(val):len() + 1 - end - return self - end; - - getValue = function(self) - local val = base.getValue(self) - return inputType == "number" and tonumber(val) or val - end; - - setInputLimit = function(self, limit) - inputLimit = tonumber(limit) or inputLimit - return self - end; - - getInputLimit = function(self) - return inputLimit - end; - - getFocusHandler = function(self) - base.getFocusHandler(self) - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - showingText = "" - if (self.parent ~= nil) then - self.parent:setCursor(true, obx + textX - wIndex, oby, self.fgColor) - end - end - end; - - loseFocusHandler = function(self) - base.loseFocusHandler(self) - if (self.parent ~= nil) then - self.parent:setCursor(false) - showingText = defaultText - end - end; - - keyHandler = function(self, event, key) - if (base.keyHandler(self, event, key)) then - internalValueChange = true - if (event == "key") then - if (key == keys.backspace) then - -- on backspace - local text = tostring(base.getValue()) - if (textX > 1) then - self:setValue(text:sub(1, textX - 2) .. text:sub(textX, text:len())) - if (textX > 1) then - textX = textX - 1 - end - if (wIndex > 1) then - if (textX < wIndex) then - wIndex = wIndex - 1 - end - end - end - end - if (key == keys.enter) then - -- on enter - if (self.parent ~= nil) then - --self.parent:removeFocusedObject(self) - end - end - if (key == keys.right) then - -- right arrow - local tLength = tostring(base.getValue()):len() - textX = textX + 1 - - if (textX > tLength) then - textX = tLength + 1 - end - if (textX < 1) then - textX = 1 - end - if (textX < wIndex) or (textX >= self.width + wIndex) then - wIndex = textX - self.width + 1 - end - if (wIndex < 1) then - wIndex = 1 - end - end - - if (key == keys.left) then - -- left arrow - textX = textX - 1 - if (textX >= 1) then - if (textX < wIndex) or (textX >= self.width + wIndex) then - wIndex = textX - end - end - if (textX < 1) then - textX = 1 - end - if (wIndex < 1) then - wIndex = 1 - end - end - end - - if (event == "char") then - local text = base.getValue() - if (text:len() < inputLimit or inputLimit <= 0) then - if (inputType == "number") then - local cache = text - if (key == ".") or (tonumber(key) ~= nil) then - self:setValue(text:sub(1, textX - 1) .. key .. text:sub(textX, text:len())) - textX = textX + 1 - end - if (tonumber(base.getValue()) == nil) then - self:setValue(cache) - end - else - self:setValue(text:sub(1, textX - 1) .. key .. text:sub(textX, text:len())) - textX = textX + 1 - end - if (textX >= self.width + wIndex) then - wIndex = wIndex + 1 - end - end - end - local obx, oby = self:getAnchorPosition() - local val = tostring(base.getValue()) - local cursorX = (textX <= val:len() and textX - 1 or val:len()) - (wIndex - 1) - - if (cursorX > self.x + self.width - 1) then - cursorX = self.x + self.width - 1 - end - if (self.parent ~= nil) then - self.parent:setCursor(true, obx + cursorX, oby, self.fgColor) - end - internalValueChange = false - end - end; - - mouseClickHandler = function(self, event, button, x, y) - if (base.mouseClickHandler(self, event, button, x, y)) then - if (event == "mouse_click") and (button == 1) then - - end - return true - end - return false - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - local verticalAlign = getTextVerticalAlign(self.height, "center") - - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - for n = 1, self.height do - if (n == verticalAlign) then - local val = tostring(base.getValue()) - local bCol = self.bgColor - local fCol = self.fgColor - local text - if (val:len() <= 0) then - text = showingText - bCol = defaultBGCol or bCol - fCol = defaultFGCol or fCol - end - - text = showingText - if (val ~= "") then - text = val - end - text = text:sub(wIndex, self.width + wIndex - 1) - local space = self.width - text:len() - if (space < 0) then - space = 0 - end - if (inputType == "password") and (val ~= "") then - text = string.rep("*", text:len()) - end - text = text .. string.rep(" ", space) - self.parent:writeText(obx, oby + (n - 1), text, bCol, fCol) - end - end - end - end - end; - } - - return setmetatable(object, base) -end - -local function Textfield(name) - local base = Object(name) - local objectType = "Textfield" - local hIndex, wIndex, textX, textY = 1, 1, 1, 1 - - local lines = { "" } - local keyWords = { [colors.purple] = { "break" } } - - base.width = 20 - base.height = 8 - base.bgColor = theme.textfieldBG - base.fgColor = theme.textfieldFG - base:setZIndex(5) - - local object = { - getType = function(self) - return objectType - end; - - getLines = function(self) - return lines - end; - - getLine = function(self, index) - return lines[index] or "" - end; - - editLine = function(self, index, text) - lines[index] = text or lines[index] - return self - end; - - addLine = function(self, text, index) - if (index ~= nil) then - table.insert(lines, index, text) - else - table.insert(lines, text) - end - return self - end; - - addKeyword = function(self, keyword, color) - - end; - - removeLine = function(self, index) - table.remove(lines, index or #lines) - if (#lines <= 0) then - table.insert(lines, "") - end - return self - end; - - getTextCursor = function(self) - return textX, textY - end; - - getFocusHandler = function(self) - base.getFocusHandler(self) - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - if (self.parent ~= nil) then - self.parent:setCursor(true, obx + textX - wIndex, oby + textY - hIndex, self.fgColor) - end - end - end; - - loseFocusHandler = function(self) - base.loseFocusHandler(self) - if (self.parent ~= nil) then - self.parent:setCursor(false) - end - end; - - keyHandler = function(self, event, key) - if (base.keyHandler(self, event, key)) then - local obx, oby = self:getAnchorPosition() - if (event == "key") then - if (key == keys.backspace) then - -- on backspace - if (lines[textY] == "") then - if (textY > 1) then - table.remove(lines, textY) - textX = lines[textY - 1]:len() + 1 - wIndex = textX - self.width + 1 - if (wIndex < 1) then - wIndex = 1 - end - textY = textY - 1 - end - elseif (textX <= 1) then - if (textY > 1) then - textX = lines[textY - 1]:len() + 1 - wIndex = textX - self.width + 1 - if (wIndex < 1) then - wIndex = 1 - end - lines[textY - 1] = lines[textY - 1] .. lines[textY] - table.remove(lines, textY) - textY = textY - 1 - end - else - lines[textY] = lines[textY]:sub(1, textX - 2) .. lines[textY]:sub(textX, lines[textY]:len()) - if (textX > 1) then - textX = textX - 1 - end - if (wIndex > 1) then - if (textX < wIndex) then - wIndex = wIndex - 1 - end - end - end - if (textY < hIndex) then - hIndex = hIndex - 1 - end - self:setValue("") - end - - if (key == keys.delete) then - -- on delete - if (textX > lines[textY]:len()) then - if (lines[textY + 1] ~= nil) then - lines[textY] = lines[textY] .. lines[textY + 1] - table.remove(lines, textY + 1) - end - else - lines[textY] = lines[textY]:sub(1, textX - 1) .. lines[textY]:sub(textX + 1, lines[textY]:len()) - end - end - - if (key == keys.enter) then - -- on enter - table.insert(lines, textY + 1, lines[textY]:sub(textX, lines[textY]:len())) - lines[textY] = lines[textY]:sub(1, textX - 1) - textY = textY + 1 - textX = 1 - wIndex = 1 - if (textY - hIndex >= self.height) then - hIndex = hIndex + 1 - end - self:setValue("") - end - - if (key == keys.up) then - -- arrow up - if (textY > 1) then - textY = textY - 1 - if (textX > lines[textY]:len() + 1) then - textX = lines[textY]:len() + 1 - end - if (wIndex > 1) then - if (textX < wIndex) then - wIndex = textX - self.width + 1 - if (wIndex < 1) then - wIndex = 1 - end - end - end - if (hIndex > 1) then - if (textY < hIndex) then - hIndex = hIndex - 1 - end - end - end - end - if (key == keys.down) then - -- arrow down - if (textY < #lines) then - textY = textY + 1 - if (textX > lines[textY]:len() + 1) then - textX = lines[textY]:len() + 1 - end - - if (textY >= hIndex + self.height) then - hIndex = hIndex + 1 - end - end - end - if (key == keys.right) then - -- arrow right - textX = textX + 1 - if (textY < #lines) then - if (textX > lines[textY]:len() + 1) then - textX = 1 - textY = textY + 1 - end - elseif (textX > lines[textY]:len()) then - textX = lines[textY]:len() + 1 - end - if (textX < 1) then - textX = 1 - end - if (textX < wIndex) or (textX >= self.width + wIndex) then - wIndex = textX - self.width + 1 - end - if (wIndex < 1) then - wIndex = 1 - end - - end - if (key == keys.left) then - -- arrow left - textX = textX - 1 - if (textX >= 1) then - if (textX < wIndex) or (textX >= self.width + wIndex) then - wIndex = textX - end - end - if (textY > 1) then - if (textX < 1) then - textY = textY - 1 - textX = lines[textY]:len() + 1 - wIndex = textX - self.width + 1 - end - end - if (textX < 1) then - textX = 1 - end - if (wIndex < 1) then - wIndex = 1 - end - end - end - - if (event == "char") then - lines[textY] = lines[textY]:sub(1, textX - 1) .. key .. lines[textY]:sub(textX, lines[textY]:len()) - textX = textX + 1 - if (textX >= self.width + wIndex) then - wIndex = wIndex + 1 - end - self:setValue("") - end - - local cursorX = (textX <= lines[textY]:len() and textX - 1 or lines[textY]:len()) - (wIndex - 1) - if (cursorX > self.x + self.width - 1) then - cursorX = self.x + self.width - 1 - end - local cursorY = (textY - hIndex < self.height and textY - hIndex or textY - hIndex - 1) - if (cursorX < 1) then - cursorX = 0 - end - self.parent:setCursor(true, obx + cursorX, oby + cursorY, self.fgColor) - return true - end - end; - - mouseClickHandler = function(self, event, button, x, y) - if (base.mouseClickHandler(self, event, button, x, y)) then - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - local anchx, anchy = self:getAnchorPosition() - if (event == "mouse_click") then - if (lines[y - oby + hIndex] ~= nil) then - textX = x - obx + wIndex - textY = y - oby + hIndex - if (textX > lines[textY]:len()) then - textX = lines[textY]:len() + 1 - end - if (textX < wIndex) then - wIndex = textX - 1 - if (wIndex < 1) then - wIndex = 1 - end - end - if (self.parent ~= nil) then - self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex) - end - end - end - if (event == "mouse_drag") then - if (lines[y - oby + hIndex] ~= nil) then - textX = x - obx + wIndex - textY = y - oby + hIndex - if (textX > lines[textY]:len()) then - textX = lines[textY]:len() + 1 - end - if (textX < wIndex) then - wIndex = textX - 1 - if (wIndex < 1) then - wIndex = 1 - end - end - if (self.parent ~= nil) then - self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex) - end - end - end - - if (event == "mouse_scroll") then - hIndex = hIndex + button - if (hIndex > #lines - (self.height - 1)) then - hIndex = #lines - (self.height - 1) - end - - if (hIndex < 1) then - hIndex = 1 - end - - if (self.parent ~= nil) then - if (obx + textX - wIndex >= obx and obx + textX - wIndex <= obx + self.width) and (oby + textY - hIndex >= oby and oby + textY - hIndex <= oby + self.height) then - self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex) - else - self.parent:setCursor(false) - end - end - end - self:setVisualChanged() - return true - end - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - self.parent:drawForegroundBox(obx, oby, self.width, self.height, self.fgColor) - for n = 1, self.height do - local text = "" - if (lines[n + hIndex - 1] ~= nil) then - text = lines[n + hIndex - 1] - end - text = text:sub(wIndex, self.width + wIndex - 1) - local space = self.width - text:len() - if (space < 0) then - space = 0 - end - text = text .. string.rep(" ", space) - self.parent:setText(obx, oby + n - 1, text) - end - end - end - end; - } - - return setmetatable(object, base) -end - -local function List(name) - local base = Object(name) - local objectType = "List" - base.width = 16 - base.height = 6 - base.bgColor = theme.listBG - base.fgColor = theme.listFG - base:setZIndex(5) - - local list = {} - local itemSelectedBG = theme.selectionBG - local itemSelectedFG = theme.selectionFG - local selectionColorActive = true - local align = "left" - local yOffset = 0 - local scrollable = true - - local object = { - getType = function(self) - return objectType - end; - - addItem = function(self, text, bgCol, fgCol, ...) - table.insert(list, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } }) - if (#list == 1) then - self:setValue(list[1]) - end - return self - end; - - setIndexOffset = function(self, yOff) - yOffset = yOff - return self - end; - - getIndexOffset = function(self) - return yOffset - end; - - removeItem = function(self, index) - table.remove(list, index) - return self - end; - - getItem = function(self, index) - return list[index] - end; - - getItemIndex = function(self) - local selected = self:getValue() - for key, value in pairs(list) do - if (value == selected) then - return key - end - end - end; - - clear = function(self) - list = {} - self:setValue({}) - return self - end; - - getItemCount = function(self) - return #list - end; - - editItem = function(self, index, text, bgCol, fgCol, ...) - table.remove(list, index) - table.insert(list, index, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } }) - return self - end; - - selectItem = function(self, index) - self:setValue(list[index] or {}) - return self - end; - - setSelectedItem = function(self, bgCol, fgCol, active) - itemSelectedBG = bgCol or self.bgColor - itemSelectedFG = fgCol or self.fgColor - selectionColorActive = active - return self - end; - - setScrollable = function(self, scroll) - scrollable = scroll - return self - end; - - mouseClickHandler = function(self, event, button, x, y) - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - if (obx <= x) and (obx + self.width > x) and (oby <= y) and (oby + self.height > y) and (self:isVisible()) then - if (event == "mouse_click") or (event == "mouse_drag") then - -- remove mouse_drag if i want to make objects moveable uwuwuwuw - if (button == 1) then - if (#list > 0) then - for n = 1, self.height do - if (list[n + yOffset] ~= nil) then - if (obx <= x) and (obx + self.width > x) and (oby + n - 1 == y) then - self:setValue(list[n + yOffset]) - self:getEventSystem():sendEvent("mouse_click", self, "mouse_click", 0, x, y, list[n + yOffset]) - end - end - end - end - end - end - - if (event == "mouse_scroll") and (scrollable) then - yOffset = yOffset + button - if (yOffset < 0) then - yOffset = 0 - end - if (button >= 1) then - if (#list > self.height) then - if (yOffset > #list - self.height) then - yOffset = #list - self.height - end - if (yOffset >= #list) then - yOffset = #list - 1 - end - else - yOffset = yOffset - 1 - end - end - end - self:setVisualChanged() - return true - end - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - for n = 1, self.height do - if (list[n + yOffset] ~= nil) then - if (list[n + yOffset] == self:getValue()) then - if (selectionColorActive) then - self.parent:writeText(obx, oby + n - 1, getTextHorizontalAlign(list[n + yOffset].text, self.width, align), itemSelectedBG, itemSelectedFG) - else - self.parent:writeText(obx, oby + n - 1, getTextHorizontalAlign(list[n + yOffset].text, self.width, align), list[n + yOffset].bgCol, list[n + yOffset].fgCol) - end - else - self.parent:writeText(obx, oby + n - 1, getTextHorizontalAlign(list[n + yOffset].text, self.width, align), list[n + yOffset].bgCol, list[n + yOffset].fgCol) - end - end - end - end - end - end; - } - - return setmetatable(object, base) -end - -local function Menubar(name) - local base = Object(name) - local objectType = "Menubar" - local object = {} - - base.width = 30 - base.height = 1 - base.bgColor = colors.gray - base.fgColor = colors.lightGray - base:setZIndex(5) - - local list = {} - local itemSelectedBG = theme.selectionBG - local itemSelectedFG = theme.selectionFG - local selectionColorActive = true - local align = "left" - local itemOffset = 0 - local space = 2 - local scrollable = false - - local function maxScroll() - local mScroll = 0 - local xPos = 1 - for n = 1, #list do - if (xPos + list[n].text:len() + space * 2 > object.w) then - mScroll = mScroll + list[n].text:len() + space * 2 - end - xPos = xPos + list[n].text:len() + space * 2 - - end - return mScroll - end - - object = { - getType = function(self) - return objectType - end; - - addItem = function(self, text, bgCol, fgCol, ...) - table.insert(list, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } }) - if (#list == 1) then - self:setValue(list[1]) - end - return self - end; - - getItemIndex = function(self) - local selected = self:getValue() - for key, value in pairs(list) do - if (value == selected) then - return key - end - end - end; - - clear = function(self) - list = {} - self:setValue({}) - return self - end; - - setSpace = function(self, _space) - space = _space or space - return self - end; - - setButtonOffset = function(self, offset) - itemOffset = offset or 0 - if (itemOffset < 0) then - itemOffset = 0 - end - - local mScroll = maxScroll() - if (itemOffset > mScroll) then - itemOffset = mScroll - end - return self - end; - - setScrollable = function(self, scroll) - scrollable = scroll - return self - end; - - removeItem = function(self, index) - table.remove(list, index) - return self - end; - - getItem = function(self, index) - return list[index] - end; - - getItemCount = function(self) - return #list - end; - - editItem = function(self, index, text, bgCol, fgCol, ...) - table.remove(list, index) - table.insert(list, index, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } }) - return self - end; - - selectItem = function(self, index) - self:setValue(list[index] or {}) - return self - end; - - setSelectedItem = function(self, bgCol, fgCol, active) - itemSelectedBG = bgCol or self.bgColor - itemSelectedFG = fgCol or self.fgColor - selectionColorActive = active - return self - end; - - mouseClickHandler = function(self, event, button, x, y) - local objX, objY = self:getAbsolutePosition(self:getAnchorPosition()) - if (objX <= x) and (objX + self.width > x) and (objY <= y) and (objY + self.height > y) and (self:isVisible()) then - if (self.parent ~= nil) then - self.parent:setFocusedObject(self) - end - if (event == "mouse_click") then - local xPos = 1 - for n = 1 + itemOffset, #list do - if (list[n] ~= nil) then - if (xPos + list[n].text:len() + space * 2 <= self.width) then - if (objX + (xPos - 1) <= x) and (objX + (xPos - 1) + list[n].text:len() + space * 2 > x) and (objY == y) then - self:setValue(list[n]) - self:getEventSystem():sendEvent("mouse_click", self, "mouse_click", 0, x, y, list[n]) - end - xPos = xPos + list[n].text:len() + space * 2 - else - break - end - end - end - - end - if (event == "mouse_scroll") and (scrollable) then - itemOffset = itemOffset + button - if (itemOffset < 0) then - itemOffset = 0 - end - - local mScroll = maxScroll() - - if (itemOffset > mScroll) then - itemOffset = mScroll - end - end - return true - end - return false - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - local xPos = 0 - for _, value in pairs(list) do - if (xPos + value.text:len() + space * 2 <= self.width) then - if (value == self:getValue()) then - self.parent:writeText(obx + (xPos - 1) + (-itemOffset), oby, getTextHorizontalAlign((" "):rep(space) .. value.text .. (" "):rep(space), value.text:len() + space * 2, align), itemSelectedBG or value.bgCol, itemSelectedFG or value.fgCol) - else - self.parent:writeText(obx + (xPos - 1) + (-itemOffset), oby, getTextHorizontalAlign((" "):rep(space) .. value.text .. (" "):rep(space), value.text:len() + space * 2, align), value.bgCol, value.fgCol) - end - xPos = xPos + value.text:len() + space * 2 - else - if (xPos < self.width + itemOffset) then - if (value == self:getValue()) then - self.parent:writeText(obx + (xPos - 1) + (-itemOffset), oby, getTextHorizontalAlign((" "):rep(space) .. value.text .. (" "):rep(space), value.text:len() + space * 2, align):sub(1, self.width + itemOffset - xPos), itemSelectedBG or value.bgCol, itemSelectedFG or value.fgCol) - else - self.parent:writeText(obx + (xPos - 1) + (-itemOffset), oby, getTextHorizontalAlign((" "):rep(space) .. value.text .. (" "):rep(space), value.text:len() + space * 2, align):sub(1, self.width + itemOffset - xPos), value.bgCol, value.fgCol) - end - xPos = xPos + value.text:len() + space * 2 - end - end - end - end - end - end; - } - - return setmetatable(object, base) -end - -local function Dropdown(name) - local base = Object(name) - local objectType = "Dropdown" - base.width = 12 - base.height = 1 - base.bgColor = theme.dropdownBG - base.fgColor = theme.dropdownFG - base:setZIndex(6) - - local list = {} - local itemSelectedBG = theme.selectionBG - local itemSelectedFG = theme.selectionFG - local selectionColorActive = true - local align = "left" - local yOffset = 0 - - local dropdownW = 16 - local dropdownH = 6 - local closedSymbol = "\16" - local openedSymbol = "\31" - local state = 1 - - local object = { - getType = function(self) - return objectType - end; - - setIndexOffset = function(self, yOff) - yOffset = yOff - return self - end; - - getIndexOffset = function(self) - return yOffset - end; - - addItem = function(self, text, bgCol, fgCol, ...) - table.insert(list, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } }) - return self - end; - - removeItem = function(self, index) - table.remove(list, index) - return self - end; - - getItem = function(self, index) - return list[index] - end; - - getItemIndex = function(self) - local selected = self:getValue() - for key, value in pairs(list) do - if (value == selected) then - return key - end - end - end; - - clear = function(self) - list = {} - self:setValue({}) - return self - end; - - getItemCount = function(self) - return #list - end; - - editItem = function(self, index, text, bgCol, fgCol, ...) - table.remove(list, index) - table.insert(list, index, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } }) - return self - end; - - selectItem = function(self, index) - self:setValue(list[index] or {}) - return self - end; - - setSelectedItem = function(self, bgCol, fgCol, active) - itemSelectedBG = bgCol or self.bgColor - itemSelectedFG = fgCol or self.fgColor - selectionColorActive = active - return self - end; - - setDropdownSize = function(self, width, height) - dropdownW, dropdownH = width, height - return self - end; - - mouseClickHandler = function(self, event, button, x, y) - if (state == 2) then - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - if (event == "mouse_click") then - -- remove mouse_drag if i want to make objects moveable uwuwuwuw - if (button == 1) then - if (#list > 0) then - for n = 1, dropdownH do - if (list[n + yOffset] ~= nil) then - if (obx <= x) and (obx + dropdownW > x) and (oby + n == y) then - self:setValue(list[n + yOffset]) - return true - end - end - end - end - end - end - - if (event == "mouse_scroll") then - yOffset = yOffset + button - if (yOffset < 0) then - yOffset = 0 - end - if (button == 1) then - if (#list > dropdownH) then - if (yOffset > #list - dropdownH) then - yOffset = #list - dropdownH - end - else - yOffset = list - 1 - end - end - return true - end - self:setVisualChanged() - end - if (base.mouseClickHandler(self, event, button, x, y)) then - state = 2 - else - state = 1 - end - end; - - draw = function(self) - if (base.draw(self)) then - local obx, oby = self:getAnchorPosition() - if (self.parent ~= nil) then - self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - if (#list >= 1) then - if (self:getValue() ~= nil) then - if (self:getValue().text ~= nil) then - if (state == 1) then - self.parent:writeText(obx, oby, getTextHorizontalAlign(self:getValue().text, self.width, align):sub(1, self.width - 1) .. closedSymbol, self.bgColor, self.fgColor) - else - self.parent:writeText(obx, oby, getTextHorizontalAlign(self:getValue().text, self.width, align):sub(1, self.width - 1) .. openedSymbol, self.bgColor, self.fgColor) - end - end - end - if (state == 2) then - for n = 1, dropdownH do - if (list[n + yOffset] ~= nil) then - if (list[n + yOffset] == self:getValue()) then - if (selectionColorActive) then - self.parent:writeText(obx, oby + n, getTextHorizontalAlign(list[n + yOffset].text, dropdownW, align), itemSelectedBG, itemSelectedFG) - else - self.parent:writeText(obx, oby + n, getTextHorizontalAlign(list[n + yOffset].text, dropdownW, align), list[n + yOffset].bgCol, list[n + yOffset].fgCol) - end - else - self.parent:writeText(obx, oby + n, getTextHorizontalAlign(list[n + yOffset].text, dropdownW, align), list[n + yOffset].bgCol, list[n + yOffset].fgCol) - end - end - end - end - end - end - end - end; - } - - return setmetatable(object, base) -end - -local function Radio(name) - local base = Object(name) - local objectType = "Radio" - base.width = 8 - base.bgColor = theme.listBG - base.fgColor = theme.listFG - base:setZIndex(5) - - local list = {} - local itemSelectedBG = theme.selectionBG - local itemSelectedFG = theme.selectionFG - local boxSelectedBG = base.bgColor - local boxSelectedFG = base.fgColor - local selectionColorActive = true - local symbol = "\7" - local align = "left" - - local object = { - getType = function(self) - return objectType - end; - - addItem = function(self, text, x, y, bgCol, fgCol, ...) - table.insert(list, { x = x or 1, y = y or 1, text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } }) - if (#list == 1) then - self:setValue(list[1]) - end - return self - end; - - removeItem = function(self, index) - table.remove(list, index) - return self - end; - - getItem = function(self, index) - return list[index] - end; - - getItemIndex = function(self) - local selected = self:getValue() - for key, value in pairs(list) do - if (value == selected) then - return key - end - end - end; - - clear = function(self) - list = {} - self:setValue({}) - return self - end; - - getItemCount = function(self) - return #list - end; - - editItem = function(self, index, text, x, y, bgCol, fgCol, ...) - table.remove(list, index) - table.insert(list, index, { x = x or 1, y = y or 1, text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } }) - return self - end; - - selectItem = function(self, index) - self:setValue(list[index] or {}) - return self - end; - - setSelectedItem = function(self, bgCol, fgCol, boxBG, boxFG, active) - itemSelectedBG = bgCol or itemSelectedBG - itemSelectedFG = fgCol or itemSelectedFG - boxSelectedBG = boxBG or boxSelectedBG - boxSelectedFG = boxFG or boxSelectedFG - selectionColorActive = active - return self - end; - - mouseClickHandler = function(self, event, button, x, y) - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - if (event == "mouse_click") then - -- remove mouse_drag if i want to make objects moveable uwuwuwuw - if (button == 1) then - if (#list > 0) then - for _, value in pairs(list) do - if (obx + value.x - 1 <= x) and (obx + value.x - 1 + value.text:len() + 2 >= x) and (oby + value.y - 1 == y) then - self:setValue(value) - if (self.parent ~= nil) then - self.parent:setFocusedObject(self) - end - --eventSystem:sendEvent(event, self, event, button, x, y) - self:setVisualChanged() - return true - end - end - end - end - end - return false - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - for _, value in pairs(list) do - if (value == self:getValue()) then - if (align == "left") then - self.parent:writeText(value.x + obx - 1, value.y + oby - 1, symbol, boxSelectedBG, boxSelectedFG) - self.parent:writeText(value.x + 2 + obx - 1, value.y + oby - 1, value.text, itemSelectedBG, itemSelectedFG) - end - else - self.parent:drawBackgroundBox(value.x + obx - 1, value.y + oby - 1, 1, 1, self.bgColor) - self.parent:writeText(value.x + 2 + obx - 1, value.y + oby - 1, value.text, value.bgCol, value.fgCol) - end - end - end - end - end; - } - - return setmetatable(object, base) -end - -local function Timer(name) - local objectType = "Timer" - - local timer = 0 - local savedRepeats = 0 - local repeats = 0 - local timerObj - local eventSystem = BasaltEvents() - - local object = { - name = name, - getType = function(self) - return objectType - end; - - getZIndex = function(self) - return 1 - end; - - getName = function(self) - return self.name - end; - - setTime = function(self, _timer, _repeats) - timer = _timer or 0 - savedRepeats = _repeats or 1 - return self - end; - - start = function(self) - repeats = savedRepeats - timerObj = os.startTimer(timer) - return self - end; - - cancel = function(self) - if (timerObj ~= nil) then - os.cancelTimer(timerObj) - end - return self - end; - - onCall = function(self, func) - eventSystem:registerEvent("timed_event", func) - return self - end; - - eventHandler = function(self, event, tObj) - if (event == "timer") and (tObj == timerObj) then - eventSystem:sendEvent("timed_event", self) - if (repeats >= 1) then - repeats = repeats - 1 - if (repeats >= 1) then - timerObj = os.startTimer(timer) - end - elseif (repeats == -1) then - timerObj = os.startTimer(timer) - end - end - end; - } - object.__index = object - - return object -end - -local function Thread(name) - local object - local objectType = "Thread" - - local func - local cRoutine - local isActive = false - - object = { - name = name, - getType = function(self) - return objectType - end; - getZIndex = function(self) - return 1 - end; - getName = function(self) - return self.name - end; - - start = function(self, f) - if (f == nil) then - error("function is nil") - end - func = f - cRoutine = coroutine.create(func) - isActive = true - local ok, result = coroutine.resume(cRoutine) - if not (ok) then - if (result ~= "Terminated") then - error("Threaderror - " .. result) - end - end - return self - end; - - getStatus = function(self, f) - if (cRoutine ~= nil) then - return coroutine.status(cRoutine) - end - return nil - end; - - stop = function(self, f) - isActive = false - return self - end; - - eventHandler = function(self, event, p1, p2, p3) - if (isActive) then - if (coroutine.status(cRoutine) ~= "dead") then - local ok, result = coroutine.resume(cRoutine, event, p1, p2, p3) - if not (ok) then - if (result ~= "Terminated") then - error("Threaderror - " .. result) - end - end - else - isActive = false - end - end - end; - - } - - object.__index = object - - return object -end - -local function Animation(name) - local object = {} - local objectType = "Animation" - - local timerObj - - local animations = {} - local index = 1 - - local nextWaitTimer = 0 - local lastFunc - - local function onPlay() - if (animations[index] ~= nil) then - animations[index].f(object, index) - end - index = index + 1 - if (animations[index] ~= nil) then - if (animations[index].t > 0) then - timerObj = os.startTimer(animations[index].t) - else - onPlay() - end - end - end - - object = { - name = name, - getType = function(self) - return objectType - end; - - getZIndex = function(self) - return 1 - end; - - getName = function(self) - return self.name - end; - - add = function(self, func, wait) - lastFunc = func - table.insert(animations, { f = func, t = wait or nextWaitTimer }) - return self - end; - - wait = function(self, wait) - nextWaitTimer = wait - return self - end; - - rep = function(self, reps) - for x = 1, reps do - table.insert(animations, { f = lastFunc, t = nextWaitTimer }) - end - return self - end; - - clear = function(self) - animations = {} - lastFunc = nil - nextWaitTimer = 0 - index = 1 - return self - end; - - play = function(self) - index = 1 - if (animations[index] ~= nil) then - if (animations[index].t > 0) then - timerObj = os.startTimer(animations[index].t) - else - onPlay() - end - end - return self - end; - - cancel = function(self) - os.cancelTimer(timerObj) - return self - end; - - eventHandler = function(self, event, tObj) - if (event == "timer") and (tObj == timerObj) then - if (animations[index] ~= nil) then - onPlay() - end - end - end; - } - object.__index = object - - return object -end - -local function Slider(name) - local base = Object(name) - local objectType = "Slider" - - base.width = 8 - base.bgColor = colors.lightGray - base.fgColor = colors.gray - base:setValue(1) - - local barType = "horizontal" - local symbol = " " - local symbolColor = colors.black - local bgSymbol = "\140" - local maxValue = base.width - local index = 1 - - local object = { - getType = function(self) - return objectType - end; - - setSymbol = function(self, _symbol) - symbol = _symbol:sub(1, 1) - self:setVisualChanged() - return self - end; - - setBackgroundSymbol = function(self, _bgSymbol) - bgSymbol = string.sub(_bgSymbol, 1, 1) - self:setVisualChanged() - return self - end; - - setSymbolColor = function(self, col) - symbolColor = col - self:setVisualChanged() - return self - end; - - setBarType = function(self, _typ) - barType = _typ:lower() - return self - end; - - mouseClickHandler = function(self, event, button, x, y) - if (base.mouseClickHandler(self, event, button, x, y)) then - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - if (barType == "horizontal") then - for _index = 0, self.width - 1 do - if (obx + _index == x) and (oby <= y) and (oby + self.height > y) then - index = _index + 1 - self:setValue(maxValue / self.width * (index)) - self:setVisualChanged() - end - end - end - if (barType == "vertical") then - for _index = 0, self.height - 1 do - if (oby + _index == y) and (obx <= x) and (obx + self.width > x) then - index = _index + 1 - self:setValue(maxValue / self.height * (index)) - self:setVisualChanged() - end - end - end - --[[if(event=="mouse_scroll")then - self:setValue(self:getValue() + (maxValue/(barType=="vertical" and self.height or self.width))*typ) - self:setVisualChanged() - end - if(self:getValue()>maxValue)then self:setValue(maxValue) end - if(self:getValue() y) then - index = math.min(_index + 1, self.width - (symbolSize - 1)) - self:setValue(maxValue / self.width * (index)) - self:setVisualChanged() - end - end - end - if (barType == "vertical") then - for _index = 0, self.height do - if (oby + _index == y) and (obx <= x) and (obx + self.width > x) then - index = math.min(_index + 1, self.height - (symbolSize - 1)) - self:setValue(maxValue / self.height * (index)) - self:setVisualChanged() - end - end - end - end - if (event == "mouse_scroll") then - index = index + button - if (index < 1) then - index = 1 - end - index = math.min(index, (barType == "vertical" and self.height or self.width) - (symbolSize - 1)) - self:setValue(maxValue / (barType == "vertical" and self.height or self.width) * index) - end - return true - end - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - if (barType == "horizontal") then - self.parent:writeText(obx, oby, bgSymbol:rep(index - 1), self.bgColor, self.fgColor) - self.parent:writeText(obx + index - 1, oby, symbol:rep(symbolSize), symbolColor, symbolColor) - self.parent:writeText(obx + index + symbolSize - 1, oby, bgSymbol:rep(self.width - (index + symbolSize - 1)), self.bgColor, self.fgColor) - end - - if (barType == "vertical") then - for n = 0, self.height - 1 do - - if (index == n + 1) then - for curIndexOffset = 0, math.min(symbolSize - 1, self.height) do - self.parent:writeText(obx, oby + n + curIndexOffset, symbol, symbolColor, symbolColor) - end - else - if (n + 1 < index) or (n + 1 > index - 1 + symbolSize) then - self.parent:writeText(obx, oby + n, bgSymbol, self.bgColor, self.fgColor) - end - end - end - end - end - end - end; - } - - return setmetatable(object, base) -end - -local function Switch(name) - local base = Object(name) - local objectType = "Switch" - - base.width = 3 - base.height = 1 - base.bgColor = colors.lightGray - base.fgColor = colors.gray - base:setValue(false) - base:setZIndex(5) - - local object = { - getType = function(self) - return objectType - end; - - - mouseClickHandler = function(self, event, button, x, y) - if (base.mouseClickHandler(self, event, button, x, y)) then - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - if ((event == "mouse_click") or (event == "mouse_drag")) and (button == 1) then - - - end - return true - end - end; - - draw = function(self) - if (base.draw(self)) then - if (self.parent ~= nil) then - local obx, oby = self:getAnchorPosition() - - end - end - end; - } - - return setmetatable(object, base) -end - -local function Frame(name, parent) - -- Frame - local base = Object(name) - local objectType = "Frame" - local objects = {} - local objZIndex = {} - local object = {} - local focusedObject - base:setZIndex(10) - - local cursorBlink = false - local xCursor = 1 - local yCursor = 1 - local cursorColor = colors.white - - local xOffset, yOffset = 0, 0 - - if (parent ~= nil) then - base.parent = parent - base.width, base.height = parent.w, parent.h - base.bgColor = theme.FrameBG - base.fgColor = theme.FrameFG - else - local termW, termH = parentTerminal.getSize() - base.width, base.height = termW, termH - base.bgColor = theme.basaltBG - base.fgColor = theme.basaltFG - end - - local function getObject(name) - for _, value in pairs(objects) do - for _, b in pairs(value) do - if (b.name == name) then - return value - end - end - end - end - - local function addObject(obj) - local zIndex = obj:getZIndex() - if (getObject(obj.name) ~= nil) then - return nil - end - if (objects[zIndex] == nil) then - for x = 1, #objZIndex + 1 do - if (objZIndex[x] ~= nil) then - if (zIndex == objZIndex[x]) then - break - end - if (zIndex > objZIndex[x]) then - table.insert(objZIndex, x, zIndex) - break - end - else - table.insert(objZIndex, zIndex) - end - end - if (#objZIndex <= 0) then - table.insert(objZIndex, zIndex) - end - objects[zIndex] = {} - end - obj.parent = object - table.insert(objects[zIndex], obj) - return obj - end - - local function removeObject(obj) - for a, b in pairs(objects) do - for key, value in pairs(b) do - if (value == obj) then - table.remove(objects[a], key) - return true; - end - end - end - return false - end - - object = { - barActive = false, - barBackground = colors.gray, - barTextcolor = colors.black, - barText = "New Frame", - barTextAlign = "left", - isMoveable = false, - - getType = function(self) - return objectType - end; - - setFocusedObject = function(self, obj) - for _, index in pairs(objZIndex) do - for _, value in pairs(objects[index]) do - if (value == obj) then - if (focusedObject ~= nil) then - focusedObject:loseFocusHandler() - end - focusedObject = obj - focusedObject:getFocusHandler() - end - end - end - return self - end; - - setOffset = function(self, xO, yO) - xOffset = xO ~= nil and math.floor(xO < 0 and math.abs(xO) or -xO) or xOffset - yOffset = yO ~= nil and math.floor(yO < 0 and math.abs(yO) or -yO) or yOffset - return self - end; - - getFrameOffset = function(self) - return xOffset, yOffset - end; - - removeFocusedObject = function(self) - if (focusedObject ~= nil) then - focusedObject:loseFocusHandler() - end - focusedObject = nil - return self - end; - - getFocusedObject = function(self) - return focusedObject - end; - - show = function(self) - base:show() - if (self.parent == nil) then - activeFrame = self - end - return self - end; - - setCursor = function(self, _blink, _xCursor, _yCursor, color) - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - cursorBlink = _blink or false - if (_xCursor ~= nil) then - xCursor = obx + _xCursor - 1 - end - if (_yCursor ~= nil) then - yCursor = oby + _yCursor - 1 - end - cursorColor = color or cursorColor - self:setVisualChanged() - return self - end; - - setMoveable = function(self, moveable) - self.isMoveable = moveable or not self.isMoveable - self:setVisualChanged() - return self; - end; - - - showBar = function(self, showIt) - self.barActive = showIt or not self.barActive - self:setVisualChanged() - return self - end; - - setBar = function(self, text, bgCol, fgCol) - self.barText = text or "" - self.barBackground = bgCol or self.barBackground - self.barTextcolor = fgCol or self.barTextcolor - self:setVisualChanged() - return self - end; - - setBarTextAlign = function(self, align) - self.barTextAlign = align or "left" - self:setVisualChanged() - return self - end; - - getVisualChanged = function(self) - local changed = base.getVisualChanged(self) - for _, index in pairs(objZIndex) do - if (objects[index] ~= nil) then - for _, value in pairs(objects[index]) do - if (value.getVisualChanged ~= nil and value:getVisualChanged()) then - changed = true - end - end - end - end - return changed - end; - - loseFocusHandler = function(self) - base.loseFocusHandler(self) - end; - - getFocusHandler = function(self) - base.getFocusHandler(self) - if (self.parent ~= nil) then - self.parent:removeObject(self) - self.parent:addObject(self) - end - end; - - keyHandler = function(self, event, key) - if (focusedObject ~= nil) then - if (focusedObject.keyHandler ~= nil) then - if (focusedObject:keyHandler(event, key)) then - return true - end - end - end - return false - end; - - backgroundKeyHandler = function(self, event, key) - base.backgroundKeyHandler(self, event, key) - for _, index in pairs(objZIndex) do - if (objects[index] ~= nil) then - for _, value in pairs(objects[index]) do - if (value.backgroundKeyHandler ~= nil) then - value:backgroundKeyHandler(event, key) - end - end - end - end - end; - - eventHandler = function(self, event, p1, p2, p3, p4) - base.eventHandler(self, event, p1, p2, p3, p4) - for _, index in pairs(objZIndex) do - if (objects[index] ~= nil) then - for _, value in pairs(objects[index]) do - if (value.eventHandler ~= nil) then - value:eventHandler(event, p1, p2, p3, p4) - end - end - end - end - if (event == "terminate") then - parentTerminal.clear() - parentTerminal.setCursorPos(1, 1) - basalt.stop() - end - end; - - mouseClickHandler = function(self, event, button, x, y) - local xO, yO = self:getOffset() - xO = xO < 0 and math.abs(xO) or -xO - yO = yO < 0 and math.abs(yO) or -yO - if (self.drag) then - if (event == "mouse_drag") then - local parentX = 1; - local parentY = 1 - if (self.parent ~= nil) then - parentX, parentY = self.parent:getAbsolutePosition(self.parent:getAnchorPosition()) - end - self:setPosition(x + self.xToRem - (parentX - 1) + xO, y - (parentY - 1) + yO) - end - if (event == "mouse_up") then - self.drag = false - end - return true - end - - if (base.mouseClickHandler(self, event, button, x, y)) then - local fx, fy = self:getAbsolutePosition(self:getAnchorPosition()) - for _, index in pairs(objZIndex) do - if (objects[index] ~= nil) then - for _, value in rpairs(objects[index]) do - if (value.mouseClickHandler ~= nil) then - if (value:mouseClickHandler(event, button, x + xO, y + yO)) then - return true - end - end - end - end - end - - if (self.isMoveable) then - if (x >= fx) and (x <= fx + self.width - 1) and (y == fy) and (event == "mouse_click") then - self.drag = true - self.xToRem = fx - x - end - end - if (focusedObject ~= nil) then - focusedObject:loseFocusHandler() - focusedObject = nil - end - return true - end - return false - end; - - setText = function(self, x, y, text) - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - if (y >= 1) and (y <= self.height) then - if (self.parent ~= nil) then - self.parent:setText(math.max(x + (obx - 1), obx) - (self.parent.x - 1), oby + y - 1 - (self.parent.y - 1), sub(text, math.max(1 - x + 1, 1), self.width - x + 1)) - else - drawHelper.setText(math.max(x + (obx - 1), obx), oby + y - 1, sub(text, math.max(1 - x + 1, 1), self.width - x + 1)) - end - end - end; - - setBG = function(self, x, y, bgCol) - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - if (y >= 1) and (y <= self.height) then - if (self.parent ~= nil) then - self.parent:setBG(math.max(x + (obx - 1), obx) - (self.parent.x - 1), oby + y - 1 - (self.parent.y - 1), sub(bgCol, math.max(1 - x + 1, 1), self.width - x + 1)) - else - drawHelper.setBG(math.max(x + (obx - 1), obx), oby + y - 1, sub(bgCol, math.max(1 - x + 1, 1), self.width - x + 1)) - end - end - end; - - setFG = function(self, x, y, fgCol) - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - if (y >= 1) and (y <= self.height) then - if (self.parent ~= nil) then - self.parent:setFG(math.max(x + (obx - 1), obx) - (self.parent.x - 1), oby + y - 1 - (self.parent.y - 1), sub(fgCol, math.max(1 - x + 1, 1), self.width - x + 1)) - else - drawHelper.setFG(math.max(x + (obx - 1), obx), oby + y - 1, sub(fgCol, math.max(1 - x + 1, 1), self.width - x + 1)) - end - end - end; - - writeText = function(self, x, y, text, bgCol, fgCol) - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - if (y >= 1) and (y <= self.height) then - if (self.parent ~= nil) then - self.parent:writeText(math.max(x + (obx - 1), obx) - (self.parent.x - 1), oby + y - 1 - (self.parent.y - 1), sub(text, math.max(1 - x + 1, 1), self.width - x + 1), bgCol, fgCol) - else - drawHelper.writeText(math.max(x + (obx - 1), obx), oby + y - 1, sub(text, math.max(1 - x + 1, 1), self.width - x + 1), bgCol, fgCol) - end - end - end; - - drawBackgroundBox = function(self, x, y, width, height, bgCol) - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - height = (y < 1 and (height + y > self.height and self.height or height + y - 1) or (height + y > self.height and self.height - y + 1 or height)) - width = (x < 1 and (width + x > self.width and self.width or width + x - 1) or (width + x > self.width and self.width - x + 1 or width)) - if (self.parent ~= nil) then - self.parent:drawBackgroundBox(math.max(x + (obx - 1), obx) - (self.parent.x - 1), math.max(y + (oby - 1), oby) - (self.parent.y - 1), width, height, bgCol) - else - drawHelper.drawBackgroundBox(math.max(x + (obx - 1), obx), math.max(y + (oby - 1), oby), width, height, bgCol) - end - end; - - drawTextBox = function(self, x, y, width, height, symbol) - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - height = (y < 1 and (height + y > self.height and self.height or height + y - 1) or (height + y > self.height and self.height - y + 1 or height)) - width = (x < 1 and (width + x > self.width and self.width or width + x - 1) or (width + x > self.width and self.width - x + 1 or width)) - if (self.parent ~= nil) then - self.parent:drawTextBox(math.max(x + (obx - 1), obx) - (self.parent.x - 1), math.max(y + (oby - 1), oby) - (self.parent.y - 1), width, height, symbol:sub(1, 1)) - else - drawHelper.drawTextBox(math.max(x + (obx - 1), obx), math.max(y + (oby - 1), oby), width, height, symbol:sub(1, 1)) - end - end; - - drawForegroundBox = function(self, x, y, width, height, fgCol) - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - height = (y < 1 and (height + y > self.height and self.height or height + y - 1) or (height + y > self.height and self.height - y + 1 or height)) - width = (x < 1 and (width + x > self.width and self.width or width + x - 1) or (width + x > self.width and self.width - x + 1 or width)) - if (self.parent ~= nil) then - self.parent:drawForegroundBox(math.max(x + (obx - 1), obx) - (self.parent.x - 1), math.max(y + (oby - 1), oby) - (self.parent.y - 1), width, height, fgCol) - else - drawHelper.drawForegroundBox(math.max(x + (obx - 1), obx), math.max(y + (oby - 1), oby), width, height, fgCol) - end - end; - - draw = function(self) - if (self:getVisualChanged()) then - if (base.draw(self)) then - local obx, oby = self:getAbsolutePosition(self:getAnchorPosition()) - local anchx, anchy = self:getAnchorPosition() - if (self.parent ~= nil) then - self.parent:drawBackgroundBox(anchx, anchy, self.width, self.height, self.bgColor) - self.parent:drawForegroundBox(anchx, anchy, self.width, self.height, self.fgColor) - self.parent:drawTextBox(anchx, anchy, self.width, self.height, " ") - else - drawHelper.drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) - drawHelper.drawForegroundBox(obx, oby, self.width, self.height, self.fgColor) - drawHelper.drawTextBox(obx, oby, self.width, self.height, " ") - end - parentTerminal.setCursorBlink(false) - if (self.barActive) then - if (self.parent ~= nil) then - self.parent:writeText(anchx, anchy, getTextHorizontalAlign(self.barText, self.width, self.barTextAlign), self.barBackground, self.barTextcolor) - else - drawHelper.writeText(obx, oby, getTextHorizontalAlign(self.barText, self.width, self.barTextAlign), self.barBackground, self.barTextcolor) - end - end - - for _, index in rpairs(objZIndex) do - if (objects[index] ~= nil) then - for _, value in pairs(objects[index]) do - if (value.draw ~= nil) then - value:draw() - end - end - end - end - - if (cursorBlink) then - parentTerminal.setTextColor(cursorColor) - parentTerminal.setCursorPos(xCursor, yCursor) - if (self.parent ~= nil) then - parentTerminal.setCursorBlink(self:isFocused()) - else - parentTerminal.setCursorBlink(cursorBlink) - end - end - self:setVisualChanged(false) - end - end - end; - - addObject = function(self, obj) - return addObject(obj) - end; - - removeObject = function(self, obj) - return removeObject(obj) - end; - - getObject = function(self, obj) - return getObject(obj) - end; - - addButton = function(self, name) - local obj = Button(name) - obj.name = name - return addObject(obj) - end; - - addLabel = function(self, name) - local obj = Label(name) - obj.name = name - obj.bgColor = self.bgColor - obj.fgColor = self.fgColor - return addObject(obj) - end; - - addCheckbox = function(self, name) - local obj = Checkbox(name) - obj.name = name - return addObject(obj) - end; - - addInput = function(self, name) - local obj = Input(name) - obj.name = name - return addObject(obj) - end; - - addProgram = function(self, name) - local obj = Program(name) - obj.name = name - return addObject(obj) - end; - - addTextfield = function(self, name) - local obj = Textfield(name) - obj.name = name - return addObject(obj) - end; - - addList = function(self, name) - local obj = List(name) - obj.name = name - return addObject(obj) - end; - - addDropdown = function(self, name) - local obj = Dropdown(name) - obj.name = name - return addObject(obj) - end; - - addRadio = function(self, name) - local obj = Radio(name) - obj.name = name - return addObject(obj) - end; - - addTimer = function(self, name) - local obj = Timer(name) - obj.name = name - return addObject(obj) - end; - - addAnimation = function(self, name) - local obj = Animation(name) - obj.name = name - return addObject(obj) - end; - - addSlider = function(self, name) - local obj = Slider(name) - obj.name = name - return addObject(obj) - end; - - addScrollbar = function(self, name) - local obj = Scrollbar(name) - obj.name = name - return addObject(obj) - end; - - addMenubar = function(self, name) - local obj = Menubar(name) - obj.name = name - return addObject(obj) - end; - - addThread = function(self, name) - local obj = Thread(name) - obj.name = name - return addObject(obj) - end; - - addPane = function(self, name) - local obj = Pane(name) - obj.name = name - return addObject(obj) - end; - - addImage = function(self, name) - local obj = Image(name) - obj.name = name - return addObject(obj) - end; - - addProgressbar = function(self, name) - local obj = Progressbar(name) - obj.name = name - return addObject(obj) - end; - - addFrame = function(self, name) - local obj = Frame(name, self) - obj.name = name - return addObject(obj) - end; - } - setmetatable(object, base) - if (parent == nil) then - table.insert(frames, object) - end - return object -end - -local updaterActive = false -local function basaltUpdateEvent(event, p1, p2, p3, p4) - if (event == "mouse_click") then - activeFrame:mouseClickHandler(event, p1, p2, p3, p4) - end - if (event == "mouse_drag") then - activeFrame:mouseClickHandler(event, p1, p2, p3, p4) - end - if (event == "mouse_up") then - activeFrame:mouseClickHandler(event, p1, p2, p3, p4) - end - if (event == "mouse_scroll") then - activeFrame:mouseClickHandler(event, p1, p2, p3, p4) - end - if (event == "key") or (event == "char") then - activeFrame:keyHandler(event, p1) - activeFrame:backgroundKeyHandler(event, p1) - end - for _, value in pairs(frames) do - value:eventHandler(event, p1, p2, p3, p4) - end - if (updaterActive) then - activeFrame:draw() - drawHelper.update() - end -end - -function basalt.autoUpdate(isActive) - parentTerminal.clear() - updaterActive = isActive or true - activeFrame:draw() - drawHelper.update() - while updaterActive do - local event, p1, p2, p3, p4 = os.pullEventRaw() -- change to raw later - basaltUpdateEvent(event, p1, p2, p3, p4) - end -end - -function basalt.update(event, p1, p2, p3, p4) - if (event ~= "nil") then - basaltUpdateEvent(event, p1, p2, p3, p4) - else - activeFrame:draw() - drawHelper.update() - end -end - -function basalt.stop() - updaterActive = false -end - -function basalt.getFrame(name) - for _, value in pairs(frames) do - if (value.name == name) then - return value - end - end -end - -function basalt.getActiveFrame() - return activeFrame -end - -function basalt.setActiveFrame(frame) - if (frame:getType() == "Frame") then - activeFrame = frame - return true - end - return false -end - -function basalt.createFrame(name) - local frame = Frame(name) - return frame -end - -function basalt.removeFrame(name) - for key, value in pairs(frames) do - if (value.name == name) then - frames[key] = nil - return true - end - end - return false -end - -if (basalt.debugger) then - basalt.debugFrame = basalt.createFrame("basaltDebuggingFrame"):showBar():setBackground(colors.lightGray):setBar("Debug", colors.black, colors.gray) - basalt.debugList = basalt.debugFrame:addList("debugList"):setSize(basalt.debugFrame.width - 2, basalt.debugFrame.height - 3):setPosition(2, 3):setScrollable(true):show() - basalt.debugFrame:addButton("back"):setAnchor("right"):setSize(1, 1):setText("\22"):onClick(function() - basalt.oldFrame:show() - end) :setBackground(colors.red):show() - basalt.debugLabel = basalt.debugFrame:addLabel("debugLabel"):onClick(function() - basalt.oldFrame = activeFrame - basalt.debugFrame:show() - end) :setBackground(colors.black):setForeground(colors.white):setAnchor("bottom"):setZIndex(20):show() -end - -if (basalt.debugger) then - function basalt.debug(...) - local args = { ... } - if (activeFrame.name ~= "basaltDebuggingFrame") then - if (activeFrame ~= basalt.debugLabel.frame) then - basalt.debugLabel:setParent(activeFrame) - end - end - local str = "" - for key, value in pairs(args) do - str = str .. tostring(value) .. (#args ~= key and ", " or "") - end - basalt.debugLabel:setText("[Debug] " .. str) - basalt.debugList:addItem(str) - if (basalt.debugList:getItemCount() > 50) then - basalt.debugList:removeItem(1) - end - basalt.debugList:setValue(basalt.debugList:getItem(basalt.debugList:getItemCount())) - basalt.debugLabel:show() - end -end - -return basalt \ No newline at end of file diff --git a/oldVersions/old/v1.1/basalt.lua b/oldVersions/old/v1.1/basalt.lua deleted file mode 100644 index 4be3003..0000000 --- a/oldVersions/old/v1.1/basalt.lua +++ /dev/null @@ -1 +0,0 @@ -local a={debugger=true,version=1}local b;local c={}local d={}local e=term.current()local f=string.sub;local g={[colors.white]="0",[colors.orange]="1",[colors.magenta]="2",[colors.lightBlue]="3",[colors.yellow]="4",[colors.lime]="5",[colors.pink]="6",[colors.gray]="7",[colors.lightGray]="8",[colors.cyan]="9",[colors.purple]="a",[colors.blue]="b",[colors.brown]="c",[colors.green]="d",[colors.red]="e",[colors.black]="f"}local h={basaltBG=colors.lightGray,basaltFG=colors.black,FrameBG=colors.gray,FrameFG=colors.black,ButtonBG=colors.gray,ButtonFG=colors.black,CheckboxBG=colors.gray,CheckboxFG=colors.black,InputBG=colors.gray,InputFG=colors.black,textfieldBG=colors.gray,textfieldFG=colors.black,listBG=colors.gray,listFG=colors.black,dropdownBG=colors.gray,dropdownFG=colors.black,radioBG=colors.gray,radioFG=colors.black,selectionBG=colors.black,selectionFG=colors.lightGray}local i={{"\32\32\32\137\156\148\158\159\148\135\135\144\159\139\32\136\157\32\159\139\32\32\143\32\32\143\32\32\32\32\32\32\32\32\147\148\150\131\148\32\32\32\151\140\148\151\140\147","\32\32\32\149\132\149\136\156\149\144\32\133\139\159\129\143\159\133\143\159\133\138\32\133\138\32\133\32\32\32\32\32\32\150\150\129\137\156\129\32\32\32\133\131\129\133\131\132","\32\32\32\130\131\32\130\131\32\32\129\32\32\32\32\130\131\32\130\131\32\32\32\32\143\143\143\32\32\32\32\32\32\130\129\32\130\135\32\32\32\32\131\32\32\131\32\131","\139\144\32\32\143\148\135\130\144\149\32\149\150\151\149\158\140\129\32\32\32\135\130\144\135\130\144\32\149\32\32\139\32\159\148\32\32\32\32\159\32\144\32\148\32\147\131\132","\159\135\129\131\143\149\143\138\144\138\32\133\130\149\149\137\155\149\159\143\144\147\130\132\32\149\32\147\130\132\131\159\129\139\151\129\148\32\32\139\131\135\133\32\144\130\151\32","\32\32\32\32\32\32\130\135\32\130\32\129\32\129\129\131\131\32\130\131\129\140\141\132\32\129\32\32\129\32\32\32\32\32\32\32\131\131\129\32\32\32\32\32\32\32\32\32","\32\32\32\32\149\32\159\154\133\133\133\144\152\141\132\133\151\129\136\153\32\32\154\32\159\134\129\130\137\144\159\32\144\32\148\32\32\32\32\32\32\32\32\32\32\32\151\129","\32\32\32\32\133\32\32\32\32\145\145\132\141\140\132\151\129\144\150\146\129\32\32\32\138\144\32\32\159\133\136\131\132\131\151\129\32\144\32\131\131\129\32\144\32\151\129\32","\32\32\32\32\129\32\32\32\32\130\130\32\32\129\32\129\32\129\130\129\129\32\32\32\32\130\129\130\129\32\32\32\32\32\32\32\32\133\32\32\32\32\32\129\32\129\32\32","\150\156\148\136\149\32\134\131\148\134\131\148\159\134\149\136\140\129\152\131\32\135\131\149\150\131\148\150\131\148\32\148\32\32\148\32\32\152\129\143\143\144\130\155\32\134\131\148","\157\129\149\32\149\32\152\131\144\144\131\148\141\140\149\144\32\149\151\131\148\32\150\32\150\131\148\130\156\133\32\144\32\32\144\32\130\155\32\143\143\144\32\152\129\32\134\32","\130\131\32\131\131\129\131\131\129\130\131\32\32\32\129\130\131\32\130\131\32\32\129\32\130\131\32\130\129\32\32\129\32\32\133\32\32\32\129\32\32\32\130\32\32\32\129\32","\150\140\150\137\140\148\136\140\132\150\131\132\151\131\148\136\147\129\136\147\129\150\156\145\138\143\149\130\151\32\32\32\149\138\152\129\149\32\32\157\152\149\157\144\149\150\131\148","\149\143\142\149\32\149\149\32\149\149\32\144\149\32\149\149\32\32\149\32\32\149\32\149\149\32\149\32\149\32\144\32\149\149\130\148\149\32\32\149\32\149\149\130\149\149\32\149","\130\131\129\129\32\129\131\131\32\130\131\32\131\131\32\131\131\129\129\32\32\130\131\32\129\32\129\130\131\32\130\131\32\129\32\129\131\131\129\129\32\129\129\32\129\130\131\32","\136\140\132\150\131\148\136\140\132\153\140\129\131\151\129\149\32\149\149\32\149\149\32\149\137\152\129\137\152\129\131\156\133\149\131\32\150\32\32\130\148\32\152\137\144\32\32\32","\149\32\32\149\159\133\149\32\149\144\32\149\32\149\32\149\32\149\150\151\129\138\155\149\150\130\148\32\149\32\152\129\32\149\32\32\32\150\32\32\149\32\32\32\32\32\32\32","\129\32\32\130\129\129\129\32\129\130\131\32\32\129\32\130\131\32\32\129\32\129\32\129\129\32\129\32\129\32\131\131\129\130\131\32\32\32\129\130\131\32\32\32\32\140\140\132","\32\154\32\159\143\32\149\143\32\159\143\32\159\144\149\159\143\32\159\137\145\159\143\144\149\143\32\32\145\32\32\32\145\149\32\144\32\149\32\143\159\32\143\143\32\159\143\32","\32\32\32\152\140\149\151\32\149\149\32\145\149\130\149\157\140\133\32\149\32\154\143\149\151\32\149\32\149\32\144\32\149\149\153\32\32\149\32\149\133\149\149\32\149\149\32\149","\32\32\32\130\131\129\131\131\32\130\131\32\130\131\129\130\131\129\32\129\32\140\140\129\129\32\129\32\129\32\137\140\129\130\32\129\32\130\32\129\32\129\129\32\129\130\131\32","\144\143\32\159\144\144\144\143\32\159\143\144\159\138\32\144\32\144\144\32\144\144\32\144\144\32\144\144\32\144\143\143\144\32\150\129\32\149\32\130\150\32\134\137\134\134\131\148","\136\143\133\154\141\149\151\32\129\137\140\144\32\149\32\149\32\149\154\159\133\149\148\149\157\153\32\154\143\149\159\134\32\130\148\32\32\149\32\32\151\129\32\32\32\32\134\32","\133\32\32\32\32\133\129\32\32\131\131\32\32\130\32\130\131\129\32\129\32\130\131\129\129\32\129\140\140\129\131\131\129\32\130\129\32\129\32\130\129\32\32\32\32\32\129\32","\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32","\32\32\32\32\32\32\32\32\32\32\32\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\32\32\32\32\32\32\32\32\32\32\32","\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32\32","\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32\32\32\32\32\149\32\32\149\32\32\32\32","\32\32\32\32\32\32\32\32\32\32\32\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\32\32\32\32\32\32\32\32\32\32\32","\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32\32\149\32","\32\32\32\32\145\32\159\139\32\151\131\132\155\143\132\134\135\145\32\149\32\158\140\129\130\130\32\152\147\155\157\134\32\32\144\144\32\32\32\32\32\32\152\131\155\131\131\129","\32\32\32\32\149\32\149\32\145\148\131\32\149\32\149\140\157\132\32\148\32\137\155\149\32\32\32\149\154\149\137\142\32\153\153\32\131\131\149\131\131\129\149\135\145\32\32\32","\32\32\32\32\129\32\130\135\32\131\131\129\134\131\132\32\129\32\32\129\32\131\131\32\32\32\32\130\131\129\32\32\32\32\129\129\32\32\32\32\32\32\130\131\129\32\32\32","\150\150\32\32\148\32\134\32\32\132\32\32\134\32\32\144\32\144\150\151\149\32\32\32\32\32\32\145\32\32\152\140\144\144\144\32\133\151\129\133\151\129\132\151\129\32\145\32","\130\129\32\131\151\129\141\32\32\142\32\32\32\32\32\149\32\149\130\149\149\32\143\32\32\32\32\142\132\32\154\143\133\157\153\132\151\150\148\151\158\132\151\150\148\144\130\148","\32\32\32\140\140\132\32\32\32\32\32\32\32\32\32\151\131\32\32\129\129\32\32\32\32\134\32\32\32\32\32\32\32\129\129\32\129\32\129\129\130\129\129\32\129\130\131\32","\156\143\32\159\141\129\153\140\132\153\137\32\157\141\32\159\142\32\150\151\129\150\131\132\140\143\144\143\141\145\137\140\148\141\141\144\157\142\32\159\140\32\151\134\32\157\141\32","\157\140\149\157\140\149\157\140\149\157\140\149\157\140\149\157\140\149\151\151\32\154\143\132\157\140\32\157\140\32\157\140\32\157\140\32\32\149\32\32\149\32\32\149\32\32\149\32","\129\32\129\129\32\129\129\32\129\129\32\129\129\32\129\129\32\129\129\131\129\32\134\32\131\131\129\131\131\129\131\131\129\131\131\129\130\131\32\130\131\32\130\131\32\130\131\32","\151\131\148\152\137\145\155\140\144\152\142\145\153\140\132\153\137\32\154\142\144\155\159\132\150\156\148\147\32\144\144\130\145\136\137\32\146\130\144\144\130\145\130\136\32\151\140\132","\151\32\149\151\155\149\149\32\149\149\32\149\149\32\149\149\32\149\149\32\149\152\137\144\157\129\149\149\32\149\149\32\149\149\32\149\149\32\149\130\150\32\32\157\129\149\32\149","\131\131\32\129\32\129\130\131\32\130\131\32\130\131\32\130\131\32\130\131\32\32\32\32\130\131\32\130\131\32\130\131\32\130\131\32\130\131\32\32\129\32\130\131\32\133\131\32","\156\143\32\159\141\129\153\140\132\153\137\32\157\141\32\159\142\32\159\159\144\152\140\144\156\143\32\159\141\129\153\140\132\157\141\32\130\145\32\32\147\32\136\153\32\130\146\32","\152\140\149\152\140\149\152\140\149\152\140\149\152\140\149\152\140\149\149\157\134\154\143\132\157\140\133\157\140\133\157\140\133\157\140\133\32\149\32\32\149\32\32\149\32\32\149\32","\130\131\129\130\131\129\130\131\129\130\131\129\130\131\129\130\131\129\130\130\131\32\134\32\130\131\129\130\131\129\130\131\129\130\131\129\32\129\32\32\129\32\32\129\32\32\129\32","\159\134\144\137\137\32\156\143\32\159\141\129\153\140\132\153\137\32\157\141\32\32\132\32\159\143\32\147\32\144\144\130\145\136\137\32\146\130\144\144\130\145\130\138\32\146\130\144","\149\32\149\149\32\149\149\32\149\149\32\149\149\32\149\149\32\149\149\32\149\131\147\129\138\134\149\149\32\149\149\32\149\149\32\149\149\32\149\154\143\149\32\157\129\154\143\149","\130\131\32\129\32\129\130\131\32\130\131\32\130\131\32\130\131\32\130\131\32\32\32\32\130\131\32\130\131\129\130\131\129\130\131\129\130\131\129\140\140\129\130\131\32\140\140\129"},{[[000110000110110000110010101000000010000000100101]],[[000000110110000000000010101000000010000000100101]],[[000000000000000000000000000000000000000000000000]],[[100010110100000010000110110000010100000100000110]],[[000000110000000010110110000110000000000000110000]],[[000000000000000000000000000000000000000000000000]],[[000000110110000010000000100000100000000000000010]],[[000000000110110100010000000010000000000000000100]],[[000000000000000000000000000000000000000000000000]],[[010000000000100110000000000000000000000110010000]],[[000000000000000000000000000010000000010110000000]],[[000000000000000000000000000000000000000000000000]],[[011110110000000100100010110000000100000000000000]],[[000000000000000000000000000000000000000000000000]],[[000000000000000000000000000000000000000000000000]],[[110000110110000000000000000000010100100010000000]],[[000010000000000000110110000000000100010010000000]],[[000000000000000000000000000000000000000000000000]],[[010110010110100110110110010000000100000110110110]],[[000000000000000000000110000000000110000000000000]],[[000000000000000000000000000000000000000000000000]],[[010100010110110000000000000000110000000010000000]],[[110110000000000000110000110110100000000010000000]],[[000000000000000000000000000000000000000000000000]],[[000100011111000100011111000100011111000100011111]],[[000000000000100100100100011011011011111111111111]],[[000000000000000000000000000000000000000000000000]],[[000100011111000100011111000100011111000100011111]],[[000000000000100100100100011011011011111111111111]],[[100100100100100100100100100100100100100100100100]],[[000000110100110110000010000011110000000000011000]],[[000000000100000000000010000011000110000000001000]],[[000000000000000000000000000000000000000000000000]],[[010000100100000000000000000100000000010010110000]],[[000000000000000000000000000000110110110110110000]],[[000000000000000000000000000000000000000000000000]],[[110110110110110110000000110110110110110110110110]],[[000000000000000000000110000000000000000000000000]],[[000000000000000000000000000000000000000000000000]],[[000000000000110110000110010000000000000000010010]],[[000010000000000000000000000000000000000000000000]],[[000000000000000000000000000000000000000000000000]],[[110110110110110110110000110110110110000000000000]],[[000000000000000000000110000000000000000000000000]],[[000000000000000000000000000000000000000000000000]],[[110110110110110110110000110000000000000000010000]],[[000000000000000000000000100000000000000110000110]],[[000000000000000000000000000000000000000000000000]]}}local j={}local k={}do local l=0;local m=#i[1]local n=#i[1][1]for o=1,m,3 do for p=1,n,3 do local q=string.char(l)local r={}r[1]=i[1][o]:sub(p,p+2)r[2]=i[1][o+1]:sub(p,p+2)r[3]=i[1][o+2]:sub(p,p+2)local s={}s[1]=i[2][o]:sub(p,p+2)s[2]=i[2][o+1]:sub(p,p+2)s[3]=i[2][o+2]:sub(p,p+2)k[q]={r,s}l=l+1 end end;j[1]=k end;local function t(u,v)local w={["0"]="1",["1"]="0"}if u<=#j then return true end;for x=#j+1,u do local y={}local z=j[x-1]for l=0,255 do local q=string.char(l)local r={}local s={}local A=z[q][1]local B=z[q][2]for o=1,#A do local C,D,E,F,G,H={},{},{},{},{},{}for p=1,#A[1]do local I=k[A[o]:sub(p,p)][1]table.insert(C,I[1])table.insert(D,I[2])table.insert(E,I[3])local J=k[A[o]:sub(p,p)][2]if B[o]:sub(p,p)=="1"then table.insert(F,J[1]:gsub("[01]",w))table.insert(G,J[2]:gsub("[01]",w))table.insert(H,J[3]:gsub("[01]",w))else table.insert(F,J[1])table.insert(G,J[2])table.insert(H,J[3])end end;table.insert(r,table.concat(C))table.insert(r,table.concat(D))table.insert(r,table.concat(E))table.insert(s,table.concat(F))table.insert(s,table.concat(G))table.insert(s,table.concat(H))end;y[q]={r,s}if v then v="Font"..x.."Yeld"..l;os.queueEvent(v)os.pullEvent(v)end end;j[x]=y end;return true end;local function K(L,M,N,O,P)if not type(M)=="string"then error("Not a String",3)end;local Q=type(N)=="string"and N:sub(1,1)or g[N]or error("Wrong Front Color",3)local R=type(O)=="string"and O:sub(1,1)or g[O]or error("Wrong Back Color",3)if j[L]==nil then t(3,false)end;local S=j[L]or error("Wrong font size selected",3)if M==""then return{{""},{""},{""}}end;local T={}for o in M:gmatch('.')do table.insert(T,o)end;local U={}local m=#S[T[1]][1]for V=1,m do local W={}for o=1,#T do W[o]=S[T[o]]and S[T[o]][1][V]or""end;U[V]=table.concat(W)end;local X={}local Y={}local Z={["0"]=Q,["1"]=R}local _={["0"]=R,["1"]=Q}for V=1,m do local a0={}local a1={}for o=1,#T do local a2=S[T[o]]and S[T[o]][2][V]or""a0[o]=a2:gsub("[01]",P and{["0"]=N:sub(o,o),["1"]=O:sub(o,o)}or Z)a1[o]=a2:gsub("[01]",P and{["0"]=O:sub(o,o),["1"]=N:sub(o,o)}or _)end;X[V]=table.concat(a0)Y[V]=table.concat(a1)end;return{U,X,Y}end;local function a3(a4)local a5=a4;local a6,m=a5.getSize()local a7={}local a8={}local a9={}local aa={}local ab={}local ac={}local ad;local ae={}local function af()ad=(" "):rep(a6)for ag=0,15 do local ah=2^ag;local ai=g[ah]ae[ah]=ai:rep(a6)end end;af()local function aj()local ak=ad;local al=ae[colors.white]local am=ae[colors.black]for an=1,m do a7[an]=f(a7[an]==nil and ak or a7[an]..ak:sub(1,a6-a7[an]:len()),1,a6)a9[an]=f(a9[an]==nil and al or a9[an]..al:sub(1,a6-a9[an]:len()),1,a6)a8[an]=f(a8[an]==nil and am or a8[an]..am:sub(1,a6-a8[an]:len()),1,a6)end end;aj()local function ao(ap,aq,ar)if aq>=1 and aq<=m then if ap+ar:len()>0 and ap<=a6 then local as=a7[aq]local at;local au=ap+#ar-1;if ap<1 then local av=1-ap+1;local aw=a6-ap+1;ar=f(ar,av,aw)elseif au>a6 then local aw=a6-ap+1;ar=f(ar,1,aw)end;if ap>1 then local aw=ap-1;at=f(as,1,aw)..ar else at=ar end;if au=1 and aq<=m then if ap+ay:len()>0 and ap<=a6 then local as=a8[aq]local at;local au=ap+#ay-1;if ap<1 then ay=f(ay,1-ap+1,a6-ap+1)elseif au>a6 then ay=f(ay,1,a6-ap+1)end;if ap>1 then at=f(as,1,ap-1)..ay else at=ay end;if au=1 and aq<=m then if ap+ay:len()>0 and ap<=a6 then local as=a9[aq]local at;local au=ap+#ay-1;if ap<1 then local av=1-ap+1;local aw=a6-ap+1;ay=f(ay,av,aw)elseif au>a6 then local aw=a6-ap+1;ay=f(ay,1,aw)end;if ap>1 then local aw=ap-1;at=f(as,1,aw)..ay else at=ay end;if au1 then while#bg>2 do table.sort(bg,function(bq,br)return bq[2]>br[2]end)local bs,bt=bf(bg),#bg;local bu,bv=bg[bt][1],bg[bs][1]for o=1,6 do if bk[o]==bu then bk[o]=bv;bg[bs][2]=bg[bs][2]+1 end end;bg[bt]=nil end;local bw=128;for o=1,#bk-1 do if bk[o]~=bk[6]then bw=bw+2^(o-1)end end;return string.char(bw),bc[bg[1][1]==bk[6]and bg[2][1]or bg[1][1]],bc[bk[6]]else return"\128",bc[bk[1]],bc[bk[1]]end end;local bx,a6,m,aB={{},{},{}},0,#b7+#b7%3,b8 or colors.black;for o=1,#b7 do if#b7[o]>a6 then a6=#b7[o]end end;for aq=0,m-1,3 do local by,bz,bA,bB={},{},{},1;for ap=0,a6-1,2 do local bk,bl={},{}for bC=1,3 do for bD=1,2 do bk[#bk+1]=b7[aq+bC]and b7[aq+bC][ap+bD]and(b7[aq+bC][ap+bD]==0 and aB or b7[aq+bC][ap+bD])or aB;bl[bk[#bk]]=bl[bk[#bk]]and bl[bk[#bk]]+1 or 1 end end;by[bB],bz[bB],bA[bB]=bj(bk,bl)bB=bB+1 end;bx[1][#bx[1]+1],bx[2][#bx[2]+1],bx[3][#bx[3]+1]=table.concat(by),table.concat(bz),table.concat(bA)end;bx.width,bx.height=#bx[1][1],#bx[1]return bx end;local function bE(bF)local bG="Object"local aP;local bH=1;local bI="left"local bJ="top"local bK=false;local bL=false;local bM=true;local bN=aI()local bO={x=1,y=1,width=1,height=1,bgColor=colors.black,fgColor=colors.white,name=bF or"Object",parent=nil,show=function(self)bL=true;bM=true;return self end,hide=function(self)bL=false;bM=true;return self end,isVisible=function(self)return bL end,setFocus=function(self)if self.parent~=nil then self.parent:setFocusedObject(self)end;return self end,setZIndex=function(self,aK)bH=aK;if self.parent~=nil then self.parent:removeObject(self)self.parent:addObject(self)end;return self end,getZIndex=function(self)return bH end,getType=function(self)return bG end,getName=function(self)return self.name end,remove=function(self)if self.parent~=nil then self.parent:removeObject(self)end;return self end,setParent=function(self,bP)if bP.getType~=nil and bP:getType()=="Frame"then self:remove()bP:addObject(self)if self.draw then self:show()end end;return self end,setValue=function(self,bQ)if aP~=bQ then aP=bQ;bM=true;self:valueChangedHandler()end;return self end,getValue=function(self)return aP end,getVisualChanged=function(self)return bM end,setVisualChanged=function(self,bR)bM=bR or true;if bR==nil then bM=true end;return self end,getEventSystem=function(self)return bN end,getParent=function(self)return self.parent end,setPosition=function(self,bS,bT,bU)if bU then self.x,self.y=math.floor(self.x+bS),math.floor(self.y+bT)else self.x,self.y=math.floor(bS),math.floor(bT)end;bM=true;return self end,getPosition=function(self)return self.x,self.y end,getVisibility=function(self)return bL end,setVisibility=function(self,bV)bL=bV or not bL;bM=true;return self end,setSize=function(self,a6,m)self.width,self.height=a6,m;bM=true;return self end,getHeight=function(self)return self.height end,getWidth=function(self)return self.width end,getSize=function(self)return self.width,self.height end,setBackground=function(self,bW)self.bgColor=bW;bM=true;return self end,getBackground=function(self)return self.bgColor end,setForeground=function(self,bW)self.fgColor=bW;bM=true;return self end,getForeground=function(self)return self.fgColor end,draw=function(self)if bL then return true end;return false end,getAbsolutePosition=function(self,ap,aq)if ap==nil then ap=self.x end;if aq==nil then aq=self.y end;if self.parent~=nil then local bX,bY=self.parent:getAbsolutePosition(self.parent:getAnchorPosition())ap=bX+ap-1;aq=bY+aq-1 end;return ap,aq end,getAnchorPosition=function(self,ap,aq,bZ)if ap==nil then ap=self.x end;if aq==nil then aq=self.y end;if bI=="right"then ap=self.parent.width-ap-self.width+2 end;if bJ=="bottom"then aq=self.parent.height-aq-self.height+2 end;local b_,c0=self:getOffset()if bK or bZ then return ap,aq end;return ap+b_,aq+c0 end,getOffset=function(self)if self.parent~=nil and bK==false then return self.parent:getFrameOffset()end;return 0,0 end,ignoreOffset=function(self,c1)bK=c1 or true;return self end,setAnchor=function(self,...)for aO,aP in pairs(table.pack(...))do if aP=="right"or aP=="left"then bI=aP end;if aP=="top"or aP=="bottom"then bJ=aP end end;bM=true;return self end,getAnchor=function(self)return bI,bJ end,onChange=function(self,aN)self:registerEvent("value_changed",aN)return self end,onClick=function(self,aN)self:registerEvent("mouse_click",aN)self:registerEvent("monitor_touch",aN)return self end,onEvent=function(self,aN)self:registerEvent("custom_event_handler",aN)return self end,onClickUp=function(self,aN)self:registerEvent("mouse_up",aN)return self end,onKey=function(self,aN)self:registerEvent("key",aN)self:registerEvent("char",aN)return self end,onKeyUp=function(self,aN)self:registerEvent("key_up",aN)return self end,onBackgroundKey=function(self,aN)self:registerEvent("background_key",aN)self:registerEvent("background_char",aN)return self end,onBackgroundKeyUp=function(self,aN)self:registerEvent("background_key_up",aN)return self end,isFocused=function(self)if self.parent~=nil then return self.parent:getFocusedObject()==self end;return false end,onGetFocus=function(self,aN)self:registerEvent("get_focus",aN)return self end,onLoseFocus=function(self,aN)self:registerEvent("lose_focus",aN)return self end,registerEvent=function(self,aL,aN)return bN:registerEvent(aL,aN)end,removeEvent=function(self,aL,aK)return bN:removeEvent(aL,aK)end,sendEvent=function(self,aL,...)return bN:sendEvent(aL,self,...)end,mouseClickHandler=function(self,aL,c2,ap,aq)local c3,c4=self:getAbsolutePosition(self:getAnchorPosition())if c3<=ap and c3+self.width>ap and c4<=aq and c4+self.height>aq and bL then if self.parent~=nil then self.parent:setFocusedObject(self)end;bN:sendEvent(aL,self,aL,c2,ap,aq)return true end;return false end,keyHandler=function(self,aL,bp)if self:isFocused()then bN:sendEvent(aL,self,aL,bp)return true end;return false end,backgroundKeyHandler=function(self,aL,bp)bN:sendEvent("background_"..aL,self,aL,bp)end,valueChangedHandler=function(self)bN:sendEvent("value_changed",self)end,eventHandler=function(self,aL,c5,c6,c7,c8)bN:sendEvent("custom_event_handler",self,aL,c5,c6,c7,c8)end,getFocusHandler=function(self)bN:sendEvent("get_focus",self)end,loseFocusHandler=function(self)bN:sendEvent("lose_focus",self)end}bO.__index=bO;return bO end;local function c9(bF)local bO={}local bG="Animation"local ca;local cb={}local aK=1;local cc=0;local cd;local function ce()if cb[aK]~=nil then cb[aK].f(bO,aK)end;aK=aK+1;if cb[aK]~=nil then if cb[aK].t>0 then ca=os.startTimer(cb[aK].t)else ce()end end end;bO={name=bF,getType=function(self)return bG end,getZIndex=function(self)return 1 end,getName=function(self)return self.name end,add=function(self,aN,cf)cd=aN;table.insert(cb,{f=aN,t=cf or cc})return self end,wait=function(self,cf)cc=cf;return self end,rep=function(self,cg)for ap=1,cg do table.insert(cb,{f=cd,t=cc})end;return self end,clear=function(self)cb={}cd=nil;cc=0;aK=1;return self end,play=function(self)aK=1;if cb[aK]~=nil then if cb[aK].t>0 then ca=os.startTimer(cb[aK].t)else ce()end end;return self end,cancel=function(self)os.cancelTimer(ca)return self end,eventHandler=function(self,aL,ch)if aL=="timer"and ch==ca then if cb[aK]~=nil then ce()end end end}bO.__index=bO;return bO end;local function ci(bF)local cj=bE(bF)local bG="Button"cj:setValue("Button")cj:setZIndex(5)cj.width=8;cj.bgColor=h.ButtonBG;cj.fgColor=h.ButtonFG;local ck="center"local cl="center"local bO={getType=function(self)return bG end,setHorizontalAlign=function(self,cm)ck=cm end,setVerticalAlign=function(self,cm)cl=cm end,setText=function(self,ar)cj:setValue(ar)return self end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()local cp=b2(self.height,cl)self.parent:drawBackgroundBox(cn,co,self.width,self.height,self.bgColor)self.parent:drawForegroundBox(cn,co,self.width,self.height,self.fgColor)self.parent:drawTextBox(cn,co,self.width,self.height," ")for ag=1,self.height do if ag==cp then self.parent:setText(cn,co+ag-1,aZ(self:getValue(),self.width,ck))end end end;self:setVisualChanged(false)end end}return setmetatable(bO,cj)end;local function cq(bF)local cj=bE(bF)local bG="Checkbox"cj:setZIndex(5)cj:setValue(false)cj.width=1;cj.height=1;cj.bgColor=h.CheckboxBG;cj.fgColor=h.CheckboxFG;local bO={symbol="\42",getType=function(self)return bG end,mouseClickHandler=function(self,aL,c2,ap,aq)if cj.mouseClickHandler(self,aL,c2,ap,aq)then if aL=="mouse_click"and c2==1 or aL=="monitor_touch"then if self:getValue()~=true and self:getValue()~=false then self:setValue(false)else self:setValue(not self:getValue())end end;return true end;return false end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()local cp=b2(self.height,"center")self.parent:drawBackgroundBox(cn,co,self.width,self.height,self.bgColor)for ag=1,self.height do if ag==cp then if self:getValue()==true then self.parent:writeText(cn,co+ag-1,aZ(self.symbol,self.width,"center"),self.bgColor,self.fgColor)else self.parent:writeText(cn,co+ag-1,aZ(" ",self.width,"center"),self.bgColor,self.fgColor)end end end end;self:setVisualChanged(false)end end}return setmetatable(bO,cj)end;local function cr(bF)local cj=bE(bF)local bG="Dropdown"cj.width=12;cj.height=1;cj.bgColor=h.dropdownBG;cj.fgColor=h.dropdownFG;cj:setZIndex(6)local cs={}local ct=h.selectionBG;local cu=h.selectionFG;local cv=true;local cw="left"local cx=0;local cy=16;local cz=6;local cA="\16"local cB="\31"local cC=false;local bO={getType=function(self)return bG end,setIndexOffset=function(self,cD)cx=cD;return self end,getIndexOffset=function(self)return cx end,addItem=function(self,ar,aB,aC,...)table.insert(cs,{text=ar,bgCol=aB or self.bgColor,fgCol=aC or self.fgColor,args={...}})return self end,getAll=function(self)return cs end,removeItem=function(self,aK)table.remove(cs,aK)return self end,getItem=function(self,aK)return cs[aK]end,getItemIndex=function(self)local cE=self:getValue()for bp,aP in pairs(cs)do if aP==cE then return bp end end end,clear=function(self)cs={}self:setValue({})return self end,getItemCount=function(self)return#cs end,editItem=function(self,aK,ar,aB,aC,...)table.remove(cs,aK)table.insert(cs,aK,{text=ar,bgCol=aB or self.bgColor,fgCol=aC or self.fgColor,args={...}})return self end,selectItem=function(self,aK)self:setValue(cs[aK]or{})return self end,setSelectedItem=function(self,aB,aC,cF)ct=aB or self.bgColor;cu=aC or self.fgColor;cv=cF;return self end,setDropdownSize=function(self,a6,m)cy,cz=a6,m;return self end,mouseClickHandler=function(self,aL,c2,ap,aq)if cC then local cn,co=self:getAbsolutePosition(self:getAnchorPosition())if aL=="mouse_click"and c2==1 or aL=="monitor_touch"then if#cs>0 then for ag=1,cz do if cs[ag+cx]~=nil then if cn<=ap and cn+cy>ap and co+ag==aq then self:setValue(cs[ag+cx])return true end end end end end;if aL=="mouse_scroll"then cx=cx+c2;if cx<0 then cx=0 end;if c2==1 then if#cs>cz then if cx>#cs-cz then cx=#cs-cz end else cx=cs-1 end end;return true end;self:setVisualChanged()end;if cj.mouseClickHandler(self,aL,c2,ap,aq)then cC=true else cC=false end end,draw=function(self)if cj.draw(self)then local cn,co=self:getAnchorPosition()if self.parent~=nil then self.parent:drawBackgroundBox(cn,co,self.width,self.height,self.bgColor)local cG=self:getValue()local ar=aZ(cG~=nil and cG.text or"",self.width,cw):sub(1,self.width-1)..(cC and cB or cA)self.parent:writeText(cn,co,ar,self.bgColor,self.fgColor)if cC then for ag=1,cz do if cs[ag+cx]~=nil then if cs[ag+cx]==cG then if cv then self.parent:writeText(cn,co+ag,aZ(cs[ag+cx].text,cy,cw),ct,cu)else self.parent:writeText(cn,co+ag,aZ(cs[ag+cx].text,cy,cw),cs[ag+cx].bgCol,cs[ag+cx].fgCol)end else self.parent:writeText(cn,co+ag,aZ(cs[ag+cx].text,cy,cw),cs[ag+cx].bgCol,cs[ag+cx].fgCol)end end end end end;self:setVisualChanged(false)end end}return setmetatable(bO,cj)end;local function cH(bF)local cj=bE(bF)local bG="Image"cj:setZIndex(2)local cI;local cJ;local cK=false;local function b6()local b9={[0]={8,4,3,6,5},{4,14,8,7},{6,10,8,7},{9,11,8,0},{1,14,8,0},{13,12,8,0},{2,10,8,0},{15,8,10,11,12,14},{0,7,1,9,2,13},{3,11,8,7},{2,6,7,15},{9,3,7,15},{13,5,7,15},{5,12,8,7},{1,4,7,15},{7,10,11,12,14}}local ba,bb,bc={},{},{}for o=0,15 do bb[2^o]=o end;do local bd="0123456789abcdef"for o=1,16 do ba[bd:sub(o,o)]=o-1;ba[o-1]=bd:sub(o,o)bc[bd:sub(o,o)]=2^(o-1)bc[2^(o-1)]=bd:sub(o,o)local be=b9[o-1]for o=1,#be do be[o]=2^be[o]end end end;local function bf(bg)local bh=b9[bb[bg[#bg][1]]]for p=1,#bh do local bi=bh[p]for o=1,#bg-1 do if bg[o][1]==bi then return o end end end;return 1 end;local function bj(bk,bl)if not bl then local bm={}bl={}for o=1,6 do local bn=bk[o]local bo=bl[bn]bl[bn],bm[o]=bo and bo+1 or 1,bn end;bk=bm end;local bg={}for bp,aP in pairs(bl)do bg[#bg+1]={bp,aP}end;if#bg>1 then while#bg>2 do table.sort(bg,function(bq,br)return bq[2]>br[2]end)local bs,bt=bf(bg),#bg;local bu,bv=bg[bt][1],bg[bs][1]for o=1,6 do if bk[o]==bu then bk[o]=bv;bg[bs][2]=bg[bs][2]+1 end end;bg[bt]=nil end;local bw=128;for o=1,#bk-1 do if bk[o]~=bk[6]then bw=bw+2^(o-1)end end;return string.char(bw),bc[bg[1][1]==bk[6]and bg[2][1]or bg[1][1]],bc[bk[6]]else return"\128",bc[bk[1]],bc[bk[1]]end end;local bx,a6,m,aB={{},{},{}},0,#cI+#cI%3,cj.bgColor or colors.black;for o=1,#cI do if#cI[o]>a6 then a6=#cI[o]end end;for aq=0,m-1,3 do local by,bz,bA,bB={},{},{},1;for ap=0,a6-1,2 do local bk,bl={},{}for bC=1,3 do for bD=1,2 do bk[#bk+1]=cI[aq+bC]and cI[aq+bC][ap+bD]and(cI[aq+bC][ap+bD]==0 and aB or cI[aq+bC][ap+bD])or aB;bl[bk[#bk]]=bl[bk[#bk]]and bl[bk[#bk]]+1 or 1 end end;by[bB],bz[bB],bA[bB]=bj(bk,bl)bB=bB+1 end;bx[1][#bx[1]+1],bx[2][#bx[2]+1],bx[3][#bx[3]+1]=table.concat(by),table.concat(bz),table.concat(bA)end;bx.width,bx.height=#bx[1][1],#bx[1]cJ=bx end;local bO={getType=function(self)return bG end,loadImage=function(self,aT)cI=paintutils.loadImage(aT)cK=false;return self end,loadBlittleImage=function(self,aT)cK=true;return self end,shrink=function(self)b6()cK=true;return self end,draw=function(self)if cj.draw(self)then if self.parent~=nil then if cI~=nil then local cn,co=self:getAnchorPosition()if cK then local b5,cL,cM=cJ[1],cJ[2],cJ[3]for o=1,cJ.height do local cN=b5[o]if type(cN)=="string"then self.parent:setText(cn,co+o-1,cN)self.parent:setFG(cn,co+o-1,cL[o])self.parent:setBG(cn,co+o-1,cM[o])elseif type(cN)=="table"then self.parent:setText(cn,co+o-1,cN[2])self.parent:setFG(cn,co+o-1,cL[o])self.parent:setBG(cn,co+o-1,cM[o])end end else for bT=1,math.min(#cI,self.height)do local cO=cI[bT]for bS=1,math.min(#cO,self.width)do if cO[bS]>0 then self.parent:drawBackgroundBox(cn+bS-1,co+bT-1,1,1,cO[bS])end end end end end end;self:setVisualChanged(false)end end}return setmetatable(bO,cj)end;local function cP(bF)local cj=bE(bF)local bG="Input"local cQ="text"local cR=0;cj:setZIndex(5)cj:setValue("")cj.width=10;cj.height=1;cj.bgColor=h.InputBG;cj.fgColor=h.InputFG;local cS=1;local cT=1;local cU=""local cV;local cW;local cX=cU;local cY=false;local bO={getType=function(self)return bG end,setInputType=function(self,cZ)if cZ=="password"or cZ=="number"or cZ=="text"then cQ=cZ end;return self end,setDefaultText=function(self,ar,c_,d0)cU=ar;cV=d0 or cV;cW=c_ or cW;if self:isFocused()then cX=""else cX=cU end;return self end,getInputType=function(self)return cQ end,setValue=function(self,cG)cj.setValue(self,tostring(cG))if not cY then cS=tostring(cG):len()+1 end;return self end,getValue=function(self)local cG=cj.getValue(self)return cQ=="number"and tonumber(cG)or cG end,setInputLimit=function(self,d1)cR=tonumber(d1)or cR;return self end,getInputLimit=function(self)return cR end,getFocusHandler=function(self)cj.getFocusHandler(self)if self.parent~=nil then local cn,co=self:getAnchorPosition()cX=""if self.parent~=nil then self.parent:setCursor(true,cn+cS-cT,co,self.fgColor)end end end,loseFocusHandler=function(self)cj.loseFocusHandler(self)if self.parent~=nil then self.parent:setCursor(false)cX=cU end end,keyHandler=function(self,aL,bp)if cj.keyHandler(self,aL,bp)then cY=true;if aL=="key"then if bp==keys.backspace then local ar=tostring(cj.getValue())if cS>1 then self:setValue(ar:sub(1,cS-2)..ar:sub(cS,ar:len()))if cS>1 then cS=cS-1 end;if cT>1 then if cSd2 then cS=d2+1 end;if cS<1 then cS=1 end;if cS=self.width+cT then cT=cS-self.width+1 end;if cT<1 then cT=1 end end;if bp==keys.left then cS=cS-1;if cS>=1 then if cS=self.width+cT then cT=cS end end;if cS<1 then cS=1 end;if cT<1 then cT=1 end end end;if aL=="char"then local ar=cj.getValue()if ar:len()=self.width+cT then cT=cT+1 end end end;local cn,co=self:getAnchorPosition()local cG=tostring(cj.getValue())local d4=(cS<=cG:len()and cS-1 or cG:len())-(cT-1)if d4>self.x+self.width-1 then d4=self.x+self.width-1 end;if self.parent~=nil then self.parent:setCursor(true,cn+d4,co,self.fgColor)end;cY=false end end,mouseClickHandler=function(self,aL,c2,ap,aq)if cj.mouseClickHandler(self,aL,c2,ap,aq)then if aL=="mouse_click"and c2==1 then end;return true end;return false end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()local cp=b2(self.height,"center")self.parent:drawBackgroundBox(cn,co,self.width,self.height,self.bgColor)for ag=1,self.height do if ag==cp then local cG=tostring(cj.getValue())local d0=self.bgColor;local c_=self.fgColor;local ar;if cG:len()<=0 then ar=cX;d0=cV or d0;c_=cW or c_ end;ar=cX;if cG~=""then ar=cG end;ar=ar:sub(cT,self.width+cT-1)local d5=self.width-ar:len()if d5<0 then d5=0 end;if cQ=="password"and cG~=""then ar=string.rep("*",ar:len())end;ar=ar..string.rep(" ",d5)self.parent:writeText(cn,co+ag-1,ar,d0,c_)end end end;self:setVisualChanged(false)end end}return setmetatable(bO,cj)end;local function d6(bF)local cj=bE(bF)local bG="Label"cj:setZIndex(3)cj.fgColor=colors.white;cj.bgcolor=colors.black;local d7=true;cj:setValue("")local ck="left"local cl="top"local d8=0;local bO={getType=function(self)return bG end,setText=function(self,ar)ar=tostring(ar)cj:setValue(ar)if d7 then self.width=ar:len()end;return self end,setTextAlign=function(self,d9,da)ck=d9 or ck;cl=da or cl;self:setVisualChanged()return self end,setFontSize=function(self,u)if u>0 and u<=4 then d8=u-1 or 0 end;return self end,getFontSize=function(self)return d8+1 end,setSize=function(self,a6,m)cj.setSize(self,a6,m)d7=false;self:setVisualChanged()return self end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()local cp=b2(self.height,cl)self.parent:drawBackgroundBox(cn,co,self.width,self.height,self.bgColor)self.parent:drawForegroundBox(cn,co,self.width,self.height,self.fgColor)self.parent:drawTextBox(cn,co,self.width,self.height," ")if d8==0 then for ag=1,self.height do if ag==cp then self.parent:writeText(cn,co+ag-1,aZ(self:getValue(),self.width,ck),self.bgColor,self.fgColor)end end else local db=K(d8,self:getValue(),self.fgColor,self.bgColor)if d7 then self.height=#db[1]-1;self.width=#db[1][1]end;for ag=1,self.height do if ag==cp then local dc,dd=self.parent:getSize()local de,df=#db[1][1],#db[1]cn=cn or math.floor((dc-de)/2)+1;co=co or math.floor((dd-df)/2)+1;for o=1,df do self.parent:setFG(cn,co+o+ag-2,aZ(db[2][o],self.width,ck))self.parent:setBG(cn,co+o+ag-2,aZ(db[3][o],self.width,ck,g[self.bgColor]))self.parent:setText(cn,co+o+ag-2,aZ(db[1][o],self.width,ck))end end end end end;self:setVisualChanged(false)end end}return setmetatable(bO,cj)end;local function dg(bF)local cj=bE(bF)local bG="List"cj.width=16;cj.height=6;cj.bgColor=h.listBG;cj.fgColor=h.listFG;cj:setZIndex(5)local cs={}local ct=h.selectionBG;local cu=h.selectionFG;local cv=true;local cw="left"local cx=0;local dh=true;local bO={getType=function(self)return bG end,addItem=function(self,ar,aB,aC,...)table.insert(cs,{text=ar,bgCol=aB or self.bgColor,fgCol=aC or self.fgColor,args={...}})if#cs==1 then self:setValue(cs[1])end;return self end,setIndexOffset=function(self,cD)cx=cD;return self end,getIndexOffset=function(self)return cx end,removeItem=function(self,aK)table.remove(cs,aK)return self end,getItem=function(self,aK)return cs[aK]end,getAll=function(self)return cs end,getItemIndex=function(self)local cE=self:getValue()for bp,aP in pairs(cs)do if aP==cE then return bp end end end,clear=function(self)cs={}self:setValue({})return self end,getItemCount=function(self)return#cs end,editItem=function(self,aK,ar,aB,aC,...)table.remove(cs,aK)table.insert(cs,aK,{text=ar,bgCol=aB or self.bgColor,fgCol=aC or self.fgColor,args={...}})return self end,selectItem=function(self,aK)self:setValue(cs[aK]or{})return self end,setSelectedItem=function(self,aB,aC,cF)ct=aB or self.bgColor;cu=aC or self.fgColor;cv=cF;return self end,setScrollable=function(self,di)dh=di;return self end,mouseClickHandler=function(self,aL,c2,ap,aq)local cn,co=self:getAbsolutePosition(self:getAnchorPosition())if cn<=ap and cn+self.width>ap and co<=aq and co+self.height>aq and self:isVisible()then if(aL=="mouse_click"or aL=="mouse_drag")and c2==1 or aL=="monitor_touch"then if#cs>0 then for ag=1,self.height do if cs[ag+cx]~=nil then if cn<=ap and cn+self.width>ap and co+ag-1==aq then self:setValue(cs[ag+cx])self:getEventSystem():sendEvent("mouse_click",self,"mouse_click",0,ap,aq,cs[ag+cx])end end end end end;if aL=="mouse_scroll"and dh then cx=cx+c2;if cx<0 then cx=0 end;if c2>=1 then if#cs>self.height then if cx>#cs-self.height then cx=#cs-self.height end;if cx>=#cs then cx=#cs-1 end else cx=cx-1 end end end;self:setVisualChanged()return true end end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()self.parent:drawBackgroundBox(cn,co,self.width,self.height,self.bgColor)for ag=1,self.height do if cs[ag+cx]~=nil then if cs[ag+cx]==self:getValue()then if cv then self.parent:writeText(cn,co+ag-1,aZ(cs[ag+cx].text,self.width,cw),ct,cu)else self.parent:writeText(cn,co+ag-1,aZ(cs[ag+cx].text,self.width,cw),cs[ag+cx].bgCol,cs[ag+cx].fgCol)end else self.parent:writeText(cn,co+ag-1,aZ(cs[ag+cx].text,self.width,cw),cs[ag+cx].bgCol,cs[ag+cx].fgCol)end end end end;self:setVisualChanged(false)end end}return setmetatable(bO,cj)end;local function dj(bF)local cj=bE(bF)local bG="Menubar"local bO={}cj.width=30;cj.height=1;cj.bgColor=colors.gray;cj.fgColor=colors.lightGray;cj:setZIndex(5)local cs={}local ct=h.selectionBG;local cu=h.selectionFG;local cv=true;local cw="left"local dk=0;local d5=1;local dh=false;local function dl()local dm=0;local bS=0;for ag=1,#cs do if bS+cs[ag].text:len()+d5*2>bO.width then if bSdm then dk=dm end;return self end,getPositionOffset=function(self)return dk end,setScrollable=function(self,di)dh=di;if di==nil then dh=true end;return self end,removeItem=function(self,aK)table.remove(cs,aK)return self end,getItem=function(self,aK)return cs[aK]end,getItemCount=function(self)return#cs end,editItem=function(self,aK,ar,aB,aC,...)table.remove(cs,aK)table.insert(cs,aK,{text=ar,bgCol=aB or self.bgColor,fgCol=aC or self.fgColor,args={...}})return self end,selectItem=function(self,aK)self:setValue(cs[aK]or{})return self end,setSelectedItem=function(self,aB,aC,cF)ct=aB or self.bgColor;cu=aC or self.fgColor;cv=cF;return self end,mouseClickHandler=function(self,aL,c2,ap,aq)if cj.mouseClickHandler(self,aL,c2,ap,aq)then local c3,c4=self:getAbsolutePosition(self:getAnchorPosition())if c3<=ap and c3+self.width>ap and c4<=aq and c4+self.height>aq and self:isVisible()then if self.parent~=nil then self.parent:setFocusedObject(self)end;if aL=="mouse_click"or aL=="monitor_touch"then local bS=0;for ag=1,#cs do if cs[ag]~=nil then if c3+bS<=ap+dk and c3+bS+cs[ag].text:len()+d5*2>ap+dk and c4==aq then self:setValue(cs[ag])self:getEventSystem():sendEvent(aL,self,aL,0,ap,aq,cs[ag])end;bS=bS+cs[ag].text:len()+d5*2 end end end;if aL=="mouse_scroll"and dh then dk=dk+c2;if dk<0 then dk=0 end;local dm=dl()if dk>dm then dk=dm end end;self:setVisualChanged(true)return true end end;return false end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()self.parent:drawBackgroundBox(cn,co,self.width,self.height,self.bgColor)local ar=""local dp=""local dq=""for aO,dr in pairs(cs)do local ds=(" "):rep(d5)..dr.text..(" "):rep(d5)ar=ar..ds;if dr==self:getValue()then dp=dp..g[ct or dr.bgCol or self.bgColor]:rep(ds:len())dq=dq..g[cu or dr.FgCol or self.fgColor]:rep(ds:len())else dp=dp..g[dr.bgCol or self.bgColor]:rep(ds:len())dq=dq..g[dr.FgCol or self.fgColor]:rep(ds:len())end end;self.parent:setText(cn,co,ar:sub(dk+1,self.width+dk))self.parent:setBG(cn,co,dp:sub(dk+1,self.width+dk))self.parent:setFG(cn,co,dq:sub(dk+1,self.width+dk))end;self:setVisualChanged(false)end end}return setmetatable(bO,cj)end;local function dt(bF)local cj=bE(bF)local bG="Pane"local bO={getType=function(self)return bG end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()self.parent:drawBackgroundBox(cn,co,self.width,self.height,self.bgColor)self.parent:drawForegroundBox(cn,co,self.width,self.height,self.bgColor)end;self:setVisualChanged(false)end end}return setmetatable(bO,cj)end;local function du(bF)local cj=bE(bF)local bG="Program"cj:setZIndex(5)local bO;local function dv(ap,aq,a6,m)local dw,dx=1,1;local b8,dy=colors.black,colors.white;local dz=false;local dA=false;local a7={}local a8={}local a9={}local dB={}local ad;local ae={}for o=0,15 do local dC=2^o;dB[dC]={e.getPaletteColour(dC)}end;local function af()ad=(" "):rep(a6)for ag=0,15 do local ah=2^ag;local ai=g[ah]ae[ah]=ai:rep(a6)end end;local function aj()af()local ak=ad;local al=ae[colors.white]local am=ae[colors.black]for ag=1,m do a7[ag]=f(a7[ag]==nil and ak or a7[ag]..ak:sub(1,a6-a7[ag]:len()),1,a6)a9[ag]=f(a9[ag]==nil and al or a9[ag]..al:sub(1,a6-a9[ag]:len()),1,a6)a8[ag]=f(a8[ag]==nil and am or a8[ag]..am:sub(1,a6-a8[ag]:len()),1,a6)end end;aj()local function dD()if dw>=1 and dx>=1 and dw<=a6 and dx<=m then else end end;local function dE(dF,dG,dH)local dI=dw;local au=dI+#dF-1;if dx>=1 and dx<=m then if dI<=a6 and au>=1 then if dI==1 and au==a6 then a7[dx]=dF;a9[dx]=dG;a8[dx]=dH else local dJ,dK,dL;if dI<1 then local dM=1-dI+1;local dN=a6-dI+1;dJ=f(dF,dM,dN)dK=f(dG,dM,dN)dL=f(dH,dM,dN)elseif au>a6 then local dN=a6-dI+1;dJ=f(dF,1,dN)dK=f(dG,1,dN)dL=f(dH,1,dN)else dJ=dF;dK=dG;dL=dH end;local dO=a7[dx]local dP=a9[dx]local dQ=a8[dx]local dR,dS,dT;if dI>1 then local dU=dI-1;dR=f(dO,1,dU)..dJ;dS=f(dP,1,dU)..dK;dT=f(dQ,1,dU)..dL else dR=dJ;dS=dK;dT=dL end;if au=1 and aq<=m then a7[eg]=a7[aq]a8[eg]=a8[aq]a9[eg]=a9[aq]else a7[eg]=ed;a9[eg]=ee;a8[eg]=ef end end end;if dA then dD()end end,isColor=function()return e.isColor()end,isColour=function()return e.isColor()end,write=function(ar)ar=tostring(ar)if dA then dE(ar,g[dy]:rep(ar:len()),g[b8]:rep(ar:len()))end end,clearLine=function()if dA then ao(1,dx,(" "):rep(a6))ax(1,dx,g[b8]:rep(a6))az(1,dx,g[dy]:rep(a6))end;if dA then dD()end end,clear=function()for ag=1,m do ao(1,ag,(" "):rep(a6))ax(1,ag,g[b8]:rep(a6))az(1,ag,g[dy]:rep(a6))end;if dA then dD()end end,blit=function(ar,eh,ei)if type(ar)~="string"then error("bad argument #1 (expected string, got "..type(ar)..")",2)end;if type(eh)~="string"then error("bad argument #2 (expected string, got "..type(eh)..")",2)end;if type(ei)~="string"then error("bad argument #3 (expected string, got "..type(ei)..")",2)end;if#eh~=#ar or#ei~=#ar then error("Arguments must be the same length",2)end;if dA then dE(ar,eh,ei)end end}return e8 end;cj.width=30;cj.height=12;local ej=dv(1,1,cj.width,cj.height)local ek;local el=false;local em={}bO={getType=function(self)return bG end,show=function(self)cj.show(self)ej.setBackgroundColor(self.bgColor)ej.setTextColor(self.fgColor)ej.basalt_setVisible(true)return self end,hide=function(self)cj.hide(self)ej.basalt_setVisible(false)return self end,setPosition=function(self,ap,aq,bU)cj.setPosition(self,ap,aq,bU)ej.basalt_reposition(self:getAnchorPosition())return self end,getBasaltWindow=function()return ej end,getBasaltProcess=function()return ek end,setSize=function(self,a6,m)cj.setSize(self,a6,m)ej.basalt_resize(self.width,self.height)return self end,getStatus=function(self)if ek~=nil then return ek:getStatus()end;return"inactive"end,execute=function(self,aT,...)ek=aR:new(aT,ej,...)ej.setBackgroundColor(colors.black)ej.setTextColor(colors.white)ej.clear()ej.setCursorPos(1,1)ek:resume()el=false;return self end,stop=function(self)if ek~=nil then if not ek:isDead()then ek:resume("terminate")if ek:isDead()then if self.parent~=nil then self.parent:setCursor(false)end end end end;return self end,pause=function(self,en)el=en or not el;if ek~=nil then if not ek:isDead()then if not el then self:injectEvents(em)em={}end end end;return self end,isPaused=function(self)return el end,injectEvent=function(self,aL,c5,c6,c7,c8,eo)if ek~=nil then if not ek:isDead()then if el==false or eo then ek:resume(aL,c5,c6,c7,c8)else table.insert(em,{event=aL,args={c5,c6,c7,c8}})end end end;return self end,getQueuedEvents=function(self)return em end,updateQueuedEvents=function(self,aJ)em=aJ or em;return self end,injectEvents=function(self,aJ)if ek~=nil then if not ek:isDead()then for aO,aP in pairs(aJ)do ek:resume(aP.event,table.unpack(aP.args))end end end;return self end,mouseClickHandler=function(self,aL,c2,ap,aq)if cj.mouseClickHandler(self,aL,c2,ap,aq)then if ek==nil then return false end;if not ek:isDead()then if not el then local ep,eq=self:getAbsolutePosition(self:getAnchorPosition(nil,nil,true))ek:resume(aL,c2,ap-ep+1,aq-eq+1)end end;return true end end,keyHandler=function(self,aL,bp)cj.keyHandler(self,aL,bp)if self:isFocused()then if ek==nil then return false end;if not ek:isDead()then if not el then if self.draw then ek:resume(aL,bp)end end end end end,getFocusHandler=function(self)cj.getFocusHandler(self)if ek~=nil then if not ek:isDead()then if not el then if self.parent~=nil then local er,es=ej.getCursorPos()local cn,co=self:getAnchorPosition()if self.parent~=nil then if cn+er-1>=1 and cn+er-1<=cn+self.width-1 and es+co-1>=1 and es+co-1<=co+self.height-1 then self.parent:setCursor(ej.getCursorBlink(),cn+er-1,es+co-1,ej.getTextColor())end end end end end end end,loseFocusHandler=function(self)cj.loseFocusHandler(self)if ek~=nil then if not ek:isDead()then if self.parent~=nil then self.parent:setCursor(false)end end end end,eventHandler=function(self,aL,c5,c6,c7,c8)if ek==nil then return end;if not ek:isDead()then if not el then if aL~="mouse_click"and aL~="monitor_touch"and aL~="mouse_up"and aL~="mouse_scroll"and aL~="mouse_drag"and aL~="key_up"and aL~="key"and aL~="char"and aL~="terminate"then ek:resume(aL,c5,c6,c7,c8)end;if self:isFocused()then local cn,co=self:getAnchorPosition()local er,es=ej.getCursorPos()if self.parent~=nil then if cn+er-1>=1 and cn+er-1<=cn+self.width-1 and es+co-1>=1 and es+co-1<=co+self.height-1 then self.parent:setCursor(ej.getCursorBlink(),cn+er-1,es+co-1,ej.getTextColor())end end;if aL=="terminate"and self:isFocused()then self:stop()end end else if aL~="mouse_click"and aL~="monitor_touch"and aL~="mouse_up"and aL~="mouse_scroll"and aL~="mouse_drag"and aL~="key_up"and aL~="key"and aL~="char"and aL~="terminate"then table.insert(em,{event=aL,args={c5,c6,c7,c8}})end end end end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()ej.basalt_reposition(cn,co)self.parent:drawBackgroundBox(cn,co,self.width,self.height,self.bgColor)ej.basalt_update()end;self:setVisualChanged(false)end end}return setmetatable(bO,cj)end;local function et(bF)local cj=bE(bF)local bG="Progressbar"local eu=0;cj:setZIndex(5)cj:setValue(false)cj.width=25;cj.height=1;cj.bgColor=h.CheckboxBG;cj.fgColor=h.CheckboxFG;local ev=colors.black;local ew=""local ex=colors.white;local ey=""local ez=0;local bO={getType=function(self)return bG end,setDirection=function(self,eA)ez=eA;return self end,setProgressBar=function(self,bW,aD,eB)ev=bW or ev;ew=aD or ew;ex=eB or ex;return self end,setBackgroundSymbol=function(self,aD)ey=aD:sub(1,1)return self end,setProgress=function(self,aP)if aP>=0 and aP<=100 and eu~=aP then eu=aP;self:setValue(eu)if eu==100 then self:progressDoneHandler()end end;return self end,getProgress=function(self)return eu end,onProgressDone=function(self,x)self:registerEvent("progress_done",x)return self end,progressDoneHandler=function(self)self:sendEvent("progress_done")end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()self.parent:drawBackgroundBox(cn,co,self.width,self.height,self.bgColor)self.parent:drawForegroundBox(cn,co,self.width,self.height,self.fgColor)self.parent:drawTextBox(cn,co,self.width,self.height,ey)if ez==1 then self.parent:drawBackgroundBox(cn,co,self.width,self.height/100*eu,ev)self.parent:drawForegroundBox(cn,co,self.width,self.height/100*eu,ex)self.parent:drawTextBox(cn,co,self.width,self.height/100*eu,ew)elseif ez==2 then self.parent:drawBackgroundBox(cn,co+math.ceil(self.height-self.height/100*eu),self.width,self.height/100*eu,ev)self.parent:drawForegroundBox(cn,co+math.ceil(self.height-self.height/100*eu),self.width,self.height/100*eu,ex)self.parent:drawTextBox(cn,co+math.ceil(self.height-self.height/100*eu),self.width,self.height/100*eu,ew)elseif ez==3 then self.parent:drawBackgroundBox(cn+math.ceil(self.width-self.width/100*eu),co,self.width/100*eu,self.height,ev)self.parent:drawForegroundBox(cn+math.ceil(self.width-self.width/100*eu),co,self.width/100*eu,self.height,ex)self.parent:drawTextBox(cn+math.ceil(self.width-self.width/100*eu),co,self.width/100*eu,self.height,ew)else self.parent:drawBackgroundBox(cn,co,self.width/100*eu,self.height,ev)self.parent:drawForegroundBox(cn,co,self.width/100*eu,self.height,ex)self.parent:drawTextBox(cn,co,self.width/100*eu,self.height,ew)end end;self:setVisualChanged(false)end end}return setmetatable(bO,cj)end;local function eC(bF)local cj=bE(bF)local bG="Radio"cj.width=8;cj.bgColor=h.listBG;cj.fgColor=h.listFG;cj:setZIndex(5)local cs={}local ct=h.selectionBG;local cu=h.selectionFG;local eD=cj.bgColor;local eE=cj.fgColor;local cv=true;local aD="\7"local cw="left"local bO={getType=function(self)return bG end,addItem=function(self,ar,ap,aq,aB,aC,...)table.insert(cs,{x=ap or 1,y=aq or 1,text=ar,bgCol=aB or self.bgColor,fgCol=aC or self.fgColor,args={...}})if#cs==1 then self:setValue(cs[1])end;return self end,getAll=function(self)return cs end,removeItem=function(self,aK)table.remove(cs,aK)return self end,getItem=function(self,aK)return cs[aK]end,getItemIndex=function(self)local cE=self:getValue()for bp,aP in pairs(cs)do if aP==cE then return bp end end end,clear=function(self)cs={}self:setValue({})return self end,getItemCount=function(self)return#cs end,editItem=function(self,aK,ar,ap,aq,aB,aC,...)table.remove(cs,aK)table.insert(cs,aK,{x=ap or 1,y=aq or 1,text=ar,bgCol=aB or self.bgColor,fgCol=aC or self.fgColor,args={...}})return self end,selectItem=function(self,aK)self:setValue(cs[aK]or{})return self end,setSelectedItem=function(self,aB,aC,eF,eG,cF)ct=aB or ct;cu=aC or cu;eD=eF or eD;eE=eG or eE;cv=cF;return self end,mouseClickHandler=function(self,aL,c2,ap,aq)local cn,co=self:getAbsolutePosition(self:getAnchorPosition())if aL=="mouse_click"and c2==1 or aL=="monitor_touch"then if#cs>0 then for aO,aP in pairs(cs)do if cn+aP.x-1<=ap and cn+aP.x-1+aP.text:len()+2>=ap and co+aP.y-1==aq then self:setValue(aP)if self.parent~=nil then self.parent:setFocusedObject(self)end;self:setVisualChanged()return true end end end end;return false end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()for aO,aP in pairs(cs)do if aP==self:getValue()then if cw=="left"then self.parent:writeText(aP.x+cn-1,aP.y+co-1,aD,eD,eE)self.parent:writeText(aP.x+2+cn-1,aP.y+co-1,aP.text,ct,cu)end else self.parent:drawBackgroundBox(aP.x+cn-1,aP.y+co-1,1,1,self.bgColor)self.parent:writeText(aP.x+2+cn-1,aP.y+co-1,aP.text,aP.bgCol,aP.fgCol)end end end;self:setVisualChanged(false)end end}return setmetatable(bO,cj)end;local function eH(bF)local cj=bE(bF)local bG="Scrollbar"cj.width=1;cj.height=8;cj.bgColor=colors.lightGray;cj.fgColor=colors.gray;cj:setValue(1)cj:setZIndex(2)local eI="vertical"local aD=" "local eJ=colors.black;local eK="\127"local eL=cj.height;local aK=1;local eM=1;local bO={getType=function(self)return bG end,setSymbol=function(self,eN)aD=eN:sub(1,1)self:setVisualChanged()return self end,setSymbolSize=function(self,u)eM=tonumber(u)or 1;if eI=="vertical"then self:setValue(aK-1*eL/(self.height-(eM-1))-eL/(self.height-(eM-1)))elseif eI=="horizontal"then self:setValue(aK-1*eL/(self.width-(eM-1))-eL/(self.width-(eM-1)))end;self:setVisualChanged()return self end,setMaxValue=function(self,cG)eL=cG;return self end,setBackgroundSymbol=function(self,eO)eK=string.sub(eO,1,1)self:setVisualChanged()return self end,setSymbolColor=function(self,eP)eJ=eP;self:setVisualChanged()return self end,setBarType=function(self,eQ)eI=eQ:lower()return self end,mouseClickHandler=function(self,aL,c2,ap,aq)if cj.mouseClickHandler(self,aL,c2,ap,aq)then local cn,co=self:getAbsolutePosition(self:getAnchorPosition())if(aL=="mouse_click"or aL=="mouse_drag")and c2==1 or aL=="monitor_touch"then if eI=="horizontal"then for eR=0,self.width do if cn+eR==ap and co<=aq and co+self.height>aq then aK=math.min(eR+1,self.width-(eM-1))self:setValue(eL/self.width*aK)self:setVisualChanged()end end end;if eI=="vertical"then for eR=0,self.height do if co+eR==aq and cn<=ap and cn+self.width>ap then aK=math.min(eR+1,self.height-(eM-1))self:setValue(eL/self.height*aK)self:setVisualChanged()end end end end;if aL=="mouse_scroll"then aK=aK+c2;if aK<1 then aK=1 end;aK=math.min(aK,(eI=="vertical"and self.height or self.width)-(eM-1))self:setValue(eL/(eI=="vertical"and self.height or self.width)*aK)end;return true end end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()if eI=="horizontal"then self.parent:writeText(cn,co,eK:rep(aK-1),self.bgColor,self.fgColor)self.parent:writeText(cn+aK-1,co,aD:rep(eM),eJ,eJ)self.parent:writeText(cn+aK+eM-1,co,eK:rep(self.width-(aK+eM-1)),self.bgColor,self.fgColor)end;if eI=="vertical"then for ag=0,self.height-1 do if aK==ag+1 then for eS=0,math.min(eM-1,self.height)do self.parent:writeText(cn,co+ag+eS,aD,eJ,eJ)end else if ag+1aK-1+eM then self.parent:writeText(cn,co+ag,eK,self.bgColor,self.fgColor)end end end end end;self:setVisualChanged(false)end end}return setmetatable(bO,cj)end;local function eT(bF)local cj=bE(bF)local bG="Slider"cj.width=8;cj.height=1;cj.bgColor=colors.lightGray;cj.fgColor=colors.gray;cj:setValue(1)local eI="horizontal"local aD=" "local eJ=colors.black;local eK="\140"local eL=cj.width;local aK=1;local eM=1;local bO={getType=function(self)return bG end,setSymbol=function(self,eN)aD=eN:sub(1,1)self:setVisualChanged()return self end,setSymbolSize=function(self,u)eM=tonumber(u)or 1;if eI=="vertical"then self:setValue(aK-1*eL/(self.height-(eM-1))-eL/(self.height-(eM-1)))elseif eI=="horizontal"then self:setValue(aK-1*eL/(self.width-(eM-1))-eL/(self.width-(eM-1)))end;self:setVisualChanged()return self end,setMaxValue=function(self,cG)eL=cG;return self end,setBackgroundSymbol=function(self,eO)eK=string.sub(eO,1,1)self:setVisualChanged()return self end,setSymbolColor=function(self,eP)eJ=eP;self:setVisualChanged()return self end,setBarType=function(self,eQ)eI=eQ:lower()return self end,mouseClickHandler=function(self,aL,c2,ap,aq)if cj.mouseClickHandler(self,aL,c2,ap,aq)then local cn,co=self:getAbsolutePosition(self:getAnchorPosition())if(aL=="mouse_click"or aL=="mouse_drag")and c2==1 or aL=="monitor_touch"then if eI=="horizontal"then for eR=0,self.width do if cn+eR==ap and co<=aq and co+self.height>aq then aK=math.min(eR+1,self.width-(eM-1))self:setValue(eL/self.width*aK)self:setVisualChanged()end end end;if eI=="vertical"then for eR=0,self.height do if co+eR==aq and cn<=ap and cn+self.width>ap then aK=math.min(eR+1,self.height-(eM-1))self:setValue(eL/self.height*aK)self:setVisualChanged()end end end end;if aL=="mouse_scroll"then aK=aK+c2;if aK<1 then aK=1 end;aK=math.min(aK,(eI=="vertical"and self.height or self.width)-(eM-1))self:setValue(eL/(eI=="vertical"and self.height or self.width)*aK)end;return true end end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()if eI=="horizontal"then self.parent:writeText(cn,co,eK:rep(aK-1),self.bgColor,self.fgColor)self.parent:writeText(cn+aK-1,co,aD:rep(eM),eJ,eJ)self.parent:writeText(cn+aK+eM-1,co,eK:rep(self.width-(aK+eM-1)),self.bgColor,self.fgColor)end;if eI=="vertical"then for ag=0,self.height-1 do if aK==ag+1 then for eS=0,math.min(eM-1,self.height)do self.parent:writeText(cn,co+ag+eS,aD,eJ,eJ)end else if ag+1aK-1+eM then self.parent:writeText(cn,co+ag,eK,self.bgColor,self.fgColor)end end end end end;self:setVisualChanged(false)end end}return setmetatable(bO,cj)end;local function eU(bF)local cj=bE(bF)local bG="Switch"cj.width=2;cj.height=1;cj.bgColor=colors.lightGray;cj.fgColor=colors.gray;cj:setValue(false)cj:setZIndex(5)local eK=colors.black;local eV=colors.red;local eW=colors.green;local bO={getType=function(self)return bG end,setSymbolColor=function(self,eJ)eK=eJ;self:setVisualChanged()return self end,setActiveBackground=function(self,ei)eW=ei;self:setVisualChanged()return self end,setInactiveBackground=function(self,ei)eV=ei;self:setVisualChanged()return self end,mouseClickHandler=function(self,aL,c2,ap,aq)if cj.mouseClickHandler(self,aL,c2,ap,aq)then local cn,co=self:getAbsolutePosition(self:getAnchorPosition())if aL=="mouse_click"and c2==1 or aL=="monitor_touch"then self:setValue(not self:getValue())end;return true end end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()self.parent:drawBackgroundBox(cn,co,self.width,self.height,self.bgColor)if self:getValue()then self.parent:drawBackgroundBox(cn,co,1,self.height,eW)self.parent:drawBackgroundBox(cn+1,co,1,self.height,eK)else self.parent:drawBackgroundBox(cn,co,1,self.height,eK)self.parent:drawBackgroundBox(cn+1,co,1,self.height,eV)end end;self:setVisualChanged(false)end end}return setmetatable(bO,cj)end;local function eX(bF)local cj=bE(bF)local bG="Textfield"local eY,cT,cS,eZ=1,1,1,1;local e_={""}local f0={[colors.purple]={"break"}}cj.width=20;cj.height=8;cj.bgColor=h.textfieldBG;cj.fgColor=h.textfieldFG;cj:setZIndex(5)local bO={getType=function(self)return bG end,getLines=function(self)return e_ end,getLine=function(self,aK)return e_[aK]or""end,editLine=function(self,aK,ar)e_[aK]=ar or e_[aK]return self end,addLine=function(self,ar,aK)if aK~=nil then table.insert(e_,aK,ar)else table.insert(e_,ar)end;return self end,addKeyword=function(self,f1,bW)end,removeLine=function(self,aK)table.remove(e_,aK or#e_)if#e_<=0 then table.insert(e_,"")end;return self end,getTextCursor=function(self)return cS,eZ end,getFocusHandler=function(self)cj.getFocusHandler(self)if self.parent~=nil then local cn,co=self:getAnchorPosition()if self.parent~=nil then self.parent:setCursor(true,cn+cS-cT,co+eZ-eY,self.fgColor)end end end,loseFocusHandler=function(self)cj.loseFocusHandler(self)if self.parent~=nil then self.parent:setCursor(false)end end,keyHandler=function(self,aL,bp)if cj.keyHandler(self,aL,bp)then local cn,co=self:getAnchorPosition()if aL=="key"then if bp==keys.backspace then if e_[eZ]==""then if eZ>1 then table.remove(e_,eZ)cS=e_[eZ-1]:len()+1;cT=cS-self.width+1;if cT<1 then cT=1 end;eZ=eZ-1 end elseif cS<=1 then if eZ>1 then cS=e_[eZ-1]:len()+1;cT=cS-self.width+1;if cT<1 then cT=1 end;e_[eZ-1]=e_[eZ-1]..e_[eZ]table.remove(e_,eZ)eZ=eZ-1 end else e_[eZ]=e_[eZ]:sub(1,cS-2)..e_[eZ]:sub(cS,e_[eZ]:len())if cS>1 then cS=cS-1 end;if cT>1 then if cSe_[eZ]:len()then if e_[eZ+1]~=nil then e_[eZ]=e_[eZ]..e_[eZ+1]table.remove(e_,eZ+1)end else e_[eZ]=e_[eZ]:sub(1,cS-1)..e_[eZ]:sub(cS+1,e_[eZ]:len())end end;if bp==keys.enter then table.insert(e_,eZ+1,e_[eZ]:sub(cS,e_[eZ]:len()))e_[eZ]=e_[eZ]:sub(1,cS-1)eZ=eZ+1;cS=1;cT=1;if eZ-eY>=self.height then eY=eY+1 end;self:setValue("")end;if bp==keys.up then if eZ>1 then eZ=eZ-1;if cS>e_[eZ]:len()+1 then cS=e_[eZ]:len()+1 end;if cT>1 then if cS1 then if eZe_[eZ]:len()+1 then cS=e_[eZ]:len()+1 end;if eZ>=eY+self.height then eY=eY+1 end end end;if bp==keys.right then cS=cS+1;if eZ<#e_ then if cS>e_[eZ]:len()+1 then cS=1;eZ=eZ+1 end elseif cS>e_[eZ]:len()then cS=e_[eZ]:len()+1 end;if cS<1 then cS=1 end;if cS=self.width+cT then cT=cS-self.width+1 end;if cT<1 then cT=1 end end;if bp==keys.left then cS=cS-1;if cS>=1 then if cS=self.width+cT then cT=cS end end;if eZ>1 then if cS<1 then eZ=eZ-1;cS=e_[eZ]:len()+1;cT=cS-self.width+1 end end;if cS<1 then cS=1 end;if cT<1 then cT=1 end end end;if aL=="char"then e_[eZ]=e_[eZ]:sub(1,cS-1)..bp..e_[eZ]:sub(cS,e_[eZ]:len())cS=cS+1;if cS>=self.width+cT then cT=cT+1 end;self:setValue("")end;local d4=(cS<=e_[eZ]:len()and cS-1 or e_[eZ]:len())-(cT-1)if d4>self.x+self.width-1 then d4=self.x+self.width-1 end;local f2=eZ-eYe_[eZ]:len()then cS=e_[eZ]:len()+1 end;if cSe_[eZ]:len()then cS=e_[eZ]:len()+1 end;if cS#e_-(self.height-1)then eY=#e_-(self.height-1)end;if eY<1 then eY=1 end;if self.parent~=nil then if cn+cS-cT>=cn and cn+cS-cT<=cn+self.width and(co+eZ-eY>=co and co+eZ-eY<=co+self.height)then self.parent:setCursor(true,f3+cS-cT,f4+eZ-eY)else self.parent:setCursor(false)end end end;self:setVisualChanged()return true end end,draw=function(self)if cj.draw(self)then if self.parent~=nil then local cn,co=self:getAnchorPosition()self.parent:drawBackgroundBox(cn,co,self.width,self.height,self.bgColor)self.parent:drawForegroundBox(cn,co,self.width,self.height,self.fgColor)for ag=1,self.height do local ar=""if e_[ag+eY-1]~=nil then ar=e_[ag+eY-1]end;ar=ar:sub(cT,self.width+cT-1)local d5=self.width-ar:len()if d5<0 then d5=0 end;ar=ar..string.rep(" ",d5)self.parent:setText(cn,co+ag-1,ar)end end;self:setVisualChanged(false)end end}return setmetatable(bO,cj)end;local function f5(bF)local bO;local bG="Thread"local aN;local f6;local f7=false;bO={name=bF,getType=function(self)return bG end,getZIndex=function(self)return 1 end,getName=function(self)return self.name end,start=function(self,x)if x==nil then error("Function provided to thread is nil")end;aN=x;f6=coroutine.create(aN)f7=true;local aX,aY=coroutine.resume(f6)if not aX then if aY~="Terminated"then error("Thread Error Occurred - "..aY)end end;return self end,getStatus=function(self,x)if f6~=nil then return coroutine.status(f6)end;return nil end,stop=function(self,x)f7=false;return self end,eventHandler=function(self,aL,c5,c6,c7)if f7 then if coroutine.status(f6)~="dead"then local aX,aY=coroutine.resume(f6,aL,c5,c6,c7)if not aX then if aY~="Terminated"then error("Thread Error Occurred - "..aY)end end else f7=false end end end}bO.__index=bO;return bO end;local function f8(bF)local bG="Timer"local f9=0;local fa=0;local fb=0;local ca;local bN=aI()local fc=false;local bO={name=bF,getType=function(self)return bG end,getZIndex=function(self)return 1 end,getName=function(self)return self.name end,setTime=function(self,fd,fe)f9=fd or 0;fa=fe or 1;return self end,start=function(self)if fc then os.cancelTimer(ca)end;fb=fa;ca=os.startTimer(f9)fc=true;return self end,isActive=function(self)return fc end,cancel=function(self)if ca~=nil then os.cancelTimer(ca)end;fc=false;return self end,onCall=function(self,aN)bN:registerEvent("timed_event",aN)return self end,eventHandler=function(self,aL,ch)if aL=="timer"and ch==ca and fc then bN:sendEvent("timed_event",self)if fb>=1 then fb=fb-1;if fb>=1 then ca=os.startTimer(f9)end elseif fb==-1 then ca=os.startTimer(f9)end end end}bO.__index=bO;return bO end;local function ff(bF,fg)local cj=bE(bF)local bG="Frame"local fh={}local fi={}local bO={}local fj;local fk=e;local fl={}local fm=false;cj:setZIndex(10)local aA=a3(fk)local dz=false;local dw=1;local dx=1;local fn=colors.white;local fo,cx=0,0;if fg~=nil then cj.parent=fg;cj.width,cj.height=fg:getSize()cj.bgColor=h.FrameBG;cj.fgColor=h.FrameFG else cj.width,cj.height=fk.getSize()cj.bgColor=h.basaltBG;cj.fgColor=h.basaltFG end;local function fp(bF)for aO,aP in pairs(fh)do for aO,br in pairs(aP)do if br.name==bF then return aP end end end end;local function fq(fr)local bH=fr:getZIndex()if fp(fr.name)~=nil then return nil end;if fh[bH]==nil then for ap=1,#fi+1 do if fi[ap]~=nil then if bH==fi[ap]then break end;if bH>fi[ap]then table.insert(fi,ap,bH)break end else table.insert(fi,bH)end end;if#fi<=0 then table.insert(fi,bH)end;fh[bH]={}end;fr.parent=bO;table.insert(fh[bH],fr)return fr end;local function fs(fr)for bq,br in pairs(fh)do for bp,aP in pairs(br)do if aP==fr then table.remove(fh[bq],bp)return true end end end;return false end;bO={barActive=false,barBackground=colors.gray,barTextcolor=colors.black,barText="New Frame",barTextAlign="left",isMoveable=false,getType=function(self)return bG end,setFocusedObject=function(self,fr)for aO,aK in pairs(fi)do for aO,aP in pairs(fh[aK])do if aP==fr then if fj~=nil then fj:loseFocusHandler()end;fj=fr;fj:getFocusHandler()end end end;return self end,setOffset=function(self,b_,c0)fo=b_~=nil and math.floor(b_<0 and math.abs(b_)or-b_)or fo;cx=c0~=nil and math.floor(c0<0 and math.abs(c0)or-c0)or cx;return self end,getFrameOffset=function(self)return fo,cx end,removeFocusedObject=function(self)if fj~=nil then fj:loseFocusHandler()end;fj=nil;return self end,getFocusedObject=function(self)return fj end,show=function(self)cj:show()if self.parent==nil and not fm then b=self end;return self end,setCursor=function(self,ft,fu,fv,bW)local cn,co=self:getAbsolutePosition(self:getAnchorPosition())dz=ft or false;if fu~=nil then dw=cn+fu-1 end;if fv~=nil then dx=co+fv-1 end;fn=bW or fn;self:setVisualChanged()return self end,setMoveable=function(self,fw)self.isMoveable=fw or not self.isMoveable;self:setVisualChanged()return self end,addMonitor=function(self,fx)local fy=peripheral.wrap(fx)fl[fx]={monitor=fx,frame=a.createFrame(self:getName().."_monitor_"..fx)}fl[fx].frame:setDisplay(fy):setFrameAsMonitor()fl[fx].frame:setSize(fy:getSize())return fl[fx].frame end,setMonitorScale=function(self,fz,fA)if fm then fk.setTextScale(fz*0.5)if fA then self:setSize(fk:getSize())end end;return self,fm end,setFrameAsMonitor=function(self,fB)fm=fB;if fB==nil then fm=true end;return self end,showBar=function(self,fC)self.barActive=fC or not self.barActive;self:setVisualChanged()return self end,setBar=function(self,ar,aB,aC)self.barText=ar or""self.barBackground=aB or self.barBackground;self.barTextcolor=aC or self.barTextcolor;self:setVisualChanged()return self end,setBarTextAlign=function(self,cw)self.barTextAlign=cw or"left"self:setVisualChanged()return self end,setDisplay=function(self,a4)fk=a4;aA=a3(fk)return self end,getDisplay=function(self)return fk end,getVisualChanged=function(self)local fD=cj.getVisualChanged(self)for aO,aK in pairs(fi)do if fh[aK]~=nil then for aO,aP in pairs(fh[aK])do if aP.getVisualChanged~=nil and aP:getVisualChanged()then fD=true end end end end;return fD end,loseFocusHandler=function(self)cj.loseFocusHandler(self)end,getFocusHandler=function(self)cj.getFocusHandler(self)if self.parent~=nil then self.parent:removeObject(self)self.parent:addObject(self)end end,keyHandler=function(self,aL,bp)if fj~=nil then if fj.keyHandler~=nil then if fj:keyHandler(aL,bp)then return true end end end;return false end,backgroundKeyHandler=function(self,aL,bp)cj.backgroundKeyHandler(self,aL,bp)for aO,aK in pairs(fi)do if fh[aK]~=nil then for aO,aP in pairs(fh[aK])do if aP.backgroundKeyHandler~=nil then aP:backgroundKeyHandler(aL,bp)end end end end end,eventHandler=function(self,aL,c5,c6,c7,c8)cj.eventHandler(self,aL,c5,c6,c7,c8)for aO,aK in pairs(fi)do if fh[aK]~=nil then for aO,aP in pairs(fh[aK])do if aP.eventHandler~=nil then aP:eventHandler(aL,c5,c6,c7,c8)end end end end;if aL=="terminate"then fk.clear()fk.setCursorPos(1,1)a.stop()end end,mouseClickHandler=function(self,aL,c2,ap,aq)local b_,c0=self:getOffset()b_=b_<0 and math.abs(b_)or-b_;c0=c0<0 and math.abs(c0)or-c0;if self.drag then if aL=="mouse_drag"then local fE=1;local fF=1;if self.parent~=nil then fE,fF=self.parent:getAbsolutePosition(self.parent:getAnchorPosition())end;self:setPosition(ap+self.xToRem-(fE-1)+b_,aq-(fF-1)+c0)end;if aL=="mouse_up"then self.drag=false end;return true end;if cj.mouseClickHandler(self,aL,c2,ap,aq)then local bX,bY=self:getAbsolutePosition(self:getAnchorPosition())if aL~="monitor_touch"or fm then for aO,aK in pairs(fi)do if fh[aK]~=nil then for aO,aP in b4(fh[aK])do if aP.mouseClickHandler~=nil then if aP:mouseClickHandler(aL,c2,ap+b_,aq+c0)then return true end end end end end elseif not fm then for aO,dr in pairs(fl)do if c2==dr.monitor then dr.frame:mouseClickHandler(aL,c2,ap,aq)end end end;if self.isMoveable then if ap>=bX and ap<=bX+self.width-1 and aq==bY and aL=="mouse_click"then self.drag=true;self.xToRem=bX-ap end end;if fj~=nil then fj:loseFocusHandler()fj=nil end;return true end;return false end,setText=function(self,ap,aq,ar)local cn,co=self:getAbsolutePosition(self:getAnchorPosition())if aq>=1 and aq<=self.height then if self.parent~=nil then self.parent:setText(math.max(ap+cn-1,cn)-(self.parent.x-1),co+aq-1-(self.parent.y-1),f(ar,math.max(1-ap+1,1),self.width-ap+1))else aA.setText(math.max(ap+cn-1,cn),co+aq-1,f(ar,math.max(1-ap+1,1),self.width-ap+1))end end end,setBG=function(self,ap,aq,aB)local cn,co=self:getAbsolutePosition(self:getAnchorPosition())if aq>=1 and aq<=self.height then if self.parent~=nil then self.parent:setBG(math.max(ap+cn-1,cn)-(self.parent.x-1),co+aq-1-(self.parent.y-1),f(aB,math.max(1-ap+1,1),self.width-ap+1))else aA.setBG(math.max(ap+cn-1,cn),co+aq-1,f(aB,math.max(1-ap+1,1),self.width-ap+1))end end end,setFG=function(self,ap,aq,aC)local cn,co=self:getAbsolutePosition(self:getAnchorPosition())if aq>=1 and aq<=self.height then if self.parent~=nil then self.parent:setFG(math.max(ap+cn-1,cn)-(self.parent.x-1),co+aq-1-(self.parent.y-1),f(aC,math.max(1-ap+1,1),self.width-ap+1))else aA.setFG(math.max(ap+cn-1,cn),co+aq-1,f(aC,math.max(1-ap+1,1),self.width-ap+1))end end end,writeText=function(self,ap,aq,ar,aB,aC)local cn,co=self:getAbsolutePosition(self:getAnchorPosition())if aq>=1 and aq<=self.height then if self.parent~=nil then self.parent:writeText(math.max(ap+cn-1,cn)-(self.parent.x-1),co+aq-1-(self.parent.y-1),f(ar,math.max(1-ap+1,1),self.width-ap+1),aB,aC)else aA.writeText(math.max(ap+cn-1,cn),co+aq-1,f(ar,math.max(1-ap+1,1),self.width-ap+1),aB,aC)end end end,drawBackgroundBox=function(self,ap,aq,a6,m,aB)local cn,co=self:getAbsolutePosition(self:getAnchorPosition())m=aq<1 and(m+aq>self.height and self.height or m+aq-1)or(m+aq>self.height and self.height-aq+1 or m)a6=ap<1 and(a6+ap>self.width and self.width or a6+ap-1)or(a6+ap>self.width and self.width-ap+1 or a6)if self.parent~=nil then self.parent:drawBackgroundBox(math.max(ap+cn-1,cn)-(self.parent.x-1),math.max(aq+co-1,co)-(self.parent.y-1),a6,m,aB)else aA.drawBackgroundBox(math.max(ap+cn-1,cn),math.max(aq+co-1,co),a6,m,aB)end end,drawTextBox=function(self,ap,aq,a6,m,aD)local cn,co=self:getAbsolutePosition(self:getAnchorPosition())m=aq<1 and(m+aq>self.height and self.height or m+aq-1)or(m+aq>self.height and self.height-aq+1 or m)a6=ap<1 and(a6+ap>self.width and self.width or a6+ap-1)or(a6+ap>self.width and self.width-ap+1 or a6)if self.parent~=nil then self.parent:drawTextBox(math.max(ap+cn-1,cn)-(self.parent.x-1),math.max(aq+co-1,co)-(self.parent.y-1),a6,m,aD:sub(1,1))else aA.drawTextBox(math.max(ap+cn-1,cn),math.max(aq+co-1,co),a6,m,aD:sub(1,1))end end,drawForegroundBox=function(self,ap,aq,a6,m,aC)local cn,co=self:getAbsolutePosition(self:getAnchorPosition())m=aq<1 and(m+aq>self.height and self.height or m+aq-1)or(m+aq>self.height and self.height-aq+1 or m)a6=ap<1 and(a6+ap>self.width and self.width or a6+ap-1)or(a6+ap>self.width and self.width-ap+1 or a6)if self.parent~=nil then self.parent:drawForegroundBox(math.max(ap+cn-1,cn)-(self.parent.x-1),math.max(aq+co-1,co)-(self.parent.y-1),a6,m,aC)else aA.drawForegroundBox(math.max(ap+cn-1,cn),math.max(aq+co-1,co),a6,m,aC)end end,draw=function(self)for aO,dr in pairs(fl)do dr.frame:draw()end;if self:getVisualChanged()then if cj.draw(self)then local cn,co=self:getAbsolutePosition(self:getAnchorPosition())local f3,f4=self:getAnchorPosition()if self.parent~=nil then self.parent:drawBackgroundBox(f3,f4,self.width,self.height,self.bgColor)self.parent:drawForegroundBox(f3,f4,self.width,self.height,self.fgColor)self.parent:drawTextBox(f3,f4,self.width,self.height," ")else aA.drawBackgroundBox(cn,co,self.width,self.height,self.bgColor)aA.drawForegroundBox(cn,co,self.width,self.height,self.fgColor)aA.drawTextBox(cn,co,self.width,self.height," ")end;fk.setCursorBlink(false)if self.barActive then if self.parent~=nil then self.parent:writeText(f3,f4,aZ(self.barText,self.width,self.barTextAlign),self.barBackground,self.barTextcolor)else aA.writeText(cn,co,aZ(self.barText,self.width,self.barTextAlign),self.barBackground,self.barTextcolor)end end;for aO,aK in b4(fi)do if fh[aK]~=nil then for aO,aP in pairs(fh[aK])do if aP.draw~=nil then aP:draw()end end end end;if dz then fk.setTextColor(fn)fk.setCursorPos(dw,dx)if self.parent~=nil then fk.setCursorBlink(self:isFocused())else fk.setCursorBlink(dz)end end;self:setVisualChanged(false)end end end,drawUpdate=function(self)aA.update()for fG,dr in pairs(fl)do dr.frame:drawUpdate()end end,addObject=function(self,fr)return fq(fr)end,removeObject=function(self,fr)return fs(fr)end,getObject=function(self,fr)return fp(fr)end,addButton=function(self,bF)local fr=ci(bF)fr.name=bF;return fq(fr)end,addLabel=function(self,bF)local fr=d6(bF)fr.bgColor=self.bgColor;fr.fgColor=self.fgColor;return fq(fr)end,addCheckbox=function(self,bF)local fr=cq(bF)return fq(fr)end,addInput=function(self,bF)local fr=cP(bF)return fq(fr)end,addProgram=function(self,bF)local fr=du(bF)return fq(fr)end,addTextfield=function(self,bF)local fr=eX(bF)return fq(fr)end,addList=function(self,bF)local fr=dg(bF)fr.name=nam;return fq(fr)end,addDropdown=function(self,bF)local fr=cr(bF)return fq(fr)end,addRadio=function(self,bF)local fr=eC(bF)return fq(fr)end,addTimer=function(self,bF)local fr=f8(bF)return fq(fr)end,addAnimation=function(self,bF)local fr=c9(bF)return fq(fr)end,addSlider=function(self,bF)local fr=eT(bF)return fq(fr)end,addScrollbar=function(self,bF)local fr=eH(bF)return fq(fr)end,addMenubar=function(self,bF)local fr=dj(bF)return fq(fr)end,addThread=function(self,bF)local fr=f5(bF)return fq(fr)end,addPane=function(self,bF)local fr=dt(bF)return fq(fr)end,addImage=function(self,bF)local fr=cH(bF)return fq(fr)end,addProgressbar=function(self,bF)local fr=et(bF)return fq(fr)end,addSwitch=function(self,bF)local fr=eU(bF)return fq(fr)end,addFrame=function(self,bF)local fr=ff(bF,self)return fq(fr)end}setmetatable(bO,cj)if fg==nil then table.insert(c,bO)end;return bO end;local fH=false;local function fI(aL,c5,c6,c7,c8)if aL=="mouse_click"then b:mouseClickHandler(aL,c5,c6,c7,c8)elseif aL=="mouse_drag"then b:mouseClickHandler(aL,c5,c6,c7,c8)elseif aL=="mouse_up"then b:mouseClickHandler(aL,c5,c6,c7,c8)elseif aL=="mouse_scroll"then b:mouseClickHandler(aL,c5,c6,c7,c8)elseif aL=="monitor_touch"then b:mouseClickHandler(aL,c5,c6,c7,c8)elseif aL=="key"or aL=="char"then b:keyHandler(aL,c5)b:backgroundKeyHandler(aL,c5)end;if aL=="key"then d[c5]=true end;if aL=="key_up"then d[c5]=false end;for aO,aP in pairs(c)do aP:eventHandler(aL,c5,c6,c7,c8)end;if fH then b:draw()b:drawUpdate()end end;function a.autoUpdate(f7)e.clear()fH=f7 or true;b:draw()b:drawUpdate()while fH do local aL,c5,c6,c7,c8=os.pullEventRaw()fI(aL,c5,c6,c7,c8)end end;function a.update(aL,c5,c6,c7,c8)if aL~=nil then fI(aL,c5,c6,c7,c8)else b:draw()b:drawUpdate()end end;function a.stop()fH=false end;function a.isKeyDown(bp)if d[bp]==nil then return false end;return d[bp]end;function a.getFrame(bF)for aO,aP in pairs(c)do if aP.name==bF then return aP end end end;function a.getActiveFrame()return b end;function a.setActiveFrame(bP)if bP:getType()=="Frame"then b=bP;return true end;return false end;function a.createFrame(bF)return ff(bF)end;function a.removeFrame(bF)for bp,aP in pairs(c)do if aP.name==bF then c[bp]=nil;return true end end;return false end;if a.debugger then a.debugFrame=a.createFrame("basaltDebuggingFrame"):showBar():setBackground(colors.lightGray):setBar("Debug",colors.black,colors.gray)a.debugList=a.debugFrame:addList("debugList"):setSize(a.debugFrame.width-2,a.debugFrame.height-3):setPosition(2,3):setScrollable(true):show()a.debugFrame:addButton("back"):setAnchor("right"):setSize(1,1):setText("\22"):onClick(function()a.oldFrame:show()end):setBackground(colors.red):show()a.debugLabel=a.debugFrame:addLabel("debugLabel"):onClick(function()a.oldFrame=b;a.debugFrame:show()end):setBackground(colors.black):setForeground(colors.white):setAnchor("bottom"):setZIndex(20):show()end;if a.debugger then function a.debug(...)local aV={...}if b.name~="basaltDebuggingFrame"then if b~=a.debugLabel.frame then a.debugLabel:setParent(b)end end;local fJ=""for bp,aP in pairs(aV)do fJ=fJ..tostring(aP)..(#aV~=bp and", "or"")end;a.debugLabel:setText("[Debug] "..fJ)a.debugList:addItem(fJ)if a.debugList:getItemCount()>50 then a.debugList:removeItem(1)end;a.debugList:setValue(a.debugList:getItem(a.debugList:getItemCount()))if a.debugList.getItemCount()>a.debugList:getHeight()then a.debugList:setIndexOffset(a.debugList:getItemCount()-a.debugList:getHeight())end;a.debugLabel:show()end end;return a \ No newline at end of file