diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 3b54d2c..0000000 --- a/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -MiRCART-cordoba/* linguist-vendored -MiRCART-nw/* linguist-vendored diff --git a/.gitignore b/.gitignore index 5713056..ebd528d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,3 @@ *.sw[op] -MiRCART-cordoba/node_modules -MiRCART-cordoba/platforms/android/.gradle -MiRCART-cordoba/platforms/android/app/build -MiRCART-cordoba/platforms/android/CordovaLib/build -MiRCART-cordoba/releases/* -MiRCART-nw/releases/* -MiRCART-www/releases/* +__pycache__/ +MiRCARTImgurApiKey.py diff --git a/MiRCART-nw/LICENCE b/MiRCART-nw/LICENCE deleted file mode 120000 index 3f75994..0000000 --- a/MiRCART-nw/LICENCE +++ /dev/null @@ -1 +0,0 @@ -../assets/text/LICENCE.asdf \ No newline at end of file diff --git a/MiRCART-nw/MiRCART.cmd b/MiRCART-nw/MiRCART.cmd deleted file mode 100755 index a19e102..0000000 --- a/MiRCART-nw/MiRCART.cmd +++ /dev/null @@ -1,3 +0,0 @@ -@echo off -start nw.exe . -rem vim:fileformat=dos diff --git a/MiRCART-nw/assets b/MiRCART-nw/assets deleted file mode 120000 index ec2e4be..0000000 --- a/MiRCART-nw/assets +++ /dev/null @@ -1 +0,0 @@ -../assets \ No newline at end of file diff --git a/MiRCART-nw/deploy.sh b/MiRCART-nw/deploy.sh deleted file mode 120000 index 2d4a8ea..0000000 --- a/MiRCART-nw/deploy.sh +++ /dev/null @@ -1 +0,0 @@ -../assets/shell/deploy-nw.sh \ No newline at end of file diff --git a/MiRCART-nw/index.html b/MiRCART-nw/index.html deleted file mode 120000 index 41e2467..0000000 --- a/MiRCART-nw/index.html +++ /dev/null @@ -1 +0,0 @@ -../assets/html/index.html \ No newline at end of file diff --git a/MiRCART-nw/nwjs.manifest b/MiRCART-nw/nwjs.manifest deleted file mode 100644 index 26f4eed..0000000 --- a/MiRCART-nw/nwjs.manifest +++ /dev/null @@ -1,4 +0,0 @@ -a9e66b292c80e86f51b616933e8491dad4007da1abe4a0ee85a3477edfd2750f releases/nwjs-v0.34.5-linux-ia32.tar.gz -2d50bc19619e9a26ace46da3a4f3a4a0e9850920267300eb35759df4cb92e2b5 releases/nwjs-v0.34.5-linux-x64.tar.gz -10409d5519662f25c1a97b027492da13cc42c8cc464c08b76de945969ae33413 releases/nwjs-v0.34.5-win-ia32.zip -77138f6965ad1ae6eba3390e5c6403d3156431ac5247fac39f4491a7c625a216 releases/nwjs-v0.34.5-win-x64.zip diff --git a/MiRCART-nw/package-lock.json b/MiRCART-nw/package-lock.json deleted file mode 100644 index b6f1c8c..0000000 --- a/MiRCART-nw/package-lock.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "MiRCART", - "version": "1.1.6", - "lockfileVersion": 1 -} diff --git a/MiRCART-nw/package.json b/MiRCART-nw/package.json deleted file mode 100644 index e9d063a..0000000 --- a/MiRCART-nw/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "author": "Lucio Andrés Illanes Albornoz , based on work by JOLLO NET NA", - "bugs": { - "url": "https://github.com/lalbornoz/MiRCART/issues" - }, - "description": "MiRCART (standalone NW app)", - "directories": { - "assets": "assets" - }, - "homepage": "https://github.com/lalbornoz/MiRCART#readme", - "license": "Jollo LNT license ", - "main": "index.html", - "name": "MiRCART-nw", - "repository": { - "type": "git", - "url": "git+https://github.com/lalbornoz/MiRCART.git" - }, - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "version": "1.1.6", - "window": { - "title": "MiRCART (standalone NW app)", - "toolbar": true, - "position": "center", - "width": 1024, - "height": 768, - "min_width": 1024, - "min_height": 768 - } -} diff --git a/MiRCART-python/.gitignore b/MiRCART-python/.gitignore deleted file mode 100644 index 04ad9ab..0000000 --- a/MiRCART-python/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -MiRCARTImgurApiKey.py -__pycache__/ -*.sw[op] diff --git a/MiRCART-python/LICENCE b/MiRCART-python/LICENCE deleted file mode 120000 index 1f126e9..0000000 --- a/MiRCART-python/LICENCE +++ /dev/null @@ -1 +0,0 @@ -../assets/text/LICENCE.MIT \ No newline at end of file diff --git a/MiRCART-www/LICENCE b/MiRCART-www/LICENCE deleted file mode 120000 index 3f75994..0000000 --- a/MiRCART-www/LICENCE +++ /dev/null @@ -1 +0,0 @@ -../assets/text/LICENCE.asdf \ No newline at end of file diff --git a/MiRCART-www/assets b/MiRCART-www/assets deleted file mode 120000 index ec2e4be..0000000 --- a/MiRCART-www/assets +++ /dev/null @@ -1 +0,0 @@ -../assets \ No newline at end of file diff --git a/MiRCART-www/deploy.sh b/MiRCART-www/deploy.sh deleted file mode 120000 index 882a98b..0000000 --- a/MiRCART-www/deploy.sh +++ /dev/null @@ -1 +0,0 @@ -../assets/shell/deploy-www.sh \ No newline at end of file diff --git a/MiRCART-www/index.html b/MiRCART-www/index.html deleted file mode 120000 index 41e2467..0000000 --- a/MiRCART-www/index.html +++ /dev/null @@ -1 +0,0 @@ -../assets/html/index.html \ No newline at end of file diff --git a/MiRCART.py b/MiRCART.py new file mode 100755 index 0000000..12085c9 --- /dev/null +++ b/MiRCART.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python3 +# +# MiRCART.py -- mIRC art editor for Windows & Linux +# Copyright (c) 2018, 2019 Lucio Andrés Illanes Albornoz +# + +import os, sys +sys.path.append(os.path.join(os.getcwd(), "libcanvas")) +sys.path.append(os.path.join(os.getcwd(), "libgui")) +sys.path.append(os.path.join(os.getcwd(), "librtl")) +sys.path.append(os.path.join(os.getcwd(), "libtools")) + +from MiRCARTFrame import MiRCARTFrame +import wx + +# +# Entry point +def main(*argv): + wxApp = wx.App(False) + appFrame = MiRCARTFrame(None) + if len(argv) > 1 \ + and len(argv[1]) > 0: + appFrame.panelCanvas.canvasInterface.canvasPathName = argv[1] + appFrame.panelCanvas.canvasImportStore.importTextFile(argv[1]) + appFrame.panelCanvas.canvasImportStore.importIntoPanel() + appFrame.onCanvasUpdate(pathName=argv[1], undoLevel=-1) + wxApp.MainLoop() +if __name__ == "__main__": + main(*sys.argv) + +# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 diff --git a/assets/css/ak.css b/assets/css/ak.css deleted file mode 100644 index 751cc94..0000000 --- a/assets/css/ak.css +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Background mIRC colours - */ -.ba {background-color: #FFFFFF} -.bb {background-color: #000000} -.bc {background-color: #00007F} -.bd {background-color: #009300} -.be {background-color: #FF0000} -.bf {background-color: #7f0000} -.bg {background-color: #9C009C} -.bh {background-color: #FC7F00} -.bi {background-color: #FFFF00} -.bj {background-color: #00FC00} -.bk {background-color: #009393} -.bl {background-color: #00FFFF} -.bm {background-color: #0000FC} -.bn {background-color: #FF00FF} -.bo {background-color: #7F7F7F} -.bp {background-color: #D2D2D2} - -/* - * Foreground mIRC colours - */ -.fa {color: #FFFFFF} -.fb {color: #000000} -.fc {color: #00007F} -.fd {color: #009300} -.fe {color: #FF0000} -.ff {color: #7F0000} -.fg {color: #9C009C} -.fh {color: #FC7F00} -.fi {color: #FFFF00} -.fj {color: #00FC00} -.fk {color: #009393} -.fl {color: #00FFFF} -.fm {color: #0000FC} -.fn {color: #FF00FF} -.fo {color: #7F7F7F} -.fp {color: #D2D2D2} - -/* - * vim:ts=2 sw=2 expandtab fenc=utf-8 foldmethod=marker nowrap tw=0 - */ diff --git a/assets/css/fonts.css b/assets/css/fonts.css deleted file mode 100644 index df42e9b..0000000 --- a/assets/css/fonts.css +++ /dev/null @@ -1,13 +0,0 @@ -@font-face { - font-family: 'FixedsysExcelsior301Regular'; - font-style: normal; - src: url('../fonts/fsex300-webfont.eot'); - src: url('../fonts/fsex300-webfont.eot?#iefix') format('embedded-opentype'), - url('../fonts/fsex300-webfont.woff') format('woff'), - url('../fonts/fsex300-webfont.ttf') format('truetype'), - url('../fonts/fsex300-webfont.svg#FixedsysExcelsior301Regular') format('svg'); -} - -/* - * vim:ts=2 sw=2 expandtab fenc=utf-8 foldmethod=marker nowrap tw=0 - */ diff --git a/assets/css/help.css b/assets/css/help.css deleted file mode 100644 index 3f44ead..0000000 --- a/assets/css/help.css +++ /dev/null @@ -1,48 +0,0 @@ -body { - background: #000000; - background-image: url('../images/tile.jpg'); - color: rgb(255,255,0); - font-family: times new roman; - font-family: 'FixedsysExcelsior301Regular'; - font-size: 16pt; -} - -/* {{{ DIV id styles */ -div#box { - background: rgba(0,0,100,0.5); - border: 3px solid #0000ff; - border-spacing: 0px; - color: #00ffff!important; - display: inline-block; - font-size: 20px; - font-size: 12pt!important; - margin: 10px 0; - padding: 10px; -} -div#box_wrapper { - margin: 0 auto; - width: 50%; -} -/* }}} */ -/* {{{ Element styles */ -h1 { - color: #ff00ff!important; - font-size: 42px; - margin-bottom: 15px; -} -h2 { - color: #00ffff!important; - margin-bottom: 15px; - margin-top: 15px; -} -p { - color: white; -} -pre { - color: white; -} -/* }}} */ - -/* - * vim:ts=2 sw=2 expandtab fenc=utf-8 foldmethod=marker nowrap tw=0 - */ diff --git a/assets/css/sally.css b/assets/css/sally.css deleted file mode 100644 index 3a4e4bc..0000000 --- a/assets/css/sally.css +++ /dev/null @@ -1,302 +0,0 @@ - -/* {{{ BODY.grid styles */ -body.grid div { - border-left: 1px solid #444444; -} -body.grid span { - border-bottom: 1px solid #444444; - border-right: 1px solid #444444; -} -body.grid .tool { - border: 1px solid #444444; -} -body.grid #brush_wrapper > div:first-child, -body.grid #canvas_wrapper > div:first-child, -body.grid #letters_wrapper > div:first-child, -body.grid #palette_wrapper > div:first-child { - border-top: 1px solid #444444; -} -/* }}} */ -/* {{{ .initial styles */ -.initial #add_custom_el, -.initial #doc_el, -.initial #export_format_el, -.initial #export_textarea, -.initial #import_button, -.initial #import_format_el, -.initial #import_textarea, -.initial #grid_el, -.initial #load_el, -.initial #save_el, -.initial #vertical_checkbox { -} -/* }}} */ -/* {{{ .selector_el styles */ -.selector_el { - border: 1px dashed white !important; - left: -999px; - margin-top: -1px; - padding-top: 1px; - pointer-events: none; - position: absolute; - top: -999px; -} -.selector_el.creating div { - display: none; } -.selector_el.dragging { - color: #00FF00; -} -/* }}} */ -/* {{{ .tool styles */ -.tool { - cursor: pointer; -} -.tool.focused { - color: white; - text-decoration: underline; -} -.tool.locked.focused { - box-shadow: 0 0; -} -.tool.radio { - margin: 0 8px 0 0; -} -.tool.radio.focused { - background-color: #6D6D6D; - box-shadow: none; - color: black; -} -/* }}} */ -/* {{{ .vertical styles */ -.vertical .wrapper, .vertical .block { - float: left; -} -.vertical #brush_container { - display: inline-block; - float: left; -} -.vertical #canvas_wrapper, -.vertical #canvas_wrapper div, -.vertical #palette_wrapper, -.vertical #palette_wrapper { - margin-right: 10px; -} -.vertical #secret_wrapper { - margin-right: 10px; -} -.vertical #secret_wrapper span { - clear: both; - float: left; -} -.vertical #tools_block { - min-width: 100%; -} -.vertical #tools_wrapper, -.vertical #ui_wrapper { - clear: none; - float: left; - width: 320px; -} -.vertical #workspace_wrapper { - float: left; - position: relative; - width: auto; -} -/* }}} */ - -/* {{{ Class & id styles (simple) */ -.bucket #canvas_wrapper { cursor: url(../images/bucket.png) 3 15, auto; } -.dropper #canvas_wrapper { cursor: url(../images/dropper.gif) 0 15, auto; } -.faded { color: #404040; } -.hidden { visibility: hidden; } -.loading .vertical #ui_wrapper { clear: none } -#experimental_palette_toggle.focused { box-shadow: none; } -#export_wrapper { display: none; } -#import_wrapper { display: none; } -#tools_block > * { cursor: crosshair; } -#workspace_wrapper { width: 100%; } -/* }}} */ -/* {{{ Class styles (complex) */ -.ba.focused { - box-shadow: inset 0 0px 2px #000, inset 0 0px 2px black; - border-color: black; -} -.block { - background-color: black; - float: left; - height: auto; - user-select: none; - -moz-user-select: none; - -webkit-user-select: none; - width: auto; -} -.block { - padding: 4px; -} -.block:nth-child(n+2) { - padding-left: 30px; -} -.close { - background: black; - cursor: pointer; - padding: 10px; - position: absolute; - right: 20px; - top: 20px; - z-index: 2; -} -.custom { - float: left; - margin-bottom: 5px; - margin-right: 5px; -} -.ed { - color: white; -} -.ed.focused { - color: white; - text-decoration: underline; -} -.faba.focused, .fbba.focused, .fcba.focused, .fdba.focused, .feba.focused, .ffba.focused, .fgba.focused, .fhba.focused, -.fiba.focused, .fjba.focused, .fkba.focused, .flba.focused, .fmba.focused, .fnba.focused, .foba.focused, .fpba.focused { - box-shadow: inset 1px 0 2px #888888, inset -1px 0 2px #888888, inset 0 1px 2px #888888, inset 0 -1px 2px #888888; -} -.focused { - box-shadow: inset 1px 0 2px white, inset -1px 0 2px white, inset 0 1px 2px white, inset 0 -1px 2px white; - border-color: white; -} -.locked { - border-bottom: 1px solid; - color: #bbbbbb; - text-decoration: none; -} -.transparent { - background-color: transparent; - background-image: url(../images/gray-dither.gif); - background-size: 8px 8px; -} -@media (-webkit-min-device-pixel-ratio: 2) { - .transparent { - background-size: 4px 4px; - } -} -.wrapper { - background-color: black; - cursor: crosshair; - float: left; - height: auto; - user-select: none; - -moz-user-select: none; - -webkit-user-select: none; - white-space: pre-wrap; - width: auto; - word-wrap: break-word; -} -/* }}} */ -/* {{{ Element styles */ -a { - display: block; -} -a:link, a:visited { - color: #6B6760; - text-decoration: none; -} -a:hover { - text-decoration: underline; -} -body { - background-color: black !important; - transition: 0.1s linear; -} -body.loading { - opacity: 0; -} -span { - display: inline-block; - line-height: 15px; - min-width: 8px; -} -textarea, input[type=text], body { - color: #6D6B6D; - font-family: 'FixedsysExcelsior301Regular'; - -webkit-font-smoothing: antialiased !important; - line-height: 11pt; - font-size: 12pt; - font-weight: 100; - margin: 0; -} -/* }}} */ -/* {{{ Id styles (complex) */ -#brush_wrapper { - border: 1px solid; - display: inline-block; - float: left; - margin-bottom: 13px; - padding-right: 10px; -} -#brush_wrapper, #letters_wrapper { - cursor: crosshair; -} -#canvas_wrapper { - box-shadow: 0 0 2px rgba(255,255,255,0.3); - margin: 3px; - white-space: pre; -} -#cursor_input { - font-size: 16px; - opacity: 0; - position: fixed; - right: 0; - top: 0; - width: 30px; -} -#export_textarea { - background: #001100; - border: 1px solid #333333; - color: #00FF00; - font-family: 'FixedsysExcelsior301Regular'; - font-size: 12pt; - height: 300px; - outline: 0; - width: 37vw; -} -#import_textarea { - background: #001100; - border: 1px solid #333333; - color: #00FF00; - font-family: 'FixedsysExcelsior301Regular'; - font-size: 12pt; - height: 300px; - outline: 0; - width: 37vw; -} -#letters_wrapper { - display: inline-block; - user-select: none; - -webkit-user-select: none; - -moz-user-select: none; -} -#secret_wrapper { - clear: right; - float: left; -} -#secret_wrapper span { - float: left; -} -#textarea_mode { - float: left; - padding: 4px; -} -#ui_wrapper { - clear: both; - float: left; - width: 100vw; -} -#ui_wrapper .block { - width: 100px; -} -/* }}} */ - -/* - * vim:ts=2 sw=2 expandtab fenc=utf-8 foldmethod=marker nowrap tw=0 - */ diff --git a/assets/fonts/fsex300-webfont.eot b/assets/fonts/fsex300-webfont.eot deleted file mode 100644 index e2e493b..0000000 Binary files a/assets/fonts/fsex300-webfont.eot and /dev/null differ diff --git a/assets/fonts/fsex300-webfont.svg b/assets/fonts/fsex300-webfont.svg deleted file mode 100644 index 787f710..0000000 --- a/assets/fonts/fsex300-webfont.svg +++ /dev/null @@ -1,6006 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/assets/fonts/fsex300-webfont.ttf b/assets/fonts/fsex300-webfont.ttf deleted file mode 100644 index 50a6699..0000000 Binary files a/assets/fonts/fsex300-webfont.ttf and /dev/null differ diff --git a/assets/fonts/fsex300-webfont.woff b/assets/fonts/fsex300-webfont.woff deleted file mode 100644 index a2225f9..0000000 Binary files a/assets/fonts/fsex300-webfont.woff and /dev/null differ diff --git a/assets/html/help.html b/assets/html/help.html deleted file mode 100644 index 1b90565..0000000 --- a/assets/html/help.html +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - MiRCART v1.1.6 documentation - - - - -
-
-

MiRCART documentation

- -

Tips on using the keyboard

-
-[                                   Decrease brush size
-]                                   Increase brush size
-<Alt> + <LMB> on canvas             Fill brush with sampled color
-<Alt> + <Shift> + <LMB> on canvas   Copy canvas to brush
-<Ctrl> + <LMB> on brush             Erase brush cell
-<Ctrl> + <LMB> on canvas            Draw with background color
-<Shift> + <LMB> on canvas           Draw line from last position
-<Shift> + <LMB> on character box    Switch to next character set
-<Shift> + <LMB> on stored brush     Delete stored brush
-<LMB> on brush                      Fill brush cell
-<RMB> on brush                      Erase brush cell
-<RMB> on palette                    Set background color (when drawing with a letter)
-        
- -

Notate bene

-

- Characters not forming part of the initial set in the character box beneath the colour palette - encode to, assuming UTF-8, 2-3 bytes in total vs. one (1) byte for those part of the initial - set (e.g. 0-9, A-Z, a-z, etc.)
-
- Internet Explorer is explicitly unsupported.
-
- Repeating patterns of alternating back- and foreground colours, and vice versa, are encoded - using a single (1) byte in mIRC format (video reverse) and as such save space, especially - with large numbers of repetitions or alternations. -

-
-
- - - - - diff --git a/assets/html/index.html b/assets/html/index.html deleted file mode 100644 index e7b146d..0000000 --- a/assets/html/index.html +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - MiRCART v1.1.6 - - - - - -
-
-
- - -
- -
-
-
- . -
-
-
-
- - -
-
-
- x fg
- x bg
- x char
- + add
-
-
-
-
- - -
- square
- circle
- cross
- text
- fill
- select
-
- rotate
- scale
- translate
- slice
-
- - -
-
- new - save - load - help -
- brush: 5 x 5
- canvas: 100 x 30
- _ grid - x vertical -
-
- ascii ansi *mirc -
-
character limit of 425 exceeded
- -
-
- ansi *mirc - - -
- -
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/assets/images/MiRCART.png b/assets/images/MiRCART.png new file mode 100644 index 0000000..fff39a2 Binary files /dev/null and b/assets/images/MiRCART.png differ diff --git a/assets/images/bucket.png b/assets/images/bucket.png deleted file mode 100644 index cfaab30..0000000 Binary files a/assets/images/bucket.png and /dev/null differ diff --git a/assets/images/dropper.gif b/assets/images/dropper.gif deleted file mode 100644 index 7d9eee1..0000000 Binary files a/assets/images/dropper.gif and /dev/null differ diff --git a/assets/images/gray-dither.gif b/assets/images/gray-dither.gif deleted file mode 100644 index 8809b7a..0000000 Binary files a/assets/images/gray-dither.gif and /dev/null differ diff --git a/assets/images/tile.jpg b/assets/images/tile.jpg deleted file mode 100644 index 143334b..0000000 Binary files a/assets/images/tile.jpg and /dev/null differ diff --git a/assets/images/toolCircle.png b/assets/images/toolCircle.png new file mode 100644 index 0000000..9e34f72 Binary files /dev/null and b/assets/images/toolCircle.png differ diff --git a/assets/images/toolClone.png b/assets/images/toolClone.png new file mode 100644 index 0000000..ea358d3 Binary files /dev/null and b/assets/images/toolClone.png differ diff --git a/assets/images/toolDecrBrushH.png b/assets/images/toolDecrBrushH.png new file mode 100644 index 0000000..6b37273 Binary files /dev/null and b/assets/images/toolDecrBrushH.png differ diff --git a/assets/images/toolDecrBrushHW.png b/assets/images/toolDecrBrushHW.png new file mode 100644 index 0000000..b5c14ca Binary files /dev/null and b/assets/images/toolDecrBrushHW.png differ diff --git a/assets/images/toolDecrBrushW.png b/assets/images/toolDecrBrushW.png new file mode 100644 index 0000000..64e964b Binary files /dev/null and b/assets/images/toolDecrBrushW.png differ diff --git a/assets/images/toolDecrCanvasH.png b/assets/images/toolDecrCanvasH.png new file mode 100644 index 0000000..1ea55ef Binary files /dev/null and b/assets/images/toolDecrCanvasH.png differ diff --git a/assets/images/toolDecrCanvasHW.png b/assets/images/toolDecrCanvasHW.png new file mode 100644 index 0000000..2bcefdc Binary files /dev/null and b/assets/images/toolDecrCanvasHW.png differ diff --git a/assets/images/toolDecrCanvasW.png b/assets/images/toolDecrCanvasW.png new file mode 100644 index 0000000..3336980 Binary files /dev/null and b/assets/images/toolDecrCanvasW.png differ diff --git a/assets/images/toolFill.png b/assets/images/toolFill.png new file mode 100644 index 0000000..54b8737 Binary files /dev/null and b/assets/images/toolFill.png differ diff --git a/assets/images/toolIncrBrushH.png b/assets/images/toolIncrBrushH.png new file mode 100644 index 0000000..157c81a Binary files /dev/null and b/assets/images/toolIncrBrushH.png differ diff --git a/assets/images/toolIncrBrushHW.png b/assets/images/toolIncrBrushHW.png new file mode 100644 index 0000000..34f3a41 Binary files /dev/null and b/assets/images/toolIncrBrushHW.png differ diff --git a/assets/images/toolIncrBrushW.png b/assets/images/toolIncrBrushW.png new file mode 100644 index 0000000..6790bfc Binary files /dev/null and b/assets/images/toolIncrBrushW.png differ diff --git a/assets/images/toolIncrCanvasH.png b/assets/images/toolIncrCanvasH.png new file mode 100644 index 0000000..a3004a6 Binary files /dev/null and b/assets/images/toolIncrCanvasH.png differ diff --git a/assets/images/toolIncrCanvasHW.png b/assets/images/toolIncrCanvasHW.png new file mode 100644 index 0000000..4002cc8 Binary files /dev/null and b/assets/images/toolIncrCanvasHW.png differ diff --git a/assets/images/toolIncrCanvasW.png b/assets/images/toolIncrCanvasW.png new file mode 100644 index 0000000..48f8053 Binary files /dev/null and b/assets/images/toolIncrCanvasW.png differ diff --git a/assets/images/toolLine.png b/assets/images/toolLine.png new file mode 100644 index 0000000..206b104 Binary files /dev/null and b/assets/images/toolLine.png differ diff --git a/assets/images/toolMove.png b/assets/images/toolMove.png new file mode 100644 index 0000000..c52a274 Binary files /dev/null and b/assets/images/toolMove.png differ diff --git a/assets/images/toolRect.png b/assets/images/toolRect.png new file mode 100644 index 0000000..851cb4a Binary files /dev/null and b/assets/images/toolRect.png differ diff --git a/assets/images/toolText.png b/assets/images/toolText.png new file mode 100644 index 0000000..d27b969 Binary files /dev/null and b/assets/images/toolText.png differ diff --git a/assets/js/app.js b/assets/js/app.js deleted file mode 100644 index 353b409..0000000 --- a/assets/js/app.js +++ /dev/null @@ -1,89 +0,0 @@ - -var dragging = false -var drawing = false -var erasing = false -var selecting = false -var filling = false -var changed = false -var transforming = false -var focused - -var canvas, tools, palette, controls, brush, mode -var current_tool, current_filetool, current_canvas -var mouse = { x: 0, y: 0 } - -function init () { - build() - bind() -} -function build () { - canvas.append(canvas_wrapper) - brush.append(brush_wrapper) - palette.append(palette_wrapper) - letters.append(letters_wrapper) - letters.repaint("Basic Latin") - - controls.circle.focus() - - brush.bg = colors.red - brush.generate() - brush.build() - - // controls.grid.use() - canvas.resize_wrapper() -} -function bind () { - canvas.bind() - palette.bind() - letters.bind() - brush.bind() - controls.bind() - keys.bind() - clipboard.bind() - - window.addEventListener('mouseup', function(e){ - dragging = erasing = false - - var ae = document.activeElement - - if ((ae !== export_textarea) && (ae !== import_textarea)) { - cursor_input.focus() - } - - if (selecting) { - selection.up(e) - } - else if (transforming) { - transform.up(e) - } - }) - window.addEventListener("touchend", function(){ - if (current_tool.name === "text") { - cursor_input.focus() - } - dragging = false - }) - - window.addEventListener('mousedown', function(e){ - // cursor_input.focus() - }) - - document.addEventListener('DOMContentLoaded', function(){ - cursor_input.focus() - document.body.classList.remove('loading') - }) - - window.onbeforeunload = function() { - // if (changed && !in_iframe()) return "You have edited this drawing." - } - - function in_iframe () { - try { - return window.self !== window.top; - } catch (e) { - return true; - } - } -} - -init() diff --git a/assets/js/clipboard.js b/assets/js/clipboard.js deleted file mode 100644 index 4c8c891..0000000 --- a/assets/js/clipboard.js +++ /dev/null @@ -1,297 +0,0 @@ -var clipboard = (function () { - - var exports = { - format: "mirc", - exporting: false, - visible: false, - canvas: document.createElement("canvas"), - canvas_r: document.createElement("canvas"), - - bind: function () { - export_textarea.addEventListener("focus", exports.export_focus) - export_textarea.addEventListener("blur", exports.blur) - import_button.addEventListener("click", exports.import_click) - import_textarea.addEventListener("focus", exports.import_focus) - import_textarea.addEventListener("paste", exports.paste) - }, - setFormat: function (name) { - return function () { - clipboard.format = name - if (! clipboard.exporting) { clipboard.export_data() } - } - }, - import_hide: function () { import_wrapper.style.display = "none"; clipboard.visible = false }, - import_show: function () { import_wrapper.style.display = "block"; clipboard.visible = true; }, - export_hide: function () { export_wrapper.style.display = "none"; clipboard.visible = false }, - export_show: function () { export_wrapper.style.display = "block"; clipboard.visible = true; changed = false }, - export_focus: function () { - if (! clipboard.exporting) { - export_textarea.focus() - export_textarea.select() - } - }, - import_focus: function () { - import_textarea.focus() - import_textarea.select() - }, - - blur: function () { - }, - - export_mode: function () { - exports.export_focus() - clipboard.exporting = true - export_cutoff_warning_el.style.display = "none" - export_format_el.style.display = "inline" - clipboard.export_data() - }, - - import_mode: function () { - import_button.style.display = "inline" - import_format_el.style.display = "inline" - import_textarea.value = "" - exports.import_focus() - }, - - paste: function (e) { - e.preventDefault() - // images will come through as files - var types = toArray(e.clipboardData.types) - import_textarea.value = "" - types.forEach(function(type, i){ - console.log(type) - // this can be text/plain or text/html.. - if (type.match('text/plain')) { - import_textarea.value = e.clipboardData.getData(type) - } - else { - console.error("unknown type!", item.type) - } - }) - }, - - import_click: function (data, no_undo) { - switch (controls.load_format.value) { - case 'ansi': - exports.import_ansi(data, no_undo) - break - case 'mirc': - exports.import_mirc(data, no_undo) - break - } - }, - - import_ansi: function (data, no_undo) { - if (data && data.preventDefault) { - data = import_textarea.value - } else { - data = data || import_textarea.value - } - - var to_json = function(string, opts){ - var lines_in = string.split(/\r?\n/) - var lines_out = [] - var bg = 1, bg_ansi = 30, bold = false, fg = 15, fg_ansi = 37 - var w = 0, h = 0 - for (var y = 0; y < lines_in.length; y++) { - var cells = [], line = lines_in[y] - if (line.length === 0) { - continue - } else { - for (var x = 0; x < line.length; x++) { - var m = line.substring(x).match(/^\x1b\[((?:\d{1,3};?)+)m/) - if (m !== null) { - m[1].split(";").forEach(function(c){ - c = parseInt(c); - if (c == 0) { - bg = 1; bg_ansi = 30; bold = false; fg = 15; fg_ansi = 37; - } else if (c == 1) { - bold = true; fg = ansi_fg_bold_import[fg_ansi]; - } else if (c == 2) { - bold = false; fg = ansi_fg_import[fg_ansi]; - } else if (ansi_bg_import[c] !== undefined) { - bg = ansi_bg_import[c]; bg_ansi = c; - } else if (bold && (ansi_fg_bold_import[c] !== undefined)) { - fg = ansi_fg_bold_import[c]; fg_ansi = c; - } else if (!bold && (ansi_fg_import[c] !== undefined)) { - fg = ansi_fg_import[c]; fg_ansi = c; - } - }); - x += (m[0].length - 1); - } else { - m = line.substring(x).match(/^\x1b\[(\d+)C/) - if (m !== null) { - for (var n = 0, nmax = parseInt(m[1]); n < nmax; n++) { - cells.push({bg: bg, fg: fg, value: " "}) - } - x += (m[0].length - 1); - } else { - cells.push({bg: bg, fg: fg, value: line[x]}) - } - } - } - if (cells.length > 0) { - if (w < cells.length) { - w = cells.length - } else if (w > cells.length) { - for (var n = cells.length, nmax = w; n < nmax; n++) { - cells.push({bg: bg, fg: fg, value: " "}) - } - } - lines_out.push(cells); h++; - } - } - } - return {h: h, lines: lines_out, w: w} - } - var json = to_json(data, {fg:0, bg:1}) - - if (!no_undo) undo.new() - if (!no_undo) undo.save_rect(0,0, canvas.w, canvas.h) - if (json.w !== canvas.w || json.h !== canvas.h){ - if (!no_undo) undo.save_size(canvas.w, canvas.h) - canvas.resize(json.w, json.h, true) - } - canvas.clear() - - for (var y = 0, line; line = json.lines[y]; y++){ - var row = canvas.aa[y] - for (var x = 0, char; char = line[x]; x++){ - var lex = row[x] - lex.char = char.value - lex.fg = char.fg - lex.bg = char.bg - lex.opacity = 1 - lex.build() - } - } - - current_filetool && current_filetool.blur() - }, - - import_mirc: function (data, no_undo) { - if (data && data.preventDefault) { - data = import_textarea.value - } else { - data = data || import_textarea.value - } - - var to_json = function(string, opts){ - var lines_in = string.split(/\r?\n/) - var lines_out = [] - var w = 0, h = 0 - for (var y = 0; y < lines_in.length; y++) { - var bg = 1, fg = 15 - var cells = [], line = lines_in[y] - if (line.length === 0) { - continue - } else { - for (var x = 0; x < line.length; x++) { - switch (line[x]) { - case "\x02": // ^B (unimplemented) - break - case "\x03": // ^C - var parseColour = function(line, x) { - if (/1[0-5]/.test(line.substr(x, 2))) { - colour = parseInt(line.substr(x, 2)) - return [colour, x + 2] - } else if (/0[0-9]/.test(line.substr(x, 2))) { - colour = parseInt(line.substr(x, 2)) - return [colour, x + 2] - } else if (/[0-9]/.test(line.substr(x, 1))) { - colour = parseInt(line.substr(x, 1)) - return [colour, x + 1] - } else { - return [undefined, x] - } - } - var bg_ = undefined, fg_ = undefined, x_ = x + 1; - [fg_, x_] = parseColour(line, x_) - if (line[x_] === ",") { - [bg_, x_] = parseColour(line, x_ + 1) - } - if ((bg_ == undefined) && (fg_ == undefined)) { - [bg, fg] = [1, 15] - } else { - bg = (bg_ != undefined) ? bg_ : bg; - fg = (fg_ != undefined) ? fg_ : fg; - }; - if (x_ != x) {x = x_ - 1}; break; - case "\x06": // ^F (unimplemented) - break - case "\x0f": // ^O - [bg, fg] = [1, 15]; break; - case "\x16": // ^V - [bg, fg] = [fg, bg]; break; - case "\x1f": // ^_ (unimplemented) - break - default: - cells.push({bg: bg, fg: fg, value: line[x]}) - } - } - if (cells.length > 0) { - if (w < cells.length) { - w = cells.length - } - lines_out.push(cells); h++; - } - } - } - return {h: h, lines: lines_out, w: w} - } - var json = to_json(data, {fg:0, bg:1}) - - if (!no_undo) undo.new() - if (!no_undo) undo.save_rect(0,0, canvas.w, canvas.h) - if (json.w !== canvas.w || json.h !== canvas.h){ - if (!no_undo) undo.save_size(canvas.w, canvas.h) - canvas.resize(json.w, json.h, true) - } - canvas.clear() - - for (var y = 0, line; line = json.lines[y]; y++){ - var row = canvas.aa[y] - for (var x = 0, char; char = line[x]; x++){ - var lex = row[x] - lex.char = char.value - lex.fg = char.fg - lex.bg = char.bg - lex.opacity = 1 - lex.build() - } - } - - current_filetool && current_filetool.blur() - }, - - export_data: function () { - var output - // switch (clipboard.format) { - switch (controls.save_format.value) { - case 'ascii': - output = canvas.ascii() - break - case 'ansi': - output = canvas.ansi() - break - case 'mirc': - output = canvas.mirc({cutoff: 425}) - break - } - if (output.cutoff){ - export_cutoff_warning_el.style.display = 'block' - } else { - export_cutoff_warning_el.style.display = 'none' - } - export_textarea.value = output - clipboard.export_focus() - return output - }, - - } - - return exports - -})() - - diff --git a/assets/js/color.js b/assets/js/color.js deleted file mode 100644 index 78fefac..0000000 --- a/assets/js/color.js +++ /dev/null @@ -1,163 +0,0 @@ - -var fillColor = 1 // black - -var color_names = ("white black dark-blue green red dark-red purple orange " + - "yellow lime teal cyan blue magenta dark-gray light-gray").split(" "); - -var all_color_hue_order = "dark-red red orange yellow lime green teal cyan blue dark-blue purple magenta black dark-gray light-gray white".split(" "); -var all_color_inv_order = "cyan teal blue dark-blue purple magenta dark-red red orange yellow lime green white light-gray dark-gray black".split(" "); -var color_hue_order = "dark-red red orange yellow lime cyan teal blue dark-blue purple magenta".split(" "); -var color_inv_order = "cyan teal blue dark-blue purple magenta dark-red red orange yellow lime green".split(" "); -var gray_names = ("black dark-gray light-gray white").split(" ") - -var fire_names = ("black dark-red red orange yellow white cyan").split(" ") -var red_names = ("black dark-red red").split(" ") -var yellow_names = ("black orange yellow white").split(" ") -var green_names = ("teal green lime").split(" ") -var blue_names = ("black dark-blue blue").split(" ") -var purple_names = ("dark-blue purple magenta red").split(" ") -var dark_gray_names = ("black dark-blue teal dark-gray light-gray white").split(" ") -var color_alphabet = "abcdefghijklmnop"; -var colors = {} -color_names.forEach(function(name, i){ - colors[name.replace("-", "")] = i - colors[name] = i -}) -colors.brown = 5 - -function get_inverse (n) { return colors[all_color_inv_order.indexOf(color_names[n])] } - -function mirc_color (n) { return mod(n, 16)|0 } -function mirc_color_reverse (n) { return mod(-(n+1), 16)|0 } -function all_hue (n) { return colors[all_color_hue_order[mod(n, 16)|0]] } -function all_inv_hue (n) { return colors[all_color_inv_order[mod(n, 16)|0]] } -function hue (n) { return colors[color_hue_order[mod(n, 11)|0]] } -function rand_hue () { return colors[color_hue_order[randint(11)]] } -function rand_gray () { return colors[gray_names[randint(4)]] } -function inv_hue (n) { return colors[color_inv_order[mod(n, 11)|0]] } -function gray (n) { return colors[gray_names[mod(n, 4)|0]] } -function fire (n) { return colors[fire_names[mod(n, 7)|0]] } -function red (n) { return colors[red_names[mod(n, 3)|0]] } -function yellow (n) { return colors[yellow_names[mod(n, 4)|0]] } -function green (n) { return colors[green_names[mod(n, 3)|0]] } -function blue (n) { return colors[blue_names[mod(n, 3)|0]] } -function purple (n) { return colors[purple_names[mod(n, 4)|0]] } -function dark_gray (n) { return colors[dark_gray_names[mod(n, 4)|0]] } - -var css_lookup = { - 'rgb(255, 255, 255)': 'A', - 'rgb(0, 0, 0)': 'B', - 'rgb(0, 0, 127)': 'C', - 'rgb(0, 147, 0)': 'D', - 'red': 'E', - 'rgb(127, 0, 0)': 'F', - 'rgb(156, 0, 156)': 'G', - 'rgb(252, 127, 0)': 'H', - 'rgb(255, 255, 0)': 'I', - 'rgb(0, 252, 0)': 'J', - 'rgb(0, 147, 147)': 'K', - 'rgb(0, 255, 255)': 'L', - 'rgb(0, 0, 252)': 'M', - 'rgb(255, 0, 255)': 'N', - 'rgb(127, 127, 127)': 'O', - 'rgb(210, 210, 210)': 'P', -}; -var css_reverse_lookup = {} -Object.keys(css_lookup).forEach(function(color){ - css_reverse_lookup[ css_lookup[color].charCodeAt(0) - 65 ] = color -}) - -var ansi_fg = [ - 97, // Bright White - 30, // Black - 94, // Blue - 32, // Green - 91, // Red - 31, // Light Red - 35, // Pink - 33, // Yellow - 93, // Light Yellow - 92, // Light Green - 36, // Cyan - 96, // Light Cyan - 34, // Light Blue - 95, // Light Pink - 90, // Grey - 37, // Light Grey -] - -var ansi_fg_import = { - 97: 0, // Bright White - 30: 1, // Black - 94: 2, // Blue - 32: 3, // Green - 91: 4, // Red - 31: 5, // Light Red - 35: 6, // Pink - 33: 7, // Yellow - 93: 8, // Light Yellow - 92: 9, // Light Green - 36: 10, // Cyan - 96: 11, // Light Cyan - 34: 12, // Light Blue - 95: 13, // Light Pink - 90: 14, // Grey - 37: 15, // Light Grey -} - -var ansi_fg_bold_import = { - 97: 0, // Bright White - 30: 14, // Grey - 94: 12, // Light Blue - 32: 9, // Light Green - 91: 4, // Light Red - 31: 4, // Light Red - 35: 13, // Light Pink - 33: 8, // Light Yellow - 93: 8, // Light Yellow - 92: 9, // Light Green - 36: 11, // Light Cyan - 96: 11, // Light Cyan - 34: 12, // Light Blue - 95: 13, // Light Pink - 90: 14, // Grey - 37: 0, // Bright White -} - -var ansi_bg = [ - 107, // Bright White - 40, // Black - 104, // Blue - 42, // Green - 101, // Red - 41, // Light Red - 45, // Pink - 43, // Yellow - 103, // Light Yellow - 102, // Light Green - 46, // Cyan - 106, // Light Cyan - 44, // Light Blue - 105, // Light Pink - 100, // Grey - 47, // Light Grey -] - -var ansi_bg_import = { - 107: 0, // Bright White - 40: 1, // Black - 104: 2, // Blue - 42: 3, // Green - 101: 4, // Red - 41: 5, // Light Red - 45: 6, // Pink - 43: 7, // Yellow - 103: 8, // Light Yellow - 102: 9, // Light Green - 46: 10, // Cyan - 106: 11, // Light Cyan - 44: 12, // Light Blue - 105: 13, // Light Pink - 100: 14, // Grey - 47: 15, // Light Grey -} diff --git a/assets/js/gfx.js b/assets/js/gfx.js deleted file mode 100644 index 54678a9..0000000 --- a/assets/js/gfx.js +++ /dev/null @@ -1,294 +0,0 @@ - -var blit = (function(){ - var blit = {} - blit.and = blit.atop = function(A, B, x, y){ - x = x || 0 ; y = y || 0 - B.forEach(function(lex, u, v){ - var cell = A.getCell(u+x, v+y) - if (cell && lex.opacity > 0) { - cell.assign(lex) - } - }) - } - blit.or = blit.under = function(A, B, x, y){ - x = x || 0 ; y = y || 0 - B.forEach(function(lex, u, v){ - var cell = A.getCell(u+x, v+y) - if (cell && cell.opacity == 0) { - cell.assign(lex) - } - }) - } - // copy the region of A beginning at x,y into B - blit.copy_from = function(A, B, x, y){ - x = x || 0 ; y = y || 0 - B.forEach(function(lex, u, v){ - var cell = A.getCell(u+x, v+y) - if (cell) { - lex.assign(cell) - } - }) - } - blit.copy_toroidal_from = function(A, B, x, y){ - x = x || 0 ; y = y || 0 - B.forEach(function(lex, u, v){ - var cell = A.get(u+x, v+y) - if (cell) { - lex.assign(cell) - } - }) - } - blit.copy_to = function(A, B, x, y){ - x = x || 0 ; y = y || 0 - B.forEach(function(lex, u, v){ - var cell = A.getCell(u+x, v+y) - if (cell) { - cell.assign(lex) - } - }) - } - blit.invert = function(A, B, x, y){ - x = x || 0 ; y = y || 0 - B.forEach(function(lex, u, v){ - var cell = A.getCell(u+x, v+y) - if (cell && lex.opacity > 0) { - cell.fg = get_inverse(cell.fg) - cell.bg = get_inverse(cell.bg) - } - }) - } - var distance_rect = function(x, y, ratio){ - return Math.sqrt((Math.pow(y * ratio, 2)) + Math.pow(x, 2)) - } - var distance_square = function(x, y, ratio){ - return Math.sqrt((Math.pow(y * ratio, 2)) + Math.pow(x * ratio, 2)) - } - blit.circle = function(A, lex){ - var hw = brush.w/2, hh = brush.h/2 - var ratio, distance - - if (brush.w === brush.h){ - distance = distance_square - ratio = hw / hh * (brush.w === 3 || brush.w === 5 ? 1.2 : 1.05) - } else { - distance = distance_rect - ratio = hw / hh - } - - A.forEach(function(lex,x,y) { - if (distance(x - hw + 0.5, y - hh + 0.5, ratio) > hw){ - lex.clear() - } - }) - } - blit.cross = function(A, lex){ - A.forEach(function(lex,x,y) { - if ((x+y)%2) { - lex.clear() - } - }) - } - blit.inverted_cross = function(A, lex){ - // 1x1 brush should still draw something - if (A.w == 1 && A.h == 1) { - return - } - A.forEach(function(lex,x,y) { - if (!((x+y)%2)) { - lex.clear() - } - }) - } - blit.square = function(A, lex){ - // i.e. no transparency - } - return blit -})() - -var draw = (function(){ - - var last_point = [0,0] - - function down (e, lex, point) { - var w = canvas.w, h = canvas.h - erasing = (e.which == "3" || e.ctrlKey) - changed = true - if (e.shiftKey) { - line (lex, last_point, point, erasing) - } - else { - stamp (canvas, brush, point[0], point[1], erasing) - } - last_point[0] = point[0] - last_point[1] = point[1] - } - - function set_last_point (e, point) { - last_point[0] = point[0] - last_point[1] = point[1] - } - - function move (e, lex, point) { - var w = canvas.w, h = canvas.h - line(lex, last_point, point, erasing) - last_point[0] = point[0] - last_point[1] = point[1] - } - - function move_toroidal (e, lex, point) { - var w = canvas.w, h = canvas.h - var src_x_quantile = quantile( last_point[0], w ) - var src_y_quantile = quantile( last_point[1], h ) - var dst_x_quantile = quantile( point[0], w ) - var dst_y_quantile = quantile( point[1], h ) - var src_x_mod = mod( last_point[0], w ) - var src_y_mod = mod( last_point[1], h ) - var dst_x_mod = mod( point[0], w ) - var dst_y_mod = mod( point[1], h ) - // if we've moved across the edge of the board, draw two lines - if (src_x_quantile != dst_x_quantile || src_y_quantile != dst_y_quantile) { - var xa, ya - if (src_x_quantile < dst_x_quantile) { - xa = [ - [src_x_mod, dst_x_mod + w], - [src_x_mod-w, dst_x_mod], - ] - } - else if (src_x_quantile == dst_x_quantile) { - xa = [ - [src_x_mod, dst_x_mod], - [src_x_mod, dst_x_mod], - ] - } - else { - xa = [ - [src_x_mod, dst_x_mod-w], - [src_x_mod+w, dst_x_mod], - ] - } - - if (src_y_quantile < dst_y_quantile) { - ya = [ - [src_y_mod, dst_y_mod + h], - [src_y_mod-h, dst_y_mod], - ] - } - else if (src_y_quantile == dst_y_quantile) { - ya = [ - [src_y_mod, dst_y_mod], - [src_y_mod, dst_y_mod], - ] - } - else { - ya = [ - [src_y_mod, dst_y_mod-h], - [src_y_mod+h, dst_y_mod], - ] - } - line(lex, [ xa[0][0], ya[0][0] ], [ xa[0][1], ya[0][1] ], erasing) - line(lex, [ xa[1][0], ya[1][0] ], [ xa[1][1], ya[1][1] ], erasing) - } - else { - var x_a = mod( last_point[0], w ) - var y_a = mod( last_point[1], h ) - var x_b = mod( point[0], w ) - var y_b = mod( point[1], h ) - var last_point_mod = [x_b, y_b], point_mod = [x_a, y_a] - line(lex, last_point_mod, point_mod, erasing) - } - last_point[0] = point[0] - last_point[1] = point[1] - // y = point.y - } - - function point (lex, x, y, erasing) { - stamp (canvas, brush, x, y, erasing) - } - - function line (lex, a, b, erasing) { - var len = dist(a[0], a[1], b[0], b[1]) - var bw = 1 - var x, y, i; - for (var i = 0; i <= len; i += bw) { - x = lerp(i / len, a[0], b[0]) - y = lerp(i / len, a[1], b[1]) - stamp (canvas, brush, x, y, erasing) - } - } - - function stamp (canvas, brush, x, y, erasing) { - var hh = brush.w/2|0 - brush.forEach(function(lex, s, t){ - s = round( s + x-hh ) - t = round( t + y-hh ) - if (s >= 0 && s < canvas.w && t >= 0 && t < canvas.h) { - if (lex.opacity === 0 && lex.char === ' ') return; - var aa = canvas.aa[t][s] - undo.save_lex(s, t, aa) - if (erasing) { - aa.erase(lex) - } - else { - aa.stamp(lex, brush) - } - } - }) - } - - function fill (lex, x, y) { - var q = [ [x,y] ] - var aa = canvas.aa - var target = aa[y][x].clone() - var n, w = 0, e = 0, j = 0 - var kk = 0 - // gets into a weird infinite loop if we don't break here.. :\ - if (target.eq(lex)) { return } - LOOP: while (q.length) { - n = q.shift() - if (aa[n[1]][n[0]].ne(target)) { - continue LOOP - } - w = e = n[0] - j = n[1] - WEST: while (w > 0) { - if (aa[j][w-1].eq(target)) { - w = w-1 - } - else { - break WEST - } - } - EAST: while (e < canvas.w-1) { - if (aa[j][e+1].eq(target)) { - e = e+1 - } - else { - break EAST - } - } - for (var i = w; i <= e; i++) { - undo.save_lex(i, j, aa[j][i]) - aa[j][i].assign(lex) - if (j > 0 && aa[j-1][i].eq(target)) { - q.push([ i, j-1 ]) - } - if (j < canvas.h-1 && aa[j+1][i].eq(target)) { - q.push([ i, j+1 ]) - } - } - } - } - - var draw = {} - draw.down = down - draw.set_last_point = set_last_point - draw.move = move - draw.move_toroidal = move_toroidal - draw.stamp = stamp - draw.line = line - draw.point = point - draw.fill = fill - return draw - -})() - diff --git a/assets/js/lex.js b/assets/js/lex.js deleted file mode 100644 index f19580f..0000000 --- a/assets/js/lex.js +++ /dev/null @@ -1,148 +0,0 @@ -function Lex (x,y) { - if (typeof x == "number") { - this.y = y - this.x = x - this.span = document.createElement("span") - } - else { - this.span = x - } - this.fg = colors.white - this.bg = colors.black - this.char = " " - this.opacity = 1 - this.focused = false -} -Lex.prototype.build = function(){ - if (isNaN(this.bg) || this.bg == Infinity || this.bg == -Infinity) this.bg = colors.black - if (isNaN(this.fg) || this.fg == Infinity || this.fg == -Infinity) this.fg = colors.black - this.span.className = this.css() - this.span.innerHTML = this.html() -} -Lex.prototype.css = function(){ - return ( - this.focused ? - "focused " : "" - ) + ( - this.opacity === 0 ? - "transparent f" + color_alphabet[modi(this.fg,16)] : - "f" + color_alphabet[modi(this.fg,16)] + " b" + color_alphabet[modi(this.bg,16)] - ) -} -Lex.prototype.html = function(){ - return this.char == " " ? " " : this.char || " " -} -Lex.prototype.read = function(){ - this.char = this.span.innerHTML - return this.char -} -Lex.prototype.ascii = function(){ - return this.char || " " -} -Lex.prototype.sanitize = function(){ - switch (this.char) { -// case "%": return "%" - case undefined: - case "": return " " - default: return this.char - } -} -Lex.prototype.ansi = function(bg_, fg_){ - var char = this.char || " " - var charIsNaN = isNaN(parseInt(char)) - if ((bg_ == this.fg) && (fg_ == this.bg)) { - bg_ = this.bg; fg_ = this.fg - return [bg_, fg_, "\x1b[7m" + char] - } else if ((bg_ != this.bg) && (fg_ != this.fg)) { - bg_ = this.bg; fg_ = this.fg; - return [bg_, fg_, "\x1b[" + ansi_bg[bg_] + ";" + ansi_fg[fg_] + "m" + char] - } else if (bg_ != this.bg) { - bg_ = this.bg - return [bg_, fg_, "\x1b[" + ansi_bg[bg_] + "m" + char] - } else if (fg_ != this.fg) { - fg_ = this.fg - return [bg_, fg_, "\x1b[" + ansi_fg[fg_] + "m" + char] - } -} -Lex.prototype.mirc = function(bg_, fg_){ - var char = this.char || " " - var charIsNaN = isNaN(parseInt(char)) - if ((bg_ == this.fg) && (fg_ == this.bg)) { - bg_ = this.bg; fg_ = this.fg - return [bg_, fg_, "\x16" + char] - } else if ((bg_ == this.bg) && (fg_ != this.fg)) { - fg_ = this.fg - return [bg_, fg_, "\x03" + ((this.fg&15) < 10 && !charIsNaN ? "0" : "") + (this.fg&15) + char] - } else { - bg_ = this.bg; fg_ = this.fg - return [bg_, fg_, "\x03" + (this.fg&15) + "," + ((this.bg&15) < 10 && !charIsNaN ? "0" : "") + (this.bg&15) + char] - } -} -Lex.prototype.assign = function (lex){ - this.fg = lex.fg - this.bg = lex.bg - this.char = lex.char - this.opacity = lex.opacity - this.build() -} -Lex.prototype.stamp = function (lex, brush){ - if (brush.draw_fg) this.fg = lex.fg - if (brush.draw_bg && lex.opacity > 0) this.bg = lex.bg - if (brush.draw_char) this.char = lex.char - this.opacity = 1 - this.build() -} -Lex.prototype.clone = function () { - var lex = new Lex (0,0) - lex.assign(this) - return lex -} -Lex.prototype.erase = function (){ - this.fg = fillColor - this.bg = fillColor - this.char = " " - this.opacity = 1 - this.build() -} -Lex.prototype.eq = function(lex){ - return lex && this.fg == lex.fg && this.bg == lex.bg && this.char == lex.char -} -Lex.prototype.eqColor = function(lex){ - return lex && this.fg == lex.fg && this.bg == lex.bg -} -Lex.prototype.ne = function(lex){ - return ! this.eq(lex) -} -Lex.prototype.clear = function(){ - this.bg = colors.black - this.fg = 0 - this.char = " " - this.opacity = 0 - this.build() -} -Lex.prototype.isClear = function(){ - return this.bg == 1 && this.fg == 0 && this.char == " " -} -Lex.prototype.focus = function(){ - if (focused) focused.blur() - this.span.classList.add('focused') - this.focused = true - focused = this -} -Lex.prototype.blur = function(){ - focused = null - this.span && this.span.classList.remove('focused') - this.focused = false - this.onBlur && this.onBlur() -} -Lex.prototype.demolish = function(){ - if (this.span.parentNode) { this.span.parentNode.removeChild(this.span) } - this.span = null -} -Lex.prototype.key = function(char, keyCode) { - if (! char) { return } - this.char = char - this.fg = brush.fg - this.build() - return true -} diff --git a/assets/js/matrix.js b/assets/js/matrix.js deleted file mode 100644 index 1ecc101..0000000 --- a/assets/js/matrix.js +++ /dev/null @@ -1,515 +0,0 @@ -function Matrix (w,h,f){ - this.x = 0 - this.y = 0 - this.w = w - this.h = h - this.f = f - this.focus_x = 0 - this.focus_y = 0 - this.initialize() -} -Matrix.prototype.initialize = function(f){ - var w = this.w || 1, h = this.h || 1, f = f || this.f - var aa = new Array (h) - for (var y = 0; y < h; y++) { - aa[y] = new Array (w) - for (var x = 0; x < w; x++) { - aa[y][x] = f(x,y) - } - } - this.aa = aa -} -Matrix.prototype.rebuild = function (){ - this.demolish() - this.initialize() - this.append() - this.bind() - this.generate && this.generate() - this.focus_clamp() - check_if_lost_focus() -} -Matrix.prototype.clone = function () { - var base = this - var clone = new Matrix(this.w, this.h, function(x,y){ - return base.getCell(x,y).clone() - }) - clone.f = this.f - return clone -} -Matrix.prototype.assign = function (mat) { - var base = this - this.demolish() - this.w = mat.w - this.h = mat.h -// this.f = function(){} - this.initialize(function(x,y){ - var el = mat.getCell(x,y).clone() - el.build() - return el - }) - this.append() - this.bind() - check_if_lost_focus() - return this -} - -Matrix.prototype.bind = function () {} -Matrix.prototype.demolish = function (){ - this.forEach(function(lex){ - lex.demolish() - }) - while (this.wrapper && this.wrapper.firstChild) { - this.wrapper.removeChild(this.wrapper.firstChild); - } - this.aa.forEach(function(row){ - row.length = 0 - }) - this.aa.length = 0 -} -Matrix.prototype.forEach = function(f){ - this.aa.forEach(function(row, y){ - row.forEach(function(lex, x){ - f(lex, x, y) - }) - }) -} -Matrix.prototype.focus_clamp = function(){ - this.focus_x = clamp(this.focus_x, 0, this.w - 1) - this.focus_y = clamp(this.focus_y, 0, this.h - 1) -} -Matrix.prototype.focus_add = function(x, y){ - this.focus(this.focus_x + x, this.focus_y + y) -} -Matrix.prototype.focus = function(x, y){ - if (x === undefined) x = this.focus_x - if (y === undefined) y = this.focus_y - x = mod(x, this.w) - y = mod(y, this.h) - this.focus_x = x - this.focus_y = y - - //focused_input = this - this.aa[y][x].focus() -} -Matrix.prototype.focusLex = function(y,x){ - if (x < 0) { - y -= 1 - } - if (x > this.aa[0].length) { - y += 1 - } - this.aa[mod(y,this.h)][mod(x,this.w)].focus() -} -Matrix.prototype.clear = function(){ - this.forEach(function(lex,x,y){ lex.clear() }) -} -Matrix.prototype.erase = function(){ - this.forEach(function(lex,x,y){ lex.erase() }) -} -Matrix.prototype.fill = function(lex){ - this.fg = lex.fg - this.bg = lex.bg - this.char = lex.char - this.opacity = lex.opacity - this.forEach(function(el,x,y){ - el.assign(lex) - el.build() - }) -} - -Matrix.prototype.build = function(){ - this.forEach(function(lex,x,y){ - lex.build() - }) -} -Matrix.prototype.append = function(wrapper){ - wrapper = this.wrapper = wrapper || this.wrapper - if (! this.wrapper) return - this.aa.forEach(function(row, y){ - var div = document.createElement("div") - row.forEach(function(lex, x) { - div.appendChild(lex.span) - }) - wrapper.appendChild( div ) - }) -} -Matrix.prototype.region = function(w,h,x,y) { - w = w || 1 - h = h || 1 - x = x || 0 - y = y || 0 - var parent = this - var mat = new Matrix(w, h, function(x,y){ - return parent.aa[y][x] - }) - mat.f = this.f - return mat -} -Matrix.prototype.setCell = function(lex,x,y){ - this.aa[y] && this.aa[y][x] && this.aa[y][x].assign(lex) -} -Matrix.prototype.getCell = function(x,y){ - if (this.aa[y] && this.aa[y][x]) return this.aa[y][x] - else return null -} -Matrix.prototype.get = function(x,y){ - y = floor(mod(y || 0, this.h)) - x = floor(mod(x || 0, this.w)) - if (this.aa[y] && this.aa[y][x]) return this.aa[y][x] - else return null -} - -Matrix.prototype.resize = function(w,h){ - w = w || canvas.w - h = h || canvas.h - var div, row, lex - var f = this.f, old_h = this.aa.length, old_w = this.aa[0].length - var wrapper = this.wrapper - w = max(w, 1) - h = max(h, 1) - if (h < old_h) { - for (var y = old_h; y > h; y--) { - row = this.aa.pop() - div = row[0].span.parentNode - row.forEach(function(lex, x){ - lex.demolish() - }) - div.parentNode.removeChild(div) - } - } - else if (h > old_h) { - for (var y = old_h; y < h; y++) { - div = document.createElement("div") - wrapper.appendChild( div ) - this.aa[y] = new Array (w) - for (var x = 0; x < w; x++) { - lex = this.aa[y][x] = f(x,y) - div.appendChild(lex.span) - } - } - } - - if (w < old_w) { - this.aa.forEach(function(row, y){ - while (row.length > w) { - lex = row.pop() - lex.demolish() - } - }) - } - else if (w > old_w) { - this.aa.forEach(function(row, y){ - div = row[0].span.parentNode - for (var x = row.length; x < w; x++) { - lex = row[x] = f(x,y) - div.appendChild(lex.span) - } - }) - } - - this.w = w - this.h = h - this.bind && this.bind() - this.focus_clamp() - if (this.wrapper && this.wrapper.parentNode != document.body) { - this.resize_wrapper() - } -} -Matrix.prototype.resize_wrapper = function(){ - var cell = canvas.aa[0][0].span - var cw = cell.offsetWidth - var ch = cell.offsetHeight -// if (canvas.grid) { ch++ } - var width = cw * this.aa[0].length - var height = ch * this.aa.length - if (canvas.grid) { width++; height++ } - this.wrapper.parentNode.style.height = "" - this.wrapper.style.width = - this.wrapper.parentNode.style.width = (width) + "px" - this.wrapper.style.top = "" -} -Matrix.prototype.ascii = function () { - var lines = this.aa.map(function(row, y){ - var last, line = "" - row.forEach(function(lex, x) { - line += lex.ascii() - }) - return line // .replace(/\s+$/,"") - }) - var txt = lines.join("\n") - return txt -} -Matrix.prototype.ansi = function (opts) { - var lines = this.aa.map(function(row, y){ - var last, line = "", bg_ = -1, fg_ = -1 - row.forEach(function(lex, x) { - if (lex.eqColor(last)) { - line += lex.sanitize() - } - else { - [bg_, fg_, line_] = lex.ansi(bg_, fg_) - line += line_; last = lex; - } - }) - return line - }) - - var txt = lines.filter(function(line){ return line.length > 0 }).join('\n') - - return txt -} -Matrix.prototype.mirc = function (opts) { - var cutoff = false - var lines = this.aa.map(function(row, y){ - var last, line = "", bg_ = -1, fg_ = -1 - row.forEach(function(lex, x) { - if (lex.eqColor(last)) { - line += lex.sanitize() - } - else { - [bg_, fg_, line_] = lex.mirc(bg_, fg_) - line += line_; last = lex; - } - }) - if (opts && opts.cutoff && line.length > opts.cutoff) { - cutoff = true - } - return line - }) - - var txt = lines.filter(function(line){ return line.length > 0 }).join('\n') - - if (cutoff) { - txt = new String(txt) - txt.cutoff = true - } - return txt -} - -var undo = (function(){ - -var max_states = 200; - -// undotimetotal = 0; - -var stack = {undo: [], redo: []}; -var current_undo = null; -var dom = {undo: undo_el, redo: redo_el}; -dom.undo.is_visible = dom.redo.is_visible = false - -var LexState = function(lex){ - this.fg = lex.fg; - this.bg = lex.bg; - this.char = lex.char; - this.opacity = lex.opacity; -}; - -var update_dom_visibility = function(type){ - var el = dom[type] - if (el.is_visible){ - if (stack[type].length === 0) { - el.classList.add('hidden') - el.is_visible = false - } - } else if (stack[type].length > 0){ - el.classList.remove('hidden') - el.is_visible = true - } -} -var update_dom = function(){ - update_dom_visibility('undo') - update_dom_visibility('redo') -} - -// state is an undo or redo state that might contain these props -// { lexs: {'0,0': LexState, ...}, // for sparse lex changes (eg brush, fill) -// focus: {x:, y: }, -// size: {w:, h: }, -// rects: [{x:, y:, w:, h:, lexs: [LexState, ...]}, ...] -// } -var new_state = function(){ - var state = {lexs:{}}; - save_focus(canvas.focus_x, canvas.focus_y, state) - return state -} -var new_redo = function(){ - return new_state() -} -var new_undo = function(){ - current_undo = new_state() - stack.redo = [] - stack.undo.push(current_undo) - if (stack.undo.length > max_states) stack.undo.shift(); - update_dom() - return current_undo -} - -var save_focus = function(x, y, state){ - state = state || current_undo - state.focus = {x:x, y:y} -} -var save_size = function(w, h, state){ - state = state || current_undo - state.size = {w:w, h:h}; -} -// the reason for stringifying the x y coords is so that each -// coordinate is saved only once in an undo state. -// otherwise there would be problems with, eg, a brush stroke -// that passed over the same grid cell twice. -var save_lex = function(x, y, lex, state){ - // var start = Date.now() - state = state || current_undo - var lexs = state.lexs; - var xy = x + "," + y; - if (xy in lexs) return; - lexs[xy] = new LexState(lex) - // undotimetotal += Date.now() - start -} -var save_focused_lex = function(state){ - state = state || current_undo - var x = canvas.focus_x - var y = canvas.focus_y - save_lex(x, y, canvas.aa[y][x], state) -} -var save_rect = function(xpos, ypos, w, h, state){ - if (w === 0 || h === 0) return; - state = state || current_undo; - state.rects = state.rects || [] - var aa = canvas.aa; - var rect = {x: xpos, y: ypos, w: w, h: h, lexs: []} - var lexs = rect.lexs - var xlen = xpos + w - var ylen = ypos + h - for (var y = ypos; y < ylen; y++){ - var aay = aa[y] - for (var x = xpos; x < xlen; x++){ - lexs.push(new LexState(aay[x])) - } - } - state.rects.push(rect) -} -var save_resize = function(w, h, old_w, old_h, state){ - state = state || current_undo - save_size(old_w, old_h, state) - if (old_w > w){ - // .---XX - // | XX - // |___XX - save_rect(w, 0, old_w - w, old_h, state) - if (old_h > h){ - // .----. - // | | - // XXXX_| - save_rect(0, h, w, old_h - h, state) - } - } else if (old_h > h){ - // .----. - // | | - // XXXXXX - save_rect(0, h, old_w, old_h - h, state) - } -} - -var restore_state = function(state){ - // all redo states will have a cached undo state on them - // an undo state might have a cached redo state - // if it doesn't have one, generate one - var make_redo = ! ('redo' in state || 'undo' in state); - var aa = canvas.aa - var lex, lexs; - - if (make_redo){ - state.redo = new_redo() - - // copy saved rects that intersect with current canvas size - // important to do this before resizing canvas - if ('rects' in state){ - for (var ri=0, rect; rect=state.rects[ri]; ri++){ - if (rect.x >= canvas.w || - rect.y >= canvas.h) continue; - var w = Math.min(rect.w, canvas.w - rect.x) - var h = Math.min(rect.h, canvas.h - rect.y) - save_rect(rect.x, rect.y, w, h, state.redo) - } - } - if ('size' in state){ - save_resize(state.size.w, state.size.h, canvas.w, canvas.h, state.redo) - } - } - - if ('size' in state){ - canvas.resize(state.size.w, state.size.h, true); - } - - if ('rects' in state){ - for (var ri=0, rect; rect=state.rects[ri]; ri++){ - lexs = rect.lexs - for (var li=0; lex=lexs[li]; li++){ - var x = (li % rect.w) + rect.x - var y = ((li / rect.w)|0) + rect.y - aa[y][x].assign(lex) - } - } - } - - lexs = state.lexs - for (var key in lexs){ - var xy = key.split(','); - lex = aa[xy[1]][xy[0]] - if (make_redo) - save_lex(xy[0], xy[1], lex, state.redo) - lex.assign(lexs[key]) - } - - if ('focus' in state){ - canvas.focus_x = state.focus.x - canvas.focus_y = state.focus.y - if (current_canvas === canvas){ - canvas.focus() - } - } -} - -var undo = function(){ - var state = stack.undo.pop(); - if (!state) return; - - restore_state(state) - - // now take the applied undo state and store it on the redo state - // and push the redo state to the redo stack - state.redo.undo = state - stack.redo.push(state.redo) - delete state.redo - - update_dom() -} - -var redo = function(){ - var state = stack.redo.pop(); - if (!state) return; - - restore_state(state) - - state.undo.redo = state - stack.undo.push(state.undo) - delete state.undo - - update_dom() -} - -return { - stack: stack, - new: new_undo, -// new_redo: new_redo, - save_focus: save_focus, - save_size: save_size, - save_lex: save_lex, - save_focused_lex: save_focused_lex, - save_rect: save_rect, - save_resize: save_resize, - undo: undo, - redo: redo -} - -})() diff --git a/assets/js/ui/brush.js b/assets/js/ui/brush.js deleted file mode 100644 index 285bc82..0000000 --- a/assets/js/ui/brush.js +++ /dev/null @@ -1,138 +0,0 @@ -var brush = (function(){ - - var brush = new Matrix (5, 5, function(x,y){ - var lex = new Lex (x,y) - lex.build() - return lex - }) - - brush.modified = false - - brush.mask = blit.circle - - brush.generate = function(){ - brush.fill(brush) - brush.mask(brush) - } - - brush.bind = function(){ - - var last_point = [0,0] - var dragging = false - var erasing = false - - brush.forEach(function(lex, x, y){ - - if (lex.bound) return - lex.bound = true - - var point = [x,y] - lex.span.addEventListener('contextmenu', function(e){ - e.preventDefault() - }) - lex.span.addEventListener('mousedown', function(e){ - e.preventDefault() - current_canvas = brush - brush.modified = true - dragging = true - erasing = (e.which == "3" || e.ctrlKey) - if (erasing) { - lex.clear() - } - else { - fillColor = brush.bg - lex.assign(brush) - } - brush.focus(x, y) - }) - lex.span.addEventListener('mousemove', function(e){ - e.preventDefault() - if (! dragging) { - return - } - erasing = (e.which == "3" || e.ctrlKey) - if (erasing) { - lex.clear() - } - else { - lex.assign(brush) - } - brush.focus(x, y) - }) - }) - window.addEventListener('mouseup', function(e){ - dragging = erasing = false - }) - } - - brush.resize = function(w, h){ - w = this.w = clamp(w, this.min, this.max) - h = this.h = clamp(h, this.min, this.max) - brush.rebuild() - controls.brush_w.char = "" + w - controls.brush_w.build() - controls.brush_h.char = "" + h - controls.brush_h.build() - } - brush.size_add = function(w, h){ - brush.resize(brush.w + w, brush.h + h) - } - brush.expand = function(i){ - brush.size_add(i, i) - } - brush.contract = function(i){ - brush.size_add(-i, -i) - } - - brush.load = function(lex){ - brush.char = lex.char - brush.fg = lex.fg - brush.bg = lex.bg - brush.opacity = 1 - } - - brush.min = 1 - brush.max = 100 - - brush.char = " " - brush.fg = 0 - brush.bg = 1 - brush.opacity = 1 - - brush.draw_fg = true - brush.draw_bg = true - brush.draw_char = true - - return brush - -})() - -var custom = (function(){ - - var exports = {} - - exports.clone = function (){ - var new_brush = brush.clone() - var wrapper = document.createElement("div") - wrapper.className = "custom" - new_brush.append(wrapper) - custom_wrapper.appendChild(wrapper) - // store in localstorage? - wrapper.addEventListener("click", function(e){ - if (e.shiftKey) { - wrapper.parentNode.removeChild(wrapper) - delete new_brush - } else { - // load this brush - exports.load(new_brush) - } - }) - } - - exports.load = function(new_brush){ - brush.assign( new_brush ) - } - - return exports - -})() diff --git a/assets/js/ui/canvas.js b/assets/js/ui/canvas.js deleted file mode 100644 index 739a083..0000000 --- a/assets/js/ui/canvas.js +++ /dev/null @@ -1,102 +0,0 @@ -var canvas = current_canvas = (function(){ - - var cols = 100 - var rows = 30 - - var canvas = new Matrix (cols, rows, function(x,y){ - var lex = new Lex (x,y) - lex.build() - return lex - }) - - canvas.bind = function(){ - - canvas.forEach(function(lex, x, y){ - - if (lex.bound) return - lex.bound = true - var point = [x,y] - lex.span.addEventListener('contextmenu', function(e){ - e.preventDefault() - }) - lex.span.addEventListener('mousedown', function(e){ - e.preventDefault() - dragging = true - current_canvas = canvas - if (e.altKey) { - if (e.shiftKey) { - blit.copy_from(canvas, brush, floor(x-brush.w/2), floor(y-brush.h/2)) - brush.mask(brush) - draw.set_last_point(e, point) - } - else { - brush.load(lex) - brush.generate() - dragging = false - } - return - } - else if (drawing) { - undo.new() - draw.down(e, lex, point) - } - else if (selecting) { - selection.down(e, lex, point) - } - else if (transforming) { - transform.down(e, lex, point) - } - else if (filling) { - undo.new() - draw.fill(brush, x, y) - } - canvas.focus(x, y) - }) - - lex.span.addEventListener("mousemove", function(e){ - mouse.x = x - mouse.y = y - if (! dragging) return - if (drawing) { - draw.move(e, lex, point) - } - else if (selecting) { - selection.move(e, lex, point) - } - else if (transforming) { - transform.move(e, lex, point) - } - canvas.focus(x, y) - }) - - }) - } - - canvas.min = 1 - canvas.max = 999 - - // canvas.resize(1, 1, true) // wont create undo state - canvas.resize = function(w, h, no_undo){ - var old_w = this.w, old_h = this.h - w = this.w = clamp(w, this.min, this.max) - h = this.h = clamp(h, this.min, this.max) - if (old_w === w && old_h === h) return; - - if (!no_undo){ - undo.new() - undo.save_resize(w, h, old_w, old_h) - } - - canvas.__proto__.resize.call(canvas, w, h) - controls.canvas_w.char = "" + w - controls.canvas_w.build() - controls.canvas_h.char = "" + h - controls.canvas_h.build() - } - canvas.size_add = function(w, h){ - canvas.resize(canvas.w + w, canvas.h + h) - } - - return canvas - -})() diff --git a/assets/js/ui/controls.js b/assets/js/ui/controls.js deleted file mode 100644 index 5ff5ab8..0000000 --- a/assets/js/ui/controls.js +++ /dev/null @@ -1,259 +0,0 @@ -var controls = (function(){ - - var controls = {} - - controls.cross = new Tool (cross_el) - controls.cross.use = function(){ - if (brush.mask == blit.cross) { - controls.cross.el.innerHTML = "ssoɹɔ" - brush.mask = blit.inverted_cross - } - else { - controls.cross.el.innerHTML = "cross" - brush.mask = blit.cross - } - brush.generate() - drawing = true - brush.modified = false - } - controls.cross.done = function(){ - controls.cross.el.innerHTML = "cross" - drawing = false - } - - controls.circle = new Tool (circle_el) - controls.circle.use = function(){ - brush.mask = blit.circle - brush.generate() - drawing = true - brush.modified = false - } - controls.circle.done = function(){ - drawing = false - } - - controls.square = new Tool (square_el) - controls.square.use = function(){ - brush.mask = blit.square - brush.generate() - brush.modified = false - drawing = true - } - controls.square.done = function(){ - drawing = false - } - - controls.text = new Tool (text_el) - controls.text.use = function(){ - current_filetool && current_filetool.blur() - } - - controls.select = new Tool (select_el) - controls.select.use = function(){ - selection.show() - } - controls.select.done = function(){ - selection.hide() - } - - controls.rotate = new Tool (rotate_el) - controls.rotate.use = function(){ - transform.set_mode('rotate') - } - controls.rotate.done = function(){ - transform.done() - } - - controls.scale = new Tool (scale_el) - controls.scale.use = function(){ - transform.set_mode('scale') - } - controls.scale.done = function(){ - transform.done() - } - - controls.slice = new Tool (slice_el) - controls.slice.use = function(){ - transform.set_mode('slice') - } - controls.slice.done = function(){ - transform.done() - } - - controls.translate = new Tool (translate_el) - controls.translate.use = function(){ - transform.set_mode('translate') - } - controls.translate.done = function(){ - transform.done() - } - - controls.fill = new Tool (fill_el) - controls.fill.use = function(){ - filling = true - document.body.classList.add("bucket") - } - controls.fill.done = function(){ - filling = false - document.body.classList.remove("bucket") - } - - controls.undo = new BlurredTool (undo_el) - controls.undo.use = function(){ - undo.undo() - } - - controls.redo = new BlurredTool (redo_el) - controls.redo.use = function(){ - undo.redo() - } - - controls.clear = new BlurredTool (clear_el) - controls.clear.use = function(){ - undo.new() - undo.save_rect(0, 0, canvas.w, canvas.h) - canvas.erase() - current_filetool && current_filetool.blur() - } - - controls.grid = new BlurredCheckbox (grid_el) - controls.grid.memorable = true - controls.grid.use = function(state){ - state = typeof state == "boolean" ? state : ! document.body.classList.contains("grid") - document.body.classList[ state ? "add" : "remove" ]('grid') - letters.grid = palette.grid = canvas.grid = state - canvas.resize_wrapper() - palette.resize_wrapper() - letters.resize_wrapper() - if (! selection.hidden) selection.reposition() - this.update( state ) - } - ClipboardTool = FileTool.extend({ - blur: function(){ - this.__blur() - clipboard.export_hide() - clipboard.import_hide() - } - }) - controls.save = new ClipboardTool (save_el) - controls.save.use = function(){ - clipboard.export_show() - clipboard.export_mode() - } - controls.load = new ClipboardTool (load_el) - controls.load.use = function(){ - clipboard.import_show() - clipboard.import_mode() - } - - controls.load_format = new RadioGroup(import_format_el) - controls.load_format.name = 'load_format' - controls.load_format.memorable = true - var cs = controls.load_format.controls - // - - controls.save_format = new RadioGroup(export_format_el) - controls.save_format.name = 'save_format' - controls.save_format.memorable = true - var cs = controls.save_format.controls - cs.mirc.use = cs.ansi.use = cs.ascii.use = function(){ - clipboard.export_data() - } - // - - controls.experimental_palette = new HiddenCheckbox (experimental_palette_toggle) - controls.experimental_palette.memorable = true - controls.experimental_palette.use = function(state){ - var state = palette.experimental(state) - this.update(state) - } - - // - - controls.fg = new BlurredCheckbox (fg_checkbox) - controls.fg.use = function(state){ - brush.draw_fg = state || ! brush.draw_fg - this.update(brush.draw_fg) - } - - controls.bg = new BlurredCheckbox (bg_checkbox) - controls.bg.use = function(state){ - brush.draw_bg = state || ! brush.draw_bg - this.update(brush.draw_bg) - } - - controls.char = new BlurredCheckbox (char_checkbox) - controls.char.use = function(state){ - brush.draw_char = state || ! brush.draw_char - this.update(brush.draw_char) - } - - controls.vertical = new BlurredCheckbox (vertical_checkbox) - controls.vertical.memorable = true - controls.vertical.use = function(state){ - canvas.vertical = typeof state == "boolean" ? state : ! canvas.vertical - controls.vertical.refresh() - } - controls.vertical.refresh = function(){ - if (canvas.vertical) { - document.body.classList.add("vertical") - } - else { - document.body.classList.remove("vertical") - } - palette.repaint() - letters.repaint() - this.update(canvas.vertical) - } - - // - - controls.brush_w = new Lex (brush_w_el) - controls.brush_h = new Lex (brush_h_el) - controls.canvas_w = new Lex (canvas_w_el) - controls.canvas_h = new Lex (canvas_h_el) - - // bind - - controls.bind = function(){ - - for (var n in controls){ - var control = controls[n] - if (typeof control === 'object' && 'bind' in control){ - control.bind() - } - } - - [ - controls.brush_w, - controls.brush_h, - controls.canvas_w, - controls.canvas_h - ].forEach(function(lex){ - lex.span.addEventListener('mousedown', function(e){ - lex.focus() - }) - }); - - controls.brush_w.key = keys.single_numeral_key(controls.brush_w, function(w){ brush.resize(w, brush.h) }) - controls.brush_w.raw_key = keys.arrow_key(function(w){ brush.size_add(w, 0) }) - - controls.brush_h.key = keys.single_numeral_key(controls.brush_h, function(h){ brush.resize(brush.w, h) }) - controls.brush_h.raw_key = keys.arrow_key(function(h){ brush.size_add(0, h) }) - - controls.canvas_w.key = keys.multi_numeral_key(controls.canvas_w, 3) - controls.canvas_w.onBlur = keys.multi_numeral_blur(controls.canvas_w, function(w){ canvas.resize(w, canvas.h) }) - controls.canvas_w.raw_key = keys.arrow_key(function(w){ canvas.size_add(w, 0) }) - - controls.canvas_h.key = keys.multi_numeral_key(controls.canvas_h, 3) - controls.canvas_h.onBlur = keys.multi_numeral_blur(controls.canvas_h, function(h){ canvas.resize(canvas.w, h) }) - controls.canvas_h.raw_key = keys.arrow_key(function(h){ canvas.size_add(0, h) }) - - add_custom_el.addEventListener("click", function(){ - custom.clone() - }) - - } - - return controls -})() diff --git a/assets/js/ui/keys.js b/assets/js/ui/keys.js deleted file mode 100644 index fc7ea3c..0000000 --- a/assets/js/ui/keys.js +++ /dev/null @@ -1,209 +0,0 @@ -var keys = (function(){ - - var keys = {} - keys.bind = function(){ - cursor_input.addEventListener('keydown', function(e){ - - // console.log("keycode:", e.keyCode) - if (e.altKey) { - document.body.classList.add("dropper") - } - - switch (e.keyCode) { - case 27: // esc - if (!selection.hidden && current_canvas === canvas){ - selection.hide() - selection.show() - } else if (focused){ - focused.blur() - } - return - } - - if (window.focused && focused.raw_key) { - focused.raw_key(e) - return - } - - switch (e.keyCode) { - case 219: // [ - if (current_tool.name != "text") { - e.preventDefault() - brush.contract(1) - brush.modified = false - check_if_lost_focus() - } - break - case 221: // ] - if (current_tool.name != "text") { - e.preventDefault() - brush.expand(1) - brush.modified = false - } - break - case 8: // backspace - e.preventDefault() - if (current_canvas === canvas) - undo.new() - current_canvas.focus_add(-1, 0) - if (current_canvas === canvas) - undo.save_focused_lex() - focused.char = " " - focused.build() - return - case 13: // return - e.preventDefault() - current_canvas.focusLex(focused.y, focused.x+1) - return - case 38: // up - e.preventDefault() - current_canvas.focus_add(0, -1) - break - case 40: // down - e.preventDefault() - current_canvas.focus_add(0, 1) - break - case 37: // left - e.preventDefault() - current_canvas.focus_add(-1, 0) - break - case 39: // right - e.preventDefault() - current_canvas.focus_add(1, 0) - break - // use typical windows and os x shortcuts - // undo: ctrl-z or cmd-z - // redo: ctrl-y or shift-cmd-z - case 89: // y - if (!e.ctrlKey && !e.metaKey) break; - e.preventDefault(); - undo.redo(); - break - case 90: // z - if (!e.ctrlKey && !e.metaKey) break; - e.preventDefault(); - if (e.shiftKey) - undo.redo(); - else - undo.undo(); - break - // default: - // if (focused) { focused.key(undefined, e.keyCode) } - } - }) - - cursor_input.addEventListener('input', function(e){ - /* - if (! e.metaKey && ! e.ctrlKey && ! e.altKey) { - e.preventDefault() - } - */ - var char = cursor_input.value - cursor_input.value = "" - - // console.log("input:", char) - - if (current_tool.name != "text" && ! brush.modified) { - brush.char = char - if (char == " ") { - brush.bg = brush.fg - } - else if (brush.bg != fillColor) { - brush.fg = brush.bg - brush.bg = fillColor - } - brush.rebuild() - } - - if (focused && char) { - var y = focused.y, x = focused.x - if (current_canvas === canvas){ - undo.new() - undo.save_focused_lex() - } - var moving = focused.key(char, e.keyCode) - if ( ! moving || ! ('y' in focused && 'x' in focused) ) { return } - current_canvas.focus_add(1, 0) - } - }) - - cursor_input.addEventListener("keyup", function(e){ - if (! e.altKey) { - document.body.classList.remove("dropper") - } - }) - } - - keys.int_key = function (f) { - return function (key, keyCode) { - var n = parseInt(key) - ! isNaN(n) && f(n) - } - } - - keys.arrow_key = function (fn) { - return function (e){ - switch (e.keyCode) { - case 38: // up - e.preventDefault() - fn(1) - break - case 40: // down - e.preventDefault() - fn(-1) - break - } - } - } - keys.left_right_key = function (fn) { - return function (e){ - switch (e.keyCode) { - case 39: // right - e.preventDefault() - fn(1) - break - case 38: // up - case 40: // down - e.preventDefault() - fn(0) - break - case 37: // left - e.preventDefault() - fn(-1) - break - } - } - } - - keys.single_numeral_key = function (lex, fn) { - return keys.int_key(function(n, keyCode){ - if (n == 0) n = 10 - lex.blur() - fn(n) - }) - } - keys.multi_numeral_key = function (lex, digits){ - return keys.int_key(function(n, keyCode){ - lex.read() - if (lex.char.length < digits) { - n = parseInt(lex.char) * 10 + n - } - lex.char = ""+n - lex.build() - }) - } - keys.multi_numeral_blur = function (lex, fn){ - return function(){ - var n = parseInt(lex.char) - if (isNaN(n)) return - fn(n) - } - } - - return keys -})() - -function check_if_lost_focus() { - if (! window.focused || ! window.focused.span) - window.focused = canvas.aa[0][0] -} diff --git a/assets/js/ui/paletters.js b/assets/js/ui/paletters.js deleted file mode 100644 index 26bac3a..0000000 --- a/assets/js/ui/paletters.js +++ /dev/null @@ -1,206 +0,0 @@ -var letters = (function(){ - - var last_charset = "" - var charset_index = 0 - var charsets = [ - 'Basic Latin', - 'Latin-1 Supplement', - 'Box Drawing', - 'Block Elements', - ] - - var letters = new Matrix (1, 1, function(x,y){ - var lex = new Lex (x,y) - return lex - }) - - letters.charset = "" - - letters.repaint = function(charset){ - letters.charset = charset = charset || last_charset - last_charset = charset - var chars = unicode.block(charset, 32) - if (chars[0] != " ") chars.unshift(" ") - if (canvas.vertical) { - letters.resize( Math.ceil( chars.length / 16 ), 16 ) - } - else { - letters.resize( 32, Math.ceil( chars.length / 32 ) ) - } - - var i = 0 - - letters.forEach(function(lex,x,y){ - if (canvas.vertical) { x=x^y;y=x^y;x=x^y } - var char = chars[i++] - if (palette.chars.indexOf(brush.char) > 1) { - lex.bg = brush.fg - lex.fg = brush.bg - } - else { - lex.bg = colors.black - lex.fg = brush.fg == fillColor ? colors.black : brush.fg - } - lex.char = char - lex.opacity = 1 - lex.build() - }) - } - - letters.bind = function(){ - letters.forEach(function(lex,x,y){ - if (lex.bound) return - lex.bound = true - - lex.span.addEventListener('mousedown', function(e){ - e.preventDefault() - if (e.shiftKey) { - charset_index = (charset_index+1) % charsets.length - letters.repaint(charsets[charset_index]) - return - } - else if (e.ctrlKey || e.which == 3) { - brush.char = lex.char - brush.bg = brush.fg - brush.fg = fillColor - } - else { - brush.char = lex.char - if (lex.char == " ") { - brush.bg = brush.fg - } - else if (brush.bg != fillColor) { - brush.fg = brush.bg - brush.bg = fillColor - } - } - if (! brush.modified) { - brush.generate() - } - palette.repaint() - }) - lex.span.addEventListener('contextmenu', function(e){ - e.preventDefault() - }) - }) - } - - return letters -})() - -var palette = (function(){ - - var palette = new Matrix (32, 2, function(x,y){ - var lex = new Lex (x,y) - return lex - }) - - var palette_index = localStorage.getItem("ascii.palette") || 1 - var palette_list = [all_hue, all_inv_hue, mirc_color, mirc_color_reverse] - var palette_fn = palette_list[palette_index] - var dither = { - aa: '▓▒░ ', - a: '▓', - b: '▒', - c: '░', - d: ' ', - p: function(n){ - return dither.aa[Math.floor(Math.abs(n) % 4)] - } - } - palette.chars = " " + dither.a + dither.b + dither.c - - palette.repaint = function(){ - var xw = use_experimental_palette ? 5 : 2 - if (canvas.vertical) { - palette.resize( xw, 16 ) - } - else { - palette.resize( 32, xw ) - } - - palette.forEach(function(lex,x,y){ - if (canvas.vertical) { x=x^y;y=x^y;x=x^y;x*=2 } - if (y < 2) { - lex.bg = palette_fn(x>>1) - lex.fg = palette_fn(x>>1) - } - else { - lex.bg = fillColor - lex.fg = palette_fn(x>>1) - } - lex.char = palette.chars[y] - lex.opacity = 1 - lex.build() - if (lex.char == "_") lex.char = " " - }) - } - palette.repaint() - var use_experimental_palette = false - palette.experimental = function(state){ - use_experimental_palette = typeof state == "boolean" ? state : ! use_experimental_palette - use_experimental_palette ? palette.resize(32, 5) : palette.resize(32, 2) - palette.repaint() - return use_experimental_palette - } - - palette.bind = function(){ - palette.forEach(function(lex, x, y){ - if (lex.bound) return - lex.bound = true - - lex.span.addEventListener('mousedown', function(e){ - e.preventDefault() - if (e.shiftKey) { - palette_index = (palette_index+1) % palette_list.length - localStorage.setItem("ascii.palette", palette_index) - palette_fn = palette_list[palette_index] - palette.repaint() - return - } - if (e.ctrlKey || e.which == 3) return - if (brush.char == " " && lex.char == " ") { - brush.fg = lex.fg - brush.bg = lex.bg - brush.char = lex.char - } - else if (lex.char != " ") { - brush.fg = lex.bg - brush.bg = lex.fg - brush.char = lex.char - } - else { - brush.fg = lex.bg - brush.bg = fillColor -// brush.char = lex.char - } - brush.opacity = lex.opacity - if (! brush.modified) { - brush.generate() - } - if (filling || e.ctrlKey) { - fillColor = lex.bg - } - letters.repaint() - }) - - lex.span.addEventListener('contextmenu', function(e){ - e.preventDefault() - fillColor = y ? lex.fg : lex.bg - palette.repaint() - brush.fg = lex.fg - brush.char = lex.char - brush.opacity = lex.opacity - brush.generate() - brush_wrapper.style.borderColor = css_reverse_lookup[fillColor] - return - }) - - }) - } - - brush_wrapper.style.borderColor = css_reverse_lookup[fillColor] - - return palette - -})() diff --git a/assets/js/ui/selection.js b/assets/js/ui/selection.js deleted file mode 100644 index 09e2194..0000000 --- a/assets/js/ui/selection.js +++ /dev/null @@ -1,159 +0,0 @@ -var selection = (function(){ - - var creating = false, moving = false, copying = false - - var selection_canvas = new Matrix (1, 1, function(x,y){ - var lex = new Lex (x,y) - lex.build() - return lex - }) - - var selector_el = document.createElement("div") - selector_el.className = "selector_el" - selection_canvas.append(selector_el) - document.body.appendChild(selector_el) - - // in selection mode.. - // - we start by clicking the canvas. this positions the selection, and copies - // the character - // - then we drag down and to the right. this resizes the selection and pushes new - // rows and columns. each of these copies the character underneath. - // - on mouseup, the selection is locked. then.. - // - drag the selection to move it -- this "cuts" it and leaves a blank space on the canvas. - // - shift-drag the selection to copy it - - var a = [0, 0] - var b = [0, 0] - var c = [0, 0] - var d = [0, 0] - - function reset () { - a[0] = a[1] = b[0] = b[1] = 0 - } - function left (a,b) { return min(a[0],b[0]) } - function top (a,b) { return min(a[1],b[1]) } - function right (a,b) { return max(a[0],b[0]) } - function bottom (a,b) { return max(a[1],b[1]) } - function width (a,b) { return abs(a[0]-b[0])+1 } - function height (a,b) { return abs(a[1]-b[1])+1 } - function mag_x (a,b) { return a[0]-b[0] } - function mag_y (a,b) { return a[1]-b[1] } - function orient (a,b) { - var l = left(a,b), m = top(a,b), n = right(a,b), o = bottom(a,b) - a[0] = l ; a[1] = m ; b[0] = n ; b[1] = o - } - - function contains (a,b,point) { - var contains_x = a[0] <= point[0] && point[0] <= b[0] - var contains_y = a[1] <= point[1] && point[1] <= b[1] - return (contains_x && contains_y) - } - function reposition (aa, bb) { - aa = aa || a - bb = bb || b - var cell = canvas.aa[top(aa, bb)][left(aa, bb)].span - var cell_left = cell.offsetLeft - var cell_top = cell.offsetTop - var cell_width = cell.offsetWidth - var cell_height = cell.offsetHeight - - var w = width(aa, bb) - var h = height(aa, bb) - - selector_el.style.top = (cell_top-1) + "px" - selector_el.style.left = (cell_left-1) + "px" - selector_el.style.width = (cell_width*w+1) + "px" - selector_el.style.height = (cell_height*h+1) + "px" - } - function down (e, lex, point){ - if ( ! contains(a,b,point) ) { - copying = false - moving = false - creating = true - a[0] = point[0] - a[1] = point[1] - b[0] = point[0] - b[1] = point[1] - reposition(a,b) - selection.hidden = false - selector_el.classList.add("creating") - } else { - copying = false - moving = true - creating = false - c[0] = point[0] - c[1] = point[1] - d[0] = point[0] - d[1] = point[1] - } - show() - selector_el.classList.remove("dragging") - } - function move (e, lex, point){ - if (creating) { - b[0] = point[0] - b[1] = point[1] - reposition(a,b) - } - else if (moving) { - d[0] = point[0] - d[1] = point[1] - var dx = - clamp( mag_x(c,d), b[0] - canvas.w + 1, a[0] ) - var dy = - clamp( mag_y(c,d), b[1] - canvas.h + 1, a[1] ) - reposition( [ a[0] + dx, a[1] + dy ], [ b[0] + dx, b[1] + dy ]) - } - else if (copying) { - } - } - function up (e) { - if (creating) { - orient(a,b) - selection_canvas.resize(width(a,b), height(a,b)) - reposition(a,b) - blit.copy_from( canvas, selection_canvas, a[0], a[1] ) - selection_canvas.build() - selector_el.classList.remove("creating") - } - if (moving) { - var dx = - clamp( mag_x(c,d), b[0] - canvas.w + 1, a[0] ) - var dy = - clamp( mag_y(c,d), b[1] - canvas.h + 1, a[1] ) - a[0] += dx - a[1] += dy - b[0] += dx - b[1] += dy - undo.new() - undo.save_rect(a[0], a[1], b[0] - a[0] + 1, b[1] - a[1] + 1) - blit.copy_to( canvas, selection_canvas, a[0], a[1] ) - } - if (copying) { - } - creating = moving = copying = false - selector_el.classList.remove("dragging") - } - - function show () { - selecting = true - } - function hide () { - reset() - selector_el.style.top = "-9999px" - selector_el.style.left = "-9999px" - selector_el.style.width = "0px" - selector_el.style.height = "0px" - creating = moving = copying = false - selection.hidden = true - selecting = false - } - - var selection = {} - selection.reposition = reposition - selection.down = down - selection.move = move - selection.up = up - selection.canvas = selection_canvas - selection.show = show - selection.hide = hide - selection.hidden = true - return selection - -})() diff --git a/assets/js/ui/tool.js b/assets/js/ui/tool.js deleted file mode 100644 index e941127..0000000 --- a/assets/js/ui/tool.js +++ /dev/null @@ -1,170 +0,0 @@ -var Tool = Model({ - init: function (el) { - this.el = el - this.lex = new Lex (el) - this.name = el.innerHTML - }, - bind: function(){ - var tool = this - tool.el.addEventListener('mousedown', function(e){ - tool.focus() - }) - tool.el.addEventListener('contextmenu', function(e){ - tool.context(e) - }) - if (tool.memorable) { - // console.log(tool.name, localStorage.getItem("ascii.tools." + tool.name) ) - tool.use( localStorage.getItem("ascii.tools." + tool.name) == "true" ) - } - }, - use: function(){}, - context: function(e){}, - done: function(){}, - focus: function(){ - // focused && focused.blur() - current_tool && current_tool.blur() - current_tool = this - this.el.classList.add('focused') - this.use() - cursor_input.focus() - }, - blur: function(){ - current_tool = null - this.el.classList.remove('focused') - this.done() - } -}) - -var FileTool = Tool.extend({ - focus: function(){ - if (current_filetool === this) { - this.blur() - return - } - current_filetool && current_filetool.blur() - current_filetool = this - this.el.classList.add('focused') - this.use() - cursor_input.focus() - }, - blur: function(){ - current_filetool = null - this.el.classList.remove('focused') - this.done() - } -}) - -var RadioItem = Tool.extend({ - init: function(group, el){ - this.group = group - this.el = el - }, - focus: function(){ - this.el.classList.add('focused') - }, - blur: function(){ - this.el.classList.remove('focused') - }, - bind: function(){ - var control = this - this.el.addEventListener('mousedown', function(){ - control.group.use(control) - }) - } -}) - -var RadioGroup = Tool.extend({ - init: function(el){ - this.el = el - this.controls = {} - var names = el.innerHTML.split(' ') - el.innerHTML = '' - var group = this - names.forEach(function(value){ - var el = document.createElement('span') - el.classList.add('radio','tool') - var control = new RadioItem(group, el) - if (value.substr(0,1) === '*') { - control.value = value = value.substr(1) - group.use(control) - } - control.value = el.innerHTML = value - group.controls[value] = control - group.el.appendChild(el) - }) - }, - use: function(control){ - if (typeof control === 'string') { - control = this.controls[control] - } - this.selected_control && this.selected_control.blur() - this.value = control.value - this.selected_control = control - control.focus() - control.use() - if (this.memorable){ - localStorage.setItem("ascii.tools." + this.name, this.value) - } - }, - bind: function(){ - var tool = this - for (var n in this.controls){ - this.controls[n].bind() - } - if (tool.memorable) { - var value = localStorage.getItem("ascii.tools." + tool.name) - if (value) tool.use(value) - } - } -}) - -var Checkbox = Tool.extend({ - init: function (el){ - this.__init(el) - var name = this.name.replace(/^[x_] /,"") - var state = localStorage.getItem("ascii.tools." + name) == "true" || this.name[0] == "x" - this.name = name - this.update(state) - }, - update: function(state){ - if (state) this.el.innerHTML = "x " + this.name - else this.el.innerHTML = "_ " + this.name - if (this.memorable) { localStorage.setItem("ascii.tools." + this.name, !! state) } - } -}) - -var BlurredCheckbox = Checkbox.extend({ - focus: function(){ - this.use() - }, - blur: function(){ - this.el.classList.remove('focused') - this.done() - } -}) - -var BlurredTool = Tool.extend({ - focus: function(){ - this.use() - }, - blur: function(){ - this.el.classList.remove('focused') - this.done() - } -}) - -var HiddenCheckbox = BlurredCheckbox.extend({ - on: "o", - off: ".", - init: function (el){ - this.el = el - this.lex = new Lex (el) - this.name = this.el.id - var state = localStorage.getItem("ascii.tools." + name) == "true" || this.el.innerHTML[0] == this.on - this.update(state) - }, - update: function(state){ - this.el.innerHTML = state ? this.on : this.off - if (this.memorable) { localStorage.setItem("ascii.tools." + this.name, !! state) } - } -}) diff --git a/assets/js/ui/transform.js b/assets/js/ui/transform.js deleted file mode 100644 index dd4fe62..0000000 --- a/assets/js/ui/transform.js +++ /dev/null @@ -1,176 +0,0 @@ -var transform = (function(){ - - var p = [0,0], q = [0,0] - var mode - var copy - - function down (e, lex, point){ - p[0] = point[0] - p[1] = point[1] - q[0] = e.pageX - q[1] = e.pageY - undo.new() - undo.save_rect(0, 0, canvas.w, canvas.h) - copy = canvas.clone() - mode.init(e) - } - function move (e, lex, point){ - var pdx = point[0] - p[0] - var pdy = point[1] - p[1] - var dx = e.pageX - q[0] - var dy = e.pageY - q[1] - var w = canvas.w - var h = canvas.h - mode.before(dx, dy, pdx, pdy, point) - for (var x = 0; x < w; x++) { - for (var y = 0; y < h; y++) { - lex = canvas.get(x, y) - if (! mode.shade( copy, canvas, lex, x, y, w, h )) { - lex.build() - } - } - } - } - function up (e){ - } - - var modes = { - - rotate: { - init: function(e){ - mode.theta = 0 - }, - before: function(dx, dy){ - var radius = dist(0, 0, dx, dy) - if (radius < 10) return - mode.theta = angle(0, 0, dx, -dy) - }, - shade: function(src, dest, lex, x, y, w, h){ - x = (x/w) * 2 - 1 - y = (y/h) * 2 - 1 - var ca = cos(mode.theta) - var sa = sin(mode.theta) - var a = x * ca - y * sa - var b = x * sa + y * ca - x = (a + 1) / 2 * w - y = (b + 1) / 2 * h - var copy = src.get(x, y) - lex.assign(copy) - return true - }, - }, - - scale: { - init: function(e){ - mode.independent = e.shiftKey || e.altKey || e.metaKey - mode.x_scale = mode.y_scale = 0 - }, - before: function(dx, dy, pdx, pdy){ - if (mode.independent) { - mode.x_scale = Math.pow(2, -pdx / (canvas.w / 8)) - mode.y_scale = Math.pow(2, -pdy / (canvas.h / 8)) - } - else { - mode.x_scale = mode.y_scale = Math.pow(2, -pdx / (canvas.w / 8)) - } - }, - shade: function(src, dest, lex, x, y, w, h){ - x = ((x-p[0])/w) * 2 - 1 - y = ((y-p[1])/h) * 2 - 1 - x *= mode.x_scale - y *= mode.y_scale - x = (x + 1) / 2 * w - y = (y + 1) / 2 * h - var copy = src.get(x+p[0], y+p[1]) - lex.assign(copy) - return true - }, - }, - - translate: { - init: function(e){ - mode.dx = mode.dy = 0 - }, - before: function(dx, dy, pdx, pdy){ - mode.dx = -pdx - mode.dy = -pdy - }, - shade: function(src, dest, lex, x, y, w, h){ - var copy = src.get(x+mode.dx, y+mode.dy) - lex.assign(copy) - return true - }, - }, - - slice: { - init: function(e){ - mode.is_y = ! (e.altKey || e.metaKey) - mode.reverse = !! (e.shiftKey) - mode.position = 0 - mode.direction = 0 - mode.last_dd = -1 - }, - before: function(dx, dy, pdx, pdy, point){ - var new_position = mode.is_y ? point[1] : point[0] - var dd = mode.is_y ? pdx : pdy - - if (mode.position !== new_position) { - mode.position = new_position - mode.direction = 0 - } - if (mode.last_dd !== -1) { - mode.direction = mode.last_dd - dd - } - console.log(mode.position) - mode.last_dd = dd - copy.assign(canvas) - }, - shade: function(src, dest, lex, x, y, w, h){ - if (mode.is_y) { - if (y >= mode.position || (mode.reverse && mode.position >= y)) { - var copy = src.get(x + mode.direction, y) - lex.assign(copy) - } - } - else if (x >= mode.position || (mode.reverse && mode.position >= x)) { - var copy = src.get(x, y + mode.direction) - lex.assign(copy) - } - return true - }, - }, - -/* - mode: { - init: function(e){ - }, - before: function(dx, dy, pdx, pdy){ - }, - shade: function(src, dest, lex, x, y, w, h){ - }, - }, -*/ - } - - function set_mode(m){ - if (m in modes) { - mode = modes[m] - transforming = true - } - } - - function done(){ - transforming = false - copy && copy.demolish() - } - - return { - down: down, - move: move, - up: up, - set_mode: set_mode, - modes: modes, - done: done, - } - -})() \ No newline at end of file diff --git a/assets/js/unicode.js b/assets/js/unicode.js deleted file mode 100644 index 0d4af8c..0000000 --- a/assets/js/unicode.js +++ /dev/null @@ -1,203 +0,0 @@ -var unicode = (function(){ - var UNICODE_BLOCK_LIST = [ - 0x0020, 0x007F, "Basic Latin", - 0x0080, 0x00FF, "Latin-1 Supplement", - 0x2500, 0x257F, "Box Drawing", - 0x2580, 0x259F, "Block Elements", - ] - var UNICODE_BLOCK_COUNT = UNICODE_BLOCK_LIST.length / 3 - var UNICODE_LOOKUP = {} - for (var i = 0, len = UNICODE_BLOCK_LIST.length; i < len; i += 3) { - UNICODE_LOOKUP[ UNICODE_BLOCK_LIST[i+2] ] = [ UNICODE_BLOCK_LIST[i], UNICODE_BLOCK_LIST[i+1] ] - } - - function block (name, n){ - var b = UNICODE_LOOKUP[name] - if (! b) return "" - return range.apply(null, b).map(function(n){ return String.fromCharCode(n) }) - } - function entities (a) { - return a.map(function(k){ return "&#" + k.join(";&#") + ";" }).join("
") - } - function index (j) { - return [ UNICODE_BLOCK_LIST[j*3], UNICODE_BLOCK_LIST[j*3+1], UNICODE_BLOCK_LIST[j*3+2], [] ] - } - function range(m,n){ - if (m > n) return [] - var a = new Array (n-m) - for (var i = 0, j = m; j <= n; i++, j++) { - a[i] = j - } - return a - } - - // [ 0xE3, 0x81, 0x82, 0xE3, 0x81, 0x84 ] => '\xE3\x81\x82\xE3\x81\x84' - // [ 0343, 0201, 0202, 0343, 0201, 0204 ] => '\343\201\202\343\201\204' - function convertBytesToEscapedString(data_bytes, base) { - var escaped = ''; - for (var i = 0; i < data_bytes.length; ++i) { - var prefix = (base == 16 ? "\\x" : "\\"); - var num_digits = base == 16 ? 2 : 3; - var escaped_byte = prefix + formatNumber(data_bytes[i], base, num_digits) - escaped += escaped_byte; - } - return escaped; - } - // r'\xE3\x81\x82\xE3\x81\x84' => [ 0xE3, 0x81, 0x82, 0xE3, 0x81, 0x84 ] - // r'\343\201\202\343\201\204' => [ 0343, 0201, 0202, 0343, 0201, 0204 ] - function convertEscapedBytesToBytes(str) { - var parts = str.split("\\x"); - parts.shift(); // Trim the first element. - var codes = []; - var max = Math.pow(2, 8); - for (var i = 0; i < parts.length; ++i) { - var code = parseInt(parts[i], 16); - if (code >= 0 && code < max) { - codes.push(code); - } else { - // Malformed code ignored. - } - } - return codes; - } - // [ 0x3042, 0x3044 ] => "あい" - function convertUnicodeCodePointsToString(unicode_codes) { - var utf16_codes = convertUnicodeCodePointsToUtf16Codes(unicode_codes); - return convertUtf16CodesToString(utf16_codes); - } - // 0x3042 => [ 0xE3, 0x81, 0x82 ] - function convertUnicodeCodePointToUtf8Bytes(unicode_code) { - var utf8_bytes = []; - if (unicode_code < 0x80) { // 1-byte - utf8_bytes.push(unicode_code); - } else if (unicode_code < (1 << 11)) { // 2-byte - utf8_bytes.push((unicode_code >>> 6) | 0xC0); - utf8_bytes.push((unicode_code & 0x3F) | 0x80); - } else if (unicode_code < (1 << 16)) { // 3-byte - utf8_bytes.push((unicode_code >>> 12) | 0xE0); - utf8_bytes.push(((unicode_code >> 6) & 0x3f) | 0x80); - utf8_bytes.push((unicode_code & 0x3F) | 0x80); - } else if (unicode_code < (1 << 21)) { // 4-byte - utf8_bytes.push((unicode_code >>> 18) | 0xF0); - utf8_bytes.push(((unicode_code >> 12) & 0x3F) | 0x80); - utf8_bytes.push(((unicode_code >> 6) & 0x3F) | 0x80); - utf8_bytes.push((unicode_code & 0x3F) | 0x80); - } - return utf8_bytes; - } - // [ 0x3042, 0x3044 ] => [ 0x3042, 0x3044 ] - // [ 0xD840, 0xDC0B ] => [ 0x2000B ] // A surrogate pair. - function convertUnicodeCodePointsToUtf16Codes(unicode_codes) { - var utf16_codes = []; - for (var i = 0; i < unicode_codes.length; ++i) { - var unicode_code = unicode_codes[i]; - if (unicode_code < (1 << 16)) { - utf16_codes.push(unicode_code); - } else { - var first = ((unicode_code - (1 << 16)) / (1 << 10)) + 0xD800; - var second = (unicode_code % (1 << 10)) + 0xDC00; - utf16_codes.push(first) - utf16_codes.push(second) - } - } - return utf16_codes; - } - // [ 0xE3, 0x81, 0x82, 0xE3, 0x81, 0x84 ] => [ 0x3042, 0x3044 ] - function convertUtf8BytesToUnicodeCodePoints(utf8_bytes) { - var unicode_codes = []; - var unicode_code = 0; - var num_followed = 0; - for (var i = 0; i < utf8_bytes.length; ++i) { - var utf8_byte = utf8_bytes[i]; - if (utf8_byte >= 0x100) { - // Malformed utf8 byte ignored. - } else if ((utf8_byte & 0xC0) == 0x80) { - if (num_followed > 0) { - unicode_code = (unicode_code << 6) | (utf8_byte & 0x3f); - num_followed -= 1; - } else { - // Malformed UTF-8 sequence ignored. - } - } else { - if (num_followed == 0) { - unicode_codes.push(unicode_code); - } else { - // Malformed UTF-8 sequence ignored. - } - if (utf8_byte < 0x80){ // 1-byte - unicode_code = utf8_byte; - num_followed = 0; - } else if ((utf8_byte & 0xE0) == 0xC0) { // 2-byte - unicode_code = utf8_byte & 0x1f; - num_followed = 1; - } else if ((utf8_byte & 0xF0) == 0xE0) { // 3-byte - unicode_code = utf8_byte & 0x0f; - num_followed = 2; - } else if ((utf8_byte & 0xF8) == 0xF0) { // 4-byte - unicode_code = utf8_byte & 0x07; - num_followed = 3; - } else { - // Malformed UTF-8 sequence ignored. - } - } - } - if (num_followed == 0) { - unicode_codes.push(unicode_code); - } else { - // Malformed UTF-8 sequence ignored. - } - unicode_codes.shift(); // Trim the first element. - return unicode_codes; - } - // [ 0x3042, 0x3044 ] => "あい" - function convertUtf16CodesToString(utf16_codes) { - var unescaped = ''; - for (var i = 0; i < utf16_codes.length; ++i) { - unescaped += String.fromCharCode(utf16_codes[i]); - } - return unescaped; - } - // 0xff => "ff" - // 0xff => "377" - function formatNumber(number, base, num_digits) { - var str = number.toString(base).toUpperCase(); - for (var i = str.length; i < num_digits; ++i) { - str = "0" + str; - } - return str; - } - - // encodes unicode characters as escaped bytes - \xFF - // encodes ONLY non-ascii characters - function escapeToEscapedBytes (txt) { - var escaped_txt = "", kode, utf8_bytes - for (var i = 0; i < txt.length; i++) { - kode = txt.charCodeAt(i) - if (kode > 0x7f) { - utf8_bytes = convertUnicodeCodePointToUtf8Bytes(kode) - escaped_txt += convertBytesToEscapedString(utf8_bytes, 16) - } - else { - escaped_txt += txt[i] - } - } - return escaped_txt - } - - // convert \xFF\xFF\xFF to unicode - function unescapeFromEscapedBytes (str) { - var data_bytes = convertEscapedBytesToBytes(str); - var unicode_codes = convertUtf8BytesToUnicodeCodePoints(data_bytes); - return convertUnicodeCodePointsToString(unicode_codes); - } - - return { - raw: UNICODE_BLOCK_LIST, - lookup: UNICODE_LOOKUP, - index: index, - range: range, - block: block, - escapeToEscapedBytes: escapeToEscapedBytes, - unescapeFromEscapedBytes: unescapeFromEscapedBytes, - } -})() diff --git a/assets/js/util.js b/assets/js/util.js deleted file mode 100644 index c71cae5..0000000 --- a/assets/js/util.js +++ /dev/null @@ -1,192 +0,0 @@ -if (window.$) { - $.fn.int = function(){ return parseInt($(this).val(),10) } - $.fn.float = function(){ return parseFloat($(this).val()) } - $.fn.string = function(){ return trim($(this).val()) } - $.fn.enable = function() { return $(this).attr("disabled",null) } - $.fn.disable = function() { return $(this).attr("disabled","disabled") } -} - -function noop(){} -function trim(s){ return s.replace(/^\s+/,"").replace(/\s+$/,"") } - -var E = Math.E -var PI = Math.PI -var PHI = (1+Math.sqrt(5))/2 -var TWO_PI = PI*2 -var LN10 = Math.LN10 -function clamp(n,a,b){ return n= 0.5 ? -1 : 1 } -function randnullsign(){ var r = random(); return r < 0.333 ? -1 : r < 0.666 ? 0 : 1 } - -function xrandom(exp){ return Math.pow(Math.random(), exp) } -function xrand(exp,n){ return (xrandom(exp)*n) } -function xrandint(exp,n){ return rand(exp,n)|0 } -function xrandrange(exp,a,b){ return a + xrand(exp,b-a) } - -function choice(a){ return a[randint(a.length)] } -function deg(n){ return n*180/PI } -function rad(n){ return n*PI/180 } -function xor(a,b){ a=!!a; b=!!b; return (a||b) && !(a&&b) } -function mod(n,m){ n = n % m; return n < 0 ? (m + n) : n } -function modi(n,m){ return floor(mod(n,m)) } -function dist(x0,y0,x1,y1){ return sqrt(pow(x1-x0,2)+pow(y1-y0,2)) } -function angle(x0,y0,x1,y1){ return atan2(y1-y0,x1-x0) } -function avg(m,n,a){ return (m*(a-1)+n)/a } -function quantize(a,b){ return floor(a/b)*b } -function quantile(a,b){ return floor(a/b) } - -function pixel(x,y){ return 4*(mod(y,actual_h)*actual_w+mod(x,actual_w)) } -function rgbpixel(d,x,y){ - var p = pixel(~~x,~~y) - r = d[p] - g = d[p+1] - b = d[p+2] - a = d[p+3] -} -function fit(d,x,y){ rgbpixel(d,x*actual_w/w,y*actual_h/h) } - -function step(a, b){ - return (b >= a) + 0 - // ^^ bool -> int -} - -function julestep (a,b,n) { - return clamp(norm(n,a,b), 0.0, 1.0); -} - -// hermite curve apparently -function smoothstep(min,max,n){ - var t = clamp((n - min) / (max - min), 0.0, 1.0); - return t * t * (3.0 - 2.0 * t) -} - -function toArray(a){ return Array.prototype.slice.call(a) } -function shuffle(a){ - for (var i = a.length; i > 0; i--){ - var r = randint(i) - var swap = a[i-1] - a[i-1] = a[r] - a[r] = swap - } - return a -} -function reverse(a){ - var reversed = [] - for (var i = 0, _len = a.length-1; i <= _len; i++){ - reversed[i] = a[_len-i] - } - return reversed -} -function deinterlace(a){ - var odd = [], even = [] - for (var i = 0, _len = a.length; i < _len; i++) { - if (i % 2) even.push(a[i]) - else odd.push(a[i]) - } - return [even, odd] -} -function weave(a){ - var aa = deinterlace(a) - var b = [] - aa[0].forEach(function(el){ b.push(el) }) - reverse(aa[1]).forEach(function(el){ b.push(el) }) - return b -} -function cssRule (selector, declaration) { - var x = document.styleSheets, y = x.length-1; - x[y].insertRule(selector+"{"+declaration+"}", x[y].cssRules.length); -} - -// easing functions -function circular (t) { return Math.sqrt( 1 - ( --t * t ) ) } -function quadratic (t) { return t * ( 2 - t ) } -function back (t) { - var b = 4; - return ( t = t - 1 ) * t * ( ( b + 1 ) * t + b ) + 1; -} -function bounce (t) { - if (t >= 1) return 1; - if ( ( t /= 1 ) < ( 1 / 2.75 ) ) { - return 7.5625 * t * t; - } else if ( t < ( 2 / 2.75 ) ) { - return 7.5625 * ( t -= ( 1.5 / 2.75 ) ) * t + 0.75; - } else if ( t < ( 2.5 / 2.75 ) ) { - return 7.5625 * ( t -= ( 2.25 / 2.75 ) ) * t + 0.9375; - } else { - return 7.5625 * ( t -= ( 2.625 / 2.75 ) ) * t + 0.984375; - } -} -function elastic (t) { - var f = 0.22, - e = 0.4; - - if ( t === 0 ) { return 0; } - if ( t == 1 ) { return 1; } - - return ( e * Math.pow( 2, - 10 * t ) * Math.sin( ( t - f / 4 ) * ( 2 * Math.PI ) / f ) + 1 ); -} - -Model=function a(b,c,d,e){function f(){var a=this,f={};a.on=function(a,b){(f[a]|| -(f[a]=[])).push(b)},a.trigger=function(a,b){for(var c=f[a],d=0;c&&d-1;)d.splice(c -,1);f[a]=b?d:[]};for(c in b)d=b[c],a[c]=typeof d=="function"?function(){return( -d=this.apply(a,arguments))===e?a:d}.bind(d):d;a.init&&a.init.apply(a,arguments) -}return f.extend=function(f){d={};for(c in b)d[c]=b[c];for(c in f)d[c]=f[c],b[c -]!==e&&(d["__"+c]=b[c]);return a(d)},f},typeof module=="object"&&(module.exports -=Model); // c-{{{-< - -function defaults (dest, src) { - dest = dest || {} - for (var i in src) { - dest[i] = typeof dest[i] == 'undefined' ? src[i] : dest[i] - } - return dest -} - -function setSelectionRange(input, selectionStart, selectionEnd) { - if (input.setSelectionRange) { - input.focus(); - input.setSelectionRange(selectionStart, selectionEnd); - } - else if (input.createTextRange) { - var range = input.createTextRange(); - range.collapse(true); - range.moveEnd('character', selectionEnd); - range.moveStart('character', selectionStart); - range.select(); - } -} -function setCaretToPos(input, pos) { - setSelectionRange(input, pos, pos); -} diff --git a/assets/shell/deploy-nw.sh b/assets/shell/deploy-nw.sh deleted file mode 100755 index 888fa79..0000000 --- a/assets/shell/deploy-nw.sh +++ /dev/null @@ -1,121 +0,0 @@ -#!/bin/sh -# - -PACKAGE_NAME="MiRCART-nw"; -RELEASE_DEPS="cpio find gunzip rm sed tar unzip wget zip"; -NWJS_MANIFEST_FNAME="nwjs.manifest"; -NWJS_PLATFORMS="linux-ia32 linux-x64 win-ia32 win-x64"; -NWJS_VERSION="0.34.5"; -NWJS_SUBDIR="nwjs-v${NWJS_VERSION}-%NWJS_PLATFORM%"; -NWJS_URL_linux="https://dl.nwjs.io/v${NWJS_VERSION}/nwjs-v${NWJS_VERSION}-%NWJS_PLATFORM%.tar.gz"; -NWJS_URL_win="https://dl.nwjs.io/v${NWJS_VERSION}/nwjs-v${NWJS_VERSION}-%NWJS_PLATFORM%.zip"; -RELEASES_DNAME="releases"; - -extract() { - local _fname="${1}" _dest_dname="${2}"; - if [ -n "${_fname}" -a -z "${_fname##*.tar.gz}" ]; then - tar -C "${_dest_dname}" -xpf "${_fname}"; - elif [ -n "${_fname}" -a -z "${_fname##*.zip}" ]; then - unzip -d "${_dest_dname}" "${_fname}"; - else - echo "error: file \`${_fname}' is of unknown archive type" >&2; exit 1; - fi; -}; - -msgf() { - local _fmt="${1}"; shift; - printf "%s >>> ${_fmt}\n" "$(date +"%d-%^b-%Y %H:%M:%S")" "${@}"; -}; - -subst() { - local _string="${1}" _search="${2}" _replace="${3}" _string_=""; - _string_="${_string%${_search}*}"; - _string_="${_string_}${_replace}" - _string_="${_string_}${_string#*${_search}}"; - echo "${_string_}"; -}; - -deploy() { - local _platform="${1}" _vflag="${2}" _nwjs_fname="" _nwjs_subdir="" _nwjs_url="" \ - _release_fname="" _release_dname="" _release_version=""; - - _nwjs_subdir="$(subst "${NWJS_SUBDIR}" "%NWJS_PLATFORM%" "${_platform}")"; - _nwjs_url="$(subst "$(eval echo \"\${NWJS_URL_${_platform%%-*}}\")" "%NWJS_PLATFORM%" "${_platform}")"; - _nwjs_fname="${RELEASES_DNAME}/${_nwjs_url##*/}"; - _release_version="$(sed -n '/^\s*"version":/s/^.*:\s*"\([0-9.]\+\)",\?\s*$/\1/p' package.json)"; - _release_dname="${RELEASES_DNAME}/${PACKAGE_NAME}-release-${_platform}-${_release_version}"; - _release_fname="${_release_dname}.zip"; - - trap "rm -fr ${_release_dname}" EXIT HUP INT QUIT PIPE TERM USR1 USR2; - if [ "${_vflag:-0}" -eq 0 ]; then - wget -cqO "${_nwjs_fname}" "${_nwjs_url}"; - else - wget -cO "${_nwjs_fname}" "${_nwjs_url}"; - fi; - if ! sha256sum --ignore-missing -c --status "${NWJS_MANIFEST_FNAME}"; then - echo "error: SHA256 sum mismatch for \`${_nwjs_fname}'" >&2; return 1; - fi; - rm -rf "${_release_dname}"; mkdir -p "${_release_dname}"; extract "${_nwjs_fname}" "${_release_dname}"; - - cd "${_release_dname}/${_nwjs_subdir}"; - find . \ - -mindepth 1 |\ - cpio --quiet -dmp ..; - cd "${OLDPWD}"; - rm -fr "${_release_dname}/${_nwjs_subdir}"; - find -L . \ - -mindepth 1 \ - -not -path "./${RELEASES_DNAME}/*" \ - -not -path "./${RELEASES_DNAME}" \ - -not -name '*.sw*' \ - -not -name "${0##*/}" \ - -not -name "${NWJS_MANIFEST_FNAME}" |\ - cpio --quiet -dLmp "${_release_dname}"; - cd "${RELEASES_DNAME}"; - if [ "${_vflag:-0}" -eq 0 ]; then - zip -9 -r "${_release_fname##${RELEASES_DNAME}/}" "${_release_dname##${RELEASES_DNAME}/}" >/dev/null; - else - zip -9 -r "${_release_fname##${RELEASES_DNAME}/}" "${_release_dname##${RELEASES_DNAME}/}"; - fi; - cd "${OLDPWD}"; rm -fr "${_release_dname}"; - trap - EXIT HUP INT QUIT PIPE TERM USR1 USR2; -}; - -usage() { - echo "usage: ${0} [-h] [-v] [platform...]" >&2; - echo " -h.........: show this screen" >&2; - echo " -v.........: be verbose" >&2; - echo " platform...: one of: \`${NWJS_PLATFORMS}'" >&2; -}; - -main() { - local _cmd="" _opt="" _platform="" _platforms="" _vflag=0; - while getopts hv _opt; do - case "${_opt}" in - h) usage; exit 0; ;; - v) _vflag=1; ;; - *) usage; exit 1; ;; - esac; done; - shift $((${OPTIND}-1)); - for _cmd in ${RELEASE_DEPS}; do - if ! which "${_cmd}" >/dev/null; then - echo "error: missing prerequisite command \`${_cmd}'"; - exit 1; - fi; - done; - _platforms="${@}"; mkdir -p "${RELEASES_DNAME}"; - for _platform in ${_platforms:-${NWJS_PLATFORMS}}; do - msgf "Building ${_platform} release..."; - if [ "${_vflag:-0}" -eq 0 ]; then - deploy "${_platform}" "${_vflag}" >/dev/null; - else - deploy "${_platform}" "${_vflag}"; - fi; - msgf "Built ${_platform} release."; - done; -}; - -set -o errexit -o noglob; -main "${@}"; - -# vim:foldmethod=marker sw=8 ts=8 tw=120 diff --git a/assets/text/LICENCE.MIT b/assets/text/LICENCE similarity index 100% rename from assets/text/LICENCE.MIT rename to assets/text/LICENCE diff --git a/assets/text/LICENCE.asdf b/assets/text/LICENCE.asdf deleted file mode 100644 index 9057f84..0000000 --- a/assets/text/LICENCE.asdf +++ /dev/null @@ -1,28 +0,0 @@ - Jollo LNT license - Version 1 - February 2015 - - Copyright, 2015. JOLLO NET NA. - The Jollo IRC Network. - - Vu, fare wanderer, confronted with raw, programmatic instruction - dans la forme la plus pure. A hesitation, troubled to the terms - qui ce license affirme. Par un voyage du explorer le mechanisme - et ponder la fabrication. Voila! La remide: egress sans risque. - - Sans trace (Leave No Trace) via sept principales: - - 0. Modifique language en advance. L'Apposer Jollo LNT license - with copies en distribuer. - - 1. Non responsible pour neglige programme du problematique. - - 2. Non sympathie pour neglige programme du problematique. - - 3. Non permission l'modifique under any circumstance. - - 4. Non permission distribution under any circumstance. - - 5. Respect les programmatic instructions. - - 6. Non interfere avec l'harmonie d'une amitie. - diff --git a/MiRCART-python/MiRCARTImgurApiKey.py.template b/assets/text/MiRCARTImgurApiKey.py.template similarity index 100% rename from MiRCART-python/MiRCARTImgurApiKey.py.template rename to assets/text/MiRCARTImgurApiKey.py.template diff --git a/assets/text/README.md b/assets/text/README.md index 531276c..d21f361 100644 --- a/assets/text/README.md +++ b/assets/text/README.md @@ -1,15 +1,19 @@ -## MiRCART-{cordoba,nw,www} -- mIRC art editor for {Android,{Linux,Windows},browsers} (WIP) -Originally based on [[1](#r1)]. +# MiRCART.py -- mIRC art editor for Windows & Linux (WIP) +* Prerequisites on Windows: install Python v3.6.x[1] and script dependencies w/ the following elevated command prompt command line: + `pip install requests urllib3 wxPython` +* Prerequisites on Linux: python3 && python-wx{gtk2.8,tools} on Debian-family Linux distributions +* Screenshot: +![Screenshot](https://github.com/lalbornoz/MiRCARTools/raw/master/assets/images/MiRCART.png "Screenshot") -## IrcMiRCARTBot.py -- IRC<->MiRC2png bot (for EFnet #MiRCART) (pending cleanup) +# IrcMiRCARTBot.py -- IRC<->MiRC2png bot (for EFnet #MiRCART) (pending cleanup) * Prerequisites: python3 && python3-{json,requests,urllib3} on Debian-family Linux distributions * IrcMiRCARTBot.py usage: IrcMiRCARTBot.py `` [``] [``] [``] [``] [``] -## MiRCARTToPngFile.py -- convert ASCII w/ mIRC control codes to monospaced PNG (pending cleanup) +# MiRCARTToPngFile.py -- convert ASCII w/ mIRC control codes to monospaced PNG (pending cleanup) * Prerequisites: python3 && python3-pil on Debian-family Linux distributions * MiRC2png.py usage: MiRC2png.py `` `` [``] [``] -## References -``Fri, 05 Jan 2018 17:01:47 +0100 [1]`` asciiblaster - +References: +Fri, 05 Jan 2018 17:01:47 +0100 [1] Python Releases for Windows | Python.org + vim:tw=0 diff --git a/assets/text/TODO b/assets/text/TODO deleted file mode 100644 index 3d86910..0000000 --- a/assets/text/TODO +++ /dev/null @@ -1,21 +0,0 @@ -1) feature: animation; Blender mIRCart Python importer plugin -2) feature: {bold,italic,underline} attributes -3) feature: comic editor/generator * -4) feature: draw w/ keyboard instead of [LR]MB -5) feature: {line,measuring} tool -6) feature: multiplayer realtime editing -7) feature: status bar w/ position, etc. -8) feature: zoom {in,out} (esp. on Android) -9) reimplement: ANSI (maybe,) {save,upload} as PNG & gallery, cutoff (print line #(s) affected, tunably,) shaders (maybe) -10) releases: provide signed release APK - -In progress: -1) each newly created & modified(!) ascii is assigned an ascii UUID, if not present already -2) each ascii w/ an ascii UUID is auto-saved to localStorage every 3 minutes -3) ascii autosaves w/ count >8 (or >8*3mins=24mins old) are purged from localStorage -4) asciis w/ count >8 are purged from localStorage -5) limits are tunable and either defaulted or localStorage'd -6) UI lists: a) asciis (with UUID) b) autosaves c) parameters -7) always prompt on close window/exit/... -8) always prompt on new -9) save to text file @ standalone app diff --git a/MiRCART-python/IrcMiRCARTBot.py b/assets/tools/IrcMiRCARTBot.py similarity index 100% rename from MiRCART-python/IrcMiRCARTBot.py rename to assets/tools/IrcMiRCARTBot.py diff --git a/MiRCART-python/MiRCARTCanonicalise.py b/assets/tools/MiRCARTCanonicalise.py similarity index 100% rename from MiRCART-python/MiRCARTCanonicalise.py rename to assets/tools/MiRCARTCanonicalise.py diff --git a/MiRCART-python/MiRCARTCheckLineLengths.sh b/assets/tools/MiRCARTCheckLineLengths.sh similarity index 100% rename from MiRCART-python/MiRCARTCheckLineLengths.sh rename to assets/tools/MiRCARTCheckLineLengths.sh diff --git a/MiRCART-python/MiRCARTReduce.py b/assets/tools/MiRCARTReduce.py similarity index 100% rename from MiRCART-python/MiRCARTReduce.py rename to assets/tools/MiRCARTReduce.py diff --git a/MiRCART-python/MiRCARTToAnsi.py b/assets/tools/MiRCARTToAnsi.py similarity index 100% rename from MiRCART-python/MiRCARTToAnsi.py rename to assets/tools/MiRCARTToAnsi.py diff --git a/MiRCART-python/MiRCARTToPngFile.py b/assets/tools/MiRCARTToPngFile.py similarity index 100% rename from MiRCART-python/MiRCARTToPngFile.py rename to assets/tools/MiRCARTToPngFile.py diff --git a/MiRCART-python/MiRCARTToPngFiles.sh b/assets/tools/MiRCARTToPngFiles.sh similarity index 100% rename from MiRCART-python/MiRCARTToPngFiles.sh rename to assets/tools/MiRCARTToPngFiles.sh diff --git a/MiRCART-python/SAUCEToAnsi.py b/assets/tools/SAUCEToAnsi.py similarity index 100% rename from MiRCART-python/SAUCEToAnsi.py rename to assets/tools/SAUCEToAnsi.py diff --git a/assets/shell/bump-version.sh b/assets/tools/bump-version.sh similarity index 100% rename from assets/shell/bump-version.sh rename to assets/tools/bump-version.sh diff --git a/assets/shell/deploy-all.sh b/assets/tools/deploy-all.sh similarity index 100% rename from assets/shell/deploy-all.sh rename to assets/tools/deploy-all.sh diff --git a/assets/shell/deploy-www.sh b/assets/tools/deploy-www.sh similarity index 100% rename from assets/shell/deploy-www.sh rename to assets/tools/deploy-www.sh diff --git a/libcanvas/MiRCARTCanvas.py b/libcanvas/MiRCARTCanvas.py new file mode 100644 index 0000000..ac96b4b --- /dev/null +++ b/libcanvas/MiRCARTCanvas.py @@ -0,0 +1,203 @@ +#!/usr/bin/env python3 +# +# MiRCARTCanvas.py -- XXX +# Copyright (c) 2018 Lucio Andrés Illanes Albornoz +# + +from MiRCARTCanvasBackend import MiRCARTCanvasBackend +from MiRCARTCanvasJournal import MiRCARTCanvasJournal +from MiRCARTCanvasExportStore import MiRCARTCanvasExportStore, haveMiRCARTToPngFile, haveUrllib +from MiRCARTCanvasImportStore import MiRCARTCanvasImportStore +from MiRCARTCanvasInterface import MiRCARTCanvasInterface +from MiRCARTImgurApiKey import MiRCARTImgurApiKey +import wx + +class MiRCARTCanvas(wx.Panel): + """XXX""" + parentFrame = None + defaultCanvasPos = defaultCanvasSize = defaultCellSize = None + canvasMap = canvasPos = canvasSize = None + brushColours = brushPos = brushSize = None + canvasBackend = canvasJournal = None + canvasExportStore = canvasImportStore = None + canvasInterface = None + imgurApiKey = MiRCARTImgurApiKey.imgurApiKey + + # {{{ _commitPatch(self, patch): XXX + def _commitPatch(self, patch): + self.canvasMap[patch[1]][patch[0]] = patch[2:] + # }}} + # {{{ _dispatchDeltaPatches(self, deltaPatches): XXX + def _dispatchDeltaPatches(self, deltaPatches): + eventDc = self.canvasBackend.getDeviceContext(self) + for patch in deltaPatches: + if self.canvasBackend.drawPatch(eventDc, patch): + self._commitPatch(patch) + self.parentFrame.onCanvasUpdate(undoLevel=self.canvasJournal.patchesUndoLevel) + # }}} + # {{{ _dispatchPatch(self, eventDc, isCursor, patch): XXX + def _dispatchPatch(self, eventDc, isCursor, patch): + if not self._canvasDirtyCursor: + self.canvasBackend.drawCursorMaskWithJournal( \ + self.canvasJournal, eventDc) + self._canvasDirtyCursor = True + if self.canvasBackend.drawPatch(eventDc, patch): + patchDeltaCell = self.canvasMap[patch[1]][patch[0]] + patchDelta = [*patch[0:2], *patchDeltaCell] + if isCursor: + self.canvasJournal.pushCursor(patchDelta) + else: + if not self._canvasDirty: + self.canvasJournal.pushDeltas([], []) + self._canvasDirty = True + self.canvasJournal.updateCurrentDeltas(patchDelta, patch) + self._commitPatch(patch) + # }}} + + # {{{ onPanelClose(self, event): XXX + def onPanelClose(self, event): + self.Destroy() + # }}} + # {{{ onPanelEnterWindow(self, event): XXX + def onPanelEnterWindow(self, event): + self.parentFrame.SetFocus() + # }}} + # {{{ onPanelInput(self, event): XXX + def onPanelInput(self, event): + eventDc = self.canvasBackend.getDeviceContext(self) + eventType = event.GetEventType() + self._canvasDirty = self._canvasDirtyCursor = False + tool = self.canvasInterface.canvasTool + if eventType == wx.wxEVT_CHAR: + mapPoint = self.brushPos + doSkip = tool.onKeyboardEvent( \ + event, mapPoint, self.brushColours, self.brushSize, \ + chr(event.GetUnicodeKey()), self._dispatchPatch, eventDc) + if doSkip: + event.Skip(); return; + else: + mapPoint = self.canvasBackend.xlateEventPoint(event, eventDc) + if mapPoint[0] >= self.canvasSize[0] \ + or mapPoint[1] >= self.canvasSize[1]: + return + self.brushPos = mapPoint + tool.onMouseEvent( \ + event, mapPoint, self.brushColours, self.brushSize, \ + event.Dragging(), event.LeftIsDown(), event.RightIsDown(), \ + self._dispatchPatch, eventDc) + if self._canvasDirty: + self.parentFrame.onCanvasUpdate(cellPos=self.brushPos, \ + undoLevel=self.canvasJournal.patchesUndoLevel) + if eventType == wx.wxEVT_MOTION: + self.parentFrame.onCanvasUpdate(cellPos=mapPoint) + # }}} + # {{{ onPanelLeaveWindow(self, event): XXX + def onPanelLeaveWindow(self, event): + eventDc = self.canvasBackend.getDeviceContext(self) + self.canvasBackend.drawCursorMaskWithJournal( \ + self.canvasJournal, eventDc) + # }}} + # {{{ onPanelPaint(self, event): XXX + def onPanelPaint(self, event): + self.canvasBackend.onPanelPaintEvent(self, event) + # }}} + # {{{ onStoreUpdate(self, newCanvasSize, newCanvas=None): XXX + def onStoreUpdate(self, newCanvasSize, newCanvas=None): + self.resize(newCanvasSize=newCanvasSize) + eventDc = self.canvasBackend.getDeviceContext(self) + for numRow in range(self.canvasSize[1]): + for numCol in range(self.canvasSize[0]): + if newCanvas != None \ + and numRow < len(newCanvas) \ + and numCol < len(newCanvas[numRow]): + self._commitPatch([ \ + numCol, numRow, *newCanvas[numRow][numCol]]) + self.canvasBackend.drawPatch(eventDc, \ + [numCol, numRow, \ + *self.canvasMap[numRow][numCol]]) + wx.SafeYield() + # }}} + # {{{ resize(self, newCanvasSize): XXX + def resize(self, newCanvasSize): + if newCanvasSize != self.canvasSize: + if self.canvasMap == None: + self.canvasMap = []; oldCanvasSize = [0, 0]; + else: + oldCanvasSize = self.canvasSize + deltaCanvasSize = [b-a for a,b in zip(oldCanvasSize, newCanvasSize)] + + newWinSize = [a*b for a,b in zip(newCanvasSize, self.canvasBackend.cellSize)] + self.SetMinSize(newWinSize) + self.SetSize(wx.DefaultCoord, wx.DefaultCoord, *newWinSize) + curWindow = self + while curWindow != None: + curWindow.Layout() + curWindow = curWindow.GetParent() + + self.canvasBackend.resize(newCanvasSize, self.canvasBackend.cellSize) + eventDc = self.canvasBackend.getDeviceContext(self) + self.canvasJournal.resetCursor(); self.canvasJournal.resetUndo(); + + if deltaCanvasSize[0] < 0: + for numRow in range(oldCanvasSize[1]): + del self.canvasMap[numRow][-1:(deltaCanvasSize[0]-1):-1] + else: + for numRow in range(oldCanvasSize[1]): + self.canvasMap[numRow].extend( \ + [[1, 1, 0, " "]] * deltaCanvasSize[0]) + for numNewCol in range(oldCanvasSize[0], newCanvasSize[0]): + self.canvasBackend.drawPatch( \ + eventDc, [numNewCol, numRow, \ + *self.canvasMap[numRow][-1]]) + if deltaCanvasSize[1] < 0: + del self.canvasMap[-1:(deltaCanvasSize[1]-1):-1] + else: + for numNewRow in range(oldCanvasSize[1], newCanvasSize[1]): + self.canvasMap.extend( \ + [[[1, 1, 0, " "]] * newCanvasSize[0]]) + for numNewCol in range(newCanvasSize[0]): + self.canvasBackend.drawPatch( \ + eventDc, [numNewCol, numNewRow, \ + *self.canvasMap[-1][-1]]) + + self.canvasSize = newCanvasSize + wx.SafeYield() + self.parentFrame.onCanvasUpdate(size=newCanvasSize, undoLevel=-1) + # }}} + + # {{{ __del__(self): destructor method + def __del__(self): + if self.canvasMap != None: + self.canvasMap.clear(); self.canvasMap = None; + # }}} + + # + # __init__(self, parent, parentFrame, defaultCanvasPos, defaultCanvasSize, defaultCellSize): initialisation method + def __init__(self, parent, parentFrame, defaultCanvasPos, defaultCanvasSize, defaultCellSize): + super().__init__(parent, pos=defaultCanvasPos, \ + size=[w*h for w,h in zip(defaultCanvasSize, defaultCellSize)]) + + self.parentFrame = parentFrame + self.canvasMap = None + self.canvasPos = defaultCanvasPos; self.canvasSize = defaultCanvasSize; + self.defaultCanvasPos = defaultCanvasPos; self.defaultCanvasSize = defaultCanvasSize; + self.brushColours = [4, 1]; self.brushPos = [0, 0]; self.brushSize = [1, 1]; + self.parentFrame.onCanvasUpdate( \ + brushSize=self.brushSize, colours=self.brushColours) + self.canvasBackend = MiRCARTCanvasBackend(defaultCanvasSize, defaultCellSize) + self.canvasJournal = MiRCARTCanvasJournal() + self.canvasExportStore = MiRCARTCanvasExportStore(parentCanvas=self) + self.canvasImportStore = MiRCARTCanvasImportStore(parentCanvas=self) + self.canvasInterface = MiRCARTCanvasInterface(self, parentFrame) + + # Bind event handlers + self.Bind(wx.EVT_CLOSE, self.onPanelClose) + self.Bind(wx.EVT_ENTER_WINDOW, self.onPanelEnterWindow) + self.Bind(wx.EVT_LEAVE_WINDOW, self.onPanelLeaveWindow) + self.parentFrame.Bind(wx.EVT_CHAR, self.onPanelInput) + for eventType in( \ + wx.EVT_LEFT_DOWN, wx.EVT_MOTION, wx.EVT_RIGHT_DOWN): + self.Bind(eventType, self.onPanelInput) + self.Bind(wx.EVT_PAINT, self.onPanelPaint) + +# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 diff --git a/libcanvas/MiRCARTCanvasBackend.py b/libcanvas/MiRCARTCanvasBackend.py new file mode 100644 index 0000000..dbe6463 --- /dev/null +++ b/libcanvas/MiRCARTCanvasBackend.py @@ -0,0 +1,157 @@ +#!/usr/bin/env python3 +# +# MiRCARTCanvasBackend.py -- XXX +# Copyright (c) 2018 Lucio Andrés Illanes Albornoz +# + +from MiRCARTColours import MiRCARTColours +import wx + +class MiRCARTCanvasBackend(): + """XXX""" + _font = _brushes = _pens = None + _lastBrush = _lastPen = None + canvasBitmap = cellSize = None + + # {{{ _drawBrushPatch(self, eventDc, patch): XXX + def _drawBrushPatch(self, eventDc, patch): + absPoint = self._xlatePoint(patch) + brushFg = self._brushes[patch[3]] + brushBg = self._brushes[patch[2]] + pen = self._pens[patch[3]] + self._setBrushDc(brushBg, brushFg, eventDc, pen) + eventDc.DrawRectangle(*absPoint, *self.cellSize) + # }}} + # {{{ _drawCharPatch(self, eventDc, patch): XXX + def _drawCharPatch(self, eventDc, patch): + absPoint = self._xlatePoint(patch) + brushFg = self._brushes[patch[2]] + brushBg = self._brushes[patch[3]] + pen = self._pens[patch[3]] + fontBitmap = wx.Bitmap(*self.cellSize) + fontDc = wx.MemoryDC(); fontDc.SelectObject(fontBitmap); + fontDc.SetTextForeground(wx.Colour(MiRCARTColours[patch[2]][0:4])) + fontDc.SetTextBackground(wx.Colour(MiRCARTColours[patch[3]][0:4])) + fontDc.SetBrush(brushBg); fontDc.SetBackground(brushBg); fontDc.SetPen(pen); + fontDc.SetFont(self._font) + fontDc.DrawRectangle(0, 0, *self.cellSize) + fontDc.DrawText(patch[5], 0, 0) + eventDc.Blit(*absPoint, *self.cellSize, fontDc, 0, 0) + # }}} + # {{{ _finiBrushesAndPens(self): XXX + def _finiBrushesAndPens(self): + for brush in self._brushes or []: + brush.Destroy() + self._brushes = None + for pen in self._pens or []: + pen.Destroy() + self._pens = None + self._lastBrushBg = self._lastBrushFg = self._lastPen = None; + # }}} + # {{{ _initBrushesAndPens(self): XXX + def _initBrushesAndPens(self): + self._brushes = [None for x in range(len(MiRCARTColours))] + self._pens = [None for x in range(len(MiRCARTColours))] + for mircColour in range(len(MiRCARTColours)): + self._brushes[mircColour] = wx.Brush( \ + wx.Colour(MiRCARTColours[mircColour][0:4]), wx.BRUSHSTYLE_SOLID) + self._pens[mircColour] = wx.Pen( \ + wx.Colour(MiRCARTColours[mircColour][0:4]), 1) + self._lastBrushBg = self._lastBrushFg = self._lastPen = None; + # }}} + # {{{ _setBrushDc(self, brushBg, brushFg, dc, pen): XXX + def _setBrushDc(self, brushBg, brushFg, dc, pen): + if self._lastBrushBg != brushBg: + dc.SetBackground(brushBg) + self._lastBrushBg = brushBg + if self._lastBrushFg != brushFg: + dc.SetBrush(brushFg) + self._lastBrushFg = brushFg + if self._lastPen != pen: + dc.SetPen(pen) + self._lastPen = pen + # }}} + # {{{ _xlatePoint(self, patch): XXX + def _xlatePoint(self, patch): + return [a*b for a,b in zip(patch[0:2], self.cellSize)] + # }}} + + # {{{ drawPatch(self, eventDc, patch): XXX + def drawPatch(self, eventDc, patch): + if patch[0] < self.canvasSize[0] \ + and patch[0] >= 0 \ + and patch[1] < self.canvasSize[1] \ + and patch[1] >= 0: + if patch[5] == " ": + self._drawBrushPatch(eventDc, patch) + else: + self._drawCharPatch(eventDc, patch) + return True + else: + return False + # }}} + # {{{ drawCursorMaskWithJournal(self, canvasJournal, eventDc): XXX + def drawCursorMaskWithJournal(self, canvasJournal, eventDc): + for patch in canvasJournal.popCursor(): + self.drawPatch(eventDc, patch) + # }}} + # {{{ getDeviceContext(self, parentWindow): XXX + def getDeviceContext(self, parentWindow): + eventDc = wx.BufferedDC( \ + wx.ClientDC(parentWindow), self.canvasBitmap) + self._lastBrushBg = self._lastBrushFg = self._lastPen = None; + return eventDc + # }}} + # {{{ onPanelPaintEvent(self, panelWindow, panelEvent): XXX + def onPanelPaintEvent(self, panelWindow, panelEvent): + if self.canvasBitmap != None: + eventDc = wx.BufferedPaintDC(panelWindow, self.canvasBitmap) + # }}} + # {{{ reset(self, canvasSize, cellSize): + def reset(self, canvasSize, cellSize): + self.resize(canvasSize, cellSize) + # }}} + # {{{ resize(self, canvasSize, cellSize): + def resize(self, canvasSize, cellSize): + winSize = [a*b for a,b in zip(canvasSize, cellSize)] + if self.canvasBitmap == None: + self.canvasBitmap = wx.Bitmap(winSize) + else: + oldDc = wx.MemoryDC() + oldDc.SelectObject(self.canvasBitmap) + newDc = wx.MemoryDC() + newBitmap = wx.Bitmap(winSize) + newDc.SelectObject(newBitmap) + newDc.Blit(0, 0, *self.canvasBitmap.GetSize(), oldDc, 0, 0) + oldDc.SelectObject(wx.NullBitmap) + self.canvasBitmap.Destroy(); self.canvasBitmap = newBitmap; + self.canvasSize = canvasSize; self.cellSize = cellSize; + self._font = wx.Font( \ + 8, \ + wx.FONTFAMILY_TELETYPE, \ + wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL) + # }}} + # {{{ xlateEventPoint(self, event, eventDc): XXX + def xlateEventPoint(self, event, eventDc): + eventPoint = event.GetLogicalPosition(eventDc) + rectX = eventPoint.x - (eventPoint.x % self.cellSize[0]) + rectY = eventPoint.y - (eventPoint.y % self.cellSize[1]) + mapX = int(rectX / self.cellSize[0] if rectX else 0) + mapY = int(rectY / self.cellSize[1] if rectY else 0) + return (mapX, mapY) + # }}} + + # {{{ __del__(self): destructor method + def __del__(self): + if self.canvasBitmap != None: + self.canvasBitmap.Destroy(); self.canvasBitmap = None; + self._finiBrushesAndPens() + # }}} + + # + # __init__(self, canvasSize, cellSize): initialisation method + def __init__(self, canvasSize, cellSize): + self._initBrushesAndPens() + self.reset(canvasSize, cellSize) + +# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 diff --git a/libcanvas/MiRCARTCanvasExportStore.py b/libcanvas/MiRCARTCanvasExportStore.py new file mode 100644 index 0000000..db6eb96 --- /dev/null +++ b/libcanvas/MiRCARTCanvasExportStore.py @@ -0,0 +1,111 @@ +#!/usr/bin/env python3 +# +# MiRCARTCanvasExportStore.py -- XXX +# Copyright (c) 2018 Lucio Andrés Illanes Albornoz +# + +import io, os, tempfile + +try: + from MiRCARTToPngFile import MiRCARTToPngFile + haveMiRCARTToPngFile = True +except ImportError: + haveMiRCARTToPngFile = False + +try: + import base64, json, requests, urllib.request + haveUrllib = True +except ImportError: + haveUrllib = False + +class MiRCARTCanvasExportStore(): + """XXX""" + parentCanvas = None + + # {{{ _exportFileToImgur(self, apiKey, imgName, imgTitle, pathName): upload single PNG file to Imgur + def _exportFileToImgur(self, apiKey, imgName, imgTitle, pathName): + with open(pathName, "rb") as requestImage: + requestImageData = requestImage.read() + requestData = { \ + "image": base64.b64encode(requestImageData), \ + "key": apiKey, \ + "name": imgName, \ + "title": imgTitle, \ + "type": "base64"} + requestHeaders = {"Authorization": "Client-ID " + apiKey} + responseHttp = requests.post( \ + "https://api.imgur.com/3/upload.json", \ + data=requestData, headers=requestHeaders) + responseDict = json.loads(responseHttp.text) + if responseHttp.status_code == 200: + return [200, responseDict.get("data").get("link")] + else: + return [responseHttp.status_code, ""] + # }}} + + # {{{ exportBitmapToPngFile(self, canvasBitmap, outPathName, outType): XXX + def exportBitmapToPngFile(self, canvasBitmap, outPathName, outType): + return canvasBitmap.ConvertToImage().SaveFile(outPathName, outType) + # }}} + # {{{ exportBitmapToImgur(self, apiKey, canvasBitmap, imgName, imgTitle, imgType): XXX + def exportBitmapToImgur(self, apiKey, canvasBitmap, imgName, imgTitle, imgType): + tmpPathName = tempfile.mkstemp() + os.close(tmpPathName[0]) + canvasBitmap.ConvertToImage().SaveFile(tmpPathName[1], imgType) + imgurResult = self._exportFileToImgur(apiKey, imgName, imgTitle, tmpPathName[1]) + os.remove(tmpPathName[1]) + return imgurResult + # }}} + # {{{ exportPastebin(self, apiDevKey, canvasMap, canvasSize, pasteName="", pastePrivate=0): XXX + def exportPastebin(self, apiDevKey, canvasMap, canvasSize, pasteName="", pastePrivate=0): + if haveUrllib: + outFile = io.StringIO() + self.exportTextFile(canvasMap, canvasSize, outFile) + requestData = { \ + "api_dev_key": apiDevKey, \ + "api_option": "paste", \ + "api_paste_code": outFile.getvalue().encode(), \ + "api_paste_name": pasteName, \ + "api_paste_private": pastePrivate} + responseHttp = requests.post("https://pastebin.com/api/api_post.php", \ + data=requestData) + if responseHttp.status_code == 200: + if responseHttp.text.startswith("http"): + return (True, responseHttp.text) + else: + return (False, responseHttp.text) + else: + return (False, str(responseHttp.status_code)) + else: + return (False, "missing requests and/or urllib3 module(s)") + # }}} + # {{{ exportPngFile(self, canvasMap, outPathName): XXX + def exportPngFile(self, canvasMap, outPathName): + if haveMiRCARTToPngFile: + MiRCARTToPngFile(canvasMap).export(outPathName) + return True + else: + return False + # }}} + # {{{ exportTextFile(self, canvasMap, canvasSize, outFile): XXX + def exportTextFile(self, canvasMap, canvasSize, outFile): + for canvasRow in range(canvasSize[1]): + canvasLastColours = [] + for canvasCol in range(canvasSize[0]): + canvasColColours = canvasMap[canvasRow][canvasCol][0] + canvasColText = canvasMap[canvasRow][canvasCol][2] + if canvasColColours != canvasLastColours: + canvasLastColours = canvasColColours + outFile.write("\x03" + \ + str(canvasColColours[0]) + \ + "," + str(canvasColColours[1])) + outFile.write(canvasColText) + outFile.write("\n") + # }}} + + # + # __init__(self, parentCanvas): initialisation method + def __init__(self, parentCanvas): + self.parentCanvas = parentCanvas + +# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 diff --git a/MiRCART-python/MiRCARTCanvasImportStore.py b/libcanvas/MiRCARTCanvasImportStore.py similarity index 100% rename from MiRCART-python/MiRCARTCanvasImportStore.py rename to libcanvas/MiRCARTCanvasImportStore.py diff --git a/libcanvas/MiRCARTCanvasInterface.py b/libcanvas/MiRCARTCanvasInterface.py new file mode 100644 index 0000000..709225d --- /dev/null +++ b/libcanvas/MiRCARTCanvasInterface.py @@ -0,0 +1,335 @@ +#!/usr/bin/env python3 +# +# MiRCARTCanvasInterface.py -- XXX +# Copyright (c) 2018 Lucio Andrés Illanes Albornoz +# + +from MiRCARTToolCircle import MiRCARTToolCircle +from MiRCARTToolFill import MiRCARTToolFill +from MiRCARTToolLine import MiRCARTToolLine +from MiRCARTToolSelectClone import MiRCARTToolSelectClone +from MiRCARTToolSelectMove import MiRCARTToolSelectMove +from MiRCARTToolRect import MiRCARTToolRect +from MiRCARTToolText import MiRCARTToolText + +import os, wx + +class MiRCARTCanvasInterface(): + """XXX""" + imgurApiKey = None + parentCanvas = parentFrame = canvasPathName = canvasTool = None + + # {{{ _dialogSaveChanges(self) + def _dialogSaveChanges(self): + with wx.MessageDialog(self.parentCanvas, \ + "Do you want to save changes to {}?".format( \ + self.canvasPathName), "MiRCART", \ + wx.CANCEL|wx.CANCEL_DEFAULT|wx.ICON_QUESTION|wx.YES_NO) as dialog: + dialogChoice = dialog.ShowModal() + return dialogChoice + # }}} + + # {{{ canvasBrushSolid(self, event): XXX + def canvasBrushSolid(self, event): + pass + # }}} + # {{{ canvasColour(self, event, numColour): XXX + def canvasColour(self, event, numColour): + if event.GetEventType() == wx.wxEVT_TOOL: + self.parentCanvas.brushColours[0] = numColour + elif event.GetEventType() == wx.wxEVT_TOOL_RCLICKED: + self.parentCanvas.brushColours[1] = numColour + self.parentFrame.onCanvasUpdate(colours=self.parentCanvas.brushColours) + # }}} + # {{{ canvasCopy(self, event): XXX + def canvasCopy(self, event): + pass + # }}} + # {{{ canvasCut(self, event): XXX + def canvasCut(self, event): + pass + # }}} + # {{{ canvasDecrBrushHeight(self, event): XXX + def canvasDecrBrushHeight(self, event): + if self.parentCanvas.brushSize[1] > 1: + self.parentCanvas.brushSize[1] -= 1 + self.parentFrame.onCanvasUpdate(brushSize=self.parentCanvas.brushSize) + # }}} + # {{{ canvasDecrBrushHeightWidth(self, event): XXX + def canvasDecrBrushHeightWidth(self, event): + self.canvasDecrBrushHeight(event) + self.canvasDecrBrushWidth(event) + # }}} + # {{{ canvasDecrBrushWidth(self, event): XXX + def canvasDecrBrushWidth(self, event): + if self.parentCanvas.brushSize[0] > 1: + self.parentCanvas.brushSize[0] -= 1 + self.parentFrame.onCanvasUpdate(brushSize=self.parentCanvas.brushSize) + # }}} + # {{{ canvasDecrCanvasHeight(self, event): XXX + def canvasDecrCanvasHeight(self, event): + if self.parentCanvas.canvasSize[1] > 1: + self.parentCanvas.resize([ \ + self.parentCanvas.canvasSize[0], \ + self.parentCanvas.canvasSize[1]-1]) + # }}} + # {{{ canvasDecrCanvasHeightWidth(self, event): XXX + def canvasDecrCanvasHeightWidth(self, event): + self.canvasDecrCanvasHeight(event) + self.canvasDecrCanvasWidth(event) + # }}} + # {{{ canvasDecrCanvasWidth(self, event): XXX + def canvasDecrCanvasWidth(self, event): + if self.parentCanvas.canvasSize[0] > 1: + self.parentCanvas.resize([ \ + self.parentCanvas.canvasSize[0]-1, \ + self.parentCanvas.canvasSize[1]]) + # }}} + # {{{ canvasDelete(self, event): XXX + def canvasDelete(self, event): + pass + # }}} + # {{{ canvasExit(self, event): XXX + def canvasExit(self, event): + if self.canvasPathName != None: + saveChanges = self._dialogSaveChanges() + if saveChanges == wx.ID_CANCEL: + return + elif saveChanges == wx.ID_NO: + pass + elif saveChanges == wx.ID_YES: + self.canvasSave(event) + self.parentFrame.Close(True) + # }}} + # {{{ canvasExportAsPng(self, event): XXX + def canvasExportAsPng(self, event): + with wx.FileDialog(self, "Save As...", os.getcwd(), "", \ + "*.png", wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT) as dialog: + if dialog.ShowModal() == wx.ID_CANCEL: + return False + else: + outPathName = dialog.GetPath() + self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT)) + self.parentCanvas.canvasExportStore.exportBitmapToPngFile( \ + self.parentCanvas.canvasBackend.canvasBitmap, outPathName, \ + wx.BITMAP_TYPE_PNG) + self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor)) + return True + # }}} + # {{{ canvasExportImgur(self, event): XXX + def canvasExportImgur(self, event): + self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT)) + imgurResult = self.parentCanvas.canvasExportStore.exportBitmapToImgur( \ + self.imgurApiKey, self.parentCanvas.canvasBackend.canvasBitmap, \ + "", "", wx.BITMAP_TYPE_PNG) + self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor)) + if imgurResult[0] == 200: + if not wx.TheClipboard.IsOpened(): + wx.TheClipboard.Open() + wx.TheClipboard.SetData(wx.TextDataObject(imgurResult[1])) + wx.TheClipboard.Close() + wx.MessageBox("Exported to Imgur: " + imgurResult[1], \ + "Export to Imgur", wx.OK|wx.ICON_INFORMATION) + else: + wx.MessageBox("Failed to export to Imgur: " + imgurResult[1], \ + "Export to Imgur", wx.OK|wx.ICON_EXCLAMATION) + # }}} + # {{{ canvasExportPastebin(self, event): XXX + def canvasExportPastebin(self, event): + self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT)) + pasteStatus, pasteResult = \ + self.parentCanvas.canvasExportStore.exportPastebin( \ + "", \ + self.parentCanvas.canvasMap, \ + self.parentCanvas.canvasSize) + self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor)) + if pasteStatus: + if not wx.TheClipboard.IsOpened(): + wx.TheClipboard.Open() + wx.TheClipboard.SetData(wx.TextDataObject(pasteResult)) + wx.TheClipboard.Close() + wx.MessageBox("Exported to Pastebin: " + pasteResult, \ + "Export to Pastebin", wx.OK|wx.ICON_INFORMATION) + else: + wx.MessageBox("Failed to export to Pastebin: " + pasteResult, \ + "Export to Pastebin", wx.OK|wx.ICON_EXCLAMATION) + # }}} + # {{{ canvasIncrBrushHeight(self, event): XXX + def canvasIncrBrushHeight(self, event): + self.parentCanvas.brushSize[1] += 1 + self.parentFrame.onCanvasUpdate(brushSize=self.parentCanvas.brushSize) + # }}} + # {{{ canvasIncrBrushHeightWidth(self, event): XXX + def canvasIncrBrushHeightWidth(self, event): + self.canvasIncrBrushHeight(event) + self.canvasIncrBrushWidth(event) + # }}} + # {{{ canvasIncrBrushWidth(self, event): XXX + def canvasIncrBrushWidth(self, event): + self.parentCanvas.brushSize[0] += 1 + self.parentFrame.onCanvasUpdate(brushSize=self.parentCanvas.brushSize) + # }}} + # {{{ canvasIncrCanvasHeight(self, event): XXX + def canvasIncrCanvasHeight(self, event): + self.parentCanvas.resize([ \ + self.parentCanvas.canvasSize[0], \ + self.parentCanvas.canvasSize[1]+1]) + # }}} + # {{{ canvasIncrCanvasHeightWidth(self, event): XXX + def canvasIncrCanvasHeightWidth(self, event): + self.canvasIncrCanvasHeight(event) + self.canvasIncrCanvasWidth(event) + # }}} + # {{{ canvasIncrCanvasWidth(self, event): XXX + def canvasIncrCanvasWidth(self, event): + self.parentCanvas.resize([ \ + self.parentCanvas.canvasSize[0]+1, \ + self.parentCanvas.canvasSize[1]]) + # }}} + # {{{ canvasNew(self, event, newCanvasSize=None): XXX + def canvasNew(self, event, newCanvasSize=None): + if self.canvasPathName != None: + saveChanges = self._dialogSaveChanges() + if saveChanges == wx.ID_CANCEL: + return + elif saveChanges == wx.ID_NO: + pass + elif saveChanges == wx.ID_YES: + self.canvasSave(event) + self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT)) + if newCanvasSize == None: + newCanvasSize = list(self.parentCanvas.defaultCanvasSize) + self.parentCanvas.canvasImportStore.importNew(newCanvasSize) + self.canvasPathName = None + self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor)) + self.parentFrame.onCanvasUpdate(pathName="", undoLevel=-1) + # }}} + # {{{ canvasOpen(self, event): XXX + def canvasOpen(self, event): + if self.canvasPathName != None: + saveChanges = self._dialogSaveChanges() + if saveChanges == wx.ID_CANCEL: + return + elif saveChanges == wx.ID_NO: + pass + elif saveChanges == wx.ID_YES: + self.canvasSave(event) + with wx.FileDialog(self.parentCanvas, "Open", os.getcwd(), "", \ + "*.txt", wx.FD_OPEN) as dialog: + if dialog.ShowModal() == wx.ID_CANCEL: + return False + else: + self.canvasPathName = dialog.GetPath() + self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT)) + self.parentCanvas.canvasImportStore.importTextFile(self.canvasPathName) + self.parentCanvas.canvasImportStore.importIntoPanel() + self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor)) + self.parentFrame.onCanvasUpdate( \ + pathName=self.canvasPathName, undoLevel=-1) + return True + # }}} + # {{{ canvasPaste(self, event): XXX + def canvasPaste(self, event): + pass + # }}} + # {{{ canvasRedo(self, event): XXX + def canvasRedo(self, event): + self.parentCanvas._dispatchDeltaPatches( \ + self.parentCanvas.canvasJournal.popRedo()) + # }}} + # {{{ canvasSave(self, event): XXX + def canvasSave(self, event): + if self.canvasPathName == None: + if self.canvasSaveAs(event) == False: + return + try: + with open(self.canvasPathName, "w") as outFile: + self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT)) + self.parentCanvas.canvasExportStore.exportTextFile( \ + self.parentCanvas.canvasMap, \ + self.parentCanvas.canvasSize, outFile) + self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor)) + return True + except IOError as error: + return False + # }}} + # {{{ canvasSaveAs(self, event): XXX + def canvasSaveAs(self, event): + with wx.FileDialog(self.parentCanvas, "Save As", os.getcwd(), "", \ + "*.txt", wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT) as dialog: + if dialog.ShowModal() == wx.ID_CANCEL: + return False + else: + self.canvasPathName = dialog.GetPath() + return self.canvasSave(event) + # }}} + # {{{ canvasToolCircle(self, event): XXX + def canvasToolCircle(self, event): + self.canvasTool = MiRCARTToolCircle(self.parentCanvas) + self.parentFrame.menuItemsById[self.parentFrame.CID_CIRCLE[0]].Check(True) + toolBar = self.parentFrame.toolBarItemsById[self.parentFrame.CID_CIRCLE[0]].GetToolBar() + toolBar.ToggleTool(self.parentFrame.CID_CIRCLE[0], True) + self.parentFrame.onCanvasUpdate(toolName=self.canvasTool.name) + # }}} + # {{{ canvasToolFill(self, event): XXX + def canvasToolFill(self, event): + self.canvasTool = MiRCARTToolFill(self.parentCanvas) + self.parentFrame.menuItemsById[self.parentFrame.CID_FILL[0]].Check(True) + toolBar = self.parentFrame.toolBarItemsById[self.parentFrame.CID_FILL[0]].GetToolBar() + toolBar.ToggleTool(self.parentFrame.CID_FILL[0], True) + self.parentFrame.onCanvasUpdate(toolName=self.canvasTool.name) + # }}} + # {{{ canvasToolLine(self, event): XXX + def canvasToolLine(self, event): + self.canvasTool = MiRCARTToolLine(self.parentCanvas) + self.parentFrame.menuItemsById[self.parentFrame.CID_LINE[0]].Check(True) + toolBar = self.parentFrame.toolBarItemsById[self.parentFrame.CID_LINE[0]].GetToolBar() + toolBar.ToggleTool(self.parentFrame.CID_LINE[0], True) + self.parentFrame.onCanvasUpdate(toolName=self.canvasTool.name) + # }}} + # {{{ canvasToolSelectClone(self, event): XXX + def canvasToolSelectClone(self, event): + self.canvasTool = MiRCARTToolSelectClone(self.parentCanvas) + self.parentFrame.menuItemsById[self.parentFrame.CID_CLONE_SELECT[0]].Check(True) + toolBar = self.parentFrame.toolBarItemsById[self.parentFrame.CID_CLONE_SELECT[0]].GetToolBar() + toolBar.ToggleTool(self.parentFrame.CID_CLONE_SELECT[0], True) + self.parentFrame.onCanvasUpdate(toolName=self.canvasTool.name) + # }}} + # {{{ canvasToolSelectMove(self, event): XXX + def canvasToolSelectMove(self, event): + self.canvasTool = MiRCARTToolSelectMove(self.parentCanvas) + self.parentFrame.menuItemsById[self.parentFrame.CID_MOVE_SELECT[0]].Check(True) + toolBar = self.parentFrame.toolBarItemsById[self.parentFrame.CID_MOVE_SELECT[0]].GetToolBar() + toolBar.ToggleTool(self.parentFrame.CID_MOVE_SELECT[0], True) + self.parentFrame.onCanvasUpdate(toolName=self.canvasTool.name) + # }}} + # {{{ canvasToolRect(self, event): XXX + def canvasToolRect(self, event): + self.canvasTool = MiRCARTToolRect(self.parentCanvas) + self.parentFrame.menuItemsById[self.parentFrame.CID_RECT[0]].Check(True) + toolBar = self.parentFrame.toolBarItemsById[self.parentFrame.CID_RECT[0]].GetToolBar() + toolBar.ToggleTool(self.parentFrame.CID_RECT[0], True) + self.parentFrame.onCanvasUpdate(toolName=self.canvasTool.name) + # }}} + # {{{ canvasToolText(self, event): XXX + def canvasToolText(self, event): + self.canvasTool = MiRCARTToolText(self.parentCanvas) + self.parentFrame.menuItemsById[self.parentFrame.CID_TEXT[0]].Check(True) + toolBar = self.parentFrame.toolBarItemsById[self.parentFrame.CID_TEXT[0]].GetToolBar() + toolBar.ToggleTool(self.parentFrame.CID_TEXT[0], True) + self.parentFrame.onCanvasUpdate(toolName=self.canvasTool.name) + # }}} + # {{{ canvasUndo(self, event): XXX + def canvasUndo(self, event): + self.parentCanvas._dispatchDeltaPatches( \ + self.parentCanvas.canvasJournal.popUndo()) + # }}} + + # + # __init__(self, parentCanvas, parentFrame): + def __init__(self, parentCanvas, parentFrame): + self.parentCanvas = parentCanvas; self.parentFrame = parentFrame; + self.canvasPathName = None + self.canvasToolRect(None) + +# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 diff --git a/libcanvas/MiRCARTCanvasJournal.py b/libcanvas/MiRCARTCanvasJournal.py new file mode 100644 index 0000000..a198cac --- /dev/null +++ b/libcanvas/MiRCARTCanvasJournal.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python3 +# +# MiRCARTCanvasJournal.py -- XXX +# Copyright (c) 2018 Lucio Andrés Illanes Albornoz +# + +class MiRCARTCanvasJournal(): + """XXX""" + patchesCursor = patchesUndo = patchesUndoLevel = None + + # {{{ popCursor(self): XXX + def popCursor(self): + if len(self.patchesCursor): + patchesCursor = self.patchesCursor + self.patchesCursor = [] + return patchesCursor + else: + return [] + # }}} + # {{{ popRedo(self): XXX + def popRedo(self): + if self.patchesUndoLevel > 0: + self.patchesUndoLevel -= 1 + patches = self.patchesUndo[self.patchesUndoLevel] + return patches[1] + else: + return [] + # }}} + # {{{ popUndo(self): XXX + def popUndo(self): + if self.patchesUndo[self.patchesUndoLevel] != None: + patches = self.patchesUndo[self.patchesUndoLevel] + self.patchesUndoLevel += 1 + return patches[0] + else: + return [] + # }}} + # {{{ pushCursor(self, patches): XXX + def pushCursor(self, patches): + self.patchesCursor.append(patches) + # }}} + # {{{ pushDeltas(self, undoPatches, redoPatches): XXX + def pushDeltas(self, undoPatches, redoPatches): + if self.patchesUndoLevel > 0: + del self.patchesUndo[0:self.patchesUndoLevel] + self.patchesUndoLevel = 0 + deltaItem = [undoPatches, redoPatches] + self.patchesUndo.insert(0, deltaItem) + return deltaItem + # }}} + # {{{ resetCursor(self): XXX + def resetCursor(self): + if self.patchesCursor != None: + self.patchesCursor.clear() + self.patchesCursor = [] + # }}} + # {{{ resetUndo(self): XXX + def resetUndo(self): + if self.patchesUndo != None: + self.patchesUndo.clear() + self.patchesUndo = [None]; self.patchesUndoLevel = 0; + # }}} + # {{{ updateCurrentDeltas(self, undoPatches, redoPatches): XXX + def updateCurrentDeltas(self, undoPatches, redoPatches): + self.patchesUndo[0][0].append(undoPatches) + self.patchesUndo[0][1].append(redoPatches) + # }}} + + # {{{ __del__(self): destructor method + def __del__(self): + self.resetCursor(); self.resetUndo(); + # }}} + + # + # __init__(self): initialisation method + def __init__(self): + self.resetCursor(); self.resetUndo(); + +# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 diff --git a/libcanvas/MiRCARTColours.py b/libcanvas/MiRCARTColours.py new file mode 100644 index 0000000..b13e1c1 --- /dev/null +++ b/libcanvas/MiRCARTColours.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python3 +# +# MiRCARTColours.py -- XXX +# Copyright (c) 2018 Lucio Andrés Illanes Albornoz +# + +# +# MiRCARTColours: mIRC colour number to RGBA map given none of ^[BFV_] (bold, italic, reverse, underline], +# +MiRCARTColours = [ + [255, 255, 255, 255, "White"], + [0, 0, 0, 255, "Black"], + [0, 0, 187, 255, "Blue"], + [0, 187, 0, 255, "Green"], + [255, 85, 85, 255, "Light Red"], + [187, 0, 0, 255, "Red"], + [187, 0, 187, 255, "Purple"], + [187, 187, 0, 255, "Yellow"], + [255, 255, 85, 255, "Light Yellow"], + [85, 255, 85, 255, "Light Green"], + [0, 187, 187, 255, "Cyan"], + [85, 255, 255, 255, "Light Cyan"], + [85, 85, 255, 255, "Light Blue"], + [255, 85, 255, 255, "Pink"], + [85, 85, 85, 255, "Grey"], + [187, 187, 187, 255, "Light Grey"], +] + +# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 diff --git a/libgui/MiRCARTFrame.py b/libgui/MiRCARTFrame.py new file mode 100644 index 0000000..80b25c1 --- /dev/null +++ b/libgui/MiRCARTFrame.py @@ -0,0 +1,234 @@ +#!/usr/bin/env python3 +# +# MiRCARTFrame.py -- XXX +# Copyright (c) 2018 Lucio Andrés Illanes Albornoz +# + +from MiRCARTCanvas import MiRCARTCanvas, haveUrllib +from MiRCARTCanvasInterface import MiRCARTCanvasInterface +from MiRCARTColours import MiRCARTColours +from MiRCARTGeneralFrame import MiRCARTGeneralFrame, \ + TID_ACCELS, TID_COMMAND, TID_LIST, TID_MENU, TID_NOTHING, TID_SELECT, TID_TOOLBAR, \ + NID_MENU_SEP, NID_TOOLBAR_HSEP, NID_TOOLBAR_VSEP + +import os, wx + +class MiRCARTFrame(MiRCARTGeneralFrame): + """XXX""" + panelCanvas = None; lastPanelState = {}; + + # {{{ Commands + # Id Type Id Labels Icon bitmap Accelerator [Initial state] + CID_NEW = [0x100, TID_COMMAND, "New", "&New", ["", wx.ART_NEW], [wx.ACCEL_CTRL, ord("N")], None, MiRCARTCanvasInterface.canvasNew] + CID_OPEN = [0x101, TID_COMMAND, "Open", "&Open", ["", wx.ART_FILE_OPEN], [wx.ACCEL_CTRL, ord("O")], None, MiRCARTCanvasInterface.canvasOpen] + CID_SAVE = [0x102, TID_COMMAND, "Save", "&Save", ["", wx.ART_FILE_SAVE], [wx.ACCEL_CTRL, ord("S")], None, MiRCARTCanvasInterface.canvasSave] + CID_SAVEAS = [0x103, TID_COMMAND, "Save As...", "Save &As...", ["", wx.ART_FILE_SAVE_AS], None, None, MiRCARTCanvasInterface.canvasSaveAs] + CID_EXPORT_AS_PNG = [0x104, TID_COMMAND, "Export as PNG...", \ + "Export as PN&G...", None, None, None, MiRCARTCanvasInterface.canvasExportAsPng] + CID_EXPORT_IMGUR = [0x105, TID_COMMAND, "Export to Imgur...", \ + "Export to I&mgur...", None, None, haveUrllib, MiRCARTCanvasInterface.canvasExportImgur] + CID_EXPORT_PASTEBIN = [0x106, TID_COMMAND, "Export to Pastebin...", \ + "Export to Pasteb&in...", None, None, haveUrllib, MiRCARTCanvasInterface.canvasExportPastebin] + CID_EXIT = [0x107, TID_COMMAND, "Exit", "E&xit", None, [wx.ACCEL_CTRL, ord("X")], None, MiRCARTCanvasInterface.canvasExit] + CID_UNDO = [0x108, TID_COMMAND, "Undo", "&Undo", ["", wx.ART_UNDO], [wx.ACCEL_CTRL, ord("Z")], False, MiRCARTCanvasInterface.canvasUndo] + CID_REDO = [0x109, TID_COMMAND, "Redo", "&Redo", ["", wx.ART_REDO], [wx.ACCEL_CTRL, ord("Y")], False, MiRCARTCanvasInterface.canvasRedo] + CID_CUT = [0x10a, TID_COMMAND, "Cut", "Cu&t", ["", wx.ART_CUT], None, False, MiRCARTCanvasInterface.canvasCut] + CID_COPY = [0x10b, TID_COMMAND, "Copy", "&Copy", ["", wx.ART_COPY], None, False, MiRCARTCanvasInterface.canvasCopy] + CID_PASTE = [0x10c, TID_COMMAND, "Paste", "&Paste", ["", wx.ART_PASTE], None, False, MiRCARTCanvasInterface.canvasPaste] + CID_DELETE = [0x10d, TID_COMMAND, "Delete", "De&lete", ["", wx.ART_DELETE], None, False, MiRCARTCanvasInterface.canvasDelete] + CID_INCRW_CANVAS = [0x10e, TID_COMMAND, "Increase canvas width", \ + "Increase canvas width", ["toolIncrCanvasW.png"], None, None, MiRCARTCanvasInterface.canvasIncrCanvasWidth] + CID_DECRW_CANVAS = [0x10f, TID_COMMAND, "Decrease canvas width", \ + "Decrease canvas width", ["toolDecrCanvasW.png"], None, None, MiRCARTCanvasInterface.canvasDecrCanvasWidth] + CID_INCRH_CANVAS = [0x110, TID_COMMAND, "Increase canvas height", \ + "Increase canvas height", ["toolIncrCanvasH.png"], None, None, MiRCARTCanvasInterface.canvasIncrCanvasHeight] + CID_DECRH_CANVAS = [0x111, TID_COMMAND, "Decrease canvas height", \ + "Decrease canvas height", ["toolDecrCanvasH.png"], None, None, MiRCARTCanvasInterface.canvasDecrCanvasHeight] + CID_INCRHW_CANVAS = [0x112, TID_COMMAND, "Increase canvas size", \ + "Increase canvas size", ["toolIncrCanvasHW.png"], None, None, MiRCARTCanvasInterface.canvasIncrCanvasHeightWidth] + CID_DECRHW_CANVAS = [0x113, TID_COMMAND, "Decrease canvas size", \ + "Decrease canvas size", ["toolDecrCanvasHW.png"], None, None, MiRCARTCanvasInterface.canvasDecrCanvasHeightWidth] + CID_INCRW_BRUSH = [0x114, TID_COMMAND, "Increase brush width", \ + "Increase brush width", ["toolIncrBrushW.png"], None, None, MiRCARTCanvasInterface.canvasIncrBrushWidth] + CID_DECRW_BRUSH = [0x115, TID_COMMAND, "Decrease brush width", \ + "Decrease brush width", ["toolDecrBrushW.png"], None, None, MiRCARTCanvasInterface.canvasDecrBrushWidth] + CID_INCRH_BRUSH = [0x116, TID_COMMAND, "Increase brush height", \ + "Increase brush height", ["toolIncrBrushH.png"], None, None, MiRCARTCanvasInterface.canvasIncrBrushHeight] + CID_DECRH_BRUSH = [0x117, TID_COMMAND, "Decrease brush height", \ + "Decrease brush height", ["toolDecrBrushH.png"], None, None, MiRCARTCanvasInterface.canvasDecrBrushHeight] + CID_INCRHW_BRUSH = [0x118, TID_COMMAND, "Increase brush size", \ + "Increase brush size", ["toolIncrBrushHW.png"], None, None, MiRCARTCanvasInterface.canvasIncrBrushHeightWidth] + CID_DECRHW_BRUSH = [0x119, TID_COMMAND, "Decrease brush size", \ + "Decrease brush size", ["toolDecrBrushHW.png"], None, None, MiRCARTCanvasInterface.canvasDecrBrushHeightWidth] + CID_SOLID_BRUSH = [0x11a, TID_SELECT, "Solid brush", "Solid brush", None, None, True, MiRCARTCanvasInterface.canvasBrushSolid] + + CID_RECT = [0x150, TID_SELECT, "Rectangle", "&Rectangle", ["toolRect.png"], [wx.ACCEL_CTRL, ord("R")], True, MiRCARTCanvasInterface.canvasToolRect] + CID_CIRCLE = [0x151, TID_SELECT, "Circle", "&Circle", ["toolCircle.png"], [wx.ACCEL_CTRL, ord("C")], False, MiRCARTCanvasInterface.canvasToolCircle] + CID_FILL = [0x152, TID_SELECT, "Fill", "&Fill", ["toolFill.png"], [wx.ACCEL_CTRL, ord("F")], False, MiRCARTCanvasInterface.canvasToolFill] + CID_LINE = [0x153, TID_SELECT, "Line", "&Line", ["toolLine.png"], [wx.ACCEL_CTRL, ord("L")], False, MiRCARTCanvasInterface.canvasToolLine] + CID_TEXT = [0x154, TID_SELECT, "Text", "&Text", ["toolText.png"], [wx.ACCEL_CTRL, ord("T")], False, MiRCARTCanvasInterface.canvasToolText] + CID_CLONE_SELECT = [0x155, TID_SELECT, "Clone", "Cl&one", ["toolClone.png"], [wx.ACCEL_CTRL, ord("E")], False, MiRCARTCanvasInterface.canvasToolSelectClone] + CID_MOVE_SELECT = [0x156, TID_SELECT, "Move", "&Move", ["toolMove.png"], [wx.ACCEL_CTRL, ord("M")], False, MiRCARTCanvasInterface.canvasToolSelectMove] + + CID_COLOUR00 = [0x1a0, TID_SELECT, "Colour #00", "Colour #00", None, None, False, MiRCARTCanvasInterface.canvasColour] + CID_COLOUR01 = [0x1a1, TID_SELECT, "Colour #01", "Colour #01", None, None, False, MiRCARTCanvasInterface.canvasColour] + CID_COLOUR02 = [0x1a2, TID_SELECT, "Colour #02", "Colour #02", None, None, False, MiRCARTCanvasInterface.canvasColour] + CID_COLOUR03 = [0x1a3, TID_SELECT, "Colour #03", "Colour #03", None, None, False, MiRCARTCanvasInterface.canvasColour] + CID_COLOUR04 = [0x1a4, TID_SELECT, "Colour #04", "Colour #04", None, None, True, MiRCARTCanvasInterface.canvasColour] + CID_COLOUR05 = [0x1a5, TID_SELECT, "Colour #05", "Colour #05", None, None, False, MiRCARTCanvasInterface.canvasColour] + CID_COLOUR06 = [0x1a6, TID_SELECT, "Colour #06", "Colour #06", None, None, False, MiRCARTCanvasInterface.canvasColour] + CID_COLOUR07 = [0x1a7, TID_SELECT, "Colour #07", "Colour #07", None, None, False, MiRCARTCanvasInterface.canvasColour] + CID_COLOUR08 = [0x1a8, TID_SELECT, "Colour #08", "Colour #08", None, None, False, MiRCARTCanvasInterface.canvasColour] + CID_COLOUR09 = [0x1a9, TID_SELECT, "Colour #09", "Colour #09", None, None, False, MiRCARTCanvasInterface.canvasColour] + CID_COLOUR10 = [0x1aa, TID_SELECT, "Colour #10", "Colour #10", None, None, False, MiRCARTCanvasInterface.canvasColour] + CID_COLOUR11 = [0x1ab, TID_SELECT, "Colour #11", "Colour #11", None, None, False, MiRCARTCanvasInterface.canvasColour] + CID_COLOUR12 = [0x1ac, TID_SELECT, "Colour #12", "Colour #12", None, None, False, MiRCARTCanvasInterface.canvasColour] + CID_COLOUR13 = [0x1ad, TID_SELECT, "Colour #13", "Colour #13", None, None, False, MiRCARTCanvasInterface.canvasColour] + CID_COLOUR14 = [0x1ae, TID_SELECT, "Colour #14", "Colour #14", None, None, False, MiRCARTCanvasInterface.canvasColour] + CID_COLOUR15 = [0x1af, TID_SELECT, "Colour #15", "Colour #15", None, None, False, MiRCARTCanvasInterface.canvasColour] + # }}} + # {{{ Menus + MID_FILE = (0x300, TID_MENU, "File", "&File", ( \ + CID_NEW, CID_OPEN, CID_SAVE, CID_SAVEAS, NID_MENU_SEP, \ + CID_EXPORT_AS_PNG, CID_EXPORT_IMGUR, CID_EXPORT_PASTEBIN, NID_MENU_SEP, \ + CID_EXIT)) + MID_EDIT = (0x301, TID_MENU, "Edit", "&Edit", ( \ + CID_UNDO, CID_REDO, NID_MENU_SEP, \ + CID_CUT, CID_COPY, CID_PASTE, CID_DELETE, NID_MENU_SEP, \ + CID_INCRW_CANVAS, CID_DECRW_CANVAS, CID_INCRH_CANVAS, CID_DECRH_CANVAS, NID_MENU_SEP, \ + CID_INCRHW_CANVAS, CID_DECRHW_CANVAS, NID_MENU_SEP, \ + CID_INCRW_BRUSH, CID_DECRW_BRUSH, CID_INCRH_BRUSH, CID_DECRH_BRUSH, NID_MENU_SEP, \ + CID_INCRHW_BRUSH, CID_DECRHW_BRUSH, NID_MENU_SEP, \ + CID_SOLID_BRUSH)) + MID_TOOLS = (0x302, TID_MENU, "Tools", "&Tools", ( \ + CID_RECT, CID_CIRCLE, CID_FILL, CID_LINE, CID_TEXT, CID_CLONE_SELECT, CID_MOVE_SELECT)) + # }}} + # {{{ Toolbars + BID_TOOLBAR = (0x400, TID_TOOLBAR, ( \ + CID_NEW, CID_OPEN, CID_SAVE, CID_SAVEAS, NID_TOOLBAR_HSEP, \ + CID_UNDO, CID_REDO, NID_TOOLBAR_HSEP, \ + CID_CUT, CID_COPY, CID_PASTE, CID_DELETE, NID_TOOLBAR_HSEP, \ + CID_INCRW_CANVAS, CID_DECRW_CANVAS, CID_INCRH_CANVAS, CID_DECRH_CANVAS, NID_TOOLBAR_HSEP, \ + CID_INCRHW_CANVAS, CID_DECRHW_CANVAS, NID_TOOLBAR_HSEP, \ + CID_RECT, CID_CIRCLE, CID_FILL, CID_LINE, CID_TEXT, CID_CLONE_SELECT, CID_MOVE_SELECT, \ + NID_TOOLBAR_VSEP, \ + CID_COLOUR00, CID_COLOUR01, CID_COLOUR02, CID_COLOUR03, CID_COLOUR04, \ + CID_COLOUR05, CID_COLOUR06, CID_COLOUR07, CID_COLOUR08, CID_COLOUR09, \ + CID_COLOUR10, CID_COLOUR11, CID_COLOUR12, CID_COLOUR13, CID_COLOUR14, \ + CID_COLOUR15, NID_TOOLBAR_HSEP, \ + CID_INCRW_BRUSH, CID_DECRW_BRUSH, CID_INCRH_BRUSH, CID_DECRH_BRUSH, NID_TOOLBAR_HSEP, \ + CID_INCRHW_BRUSH, CID_DECRHW_BRUSH)) + # }}} + # {{{ Accelerators (hotkeys) + AID_EDIT = (0x500, TID_ACCELS, ( \ + CID_NEW, CID_OPEN, CID_SAVE, CID_EXIT, CID_UNDO, CID_REDO, \ + CID_RECT, CID_CIRCLE, CID_FILL, CID_LINE, CID_TEXT, CID_CLONE_SELECT, CID_MOVE_SELECT)) + # }}} + # {{{ Lists + LID_ACCELS = (0x600, TID_LIST, (AID_EDIT)) + LID_MENUS = (0x601, TID_LIST, (MID_FILE, MID_EDIT, MID_TOOLS)) + LID_TOOLBARS = (0x602, TID_LIST, (BID_TOOLBAR)) + # }}} + + # {{{ _initPaletteToolBitmaps(self): XXX + def _initPaletteToolBitmaps(self): + paletteDescr = ( \ + self.CID_COLOUR00, self.CID_COLOUR01, self.CID_COLOUR02, self.CID_COLOUR03, self.CID_COLOUR04, \ + self.CID_COLOUR05, self.CID_COLOUR06, self.CID_COLOUR07, self.CID_COLOUR08, self.CID_COLOUR09, \ + self.CID_COLOUR10, self.CID_COLOUR11, self.CID_COLOUR12, self.CID_COLOUR13, self.CID_COLOUR14, \ + self.CID_COLOUR15) + for numColour in range(len(paletteDescr)): + toolBitmapColour = MiRCARTColours[numColour][0:4] + toolBitmap = wx.Bitmap((16,16)) + toolBitmapDc = wx.MemoryDC(); toolBitmapDc.SelectObject(toolBitmap); + toolBitmapBrush = wx.Brush( \ + wx.Colour(toolBitmapColour), wx.BRUSHSTYLE_SOLID) + toolBitmapDc.SetBrush(toolBitmapBrush) + toolBitmapDc.SetBackground(toolBitmapBrush) + toolBitmapDc.SetPen(wx.Pen(wx.Colour(toolBitmapColour), 1)) + toolBitmapDc.DrawRectangle(0, 0, 16, 16) + paletteDescr[numColour][4] = ["", None, toolBitmap] + # }}} + + # {{{ onInput(self, event): XXX + def onInput(self, event): + eventId = event.GetId() + if eventId >= self.CID_COLOUR00[0] \ + and eventId <= self.CID_COLOUR15[0]: + numColour = eventId - self.CID_COLOUR00[0] + self.itemsById[eventId][7](self.panelCanvas.canvasInterface, event, numColour) + else: + self.itemsById[eventId][7](self.panelCanvas.canvasInterface, event) + # }}} + # {{{ onCanvasUpdate(self, newBrushSize=None, newCellPos=None, newColours=None, newPathName=None, newSize=None, newToolName=None, newUndoLevel=None): XXX + def onCanvasUpdate(self, **kwargs): + self.lastPanelState.update(kwargs) + textItems = [] + if "cellPos" in self.lastPanelState: + textItems.append("X: {:03d} Y: {:03d}".format( \ + *self.lastPanelState["cellPos"])) + if "size" in self.lastPanelState: + textItems.append("W: {:03d} H: {:03d}".format( \ + *self.lastPanelState["size"])) + if "brushSize" in self.lastPanelState: + textItems.append("Brush: {:02d}x{:02d}".format( \ + *self.lastPanelState["brushSize"])) + if "colours" in self.lastPanelState: + textItems.append("FG: {:02d}, BG: {:02d}".format( \ + *self.lastPanelState["colours"])) + textItems.append("{} on {}".format( \ + MiRCARTColours[self.lastPanelState["colours"][0]][4], \ + MiRCARTColours[self.lastPanelState["colours"][1]][4])) + if "pathName" in self.lastPanelState: + if self.lastPanelState["pathName"] != "": + basePathName = os.path.basename(self.lastPanelState["pathName"]) + textItems.append("Current file: {}".format(basePathName)) + self.SetTitle("{} - MiRCART".format(basePathName)) + else: + self.SetTitle("MiRCART") + if "toolName" in self.lastPanelState: + textItems.append("Current tool: {}".format( \ + self.lastPanelState["toolName"])) + self.statusBar.SetStatusText(" | ".join(textItems)) + if "undoLevel" in self.lastPanelState: + if self.lastPanelState["undoLevel"] >= 0: + self.menuItemsById[self.CID_UNDO[0]].Enable(True) + toolBar = self.toolBarItemsById[self.CID_UNDO[0]].GetToolBar() + toolBar.EnableTool(self.CID_UNDO[0], True) + else: + self.menuItemsById[self.CID_UNDO[0]].Enable(False) + toolBar = self.toolBarItemsById[self.CID_UNDO[0]].GetToolBar() + toolBar.EnableTool(self.CID_UNDO[0], False) + if self.lastPanelState["undoLevel"] > 0: + self.menuItemsById[self.CID_REDO[0]].Enable(True) + toolBar = self.toolBarItemsById[self.CID_REDO[0]].GetToolBar() + toolBar.EnableTool(self.CID_REDO[0], True) + else: + self.menuItemsById[self.CID_REDO[0]].Enable(False) + toolBar = self.toolBarItemsById[self.CID_REDO[0]].GetToolBar() + toolBar.EnableTool(self.CID_REDO[0], False) + # }}} + + # {{{ __del__(self): destructor method + def __del__(self): + if self.panelCanvas != None: + del self.panelCanvas; self.panelCanvas = None; + # }}} + + # + # __init__(self, parent, appSize=(840, 630), defaultCanvasPos=(0, 75), defaultCanvasSize=(100, 30), defaultCellSize=(7, 14)): initialisation method + def __init__(self, parent, appSize=(840, 630), defaultCanvasPos=(0, 75), defaultCanvasSize=(100, 30), defaultCellSize=(7, 14)): + self._initPaletteToolBitmaps() + self.panelSkin = super().__init__(parent, wx.ID_ANY, "MiRCART", size=appSize) + self.panelCanvas = MiRCARTCanvas(self.panelSkin, parentFrame=self, \ + defaultCanvasPos=defaultCanvasPos, \ + defaultCanvasSize=defaultCanvasSize, \ + defaultCellSize=defaultCellSize) + self.panelCanvas.canvasInterface.canvasNew(None) + self.sizerSkin.AddSpacer(5) + self.sizerSkin.Add(self.panelCanvas, 0, wx.ALL|wx.EXPAND, 14) + self.panelSkin.SetSizer(self.sizerSkin) + self.panelSkin.SetAutoLayout(1) + self.sizerSkin.Fit(self.panelSkin) + +# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 diff --git a/libgui/MiRCARTGeneralFrame.py b/libgui/MiRCARTGeneralFrame.py new file mode 100644 index 0000000..6c6804a --- /dev/null +++ b/libgui/MiRCARTGeneralFrame.py @@ -0,0 +1,169 @@ +#!/usr/bin/env python3 +# +# MiRCARTGeneralFrame.py -- XXX +# Copyright (c) 2018 Lucio Andrés Illanes Albornoz +# + +import os, sys, wx + +# +# Types +TID_ACCELS = (0x001) +TID_COMMAND = (0x002) +TID_LIST = (0x003) +TID_MENU = (0x004) +TID_NOTHING = (0x005) +TID_SELECT = (0x006) +TID_TOOLBAR = (0x007) + +# +# Non-items +NID_MENU_SEP = (0x200, TID_NOTHING) +NID_TOOLBAR_HSEP = (0x201, TID_NOTHING) +NID_TOOLBAR_VSEP = (0x202, TID_NOTHING) + +class MiRCARTGeneralFrame(wx.Frame): + """XXX""" + accelItemsById = itemsById = menuItemsById = toolBarItemsById = None + statusBar = toolBars = None + panelSkin = sizerSkin = None + + # {{{ _initAccelTable(self, accelsDescr): XXX + def _initAccelTable(self, accelsDescr): + accelTableEntries = [wx.AcceleratorEntry() for n in range(len(accelsDescr[2]))] + self.accelItemsById = {} + for numAccel in range(len(accelsDescr[2])): + accelDescr = accelsDescr[2][numAccel] + if accelDescr[5] != None: + self.itemsById[accelDescr[0]] = accelDescr + accelTableEntries[numAccel].Set(*accelDescr[5], accelDescr[0]) + self.accelItemsById[accelDescr[0]] = accelTableEntries[numAccel] + self.Bind(wx.EVT_MENU, self.onInput, id=accelDescr[0]) + return accelTableEntries + # }}} + # {{{ _initMenus(self, menusDescr): XXX + def _initMenus(self, menusDescr): + self.menuItemsById = {}; menuBar = wx.MenuBar(); + for menuDescr in menusDescr: + menuWindow = wx.Menu() + for menuItem in menuDescr[4]: + if menuItem == NID_MENU_SEP: + menuWindow.AppendSeparator() + elif menuItem[1] == TID_SELECT: + self.itemsById[menuItem[0]] = menuItem + menuItemWindow = menuWindow.AppendRadioItem(menuItem[0], menuItem[3], menuItem[2]) + if menuItem[5] != None: + menuItemWindow.SetAccel(self.accelItemsById[menuItem[0]]) + self.menuItemsById[menuItem[0]] = menuItemWindow + self.Bind(wx.EVT_MENU, self.onInput, menuItemWindow) + if menuItem[6] != None: + menuItemWindow.Check(menuItem[6]) + else: + self.itemsById[menuItem[0]] = menuItem + menuItemWindow = menuWindow.Append(menuItem[0], menuItem[3], menuItem[2]) + if menuItem[5] != None: + menuItemWindow.SetAccel(self.accelItemsById[menuItem[0]]) + self.menuItemsById[menuItem[0]] = menuItemWindow + self.Bind(wx.EVT_MENU, self.onInput, menuItemWindow) + if menuItem[6] != None: + menuItemWindow.Enable(menuItem[6]) + menuBar.Append(menuWindow, menuDescr[3]) + return menuBar + # }}} + # {{{ _initToolBars(self, toolBarsDescr, panelSkin): XXX + def _initToolBars(self, toolBarsDescr, panelSkin): + self.toolBarItemsById = {} + self.sizerSkin = wx.BoxSizer(wx.VERTICAL) + self.toolBars = [None]; numToolBar = 0; + for toolBarItem in toolBarsDescr[2]: + if self.toolBars[numToolBar] == None: + self.toolBars[numToolBar] = \ + wx.ToolBar(panelSkin, -1, \ + style=wx.HORIZONTAL|wx.TB_FLAT|wx.TB_NODIVIDER) + self.toolBars[numToolBar].SetToolBitmapSize((16,16)) + if toolBarItem == NID_TOOLBAR_HSEP: + self.toolBars[numToolBar].AddSeparator() + elif toolBarItem == NID_TOOLBAR_VSEP: + numToolBar += 1; self.toolBars.append(None); + elif toolBarItem[1] == TID_SELECT: + self.itemsById[toolBarItem[0]] = toolBarItem + toolBarItemWindow = \ + self.toolBars[numToolBar].AddRadioTool( \ + toolBarItem[0], toolBarItem[2], toolBarItem[4][2]) + self.toolBarItemsById[toolBarItem[0]] = toolBarItemWindow + if toolBarItem[6] != None: + toolBarItemWindow.Toggle(toolBarItem[6]) + self.Bind(wx.EVT_TOOL, self.onInput, toolBarItemWindow) + self.Bind(wx.EVT_TOOL_RCLICKED, self.onInput, toolBarItemWindow) + else: + self.itemsById[toolBarItem[0]] = toolBarItem + toolBarItemWindow = \ + self.toolBars[numToolBar].AddTool( \ + toolBarItem[0], toolBarItem[2], toolBarItem[4][2]) + self.toolBarItemsById[toolBarItem[0]] = toolBarItemWindow + if toolBarItem[6] != None: + toolBarItemWindow.Enable(toolBarItem[6]) + self.Bind(wx.EVT_TOOL, self.onInput, toolBarItemWindow) + self.Bind(wx.EVT_TOOL_RCLICKED, self.onInput, toolBarItemWindow) + for numToolBar in range(len(self.toolBars)): + self.sizerSkin.Add( \ + self.toolBars[numToolBar], 0, wx.ALL|wx.ALIGN_LEFT, 3) + self.toolBars[numToolBar].Realize() + self.toolBars[numToolBar].Fit() + # }}} + # {{{ _initToolBitmaps(self, toolBarsDescr): XXX + def _initToolBitmaps(self, toolBarsDescr): + for toolBarItem in toolBarsDescr[2]: + if toolBarItem == NID_TOOLBAR_HSEP \ + or toolBarItem == NID_TOOLBAR_VSEP: + continue + elif toolBarItem[4] == None: + toolBarItem[4] = ["", None, wx.ArtProvider.GetBitmap( \ + wx.ART_HELP, wx.ART_TOOLBAR, (16,16))] + elif toolBarItem[4][0] == "" \ + and toolBarItem[4][1] != None: + toolBarItem[4] = ["", None, wx.ArtProvider.GetBitmap( \ + toolBarItem[4][1], wx.ART_TOOLBAR, (16,16))] + elif toolBarItem[4][0] == "" \ + and toolBarItem[4][1] == None: + toolBarItem[4] = ["", None, toolBarItem[4][2]] + elif toolBarItem[4][0] != "": + toolBitmapPathName = os.path.dirname(sys.argv[0]) + toolBitmapPathName = os.path.join(toolBitmapPathName, \ + "assets", "images", toolBarItem[4][0]) + toolBitmap = wx.Bitmap((16,16)) + toolBitmap.LoadFile(toolBitmapPathName, wx.BITMAP_TYPE_ANY) + toolBarItem[4] = ["", None, toolBitmap] + # }}} + # {{{ onInput(self, event): XXX + def onInput(self, event): + pass + # }}} + + # + # __init__(self, *args, **kwargs): initialisation method + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs); self.itemsById = {}; + panelSkin = wx.Panel(self, wx.ID_ANY) + + # Initialise accelerators (hotkeys) + accelTable = wx.AcceleratorTable( \ + self._initAccelTable(self.LID_ACCELS[2])) + self.SetAcceleratorTable(accelTable) + + # Initialise menu bar, menus & menu items + # Initialise toolbar & toolbar items + menuBar = self._initMenus(self.LID_MENUS[2]) + self.SetMenuBar(menuBar) + self._initToolBitmaps(self.LID_TOOLBARS[2]) + toolBar = self._initToolBars(self.LID_TOOLBARS[2], panelSkin) + + # Initialise status bar + self.statusBar = self.CreateStatusBar() + + # Set focus on & show window + self.SetFocus(); self.Show(True); + + return panelSkin + +# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 diff --git a/MiRCART-python/IrcClient.py b/librtl/IrcClient.py similarity index 100% rename from MiRCART-python/IrcClient.py rename to librtl/IrcClient.py diff --git a/libtools/MiRCARTTool.py b/libtools/MiRCARTTool.py new file mode 100644 index 0000000..b63b0c7 --- /dev/null +++ b/libtools/MiRCARTTool.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python3 +# +# MiRCARTTool.py -- XXX +# Copyright (c) 2018 Lucio Andrés Illanes Albornoz +# + +class MiRCARTTool(): + """XXX""" + parentCanvas = None + + # {{{ onKeyboardEvent(self, event, atPoint, brushColours, brushSize, keyChar, dispatchFn, eventDc): + def onKeyboardEvent(self, event, atPoint, brushColours, brushSize, keyChar, dispatchFn, eventDc): + return True + # }}} + # {{{ onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc): XXX + def onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc): + return () + # }}} + + # + # __init__(self, parentCanvas): initialisation method + def __init__(self, parentCanvas): + self.parentCanvas = parentCanvas + +# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 diff --git a/libtools/MiRCARTToolCircle.py b/libtools/MiRCARTToolCircle.py new file mode 100644 index 0000000..161b2c6 --- /dev/null +++ b/libtools/MiRCARTToolCircle.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python3 +# +# MiRCARTToolCircle.py -- XXX +# Copyright (c) 2018 Lucio Andrés Illanes Albornoz +# + +from MiRCARTTool import MiRCARTTool + +class MiRCARTToolCircle(MiRCARTTool): + """XXX""" + name = "Circle" + + # + # onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc): XXX + def onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc): + brushColours = brushColours.copy() + if isLeftDown: + brushColours[1] = brushColours[0] + elif isRightDown: + brushColours[0] = brushColours[1] + else: + brushColours[1] = brushColours[0] + _brushSize = brushSize[0]*2 + originPoint = (_brushSize/2, _brushSize/2) + radius = _brushSize + for brushY in range(-radius, radius + 1): + for brushX in range(-radius, radius + 1): + if ((brushX**2)+(brushY**2) < (((radius**2)+radius)*0.8)): + patch = [ \ + atPoint[0] + int(originPoint[0]+brushX), \ + atPoint[1] + int(originPoint[1]+brushY), \ + *brushColours, 0, " "] + if isLeftDown or isRightDown: + dispatchFn(eventDc, False, patch); dispatchFn(eventDc, True, patch); + else: + dispatchFn(eventDc, True, patch) + +# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 diff --git a/libtools/MiRCARTToolFill.py b/libtools/MiRCARTToolFill.py new file mode 100644 index 0000000..7ce1609 --- /dev/null +++ b/libtools/MiRCARTToolFill.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python3 +# +# MiRCARTToolFill.py -- XXX +# Copyright (c) 2018 Lucio Andrés Illanes Albornoz +# + +from MiRCARTTool import MiRCARTTool + +class MiRCARTToolFill(MiRCARTTool): + """XXX""" + name = "Fill" + + # + # onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc): XXX + def onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc): + pointStack = [list(atPoint)]; pointsDone = []; + testColour = self.parentCanvas.canvasMap[atPoint[1]][atPoint[0]][0:2] + if isLeftDown or isRightDown: + if isRightDown: + brushColours = [brushColours[1], brushColours[0]] + while len(pointStack) > 0: + point = pointStack.pop() + pointCell = self.parentCanvas.canvasMap[point[1]][point[0]] + if pointCell[0:2] == testColour: + if not point in pointsDone: + dispatchFn(eventDc, False, [*point, \ + brushColours[0], brushColours[0], 0, " "]) + if point[0] > 0: + pointStack.append([point[0] - 1, point[1]]) + if point[0] < (self.parentCanvas.canvasSize[0] - 1): + pointStack.append([point[0] + 1, point[1]]) + if point[1] > 0: + pointStack.append([point[0], point[1] - 1]) + if point[1] < (self.parentCanvas.canvasSize[1] - 1): + pointStack.append([point[0], point[1] + 1]) + pointsDone += [point] + +# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 diff --git a/libtools/MiRCARTToolLine.py b/libtools/MiRCARTToolLine.py new file mode 100644 index 0000000..9133289 --- /dev/null +++ b/libtools/MiRCARTToolLine.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python3 +# +# MiRCARTToolLine.py -- XXX +# Copyright (c) 2018 Lucio Andrés Illanes Albornoz +# + +from MiRCARTTool import MiRCARTTool + +class MiRCARTToolLine(MiRCARTTool): + """XXX""" + name = "Line" + toolColours = toolOriginPoint = toolState = None + + TS_NONE = 0 + TS_ORIGIN = 1 + + # {{{ _pointDelta(self, a, b): XXX + def _pointDelta(self, a, b): + return [a2-a1 for a1, a2 in zip(a, b)] + # }}} + # {{{ _pointSwap(self, a, b): XXX + def _pointSwap(self, a, b): + return [b, a] + # }}} + # {{{ _getLine(self, brushColours, brushSize, eventDc, isCursor, originPoint, targetPoint, dispatchFn): XXX + def _getLine(self, brushColours, brushSize, eventDc, isCursor, originPoint, targetPoint, dispatchFn): + originPoint = originPoint.copy(); targetPoint = targetPoint.copy(); + pointDelta = self._pointDelta(originPoint, targetPoint) + lineXSign = 1 if pointDelta[0] > 0 else -1; + lineYSign = 1 if pointDelta[1] > 0 else -1; + pointDelta = [abs(a) for a in pointDelta] + if pointDelta[0] > pointDelta[1]: + lineXX, lineXY, lineYX, lineYY = lineXSign, 0, 0, lineYSign + else: + pointDelta = [pointDelta[1], pointDelta[0]] + lineXX, lineXY, lineYX, lineYY = 0, lineYSign, lineXSign, 0 + lineD = 2 * pointDelta[1] - pointDelta[0]; lineY = 0; + for lineX in range(pointDelta[0] + 1): + for brushStep in range(brushSize[0]): + patch = [ \ + originPoint[0] + lineX*lineXX + lineY*lineYX + brushStep, \ + originPoint[1] + lineX*lineXY + lineY*lineYY, \ + *brushColours, 0, " "] + if isCursor: + dispatchFn(eventDc, False, patch); dispatchFn(eventDc, True, patch); + else: + dispatchFn(eventDc, True, patch) + if lineD > 0: + lineD -= pointDelta[0]; lineY += 1; + lineD += pointDelta[1] + # }}} + + # + # onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc): XXX + def onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc): + brushColours = brushColours.copy() + if isLeftDown: + brushColours[1] = brushColours[0] + elif isRightDown: + brushColours[0] = brushColours[1] + else: + brushColours[1] = brushColours[0] + if self.toolState == self.TS_NONE: + if isLeftDown or isRightDown: + self.toolColours = brushColours + self.toolOriginPoint = list(atPoint) + self.toolState = self.TS_ORIGIN + dispatchFn(eventDc, True, [*atPoint, *brushColours, 0, " "]) + elif self.toolState == self.TS_ORIGIN: + targetPoint = list(atPoint) + originPoint = self.toolOriginPoint + self._getLine(self.toolColours, brushSize, \ + eventDc, isLeftDown or isRightDown, \ + originPoint, targetPoint, dispatchFn) + if isLeftDown or isRightDown: + self.toolColours = None + self.toolOriginPoint = None + self.toolState = self.TS_NONE + + # __init__(self, *args): initialisation method + def __init__(self, *args): + super().__init__(*args) + self.toolColours = None + self.toolOriginPoint = None + self.toolState = self.TS_NONE + +# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 diff --git a/libtools/MiRCARTToolRect.py b/libtools/MiRCARTToolRect.py new file mode 100644 index 0000000..b9377e2 --- /dev/null +++ b/libtools/MiRCARTToolRect.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 +# +# MiRCARTToolRect.py -- XXX +# Copyright (c) 2018 Lucio Andrés Illanes Albornoz +# + +from MiRCARTTool import MiRCARTTool + +class MiRCARTToolRect(MiRCARTTool): + """XXX""" + name = "Rectangle" + + # + # onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc): XXX + def onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc): + brushColours = brushColours.copy() + if isLeftDown: + brushColours[1] = brushColours[0] + elif isRightDown: + brushColours[0] = brushColours[1] + else: + brushColours[1] = brushColours[0] + brushSize = brushSize.copy() + if brushSize[0] > 1: + brushSize[0] *= 2 + for brushRow in range(brushSize[1]): + for brushCol in range(brushSize[0]): + patch = [atPoint[0] + brushCol, atPoint[1] + brushRow, *brushColours, 0, " "] + if isLeftDown or isRightDown: + dispatchFn(eventDc, False, patch); dispatchFn(eventDc, True, patch); + else: + dispatchFn(eventDc, True, patch) + +# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 diff --git a/libtools/MiRCARTToolSelect.py b/libtools/MiRCARTToolSelect.py new file mode 100644 index 0000000..0733d2b --- /dev/null +++ b/libtools/MiRCARTToolSelect.py @@ -0,0 +1,111 @@ +#!/usr/bin/env python3 +# +# MiRCARTToolSelect.py -- XXX +# Copyright (c) 2018 Lucio Andrés Illanes Albornoz +# + +from MiRCARTTool import MiRCARTTool + +class MiRCARTToolSelect(MiRCARTTool): + """XXX""" + toolColours = toolRect = toolState = None + toolLastAtPoint = None + toolSelectMap = None + srcRect = None + + TS_NONE = 0 + TS_ORIGIN = 1 + TS_TARGET = 2 + + # {{{ _drawSelectRect(self, rect, dispatchFn, eventDc): XXX + def _drawSelectRect(self, rect, dispatchFn, eventDc): + rectFrame = [ \ + [rect[0][0]-1, rect[0][1]-1], \ + [rect[1][0]+1, rect[1][1]+1]] + if rectFrame[0][0] > rectFrame[1][0]: + rectFrame[0][0], rectFrame[1][0] = \ + rectFrame[1][0], rectFrame[0][0] + if rectFrame[0][1] > rectFrame[1][1]: + rectFrame[0][1], rectFrame[1][1] = \ + rectFrame[1][1], rectFrame[0][1] + curColours = [0, 0] + for rectX in range(rectFrame[0][0], rectFrame[1][0]+1): + if curColours == [0, 0]: + curColours = [1, 1] + else: + curColours = [0, 0] + dispatchFn(eventDc, True, \ + [rectX, rectFrame[0][1], *curColours, 0, " "]) + dispatchFn(eventDc, True, \ + [rectX, rectFrame[1][1], *curColours, 0, " "]) + for rectY in range(rectFrame[0][1], rectFrame[1][1]+1): + if curColours == [0, 0]: + curColours = [1, 1] + else: + curColours = [0, 0] + dispatchFn(eventDc, True, \ + [rectFrame[0][0], rectY, *curColours, 0, " "]) + dispatchFn(eventDc, True, \ + [rectFrame[1][0], rectY, *curColours, 0, " "]) + # }}} + + # + # onSelectEvent(self, event, atPoint, selectRect, brushColours, brushSize, isLeftDown, isRightDown, dispatchFn, eventDc): XXX + def onSelectEvent(self, event, atPoint, selectRect, brushColours, brushSize, isLeftDown, isRightDown, dispatchFn, eventDc): + pass + + # + # onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc): XXX + def onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc): + if self.toolState == self.TS_NONE: + if isLeftDown or isRightDown: + self.toolColours = [0, 1] + self.toolRect = [list(atPoint), []] + self.toolState = self.TS_ORIGIN + else: + dispatchFn(eventDc, True, \ + [*atPoint, *brushColours, 0, " "]) + elif self.toolState == self.TS_ORIGIN: + self.toolRect[1] = list(atPoint) + if isLeftDown or isRightDown: + if self.toolRect[0][0] > self.toolRect[1][0]: + self.toolRect[0][0], self.toolRect[1][0] = \ + self.toolRect[1][0], self.toolRect[0][0] + if self.toolRect[0][1] > self.toolRect[1][1]: + self.toolRect[0][1], self.toolRect[1][1] = \ + self.toolRect[1][1], self.toolRect[0][1] + self.srcRect = self.toolRect[0] + self.toolLastAtPoint = list(atPoint) + self.toolState = self.TS_TARGET + self.toolSelectMap = [] + for numRow in range((self.toolRect[1][1] - self.toolRect[0][1]) + 1): + self.toolSelectMap.append([]) + for numCol in range((self.toolRect[1][0] - self.toolRect[0][0]) + 1): + rectY = self.toolRect[0][1] + numRow + rectX = self.toolRect[0][0] + numCol + self.toolSelectMap[numRow].append( \ + self.parentCanvas.canvasMap[rectY][rectX]) + self._drawSelectRect(self.toolRect, dispatchFn, eventDc) + elif self.toolState == self.TS_TARGET: + if isRightDown: + self.onSelectEvent(event, atPoint, self.toolRect, \ + brushColours, brushSize, isLeftDown, isRightDown, \ + dispatchFn, eventDc) + self.toolColours = None + self.toolRect = None + self.toolState = self.TS_NONE + else: + self.onSelectEvent(event, atPoint, self.toolRect, \ + brushColours, brushSize, isLeftDown, isRightDown, \ + dispatchFn, eventDc) + + # __init__(self, *args): initialisation method + def __init__(self, *args): + super().__init__(*args) + self.toolColours = None + self.toolRect = None + self.toolState = self.TS_NONE + self.toolLastAtPoint = None + self.toolSelectMap = None + +# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 diff --git a/libtools/MiRCARTToolSelectClone.py b/libtools/MiRCARTToolSelectClone.py new file mode 100644 index 0000000..08550b1 --- /dev/null +++ b/libtools/MiRCARTToolSelectClone.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 +# +# MiRCARTToolSelectClone.py -- XXX +# Copyright (c) 2018 Lucio Andrés Illanes Albornoz +# + +from MiRCARTToolSelect import MiRCARTToolSelect + +class MiRCARTToolSelectClone(MiRCARTToolSelect): + """XXX""" + name = "Clone selection" + + # + # onSelectEvent(self, event, atPoint, selectRect, brushColours, brushSize, isLeftDown, isRightDown, dispatchFn, eventDc): XXX + def onSelectEvent(self, event, atPoint, selectRect, brushColours, brushSize, isLeftDown, isRightDown, dispatchFn, eventDc): + if isLeftDown: + atPoint = list(atPoint) + disp = [atPoint[0]-self.toolLastAtPoint[0], \ + atPoint[1]-self.toolLastAtPoint[1]] + self.toolLastAtPoint = atPoint + newToolRect = [ \ + [selectRect[0][0]+disp[0], selectRect[0][1]+disp[1]], \ + [selectRect[1][0]+disp[0], selectRect[1][1]+disp[1]]] + isCursor = True + elif isRightDown: + disp = [0, 0] + newToolRect = selectRect.copy() + isCursor = False + else: + disp = [0, 0] + newToolRect = selectRect.copy() + isCursor = True + for numRow in range(len(self.toolSelectMap)): + for numCol in range(len(self.toolSelectMap[numRow])): + cellOld = self.toolSelectMap[numRow][numCol] + rectY = selectRect[0][1] + numRow + rectX = selectRect[0][0] + numCol + dispatchFn(eventDc, isCursor, [rectX+disp[0], rectY+disp[1], *cellOld]) + self._drawSelectRect(newToolRect, dispatchFn, eventDc) + self.toolRect = newToolRect + +# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 diff --git a/libtools/MiRCARTToolSelectMove.py b/libtools/MiRCARTToolSelectMove.py new file mode 100644 index 0000000..ed0513b --- /dev/null +++ b/libtools/MiRCARTToolSelectMove.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python3 +# +# MiRCARTToolSelectMove.py -- XXX +# Copyright (c) 2018 Lucio Andrés Illanes Albornoz +# + +from MiRCARTToolSelect import MiRCARTToolSelect + +class MiRCARTToolSelectMove(MiRCARTToolSelect): + """XXX""" + name = "Move selection" + + # + # onSelectEvent(self, event, atPoint, selectRect, brushColours, brushSize, isLeftDown, isRightDown, dispatchFn, eventDc): XXX + def onSelectEvent(self, event, atPoint, selectRect, brushColours, brushSize, isLeftDown, isRightDown, dispatchFn, eventDc): + if isLeftDown: + atPoint = list(atPoint) + disp = [atPoint[0]-self.toolLastAtPoint[0], \ + atPoint[1]-self.toolLastAtPoint[1]] + self.toolLastAtPoint = atPoint + newToolRect = [ \ + [selectRect[0][0]+disp[0], selectRect[0][1]+disp[1]], \ + [selectRect[1][0]+disp[0], selectRect[1][1]+disp[1]]] + isCursor = True + elif isRightDown: + disp = [0, 0] + newToolRect = selectRect.copy() + isCursor = False + else: + disp = [0, 0] + newToolRect = selectRect.copy() + isCursor = True + for numRow in range(len(self.toolSelectMap)): + for numCol in range(len(self.toolSelectMap[numRow])): + dispatchFn(eventDc, isCursor, [self.srcRect[0] + numCol, \ + self.srcRect[1] + numRow, 1, 1, 0, " "]) + for numRow in range(len(self.toolSelectMap)): + for numCol in range(len(self.toolSelectMap[numRow])): + cellOld = self.toolSelectMap[numRow][numCol] + rectY = selectRect[0][1] + numRow + rectX = selectRect[0][0] + numCol + dispatchFn(eventDc, isCursor, [rectX+disp[0], rectY+disp[1], *cellOld]) + self._drawSelectRect(newToolRect, dispatchFn, eventDc) + self.toolRect = newToolRect + +# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 diff --git a/libtools/MiRCARTToolText.py b/libtools/MiRCARTToolText.py new file mode 100644 index 0000000..8ae87ed --- /dev/null +++ b/libtools/MiRCARTToolText.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 +# +# MiRCARTToolText.py -- XXX +# Copyright (c) 2018 Lucio Andrés Illanes Albornoz +# + +from MiRCARTTool import MiRCARTTool +import wx + +class MiRCARTToolText(MiRCARTTool): + """XXX""" + name = "Text" + textColours = textPos = None + + # + # onKeyboardEvent(self, event, atPoint, brushColours, brushSize, keyChar, dispatchFn, eventDc): XXX + def onKeyboardEvent(self, event, atPoint, brushColours, brushSize, keyChar, dispatchFn, eventDc): + keyModifiers = event.GetModifiers() + if keyModifiers != wx.MOD_NONE \ + and keyModifiers != wx.MOD_SHIFT: + return True + else: + if self.textColours == None: + self.textColours = brushColours.copy() + if self.textPos == None: + self.textPos = list(atPoint) + dispatchFn(eventDc, False, [*self.textPos, *self.textColours, 0, keyChar]) + if self.textPos[0] < (self.parentCanvas.canvasSize[0] - 1): + self.textPos[0] += 1 + elif self.textPos[1] < (self.parentCanvas.canvasSize[1] - 1): + self.textPos[0] = 0 + self.textPos[1] += 1 + else: + self.textPos = [0, 0] + return False + + # + # onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc): XXX + def onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc): + if isLeftDown: + self.textColours = brushColours.copy() + self.textPos = list(atPoint) + elif isRightDown: + self.textColours = [brushColours[1], brushColours[0]] + self.textPos = list(atPoint) + else: + if self.textColours == None: + self.textColours = brushColours.copy() + self.textPos = list(atPoint) + dispatchFn(eventDc, True, [*self.textPos, *self.textColours, 0, "_"]) + +# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120