You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1735 lines
70 KiB
1735 lines
70 KiB
<!doctype html> |
|
<html lang="en"> |
|
<head> |
|
<meta charset="utf-8"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" /> |
|
<meta name="generator" content="pdoc 0.9.2" /> |
|
<title>TermTk.TTkCore.canvas API documentation</title> |
|
<meta name="description" content="" /> |
|
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin> |
|
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin> |
|
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin> |
|
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style> |
|
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style> |
|
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style> |
|
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script> |
|
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script> |
|
</head> |
|
<body> |
|
<main> |
|
<article id="content"> |
|
<header> |
|
<h1 class="title">Module <code>TermTk.TTkCore.canvas</code></h1> |
|
</header> |
|
<section id="section-intro"> |
|
<details class="source"> |
|
<summary> |
|
<span>Expand source code</span> |
|
</summary> |
|
<pre><code class="python">#!/usr/bin/env python3 |
|
|
|
# MIT License |
|
# |
|
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com> |
|
# |
|
# Permission is hereby granted, free of charge, to any person obtaining a copy |
|
# of this software and associated documentation files (the "Software"), to deal |
|
# in the Software without restriction, including without limitation the rights |
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
# copies of the Software, and to permit persons to whom the Software is |
|
# furnished to do so, subject to the following conditions: |
|
# |
|
# The above copyright notice and this permission notice shall be included in all |
|
# copies or substantial portions of the Software. |
|
# |
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
|
# SOFTWARE. |
|
|
|
import math |
|
|
|
import TermTk.libbpytop as lbt |
|
from TermTk.TTkCore.constant import TTkK |
|
from TermTk.TTkCore.log import TTkLog |
|
from TermTk.TTkCore.cfg import * |
|
from TermTk.TTkCore.color import * |
|
from TermTk.TTkCore.helper import * |
|
from TermTk.TTkGui.theme import * |
|
|
|
class TTkCanvas: |
|
''' |
|
TTkCanvas |
|
canvas window primitives |
|
... |
|
Attributes |
|
---------- |
|
Methods |
|
------- |
|
__init__({}) |
|
input obj{ width, height} |
|
|
|
resize(w, h) |
|
- resize the canvas keeping or cutting the current one |
|
in w = the width of the new canvas |
|
in h = the height of the new canvas |
|
''' |
|
__slots__ = ('_widget', '_width', '_height', '_newWidth', '_newHeight','_theme', '_data', '_colors', '_visible') |
|
def __init__(self, *args, **kwargs): |
|
self._widget = kwargs.get('widget', None) |
|
self._visible = True |
|
self._width = 0 |
|
self._height = 0 |
|
self._data = [[0]] |
|
self._colors = [[TTkColor.RST]] |
|
self._newWidth = kwargs.get('width', 0 ) |
|
self._newHeight = kwargs.get('height', 0 ) |
|
self.updateSize() |
|
# self.resize(self._width, self._height) |
|
# TTkLog.debug((self._width, self._height)) |
|
|
|
def getWidget(self): return self._widget |
|
|
|
def updateSize(self): |
|
if not self._visible: return |
|
w,h = self._newWidth, self._newHeight |
|
if w == self._width and h == self._height: |
|
return |
|
self._data = [[]]*h |
|
self._colors = [[]]*h |
|
for i in range(0,h): |
|
self._data[i] = [' ']*w |
|
self._colors[i] = [TTkColor.RST]*w |
|
self._width = w |
|
self._height = h |
|
|
|
def resize(self, w, h): |
|
self._newWidth = w |
|
self._newHeight = h |
|
|
|
def clean(self, pos=(0, 0), size=None): |
|
if not self._visible: return |
|
x,y = pos |
|
w,h = size if size is not None else (self._width, self._height) |
|
for iy in range(y,y+h): |
|
for ix in range(x,x+w): |
|
self._data[iy][ix] = ' ' |
|
self._colors[iy][ix] = TTkColor.RST |
|
|
|
def hide(self): |
|
self._visible = False |
|
|
|
def show(self): |
|
self._visible = True |
|
|
|
def _set(self, _y, _x, _ch, _col=TTkColor.RST): |
|
if _y < self._height and \ |
|
_x < self._width and \ |
|
_x >= 0 and _y >=0 : |
|
self._data[_y][_x] = _ch |
|
self._colors[_y][_x] = _col.mod(_x,_y) |
|
|
|
def drawVLine(self, pos, size, color=TTkColor.RST): |
|
if size == 0: return |
|
x,y = pos |
|
ln = TTkCfg.theme.vline |
|
self._set(y, x, ln[0], color) |
|
self._set(y+size-1, x, ln[2], color) |
|
if size > 2: |
|
for i in range(1,size-1): |
|
self._set(y+i, x, ln[1], color) |
|
|
|
def drawHLine(self, pos, size, color=TTkColor.RST): |
|
if size == 0: return |
|
x,y = pos |
|
ln = TTkCfg.theme.hline |
|
if size == 1: |
|
txt = ln[0] |
|
elif size == 2: |
|
txt = ln[0]+ln[2] |
|
else: |
|
txt = ln[0]+(ln[1]*(size-2))+ln[2] |
|
self.drawText(pos=pos, text=txt, color=color) |
|
|
|
''' |
|
pos = (x:int, y:int) |
|
items = [str] # list of str to be written (for each column) |
|
size = [int] # list of output sizes (for each column) |
|
colors = [TTkColor] # list of colors (for each column) |
|
alignments = [TTkK.alignment] # list of txtalignments (for each column) |
|
''' |
|
def drawTableLine(self, pos, items, sizes, colors, alignments ): |
|
x,y = pos |
|
for i in range(0,len(items)): |
|
txt = items[i] |
|
w = sizes[i] |
|
color = colors[i] |
|
align = alignments[i] |
|
if w > 0: |
|
line = "" |
|
lentxt = len(txt) |
|
if lentxt > w: |
|
line += txt[0:w] |
|
else: |
|
pad = w-lentxt |
|
if align == TTkK.NONE or align == TTkK.LEFT_ALIGN: |
|
line += txt + " "*pad |
|
elif align == TTkK.RIGHT_ALIGN: |
|
line += " "*pad + txt |
|
elif align == TTkK.CENTER_ALIGN: |
|
p1 = pad//2 |
|
p2 = pad-p1 |
|
line += " "*p1 + txt+" "*p2 |
|
elif align == TTkK.JUSTIFY: |
|
# TODO: Text Justification |
|
line += txt + " "*pad |
|
self.drawText(pos=(x,y), text=line, color=color) |
|
x += w + 1 |
|
|
|
def drawText(self, pos, text, width=None, color=TTkColor.RST, alignment=TTkK.NONE): |
|
if not self._visible: return |
|
lentxt = len(text) |
|
if width is None or width<0: |
|
width = lentxt |
|
x,y = pos |
|
|
|
if lentxt < width: |
|
pad = width-lentxt |
|
if alignment == TTkK.NONE or alignment == TTkK.LEFT_ALIGN: |
|
text = text + " "*pad |
|
elif alignment == TTkK.RIGHT_ALIGN: |
|
text = " "*pad + text |
|
elif alignment == TTkK.CENTER_ALIGN: |
|
p1 = pad//2 |
|
p2 = pad-p1 |
|
text = " "*p1 + text+" "*p2 |
|
elif alignment == TTkK.JUSTIFY: |
|
# TODO: Text Justification |
|
text = text + " "*pad |
|
|
|
arr = list(text) |
|
for i in range(0, len(arr)): |
|
self._set(y, x+i, arr[i], color) |
|
|
|
def drawBoxTitle(self, pos, size, text, align=TTkK.CENTER_ALIGN, color=TTkColor.RST, colorText=TTkColor.RST, grid=0): |
|
if not self._visible: return |
|
x,y = pos |
|
w,h = size |
|
if w < 4: return |
|
gg = TTkCfg.theme.grid[grid] |
|
|
|
if len(text) > w-4: |
|
text = text[:w-4] |
|
if align == TTkK.CENTER_ALIGN: |
|
l = (w-2-len(text))//2 |
|
elif align == TTkK.LEFT_ALIGN: |
|
l=1 |
|
else: |
|
l = w-2-len(text) |
|
r = l+len(text)+1 |
|
|
|
self._set(y,l, gg[7], color) |
|
self._set(y,r, gg[6], color) |
|
self.drawText(pos=(l+1,y),text=text,color=colorText) |
|
|
|
|
|
|
|
def drawBox(self, pos, size, color=TTkColor.RST, grid=0): |
|
self.drawGrid(pos=pos, size=size, color=color, grid=grid) |
|
|
|
def drawButtonBox(self, pos, size, color=TTkColor.RST, grid=0): |
|
if not self._visible: return |
|
x,y = pos |
|
w,h = size |
|
gg = TTkCfg.theme.buttonBox[grid] |
|
# 4 corners |
|
self._set(y, x, gg[0], color) |
|
self._set(y, x+w-1, gg[2], color) |
|
self._set(y+h-1, x, gg[6], color) |
|
self._set(y+h-1, x+w-1, gg[8], color) |
|
if w > 2: |
|
for i in range(x+1,x+w-1): |
|
self._set(y, i, gg[1], color) |
|
self._set(y+h-1, i, gg[7], color) |
|
if h > 2: |
|
for i in range(y+1,y+h-1): |
|
self._set(i, x, gg[3], color) |
|
self._set(i, x+w-1, gg[5], color) |
|
|
|
def drawGrid(self, pos, size, hlines=[], vlines=[], color=TTkColor.RST, grid=0): |
|
if not self._visible: return |
|
x,y = pos |
|
w,h = size |
|
gg = TTkCfg.theme.grid[grid] |
|
# 4 corners |
|
self._set(y, x, gg[0x00], color) |
|
self._set(y, x+w-1, gg[0x03], color) |
|
self._set(y+h-1, x, gg[0x0C], color) |
|
self._set(y+h-1, x+w-1, gg[0x0F], color) |
|
if w > 2: |
|
# Top/Bottom Line |
|
for i in range(x+1,x+w-1): |
|
self._set(y, i, gg[0x01], color) |
|
self._set(y+h-1, i, gg[0x0D], color) |
|
if h > 2: |
|
# Left/Right Line |
|
for i in range(y+1,y+h-1): |
|
self._set(i, x, gg[0x04], color) |
|
self._set(i, x+w-1, gg[0x07], color) |
|
# Draw horizontal lines |
|
for iy in hlines: |
|
iy += y |
|
if not (0 < iy < h): continue |
|
self._set(iy, x, gg[0x08], color) |
|
self._set(iy, x+w-1, gg[0x0B], color) |
|
if w > 2: |
|
for ix in range(x+1,x+w-1): |
|
self._set(iy, ix, gg[0x09], color) |
|
# Draw vertical lines |
|
for ix in vlines: |
|
ix+=x |
|
if not (0 < ix < w): continue |
|
self._set(y, ix, gg[0x02], color) |
|
self._set(y+h-1, ix, gg[0x0E], color) |
|
if h > 2: |
|
for iy in range(y+1,y+h-1): |
|
self._set(iy, ix, gg[0x06], color) |
|
# Draw intersections |
|
for iy in hlines: |
|
for ix in vlines: |
|
self._set(y+iy, x+ix, gg[0x0A], color) |
|
|
|
def drawScroll(self, pos, size, slider, orientation, color=TTkColor.RST): |
|
if not self._visible: return |
|
x,y = pos |
|
f,t = slider # slider from-to position |
|
if orientation == TTkK.HORIZONTAL: |
|
for i in range(x+1,x+size-1): # H line |
|
self._set(y,x+i, TTkCfg.theme.hscroll[1], color) |
|
for i in range(f,t): # Slider |
|
self._set(y,x+i, TTkCfg.theme.hscroll[2], color) |
|
self._set(y,x, TTkCfg.theme.hscroll[0], color) # Left Arrow |
|
self._set(y,x+size-1, TTkCfg.theme.hscroll[3], color) # Right Arrow |
|
else: |
|
for i in range(y+1,y+size-1): # V line |
|
self._set(y+i,x, TTkCfg.theme.vscroll[1], color) |
|
for i in range(f,t): # Slider |
|
self._set(y+i,x, TTkCfg.theme.vscroll[2], color) |
|
self._set(y,x, TTkCfg.theme.vscroll[0], color) # Up Arrow |
|
self._set(y+size-1,x, TTkCfg.theme.vscroll[3], color) # Down Arrow |
|
pass |
|
|
|
def drawTab( |
|
self, pos, size, |
|
labels, labelsPos, selected, |
|
offset, leftScroller, rightScroller, slim=False, |
|
color=TTkColor.RST, borderColor=TTkColor.RST, selectColor=TTkColor.RST): |
|
x,y = pos |
|
w,h = size |
|
tt = TTkCfg.theme.tab |
|
# phase 0 - Draw the Bottom bar |
|
if slim: |
|
bottomBar = tt[18]+tt[19]*(w-2)+tt[20] |
|
bottomPos = y+1 |
|
else: |
|
bottomBar = tt[11]+tt[12]*(w-2)+tt[15] |
|
bottomPos = y+2 |
|
self.drawText(pos=(x,bottomPos),text=bottomBar) |
|
# phase 1 - Draw From left to 'Selected' |
|
# phase 2 - Draw From right to 'Selected' |
|
def _drawTabSlim(x,y,a,b,c,d,e,txt,txtColor,borderColor): |
|
lentext = len(txt) |
|
center = a+txt+b |
|
bottom = c+d*(lentext)+e |
|
self.drawText(pos=(x,y),text=center, color=borderColor) |
|
self.drawText(pos=(x+1,y),text=txt, color=txtColor) |
|
self.drawText(pos=(x,y+1),text=bottom, color=borderColor) |
|
def _drawTab(x,y,a,b,c,d,e,f,g,h,i,j,k,l,m,txt,txtColor,borderColor,slim): |
|
if slim: return _drawTabSlim(x,y,i,j,k,l,m,txt,txtColor,borderColor) |
|
lentext = len(txt) |
|
top = a+b*lentext+c |
|
center = d+txt+e |
|
bottom = f+g*(lentext)+h |
|
self.drawText(pos=(x,y+0),text=top, color=borderColor) |
|
self.drawText(pos=(x,y+1),text=center, color=borderColor) |
|
self.drawText(pos=(x+1,y+1),text=txt, color=txtColor) |
|
self.drawText(pos=(x,y+2),text=bottom, color=borderColor) |
|
|
|
for i in list( range(offset )) + \ |
|
list(reversed(range(offset+1, len(labels)) )): |
|
text = labels[i] |
|
posx = labelsPos[i] |
|
_drawTab(x+posx,y,tt[0],tt[1],tt[3],tt[9],tt[9],tt[12],tt[12],tt[12],tt[9],tt[9],tt[23],tt[19],tt[24], text, color, borderColor, slim) |
|
# phase 3 - Draw 'Selected' |
|
if selected != -1: |
|
i = selected |
|
text = labels[i] |
|
posx = labelsPos[i] |
|
_drawTab(x+posx,y,tt[4],tt[5],tt[6],tt[10],tt[10],tt[14],tt[12],tt[14],tt[10],tt[10],tt[21],tt[12],tt[22], text, selectColor, borderColor, slim) |
|
if selected != offset: |
|
i = offset |
|
text = labels[i] |
|
posx = labelsPos[i] |
|
_drawTab(x+posx,y,tt[0],tt[1],tt[3],tt[9],tt[9],tt[13],tt[12],tt[13],tt[9],tt[9],tt[18],tt[19],tt[20], text, color, borderColor, slim) |
|
# phase 4 - Draw left right tilt |
|
if leftScroller: |
|
top = tt[7]+tt[1] |
|
center = tt[9]+tt[31] |
|
if slim: |
|
self.drawText(pos=(x,y),text=center, color=borderColor) |
|
else: |
|
self.drawText(pos=(x,y+0),text=top, color=borderColor) |
|
self.drawText(pos=(x,y+1),text=center, color=borderColor) |
|
if rightScroller: |
|
top = tt[1]+tt[8] |
|
center = tt[32]+tt[9] |
|
if slim: |
|
self.drawText(pos=(x+w-2,y),text=center, color=borderColor) |
|
else: |
|
self.drawText(pos=(x+w-2,y+0),text=top, color=borderColor) |
|
self.drawText(pos=(x+w-2,y+1),text=center, color=borderColor) |
|
|
|
def drawHChart(self, pos, values, zoom=1.0, color=TTkColor.RST): |
|
x,y=pos |
|
v1,v2 = values |
|
gb=TTkCfg.theme.braille |
|
|
|
''' |
|
loop 0 1 2 3 = range(0,1+maxt//4) |
|
v1 13 |---|---|---|--| |
|
v2 10 |---|---|-| |
|
maxt 13 |---|---|---|--| |
|
out 4,4 4,4 4,2 3,0 0,0 |
|
o1 = 4 if v1-4 > i*4 else v1-i*4 |
|
''' |
|
# TTkLog.debug(f"{(v1,v2)} z{zoom}") |
|
zl1 = [ int(i*zoom) for i in v1 ] |
|
zl2 = [ int(i*zoom) for i in v2 ] |
|
maxz = max(max(zl1),max(zl2),0) |
|
minz = min(min(zl1),min(zl2),0) |
|
filled = True |
|
for i in range(int(minz//4),int(maxz//4)+2): |
|
ts1 = i*4 |
|
ts2 = i*4+4 |
|
''' |
|
Braille bits: |
|
o2 o1 = 4 bits each |
|
|
|
1 5 Braille dots |
|
2 6 |
|
3 7 |
|
4 8 |
|
|
|
TTkTheme.braille[( o1<<4 | o2 )] = Braille UTF-8 char |
|
''' |
|
braille = 0x00 |
|
for ii in range(len(zl1)): |
|
z1 = zl1[ii] |
|
z2 = zl2[ii] |
|
o1,o2 = 0,0 |
|
#TTkLog.debug |
|
if not filled or ii>0: |
|
if ts1 <= z1 < ts2: o1 = 0x80>>max(0,int(z1-ts1)) |
|
if ts1 <= z2 < ts2: o2 = 0x08>>max(0,int(z2-ts1)) |
|
else: |
|
if (0<=ts1<z1)or(0>ts1>z1): o1 = 0xf0 |
|
if (0<=ts1<z2)or(0>ts1>z2): o2 = 0x0f |
|
k1 = 0x0f80 if z1>=0 else 0x00f0 |
|
k2 = 0x00f8 if z2>=0 else 0x000f |
|
if ts1 <= z1 < ts2: o1 = 0xf0&(k1>>max(0,int(z1-ts1))) |
|
if ts1 <= z2 < ts2: o2 = 0x0f&(k2>>max(0,int(z2-ts1))) |
|
braille ^= (o1|o2) |
|
# braille &= 0xff |
|
#TTkLog.debug(f"z:{zl1,zl2}, ts:{ts1,ts2},{o1,o2}") |
|
#if braille<0 or braille>0xff: |
|
# TTkLog.debug(f"z:{zl1,zl2},t:{t1,t2},i:{i} {t1-i*4} {t2-i*4} o:{o1,o2}, {hex(braille)}") |
|
self._set(y-i-1,x, gb[braille], color) |
|
|
|
def drawMenuBarBg(self, pos, size, color=TTkColor.RST ): |
|
mb = TTkCfg.theme.menuBar |
|
self.drawText(pos, text=f"{mb[3]}{mb[1]*(size-2)}{mb[4]}", color=color) |
|
|
|
def drawMenuBarButton(self, pos, width, text, border=True, submenu=False, shortcuts=[], color=TTkColor.RST, borderColor=TTkColor.RST, shortcutColor=TTkColor.UNDERLINE ): |
|
mb = TTkCfg.theme.menuBar |
|
x,y = pos |
|
if border: |
|
self.drawText(pos=(x,y), color=borderColor ,text=mb[2]) |
|
self.drawText(pos=(x+1+len(text),y), color=borderColor ,text=mb[0]) |
|
self.drawText(pos=(x+1,y), color=color ,text=text) |
|
off = 1 |
|
else: |
|
self.drawText(pos=(x,y), color=color ,text=text) |
|
if submenu: |
|
self._set(y,x+width-1, mb[5], color) |
|
off = 0 |
|
for i in shortcuts: |
|
self._set(y,x+i+off, text[i], shortcutColor) |
|
|
|
def execPaint(self, winw, winh): |
|
pass |
|
|
|
''' |
|
geom = (x,y,w,h) |
|
bound = (x,y,w,h) |
|
|
|
x x+w |
|
canvas: |xxxxxxxxxxxxxxxxxxxxxxx| |
|
slice: |-----------| |
|
bx bx+bw |
|
bound: |--------| |
|
0 self._width |
|
self._canvas: |----|xxxxxx|----------| |
|
''' |
|
def paintCanvas(self, canvas, geom, slice, bound): |
|
# TTkLog.debug(f"PaintCanvas:{(x,y,w,h)}") |
|
x, y, w, h = geom |
|
bx,by,bw,bh = bound |
|
# out of bound |
|
if not self._visible: return |
|
if not canvas._visible: return |
|
if canvas._width==0 or canvas._height==0: return |
|
if x+w < bx or y+h<by or bx+bw<x or by+bh<y: |
|
return |
|
|
|
x = min(x,self._width-1) |
|
y = min(y,self._height-1) |
|
w = min(w,self._width-x) |
|
h = min(h,self._height-y) |
|
|
|
# if x>=self._width: x=self._width-1 |
|
# if y>=self._height: y=self._height-1 |
|
# if w>=self._width-x: w=self._width-x |
|
# if h>=self._height-y: h=self._height-y |
|
|
|
xoffset = 0 if x>=bx else bx-x |
|
yoffset = 0 if y>=by else by-y |
|
wslice = w if x+w < bx+bw else bx+bw-x |
|
hslice = h if y+h < by+bh else by+bh-y |
|
|
|
|
|
for iy in range(yoffset,hslice): |
|
for ix in range(xoffset,wslice): |
|
#TTkLog.debug(f"PaintCanvas:{(ix,iy)}") |
|
if iy > len(canvas._data)-1: |
|
TTkLog.debug(f"{canvas._width, canvas._height} - {(yoffset,hslice)}, {(xoffset,wslice)}, {slice}") |
|
b = canvas._data[iy] |
|
a = b[ix] |
|
self._data[y+iy][x+ix] = a # canvas._data[iy][ix] |
|
self._colors[y+iy][x+ix] = canvas._colors[iy][ix] |
|
|
|
def pushToTerminal(self, x, y, w, h): |
|
# TTkLog.debug("pushToTerminal") |
|
lastcolor = TTkColor.RST |
|
for y in range(0, self._height): |
|
ansi = TTkColor.RST+lbt.Mv.t(y+1,1) |
|
for x in range(0, self._width): |
|
ch = self._data[y][x] |
|
color = self._colors[y][x] |
|
if color != lastcolor: |
|
ansi += color-lastcolor |
|
lastcolor = color |
|
ansi+=ch |
|
lbt.Term.push(ansi)</code></pre> |
|
</details> |
|
</section> |
|
<section> |
|
</section> |
|
<section> |
|
</section> |
|
<section> |
|
</section> |
|
<section> |
|
<h2 class="section-title" id="header-classes">Classes</h2> |
|
<dl> |
|
<dt id="TermTk.TTkCore.canvas.TTkCanvas"><code class="flex name class"> |
|
<span>class <span class="ident">TTkCanvas</span></span> |
|
<span>(</span><span>*args, **kwargs)</span> |
|
</code></dt> |
|
<dd> |
|
<div class="desc"><p>TTkCanvas |
|
canvas window primitives |
|
… |
|
Attributes</p> |
|
<hr> |
|
<h2 id="methods">Methods</h2> |
|
<p><strong>init</strong>({}) |
|
input obj{ width, height}</p> |
|
<p>resize(w, h) |
|
- resize the canvas keeping or cutting the current one |
|
in |
|
w = the width of the new canvas |
|
in |
|
h = the height of the new canvas</p></div> |
|
<details class="source"> |
|
<summary> |
|
<span>Expand source code</span> |
|
</summary> |
|
<pre><code class="python">class TTkCanvas: |
|
''' |
|
TTkCanvas |
|
canvas window primitives |
|
... |
|
Attributes |
|
---------- |
|
Methods |
|
------- |
|
__init__({}) |
|
input obj{ width, height} |
|
|
|
resize(w, h) |
|
- resize the canvas keeping or cutting the current one |
|
in w = the width of the new canvas |
|
in h = the height of the new canvas |
|
''' |
|
__slots__ = ('_widget', '_width', '_height', '_newWidth', '_newHeight','_theme', '_data', '_colors', '_visible') |
|
def __init__(self, *args, **kwargs): |
|
self._widget = kwargs.get('widget', None) |
|
self._visible = True |
|
self._width = 0 |
|
self._height = 0 |
|
self._data = [[0]] |
|
self._colors = [[TTkColor.RST]] |
|
self._newWidth = kwargs.get('width', 0 ) |
|
self._newHeight = kwargs.get('height', 0 ) |
|
self.updateSize() |
|
# self.resize(self._width, self._height) |
|
# TTkLog.debug((self._width, self._height)) |
|
|
|
def getWidget(self): return self._widget |
|
|
|
def updateSize(self): |
|
if not self._visible: return |
|
w,h = self._newWidth, self._newHeight |
|
if w == self._width and h == self._height: |
|
return |
|
self._data = [[]]*h |
|
self._colors = [[]]*h |
|
for i in range(0,h): |
|
self._data[i] = [' ']*w |
|
self._colors[i] = [TTkColor.RST]*w |
|
self._width = w |
|
self._height = h |
|
|
|
def resize(self, w, h): |
|
self._newWidth = w |
|
self._newHeight = h |
|
|
|
def clean(self, pos=(0, 0), size=None): |
|
if not self._visible: return |
|
x,y = pos |
|
w,h = size if size is not None else (self._width, self._height) |
|
for iy in range(y,y+h): |
|
for ix in range(x,x+w): |
|
self._data[iy][ix] = ' ' |
|
self._colors[iy][ix] = TTkColor.RST |
|
|
|
def hide(self): |
|
self._visible = False |
|
|
|
def show(self): |
|
self._visible = True |
|
|
|
def _set(self, _y, _x, _ch, _col=TTkColor.RST): |
|
if _y < self._height and \ |
|
_x < self._width and \ |
|
_x >= 0 and _y >=0 : |
|
self._data[_y][_x] = _ch |
|
self._colors[_y][_x] = _col.mod(_x,_y) |
|
|
|
def drawVLine(self, pos, size, color=TTkColor.RST): |
|
if size == 0: return |
|
x,y = pos |
|
ln = TTkCfg.theme.vline |
|
self._set(y, x, ln[0], color) |
|
self._set(y+size-1, x, ln[2], color) |
|
if size > 2: |
|
for i in range(1,size-1): |
|
self._set(y+i, x, ln[1], color) |
|
|
|
def drawHLine(self, pos, size, color=TTkColor.RST): |
|
if size == 0: return |
|
x,y = pos |
|
ln = TTkCfg.theme.hline |
|
if size == 1: |
|
txt = ln[0] |
|
elif size == 2: |
|
txt = ln[0]+ln[2] |
|
else: |
|
txt = ln[0]+(ln[1]*(size-2))+ln[2] |
|
self.drawText(pos=pos, text=txt, color=color) |
|
|
|
''' |
|
pos = (x:int, y:int) |
|
items = [str] # list of str to be written (for each column) |
|
size = [int] # list of output sizes (for each column) |
|
colors = [TTkColor] # list of colors (for each column) |
|
alignments = [TTkK.alignment] # list of txtalignments (for each column) |
|
''' |
|
def drawTableLine(self, pos, items, sizes, colors, alignments ): |
|
x,y = pos |
|
for i in range(0,len(items)): |
|
txt = items[i] |
|
w = sizes[i] |
|
color = colors[i] |
|
align = alignments[i] |
|
if w > 0: |
|
line = "" |
|
lentxt = len(txt) |
|
if lentxt > w: |
|
line += txt[0:w] |
|
else: |
|
pad = w-lentxt |
|
if align == TTkK.NONE or align == TTkK.LEFT_ALIGN: |
|
line += txt + " "*pad |
|
elif align == TTkK.RIGHT_ALIGN: |
|
line += " "*pad + txt |
|
elif align == TTkK.CENTER_ALIGN: |
|
p1 = pad//2 |
|
p2 = pad-p1 |
|
line += " "*p1 + txt+" "*p2 |
|
elif align == TTkK.JUSTIFY: |
|
# TODO: Text Justification |
|
line += txt + " "*pad |
|
self.drawText(pos=(x,y), text=line, color=color) |
|
x += w + 1 |
|
|
|
def drawText(self, pos, text, width=None, color=TTkColor.RST, alignment=TTkK.NONE): |
|
if not self._visible: return |
|
lentxt = len(text) |
|
if width is None or width<0: |
|
width = lentxt |
|
x,y = pos |
|
|
|
if lentxt < width: |
|
pad = width-lentxt |
|
if alignment == TTkK.NONE or alignment == TTkK.LEFT_ALIGN: |
|
text = text + " "*pad |
|
elif alignment == TTkK.RIGHT_ALIGN: |
|
text = " "*pad + text |
|
elif alignment == TTkK.CENTER_ALIGN: |
|
p1 = pad//2 |
|
p2 = pad-p1 |
|
text = " "*p1 + text+" "*p2 |
|
elif alignment == TTkK.JUSTIFY: |
|
# TODO: Text Justification |
|
text = text + " "*pad |
|
|
|
arr = list(text) |
|
for i in range(0, len(arr)): |
|
self._set(y, x+i, arr[i], color) |
|
|
|
def drawBoxTitle(self, pos, size, text, align=TTkK.CENTER_ALIGN, color=TTkColor.RST, colorText=TTkColor.RST, grid=0): |
|
if not self._visible: return |
|
x,y = pos |
|
w,h = size |
|
if w < 4: return |
|
gg = TTkCfg.theme.grid[grid] |
|
|
|
if len(text) > w-4: |
|
text = text[:w-4] |
|
if align == TTkK.CENTER_ALIGN: |
|
l = (w-2-len(text))//2 |
|
elif align == TTkK.LEFT_ALIGN: |
|
l=1 |
|
else: |
|
l = w-2-len(text) |
|
r = l+len(text)+1 |
|
|
|
self._set(y,l, gg[7], color) |
|
self._set(y,r, gg[6], color) |
|
self.drawText(pos=(l+1,y),text=text,color=colorText) |
|
|
|
|
|
|
|
def drawBox(self, pos, size, color=TTkColor.RST, grid=0): |
|
self.drawGrid(pos=pos, size=size, color=color, grid=grid) |
|
|
|
def drawButtonBox(self, pos, size, color=TTkColor.RST, grid=0): |
|
if not self._visible: return |
|
x,y = pos |
|
w,h = size |
|
gg = TTkCfg.theme.buttonBox[grid] |
|
# 4 corners |
|
self._set(y, x, gg[0], color) |
|
self._set(y, x+w-1, gg[2], color) |
|
self._set(y+h-1, x, gg[6], color) |
|
self._set(y+h-1, x+w-1, gg[8], color) |
|
if w > 2: |
|
for i in range(x+1,x+w-1): |
|
self._set(y, i, gg[1], color) |
|
self._set(y+h-1, i, gg[7], color) |
|
if h > 2: |
|
for i in range(y+1,y+h-1): |
|
self._set(i, x, gg[3], color) |
|
self._set(i, x+w-1, gg[5], color) |
|
|
|
def drawGrid(self, pos, size, hlines=[], vlines=[], color=TTkColor.RST, grid=0): |
|
if not self._visible: return |
|
x,y = pos |
|
w,h = size |
|
gg = TTkCfg.theme.grid[grid] |
|
# 4 corners |
|
self._set(y, x, gg[0x00], color) |
|
self._set(y, x+w-1, gg[0x03], color) |
|
self._set(y+h-1, x, gg[0x0C], color) |
|
self._set(y+h-1, x+w-1, gg[0x0F], color) |
|
if w > 2: |
|
# Top/Bottom Line |
|
for i in range(x+1,x+w-1): |
|
self._set(y, i, gg[0x01], color) |
|
self._set(y+h-1, i, gg[0x0D], color) |
|
if h > 2: |
|
# Left/Right Line |
|
for i in range(y+1,y+h-1): |
|
self._set(i, x, gg[0x04], color) |
|
self._set(i, x+w-1, gg[0x07], color) |
|
# Draw horizontal lines |
|
for iy in hlines: |
|
iy += y |
|
if not (0 < iy < h): continue |
|
self._set(iy, x, gg[0x08], color) |
|
self._set(iy, x+w-1, gg[0x0B], color) |
|
if w > 2: |
|
for ix in range(x+1,x+w-1): |
|
self._set(iy, ix, gg[0x09], color) |
|
# Draw vertical lines |
|
for ix in vlines: |
|
ix+=x |
|
if not (0 < ix < w): continue |
|
self._set(y, ix, gg[0x02], color) |
|
self._set(y+h-1, ix, gg[0x0E], color) |
|
if h > 2: |
|
for iy in range(y+1,y+h-1): |
|
self._set(iy, ix, gg[0x06], color) |
|
# Draw intersections |
|
for iy in hlines: |
|
for ix in vlines: |
|
self._set(y+iy, x+ix, gg[0x0A], color) |
|
|
|
def drawScroll(self, pos, size, slider, orientation, color=TTkColor.RST): |
|
if not self._visible: return |
|
x,y = pos |
|
f,t = slider # slider from-to position |
|
if orientation == TTkK.HORIZONTAL: |
|
for i in range(x+1,x+size-1): # H line |
|
self._set(y,x+i, TTkCfg.theme.hscroll[1], color) |
|
for i in range(f,t): # Slider |
|
self._set(y,x+i, TTkCfg.theme.hscroll[2], color) |
|
self._set(y,x, TTkCfg.theme.hscroll[0], color) # Left Arrow |
|
self._set(y,x+size-1, TTkCfg.theme.hscroll[3], color) # Right Arrow |
|
else: |
|
for i in range(y+1,y+size-1): # V line |
|
self._set(y+i,x, TTkCfg.theme.vscroll[1], color) |
|
for i in range(f,t): # Slider |
|
self._set(y+i,x, TTkCfg.theme.vscroll[2], color) |
|
self._set(y,x, TTkCfg.theme.vscroll[0], color) # Up Arrow |
|
self._set(y+size-1,x, TTkCfg.theme.vscroll[3], color) # Down Arrow |
|
pass |
|
|
|
def drawTab( |
|
self, pos, size, |
|
labels, labelsPos, selected, |
|
offset, leftScroller, rightScroller, slim=False, |
|
color=TTkColor.RST, borderColor=TTkColor.RST, selectColor=TTkColor.RST): |
|
x,y = pos |
|
w,h = size |
|
tt = TTkCfg.theme.tab |
|
# phase 0 - Draw the Bottom bar |
|
if slim: |
|
bottomBar = tt[18]+tt[19]*(w-2)+tt[20] |
|
bottomPos = y+1 |
|
else: |
|
bottomBar = tt[11]+tt[12]*(w-2)+tt[15] |
|
bottomPos = y+2 |
|
self.drawText(pos=(x,bottomPos),text=bottomBar) |
|
# phase 1 - Draw From left to 'Selected' |
|
# phase 2 - Draw From right to 'Selected' |
|
def _drawTabSlim(x,y,a,b,c,d,e,txt,txtColor,borderColor): |
|
lentext = len(txt) |
|
center = a+txt+b |
|
bottom = c+d*(lentext)+e |
|
self.drawText(pos=(x,y),text=center, color=borderColor) |
|
self.drawText(pos=(x+1,y),text=txt, color=txtColor) |
|
self.drawText(pos=(x,y+1),text=bottom, color=borderColor) |
|
def _drawTab(x,y,a,b,c,d,e,f,g,h,i,j,k,l,m,txt,txtColor,borderColor,slim): |
|
if slim: return _drawTabSlim(x,y,i,j,k,l,m,txt,txtColor,borderColor) |
|
lentext = len(txt) |
|
top = a+b*lentext+c |
|
center = d+txt+e |
|
bottom = f+g*(lentext)+h |
|
self.drawText(pos=(x,y+0),text=top, color=borderColor) |
|
self.drawText(pos=(x,y+1),text=center, color=borderColor) |
|
self.drawText(pos=(x+1,y+1),text=txt, color=txtColor) |
|
self.drawText(pos=(x,y+2),text=bottom, color=borderColor) |
|
|
|
for i in list( range(offset )) + \ |
|
list(reversed(range(offset+1, len(labels)) )): |
|
text = labels[i] |
|
posx = labelsPos[i] |
|
_drawTab(x+posx,y,tt[0],tt[1],tt[3],tt[9],tt[9],tt[12],tt[12],tt[12],tt[9],tt[9],tt[23],tt[19],tt[24], text, color, borderColor, slim) |
|
# phase 3 - Draw 'Selected' |
|
if selected != -1: |
|
i = selected |
|
text = labels[i] |
|
posx = labelsPos[i] |
|
_drawTab(x+posx,y,tt[4],tt[5],tt[6],tt[10],tt[10],tt[14],tt[12],tt[14],tt[10],tt[10],tt[21],tt[12],tt[22], text, selectColor, borderColor, slim) |
|
if selected != offset: |
|
i = offset |
|
text = labels[i] |
|
posx = labelsPos[i] |
|
_drawTab(x+posx,y,tt[0],tt[1],tt[3],tt[9],tt[9],tt[13],tt[12],tt[13],tt[9],tt[9],tt[18],tt[19],tt[20], text, color, borderColor, slim) |
|
# phase 4 - Draw left right tilt |
|
if leftScroller: |
|
top = tt[7]+tt[1] |
|
center = tt[9]+tt[31] |
|
if slim: |
|
self.drawText(pos=(x,y),text=center, color=borderColor) |
|
else: |
|
self.drawText(pos=(x,y+0),text=top, color=borderColor) |
|
self.drawText(pos=(x,y+1),text=center, color=borderColor) |
|
if rightScroller: |
|
top = tt[1]+tt[8] |
|
center = tt[32]+tt[9] |
|
if slim: |
|
self.drawText(pos=(x+w-2,y),text=center, color=borderColor) |
|
else: |
|
self.drawText(pos=(x+w-2,y+0),text=top, color=borderColor) |
|
self.drawText(pos=(x+w-2,y+1),text=center, color=borderColor) |
|
|
|
def drawHChart(self, pos, values, zoom=1.0, color=TTkColor.RST): |
|
x,y=pos |
|
v1,v2 = values |
|
gb=TTkCfg.theme.braille |
|
|
|
''' |
|
loop 0 1 2 3 = range(0,1+maxt//4) |
|
v1 13 |---|---|---|--| |
|
v2 10 |---|---|-| |
|
maxt 13 |---|---|---|--| |
|
out 4,4 4,4 4,2 3,0 0,0 |
|
o1 = 4 if v1-4 > i*4 else v1-i*4 |
|
''' |
|
# TTkLog.debug(f"{(v1,v2)} z{zoom}") |
|
zl1 = [ int(i*zoom) for i in v1 ] |
|
zl2 = [ int(i*zoom) for i in v2 ] |
|
maxz = max(max(zl1),max(zl2),0) |
|
minz = min(min(zl1),min(zl2),0) |
|
filled = True |
|
for i in range(int(minz//4),int(maxz//4)+2): |
|
ts1 = i*4 |
|
ts2 = i*4+4 |
|
''' |
|
Braille bits: |
|
o2 o1 = 4 bits each |
|
|
|
1 5 Braille dots |
|
2 6 |
|
3 7 |
|
4 8 |
|
|
|
TTkTheme.braille[( o1<<4 | o2 )] = Braille UTF-8 char |
|
''' |
|
braille = 0x00 |
|
for ii in range(len(zl1)): |
|
z1 = zl1[ii] |
|
z2 = zl2[ii] |
|
o1,o2 = 0,0 |
|
#TTkLog.debug |
|
if not filled or ii>0: |
|
if ts1 <= z1 < ts2: o1 = 0x80>>max(0,int(z1-ts1)) |
|
if ts1 <= z2 < ts2: o2 = 0x08>>max(0,int(z2-ts1)) |
|
else: |
|
if (0<=ts1<z1)or(0>ts1>z1): o1 = 0xf0 |
|
if (0<=ts1<z2)or(0>ts1>z2): o2 = 0x0f |
|
k1 = 0x0f80 if z1>=0 else 0x00f0 |
|
k2 = 0x00f8 if z2>=0 else 0x000f |
|
if ts1 <= z1 < ts2: o1 = 0xf0&(k1>>max(0,int(z1-ts1))) |
|
if ts1 <= z2 < ts2: o2 = 0x0f&(k2>>max(0,int(z2-ts1))) |
|
braille ^= (o1|o2) |
|
# braille &= 0xff |
|
#TTkLog.debug(f"z:{zl1,zl2}, ts:{ts1,ts2},{o1,o2}") |
|
#if braille<0 or braille>0xff: |
|
# TTkLog.debug(f"z:{zl1,zl2},t:{t1,t2},i:{i} {t1-i*4} {t2-i*4} o:{o1,o2}, {hex(braille)}") |
|
self._set(y-i-1,x, gb[braille], color) |
|
|
|
def drawMenuBarBg(self, pos, size, color=TTkColor.RST ): |
|
mb = TTkCfg.theme.menuBar |
|
self.drawText(pos, text=f"{mb[3]}{mb[1]*(size-2)}{mb[4]}", color=color) |
|
|
|
def drawMenuBarButton(self, pos, width, text, border=True, submenu=False, shortcuts=[], color=TTkColor.RST, borderColor=TTkColor.RST, shortcutColor=TTkColor.UNDERLINE ): |
|
mb = TTkCfg.theme.menuBar |
|
x,y = pos |
|
if border: |
|
self.drawText(pos=(x,y), color=borderColor ,text=mb[2]) |
|
self.drawText(pos=(x+1+len(text),y), color=borderColor ,text=mb[0]) |
|
self.drawText(pos=(x+1,y), color=color ,text=text) |
|
off = 1 |
|
else: |
|
self.drawText(pos=(x,y), color=color ,text=text) |
|
if submenu: |
|
self._set(y,x+width-1, mb[5], color) |
|
off = 0 |
|
for i in shortcuts: |
|
self._set(y,x+i+off, text[i], shortcutColor) |
|
|
|
def execPaint(self, winw, winh): |
|
pass |
|
|
|
''' |
|
geom = (x,y,w,h) |
|
bound = (x,y,w,h) |
|
|
|
x x+w |
|
canvas: |xxxxxxxxxxxxxxxxxxxxxxx| |
|
slice: |-----------| |
|
bx bx+bw |
|
bound: |--------| |
|
0 self._width |
|
self._canvas: |----|xxxxxx|----------| |
|
''' |
|
def paintCanvas(self, canvas, geom, slice, bound): |
|
# TTkLog.debug(f"PaintCanvas:{(x,y,w,h)}") |
|
x, y, w, h = geom |
|
bx,by,bw,bh = bound |
|
# out of bound |
|
if not self._visible: return |
|
if not canvas._visible: return |
|
if canvas._width==0 or canvas._height==0: return |
|
if x+w < bx or y+h<by or bx+bw<x or by+bh<y: |
|
return |
|
|
|
x = min(x,self._width-1) |
|
y = min(y,self._height-1) |
|
w = min(w,self._width-x) |
|
h = min(h,self._height-y) |
|
|
|
# if x>=self._width: x=self._width-1 |
|
# if y>=self._height: y=self._height-1 |
|
# if w>=self._width-x: w=self._width-x |
|
# if h>=self._height-y: h=self._height-y |
|
|
|
xoffset = 0 if x>=bx else bx-x |
|
yoffset = 0 if y>=by else by-y |
|
wslice = w if x+w < bx+bw else bx+bw-x |
|
hslice = h if y+h < by+bh else by+bh-y |
|
|
|
|
|
for iy in range(yoffset,hslice): |
|
for ix in range(xoffset,wslice): |
|
#TTkLog.debug(f"PaintCanvas:{(ix,iy)}") |
|
if iy > len(canvas._data)-1: |
|
TTkLog.debug(f"{canvas._width, canvas._height} - {(yoffset,hslice)}, {(xoffset,wslice)}, {slice}") |
|
b = canvas._data[iy] |
|
a = b[ix] |
|
self._data[y+iy][x+ix] = a # canvas._data[iy][ix] |
|
self._colors[y+iy][x+ix] = canvas._colors[iy][ix] |
|
|
|
def pushToTerminal(self, x, y, w, h): |
|
# TTkLog.debug("pushToTerminal") |
|
lastcolor = TTkColor.RST |
|
for y in range(0, self._height): |
|
ansi = TTkColor.RST+lbt.Mv.t(y+1,1) |
|
for x in range(0, self._width): |
|
ch = self._data[y][x] |
|
color = self._colors[y][x] |
|
if color != lastcolor: |
|
ansi += color-lastcolor |
|
lastcolor = color |
|
ansi+=ch |
|
lbt.Term.push(ansi)</code></pre> |
|
</details> |
|
<h3>Methods</h3> |
|
<dl> |
|
<dt id="TermTk.TTkCore.canvas.TTkCanvas.clean"><code class="name flex"> |
|
<span>def <span class="ident">clean</span></span>(<span>self, pos=(0, 0), size=None)</span> |
|
</code></dt> |
|
<dd> |
|
<div class="desc"></div> |
|
<details class="source"> |
|
<summary> |
|
<span>Expand source code</span> |
|
</summary> |
|
<pre><code class="python">def clean(self, pos=(0, 0), size=None): |
|
if not self._visible: return |
|
x,y = pos |
|
w,h = size if size is not None else (self._width, self._height) |
|
for iy in range(y,y+h): |
|
for ix in range(x,x+w): |
|
self._data[iy][ix] = ' ' |
|
self._colors[iy][ix] = TTkColor.RST</code></pre> |
|
</details> |
|
</dd> |
|
<dt id="TermTk.TTkCore.canvas.TTkCanvas.drawBox"><code class="name flex"> |
|
<span>def <span class="ident">drawBox</span></span>(<span>self, pos, size, color=<TermTk.TTkCore.color._TTkColor object>, grid=0)</span> |
|
</code></dt> |
|
<dd> |
|
<div class="desc"></div> |
|
<details class="source"> |
|
<summary> |
|
<span>Expand source code</span> |
|
</summary> |
|
<pre><code class="python">def drawBox(self, pos, size, color=TTkColor.RST, grid=0): |
|
self.drawGrid(pos=pos, size=size, color=color, grid=grid)</code></pre> |
|
</details> |
|
</dd> |
|
<dt id="TermTk.TTkCore.canvas.TTkCanvas.drawBoxTitle"><code class="name flex"> |
|
<span>def <span class="ident">drawBoxTitle</span></span>(<span>self, pos, size, text, align=3, color=<TermTk.TTkCore.color._TTkColor object>, colorText=<TermTk.TTkCore.color._TTkColor object>, grid=0)</span> |
|
</code></dt> |
|
<dd> |
|
<div class="desc"></div> |
|
<details class="source"> |
|
<summary> |
|
<span>Expand source code</span> |
|
</summary> |
|
<pre><code class="python">def drawBoxTitle(self, pos, size, text, align=TTkK.CENTER_ALIGN, color=TTkColor.RST, colorText=TTkColor.RST, grid=0): |
|
if not self._visible: return |
|
x,y = pos |
|
w,h = size |
|
if w < 4: return |
|
gg = TTkCfg.theme.grid[grid] |
|
|
|
if len(text) > w-4: |
|
text = text[:w-4] |
|
if align == TTkK.CENTER_ALIGN: |
|
l = (w-2-len(text))//2 |
|
elif align == TTkK.LEFT_ALIGN: |
|
l=1 |
|
else: |
|
l = w-2-len(text) |
|
r = l+len(text)+1 |
|
|
|
self._set(y,l, gg[7], color) |
|
self._set(y,r, gg[6], color) |
|
self.drawText(pos=(l+1,y),text=text,color=colorText)</code></pre> |
|
</details> |
|
</dd> |
|
<dt id="TermTk.TTkCore.canvas.TTkCanvas.drawButtonBox"><code class="name flex"> |
|
<span>def <span class="ident">drawButtonBox</span></span>(<span>self, pos, size, color=<TermTk.TTkCore.color._TTkColor object>, grid=0)</span> |
|
</code></dt> |
|
<dd> |
|
<div class="desc"></div> |
|
<details class="source"> |
|
<summary> |
|
<span>Expand source code</span> |
|
</summary> |
|
<pre><code class="python">def drawButtonBox(self, pos, size, color=TTkColor.RST, grid=0): |
|
if not self._visible: return |
|
x,y = pos |
|
w,h = size |
|
gg = TTkCfg.theme.buttonBox[grid] |
|
# 4 corners |
|
self._set(y, x, gg[0], color) |
|
self._set(y, x+w-1, gg[2], color) |
|
self._set(y+h-1, x, gg[6], color) |
|
self._set(y+h-1, x+w-1, gg[8], color) |
|
if w > 2: |
|
for i in range(x+1,x+w-1): |
|
self._set(y, i, gg[1], color) |
|
self._set(y+h-1, i, gg[7], color) |
|
if h > 2: |
|
for i in range(y+1,y+h-1): |
|
self._set(i, x, gg[3], color) |
|
self._set(i, x+w-1, gg[5], color)</code></pre> |
|
</details> |
|
</dd> |
|
<dt id="TermTk.TTkCore.canvas.TTkCanvas.drawGrid"><code class="name flex"> |
|
<span>def <span class="ident">drawGrid</span></span>(<span>self, pos, size, hlines=[], vlines=[], color=<TermTk.TTkCore.color._TTkColor object>, grid=0)</span> |
|
</code></dt> |
|
<dd> |
|
<div class="desc"></div> |
|
<details class="source"> |
|
<summary> |
|
<span>Expand source code</span> |
|
</summary> |
|
<pre><code class="python">def drawGrid(self, pos, size, hlines=[], vlines=[], color=TTkColor.RST, grid=0): |
|
if not self._visible: return |
|
x,y = pos |
|
w,h = size |
|
gg = TTkCfg.theme.grid[grid] |
|
# 4 corners |
|
self._set(y, x, gg[0x00], color) |
|
self._set(y, x+w-1, gg[0x03], color) |
|
self._set(y+h-1, x, gg[0x0C], color) |
|
self._set(y+h-1, x+w-1, gg[0x0F], color) |
|
if w > 2: |
|
# Top/Bottom Line |
|
for i in range(x+1,x+w-1): |
|
self._set(y, i, gg[0x01], color) |
|
self._set(y+h-1, i, gg[0x0D], color) |
|
if h > 2: |
|
# Left/Right Line |
|
for i in range(y+1,y+h-1): |
|
self._set(i, x, gg[0x04], color) |
|
self._set(i, x+w-1, gg[0x07], color) |
|
# Draw horizontal lines |
|
for iy in hlines: |
|
iy += y |
|
if not (0 < iy < h): continue |
|
self._set(iy, x, gg[0x08], color) |
|
self._set(iy, x+w-1, gg[0x0B], color) |
|
if w > 2: |
|
for ix in range(x+1,x+w-1): |
|
self._set(iy, ix, gg[0x09], color) |
|
# Draw vertical lines |
|
for ix in vlines: |
|
ix+=x |
|
if not (0 < ix < w): continue |
|
self._set(y, ix, gg[0x02], color) |
|
self._set(y+h-1, ix, gg[0x0E], color) |
|
if h > 2: |
|
for iy in range(y+1,y+h-1): |
|
self._set(iy, ix, gg[0x06], color) |
|
# Draw intersections |
|
for iy in hlines: |
|
for ix in vlines: |
|
self._set(y+iy, x+ix, gg[0x0A], color)</code></pre> |
|
</details> |
|
</dd> |
|
<dt id="TermTk.TTkCore.canvas.TTkCanvas.drawHChart"><code class="name flex"> |
|
<span>def <span class="ident">drawHChart</span></span>(<span>self, pos, values, zoom=1.0, color=<TermTk.TTkCore.color._TTkColor object>)</span> |
|
</code></dt> |
|
<dd> |
|
<div class="desc"></div> |
|
<details class="source"> |
|
<summary> |
|
<span>Expand source code</span> |
|
</summary> |
|
<pre><code class="python">def drawHChart(self, pos, values, zoom=1.0, color=TTkColor.RST): |
|
x,y=pos |
|
v1,v2 = values |
|
gb=TTkCfg.theme.braille |
|
|
|
''' |
|
loop 0 1 2 3 = range(0,1+maxt//4) |
|
v1 13 |---|---|---|--| |
|
v2 10 |---|---|-| |
|
maxt 13 |---|---|---|--| |
|
out 4,4 4,4 4,2 3,0 0,0 |
|
o1 = 4 if v1-4 > i*4 else v1-i*4 |
|
''' |
|
# TTkLog.debug(f"{(v1,v2)} z{zoom}") |
|
zl1 = [ int(i*zoom) for i in v1 ] |
|
zl2 = [ int(i*zoom) for i in v2 ] |
|
maxz = max(max(zl1),max(zl2),0) |
|
minz = min(min(zl1),min(zl2),0) |
|
filled = True |
|
for i in range(int(minz//4),int(maxz//4)+2): |
|
ts1 = i*4 |
|
ts2 = i*4+4 |
|
''' |
|
Braille bits: |
|
o2 o1 = 4 bits each |
|
|
|
1 5 Braille dots |
|
2 6 |
|
3 7 |
|
4 8 |
|
|
|
TTkTheme.braille[( o1<<4 | o2 )] = Braille UTF-8 char |
|
''' |
|
braille = 0x00 |
|
for ii in range(len(zl1)): |
|
z1 = zl1[ii] |
|
z2 = zl2[ii] |
|
o1,o2 = 0,0 |
|
#TTkLog.debug |
|
if not filled or ii>0: |
|
if ts1 <= z1 < ts2: o1 = 0x80>>max(0,int(z1-ts1)) |
|
if ts1 <= z2 < ts2: o2 = 0x08>>max(0,int(z2-ts1)) |
|
else: |
|
if (0<=ts1<z1)or(0>ts1>z1): o1 = 0xf0 |
|
if (0<=ts1<z2)or(0>ts1>z2): o2 = 0x0f |
|
k1 = 0x0f80 if z1>=0 else 0x00f0 |
|
k2 = 0x00f8 if z2>=0 else 0x000f |
|
if ts1 <= z1 < ts2: o1 = 0xf0&(k1>>max(0,int(z1-ts1))) |
|
if ts1 <= z2 < ts2: o2 = 0x0f&(k2>>max(0,int(z2-ts1))) |
|
braille ^= (o1|o2) |
|
# braille &= 0xff |
|
#TTkLog.debug(f"z:{zl1,zl2}, ts:{ts1,ts2},{o1,o2}") |
|
#if braille<0 or braille>0xff: |
|
# TTkLog.debug(f"z:{zl1,zl2},t:{t1,t2},i:{i} {t1-i*4} {t2-i*4} o:{o1,o2}, {hex(braille)}") |
|
self._set(y-i-1,x, gb[braille], color)</code></pre> |
|
</details> |
|
</dd> |
|
<dt id="TermTk.TTkCore.canvas.TTkCanvas.drawHLine"><code class="name flex"> |
|
<span>def <span class="ident">drawHLine</span></span>(<span>self, pos, size, color=<TermTk.TTkCore.color._TTkColor object>)</span> |
|
</code></dt> |
|
<dd> |
|
<div class="desc"></div> |
|
<details class="source"> |
|
<summary> |
|
<span>Expand source code</span> |
|
</summary> |
|
<pre><code class="python">def drawHLine(self, pos, size, color=TTkColor.RST): |
|
if size == 0: return |
|
x,y = pos |
|
ln = TTkCfg.theme.hline |
|
if size == 1: |
|
txt = ln[0] |
|
elif size == 2: |
|
txt = ln[0]+ln[2] |
|
else: |
|
txt = ln[0]+(ln[1]*(size-2))+ln[2] |
|
self.drawText(pos=pos, text=txt, color=color)</code></pre> |
|
</details> |
|
</dd> |
|
<dt id="TermTk.TTkCore.canvas.TTkCanvas.drawMenuBarBg"><code class="name flex"> |
|
<span>def <span class="ident">drawMenuBarBg</span></span>(<span>self, pos, size, color=<TermTk.TTkCore.color._TTkColor object>)</span> |
|
</code></dt> |
|
<dd> |
|
<div class="desc"></div> |
|
<details class="source"> |
|
<summary> |
|
<span>Expand source code</span> |
|
</summary> |
|
<pre><code class="python">def drawMenuBarBg(self, pos, size, color=TTkColor.RST ): |
|
mb = TTkCfg.theme.menuBar |
|
self.drawText(pos, text=f"{mb[3]}{mb[1]*(size-2)}{mb[4]}", color=color)</code></pre> |
|
</details> |
|
</dd> |
|
<dt id="TermTk.TTkCore.canvas.TTkCanvas.drawMenuBarButton"><code class="name flex"> |
|
<span>def <span class="ident">drawMenuBarButton</span></span>(<span>self, pos, width, text, border=True, submenu=False, shortcuts=[], color=<TermTk.TTkCore.color._TTkColor object>, borderColor=<TermTk.TTkCore.color._TTkColor object>, shortcutColor=<TermTk.TTkCore.color._TTkColor object>)</span> |
|
</code></dt> |
|
<dd> |
|
<div class="desc"></div> |
|
<details class="source"> |
|
<summary> |
|
<span>Expand source code</span> |
|
</summary> |
|
<pre><code class="python">def drawMenuBarButton(self, pos, width, text, border=True, submenu=False, shortcuts=[], color=TTkColor.RST, borderColor=TTkColor.RST, shortcutColor=TTkColor.UNDERLINE ): |
|
mb = TTkCfg.theme.menuBar |
|
x,y = pos |
|
if border: |
|
self.drawText(pos=(x,y), color=borderColor ,text=mb[2]) |
|
self.drawText(pos=(x+1+len(text),y), color=borderColor ,text=mb[0]) |
|
self.drawText(pos=(x+1,y), color=color ,text=text) |
|
off = 1 |
|
else: |
|
self.drawText(pos=(x,y), color=color ,text=text) |
|
if submenu: |
|
self._set(y,x+width-1, mb[5], color) |
|
off = 0 |
|
for i in shortcuts: |
|
self._set(y,x+i+off, text[i], shortcutColor)</code></pre> |
|
</details> |
|
</dd> |
|
<dt id="TermTk.TTkCore.canvas.TTkCanvas.drawScroll"><code class="name flex"> |
|
<span>def <span class="ident">drawScroll</span></span>(<span>self, pos, size, slider, orientation, color=<TermTk.TTkCore.color._TTkColor object>)</span> |
|
</code></dt> |
|
<dd> |
|
<div class="desc"></div> |
|
<details class="source"> |
|
<summary> |
|
<span>Expand source code</span> |
|
</summary> |
|
<pre><code class="python">def drawScroll(self, pos, size, slider, orientation, color=TTkColor.RST): |
|
if not self._visible: return |
|
x,y = pos |
|
f,t = slider # slider from-to position |
|
if orientation == TTkK.HORIZONTAL: |
|
for i in range(x+1,x+size-1): # H line |
|
self._set(y,x+i, TTkCfg.theme.hscroll[1], color) |
|
for i in range(f,t): # Slider |
|
self._set(y,x+i, TTkCfg.theme.hscroll[2], color) |
|
self._set(y,x, TTkCfg.theme.hscroll[0], color) # Left Arrow |
|
self._set(y,x+size-1, TTkCfg.theme.hscroll[3], color) # Right Arrow |
|
else: |
|
for i in range(y+1,y+size-1): # V line |
|
self._set(y+i,x, TTkCfg.theme.vscroll[1], color) |
|
for i in range(f,t): # Slider |
|
self._set(y+i,x, TTkCfg.theme.vscroll[2], color) |
|
self._set(y,x, TTkCfg.theme.vscroll[0], color) # Up Arrow |
|
self._set(y+size-1,x, TTkCfg.theme.vscroll[3], color) # Down Arrow |
|
pass</code></pre> |
|
</details> |
|
</dd> |
|
<dt id="TermTk.TTkCore.canvas.TTkCanvas.drawTab"><code class="name flex"> |
|
<span>def <span class="ident">drawTab</span></span>(<span>self, pos, size, labels, labelsPos, selected, offset, leftScroller, rightScroller, slim=False, color=<TermTk.TTkCore.color._TTkColor object>, borderColor=<TermTk.TTkCore.color._TTkColor object>, selectColor=<TermTk.TTkCore.color._TTkColor object>)</span> |
|
</code></dt> |
|
<dd> |
|
<div class="desc"></div> |
|
<details class="source"> |
|
<summary> |
|
<span>Expand source code</span> |
|
</summary> |
|
<pre><code class="python">def drawTab( |
|
self, pos, size, |
|
labels, labelsPos, selected, |
|
offset, leftScroller, rightScroller, slim=False, |
|
color=TTkColor.RST, borderColor=TTkColor.RST, selectColor=TTkColor.RST): |
|
x,y = pos |
|
w,h = size |
|
tt = TTkCfg.theme.tab |
|
# phase 0 - Draw the Bottom bar |
|
if slim: |
|
bottomBar = tt[18]+tt[19]*(w-2)+tt[20] |
|
bottomPos = y+1 |
|
else: |
|
bottomBar = tt[11]+tt[12]*(w-2)+tt[15] |
|
bottomPos = y+2 |
|
self.drawText(pos=(x,bottomPos),text=bottomBar) |
|
# phase 1 - Draw From left to 'Selected' |
|
# phase 2 - Draw From right to 'Selected' |
|
def _drawTabSlim(x,y,a,b,c,d,e,txt,txtColor,borderColor): |
|
lentext = len(txt) |
|
center = a+txt+b |
|
bottom = c+d*(lentext)+e |
|
self.drawText(pos=(x,y),text=center, color=borderColor) |
|
self.drawText(pos=(x+1,y),text=txt, color=txtColor) |
|
self.drawText(pos=(x,y+1),text=bottom, color=borderColor) |
|
def _drawTab(x,y,a,b,c,d,e,f,g,h,i,j,k,l,m,txt,txtColor,borderColor,slim): |
|
if slim: return _drawTabSlim(x,y,i,j,k,l,m,txt,txtColor,borderColor) |
|
lentext = len(txt) |
|
top = a+b*lentext+c |
|
center = d+txt+e |
|
bottom = f+g*(lentext)+h |
|
self.drawText(pos=(x,y+0),text=top, color=borderColor) |
|
self.drawText(pos=(x,y+1),text=center, color=borderColor) |
|
self.drawText(pos=(x+1,y+1),text=txt, color=txtColor) |
|
self.drawText(pos=(x,y+2),text=bottom, color=borderColor) |
|
|
|
for i in list( range(offset )) + \ |
|
list(reversed(range(offset+1, len(labels)) )): |
|
text = labels[i] |
|
posx = labelsPos[i] |
|
_drawTab(x+posx,y,tt[0],tt[1],tt[3],tt[9],tt[9],tt[12],tt[12],tt[12],tt[9],tt[9],tt[23],tt[19],tt[24], text, color, borderColor, slim) |
|
# phase 3 - Draw 'Selected' |
|
if selected != -1: |
|
i = selected |
|
text = labels[i] |
|
posx = labelsPos[i] |
|
_drawTab(x+posx,y,tt[4],tt[5],tt[6],tt[10],tt[10],tt[14],tt[12],tt[14],tt[10],tt[10],tt[21],tt[12],tt[22], text, selectColor, borderColor, slim) |
|
if selected != offset: |
|
i = offset |
|
text = labels[i] |
|
posx = labelsPos[i] |
|
_drawTab(x+posx,y,tt[0],tt[1],tt[3],tt[9],tt[9],tt[13],tt[12],tt[13],tt[9],tt[9],tt[18],tt[19],tt[20], text, color, borderColor, slim) |
|
# phase 4 - Draw left right tilt |
|
if leftScroller: |
|
top = tt[7]+tt[1] |
|
center = tt[9]+tt[31] |
|
if slim: |
|
self.drawText(pos=(x,y),text=center, color=borderColor) |
|
else: |
|
self.drawText(pos=(x,y+0),text=top, color=borderColor) |
|
self.drawText(pos=(x,y+1),text=center, color=borderColor) |
|
if rightScroller: |
|
top = tt[1]+tt[8] |
|
center = tt[32]+tt[9] |
|
if slim: |
|
self.drawText(pos=(x+w-2,y),text=center, color=borderColor) |
|
else: |
|
self.drawText(pos=(x+w-2,y+0),text=top, color=borderColor) |
|
self.drawText(pos=(x+w-2,y+1),text=center, color=borderColor)</code></pre> |
|
</details> |
|
</dd> |
|
<dt id="TermTk.TTkCore.canvas.TTkCanvas.drawTableLine"><code class="name flex"> |
|
<span>def <span class="ident">drawTableLine</span></span>(<span>self, pos, items, sizes, colors, alignments)</span> |
|
</code></dt> |
|
<dd> |
|
<div class="desc"></div> |
|
<details class="source"> |
|
<summary> |
|
<span>Expand source code</span> |
|
</summary> |
|
<pre><code class="python">def drawTableLine(self, pos, items, sizes, colors, alignments ): |
|
x,y = pos |
|
for i in range(0,len(items)): |
|
txt = items[i] |
|
w = sizes[i] |
|
color = colors[i] |
|
align = alignments[i] |
|
if w > 0: |
|
line = "" |
|
lentxt = len(txt) |
|
if lentxt > w: |
|
line += txt[0:w] |
|
else: |
|
pad = w-lentxt |
|
if align == TTkK.NONE or align == TTkK.LEFT_ALIGN: |
|
line += txt + " "*pad |
|
elif align == TTkK.RIGHT_ALIGN: |
|
line += " "*pad + txt |
|
elif align == TTkK.CENTER_ALIGN: |
|
p1 = pad//2 |
|
p2 = pad-p1 |
|
line += " "*p1 + txt+" "*p2 |
|
elif align == TTkK.JUSTIFY: |
|
# TODO: Text Justification |
|
line += txt + " "*pad |
|
self.drawText(pos=(x,y), text=line, color=color) |
|
x += w + 1</code></pre> |
|
</details> |
|
</dd> |
|
<dt id="TermTk.TTkCore.canvas.TTkCanvas.drawText"><code class="name flex"> |
|
<span>def <span class="ident">drawText</span></span>(<span>self, pos, text, width=None, color=<TermTk.TTkCore.color._TTkColor object>, alignment=0)</span> |
|
</code></dt> |
|
<dd> |
|
<div class="desc"></div> |
|
<details class="source"> |
|
<summary> |
|
<span>Expand source code</span> |
|
</summary> |
|
<pre><code class="python">def drawText(self, pos, text, width=None, color=TTkColor.RST, alignment=TTkK.NONE): |
|
if not self._visible: return |
|
lentxt = len(text) |
|
if width is None or width<0: |
|
width = lentxt |
|
x,y = pos |
|
|
|
if lentxt < width: |
|
pad = width-lentxt |
|
if alignment == TTkK.NONE or alignment == TTkK.LEFT_ALIGN: |
|
text = text + " "*pad |
|
elif alignment == TTkK.RIGHT_ALIGN: |
|
text = " "*pad + text |
|
elif alignment == TTkK.CENTER_ALIGN: |
|
p1 = pad//2 |
|
p2 = pad-p1 |
|
text = " "*p1 + text+" "*p2 |
|
elif alignment == TTkK.JUSTIFY: |
|
# TODO: Text Justification |
|
text = text + " "*pad |
|
|
|
arr = list(text) |
|
for i in range(0, len(arr)): |
|
self._set(y, x+i, arr[i], color)</code></pre> |
|
</details> |
|
</dd> |
|
<dt id="TermTk.TTkCore.canvas.TTkCanvas.drawVLine"><code class="name flex"> |
|
<span>def <span class="ident">drawVLine</span></span>(<span>self, pos, size, color=<TermTk.TTkCore.color._TTkColor object>)</span> |
|
</code></dt> |
|
<dd> |
|
<div class="desc"></div> |
|
<details class="source"> |
|
<summary> |
|
<span>Expand source code</span> |
|
</summary> |
|
<pre><code class="python">def drawVLine(self, pos, size, color=TTkColor.RST): |
|
if size == 0: return |
|
x,y = pos |
|
ln = TTkCfg.theme.vline |
|
self._set(y, x, ln[0], color) |
|
self._set(y+size-1, x, ln[2], color) |
|
if size > 2: |
|
for i in range(1,size-1): |
|
self._set(y+i, x, ln[1], color)</code></pre> |
|
</details> |
|
</dd> |
|
<dt id="TermTk.TTkCore.canvas.TTkCanvas.execPaint"><code class="name flex"> |
|
<span>def <span class="ident">execPaint</span></span>(<span>self, winw, winh)</span> |
|
</code></dt> |
|
<dd> |
|
<div class="desc"></div> |
|
<details class="source"> |
|
<summary> |
|
<span>Expand source code</span> |
|
</summary> |
|
<pre><code class="python">def execPaint(self, winw, winh): |
|
pass</code></pre> |
|
</details> |
|
</dd> |
|
<dt id="TermTk.TTkCore.canvas.TTkCanvas.getWidget"><code class="name flex"> |
|
<span>def <span class="ident">getWidget</span></span>(<span>self)</span> |
|
</code></dt> |
|
<dd> |
|
<div class="desc"></div> |
|
<details class="source"> |
|
<summary> |
|
<span>Expand source code</span> |
|
</summary> |
|
<pre><code class="python">def getWidget(self): return self._widget</code></pre> |
|
</details> |
|
</dd> |
|
<dt id="TermTk.TTkCore.canvas.TTkCanvas.hide"><code class="name flex"> |
|
<span>def <span class="ident">hide</span></span>(<span>self)</span> |
|
</code></dt> |
|
<dd> |
|
<div class="desc"></div> |
|
<details class="source"> |
|
<summary> |
|
<span>Expand source code</span> |
|
</summary> |
|
<pre><code class="python">def hide(self): |
|
self._visible = False</code></pre> |
|
</details> |
|
</dd> |
|
<dt id="TermTk.TTkCore.canvas.TTkCanvas.paintCanvas"><code class="name flex"> |
|
<span>def <span class="ident">paintCanvas</span></span>(<span>self, canvas, geom, slice, bound)</span> |
|
</code></dt> |
|
<dd> |
|
<div class="desc"></div> |
|
<details class="source"> |
|
<summary> |
|
<span>Expand source code</span> |
|
</summary> |
|
<pre><code class="python">def paintCanvas(self, canvas, geom, slice, bound): |
|
# TTkLog.debug(f"PaintCanvas:{(x,y,w,h)}") |
|
x, y, w, h = geom |
|
bx,by,bw,bh = bound |
|
# out of bound |
|
if not self._visible: return |
|
if not canvas._visible: return |
|
if canvas._width==0 or canvas._height==0: return |
|
if x+w < bx or y+h<by or bx+bw<x or by+bh<y: |
|
return |
|
|
|
x = min(x,self._width-1) |
|
y = min(y,self._height-1) |
|
w = min(w,self._width-x) |
|
h = min(h,self._height-y) |
|
|
|
# if x>=self._width: x=self._width-1 |
|
# if y>=self._height: y=self._height-1 |
|
# if w>=self._width-x: w=self._width-x |
|
# if h>=self._height-y: h=self._height-y |
|
|
|
xoffset = 0 if x>=bx else bx-x |
|
yoffset = 0 if y>=by else by-y |
|
wslice = w if x+w < bx+bw else bx+bw-x |
|
hslice = h if y+h < by+bh else by+bh-y |
|
|
|
|
|
for iy in range(yoffset,hslice): |
|
for ix in range(xoffset,wslice): |
|
#TTkLog.debug(f"PaintCanvas:{(ix,iy)}") |
|
if iy > len(canvas._data)-1: |
|
TTkLog.debug(f"{canvas._width, canvas._height} - {(yoffset,hslice)}, {(xoffset,wslice)}, {slice}") |
|
b = canvas._data[iy] |
|
a = b[ix] |
|
self._data[y+iy][x+ix] = a # canvas._data[iy][ix] |
|
self._colors[y+iy][x+ix] = canvas._colors[iy][ix]</code></pre> |
|
</details> |
|
</dd> |
|
<dt id="TermTk.TTkCore.canvas.TTkCanvas.pushToTerminal"><code class="name flex"> |
|
<span>def <span class="ident">pushToTerminal</span></span>(<span>self, x, y, w, h)</span> |
|
</code></dt> |
|
<dd> |
|
<div class="desc"></div> |
|
<details class="source"> |
|
<summary> |
|
<span>Expand source code</span> |
|
</summary> |
|
<pre><code class="python">def pushToTerminal(self, x, y, w, h): |
|
# TTkLog.debug("pushToTerminal") |
|
lastcolor = TTkColor.RST |
|
for y in range(0, self._height): |
|
ansi = TTkColor.RST+lbt.Mv.t(y+1,1) |
|
for x in range(0, self._width): |
|
ch = self._data[y][x] |
|
color = self._colors[y][x] |
|
if color != lastcolor: |
|
ansi += color-lastcolor |
|
lastcolor = color |
|
ansi+=ch |
|
lbt.Term.push(ansi)</code></pre> |
|
</details> |
|
</dd> |
|
<dt id="TermTk.TTkCore.canvas.TTkCanvas.resize"><code class="name flex"> |
|
<span>def <span class="ident">resize</span></span>(<span>self, w, h)</span> |
|
</code></dt> |
|
<dd> |
|
<div class="desc"></div> |
|
<details class="source"> |
|
<summary> |
|
<span>Expand source code</span> |
|
</summary> |
|
<pre><code class="python">def resize(self, w, h): |
|
self._newWidth = w |
|
self._newHeight = h</code></pre> |
|
</details> |
|
</dd> |
|
<dt id="TermTk.TTkCore.canvas.TTkCanvas.show"><code class="name flex"> |
|
<span>def <span class="ident">show</span></span>(<span>self)</span> |
|
</code></dt> |
|
<dd> |
|
<div class="desc"></div> |
|
<details class="source"> |
|
<summary> |
|
<span>Expand source code</span> |
|
</summary> |
|
<pre><code class="python">def show(self): |
|
self._visible = True</code></pre> |
|
</details> |
|
</dd> |
|
<dt id="TermTk.TTkCore.canvas.TTkCanvas.updateSize"><code class="name flex"> |
|
<span>def <span class="ident">updateSize</span></span>(<span>self)</span> |
|
</code></dt> |
|
<dd> |
|
<div class="desc"></div> |
|
<details class="source"> |
|
<summary> |
|
<span>Expand source code</span> |
|
</summary> |
|
<pre><code class="python">def updateSize(self): |
|
if not self._visible: return |
|
w,h = self._newWidth, self._newHeight |
|
if w == self._width and h == self._height: |
|
return |
|
self._data = [[]]*h |
|
self._colors = [[]]*h |
|
for i in range(0,h): |
|
self._data[i] = [' ']*w |
|
self._colors[i] = [TTkColor.RST]*w |
|
self._width = w |
|
self._height = h</code></pre> |
|
</details> |
|
</dd> |
|
</dl> |
|
</dd> |
|
</dl> |
|
</section> |
|
</article> |
|
<nav id="sidebar"> |
|
<h1>Index</h1> |
|
<div class="toc"> |
|
<ul></ul> |
|
</div> |
|
<ul id="index"> |
|
<li><h3>Super-module</h3> |
|
<ul> |
|
<li><code><a title="TermTk.TTkCore" href="index.html">TermTk.TTkCore</a></code></li> |
|
</ul> |
|
</li> |
|
<li><h3><a href="#header-classes">Classes</a></h3> |
|
<ul> |
|
<li> |
|
<h4><code><a title="TermTk.TTkCore.canvas.TTkCanvas" href="#TermTk.TTkCore.canvas.TTkCanvas">TTkCanvas</a></code></h4> |
|
<ul class="two-column"> |
|
<li><code><a title="TermTk.TTkCore.canvas.TTkCanvas.clean" href="#TermTk.TTkCore.canvas.TTkCanvas.clean">clean</a></code></li> |
|
<li><code><a title="TermTk.TTkCore.canvas.TTkCanvas.drawBox" href="#TermTk.TTkCore.canvas.TTkCanvas.drawBox">drawBox</a></code></li> |
|
<li><code><a title="TermTk.TTkCore.canvas.TTkCanvas.drawBoxTitle" href="#TermTk.TTkCore.canvas.TTkCanvas.drawBoxTitle">drawBoxTitle</a></code></li> |
|
<li><code><a title="TermTk.TTkCore.canvas.TTkCanvas.drawButtonBox" href="#TermTk.TTkCore.canvas.TTkCanvas.drawButtonBox">drawButtonBox</a></code></li> |
|
<li><code><a title="TermTk.TTkCore.canvas.TTkCanvas.drawGrid" href="#TermTk.TTkCore.canvas.TTkCanvas.drawGrid">drawGrid</a></code></li> |
|
<li><code><a title="TermTk.TTkCore.canvas.TTkCanvas.drawHChart" href="#TermTk.TTkCore.canvas.TTkCanvas.drawHChart">drawHChart</a></code></li> |
|
<li><code><a title="TermTk.TTkCore.canvas.TTkCanvas.drawHLine" href="#TermTk.TTkCore.canvas.TTkCanvas.drawHLine">drawHLine</a></code></li> |
|
<li><code><a title="TermTk.TTkCore.canvas.TTkCanvas.drawMenuBarBg" href="#TermTk.TTkCore.canvas.TTkCanvas.drawMenuBarBg">drawMenuBarBg</a></code></li> |
|
<li><code><a title="TermTk.TTkCore.canvas.TTkCanvas.drawMenuBarButton" href="#TermTk.TTkCore.canvas.TTkCanvas.drawMenuBarButton">drawMenuBarButton</a></code></li> |
|
<li><code><a title="TermTk.TTkCore.canvas.TTkCanvas.drawScroll" href="#TermTk.TTkCore.canvas.TTkCanvas.drawScroll">drawScroll</a></code></li> |
|
<li><code><a title="TermTk.TTkCore.canvas.TTkCanvas.drawTab" href="#TermTk.TTkCore.canvas.TTkCanvas.drawTab">drawTab</a></code></li> |
|
<li><code><a title="TermTk.TTkCore.canvas.TTkCanvas.drawTableLine" href="#TermTk.TTkCore.canvas.TTkCanvas.drawTableLine">drawTableLine</a></code></li> |
|
<li><code><a title="TermTk.TTkCore.canvas.TTkCanvas.drawText" href="#TermTk.TTkCore.canvas.TTkCanvas.drawText">drawText</a></code></li> |
|
<li><code><a title="TermTk.TTkCore.canvas.TTkCanvas.drawVLine" href="#TermTk.TTkCore.canvas.TTkCanvas.drawVLine">drawVLine</a></code></li> |
|
<li><code><a title="TermTk.TTkCore.canvas.TTkCanvas.execPaint" href="#TermTk.TTkCore.canvas.TTkCanvas.execPaint">execPaint</a></code></li> |
|
<li><code><a title="TermTk.TTkCore.canvas.TTkCanvas.getWidget" href="#TermTk.TTkCore.canvas.TTkCanvas.getWidget">getWidget</a></code></li> |
|
<li><code><a title="TermTk.TTkCore.canvas.TTkCanvas.hide" href="#TermTk.TTkCore.canvas.TTkCanvas.hide">hide</a></code></li> |
|
<li><code><a title="TermTk.TTkCore.canvas.TTkCanvas.paintCanvas" href="#TermTk.TTkCore.canvas.TTkCanvas.paintCanvas">paintCanvas</a></code></li> |
|
<li><code><a title="TermTk.TTkCore.canvas.TTkCanvas.pushToTerminal" href="#TermTk.TTkCore.canvas.TTkCanvas.pushToTerminal">pushToTerminal</a></code></li> |
|
<li><code><a title="TermTk.TTkCore.canvas.TTkCanvas.resize" href="#TermTk.TTkCore.canvas.TTkCanvas.resize">resize</a></code></li> |
|
<li><code><a title="TermTk.TTkCore.canvas.TTkCanvas.show" href="#TermTk.TTkCore.canvas.TTkCanvas.show">show</a></code></li> |
|
<li><code><a title="TermTk.TTkCore.canvas.TTkCanvas.updateSize" href="#TermTk.TTkCore.canvas.TTkCanvas.updateSize">updateSize</a></code></li> |
|
</ul> |
|
</li> |
|
</ul> |
|
</li> |
|
</ul> |
|
</nav> |
|
</main> |
|
<footer id="footer"> |
|
<p>Generated by <a href="https://pdoc3.github.io/pdoc"><cite>pdoc</cite> 0.9.2</a>.</p> |
|
</footer> |
|
</body> |
|
</html> |