Terminal alternative - Snorre - 12-19-2014 05:13 PM
Hello,
this program is borrowed from the german HP-Prime forum.
It was written because the builtin terminal has some drawbacks (which were introduced in some recent firmware update) -- mainly very size-limited line buffer and not displaying the most recent PRINTed line.
Beware: This program does not break long lines as the builtin terminal would do, and G9 is used as drawing buffer.
Program "TERM":
Code:
EXPORT LiveView:=1; // Visible while outputting?
BackColor:=RGB(0,0,0);
TextColor:=RGB(0,255,0);
BarBColor:=RGB(0,128,0);
BarFColor:=RGB(64,255,64);
Capacity:=9999; // = max list size
FontSize:=2;
Buffer:={};
LastTouchY,Top;
LineHeight()
BEGIN 2*FontSize+10; END;
TotalHeight()
BEGIN SIZE(Buffer)*LineHeight; END;
MaxTop()
BEGIN MAX(TotalHeight-240,0); END;
Redraw(top)
BEGIN
// Draw buffered lines
LOCAL h:=LineHeight;
LOCAL n:=SIZE(Buffer),
k:=IP(top/h),
y:=-(top MOD h);
DIMGROB_P(G9,320,240,BackColor);
WHILE k<n AND y<240 DO
TEXTOUT_P(Buffer(k:=k+1),G9,0,y,
FontSize,TextColor);
y:=y+h;
END;
// Draw scrollbar
LOCAL t:=TotalHeight;
IF t≥240 THEN
y:=240*top/t;
RECT_P(G9,318,0,319,239,BarBColor);
RECT_P(G9,318,y,319,y+240²/t,BarFColor);
END;
// Show
BLIT(G9);
Top:=top;
END;
MoveTo(top)
BEGIN
top:=MAX(MIN(top,MaxTop),0);
IF top≠Top THEN Redraw(top); END;
END;
Resize(fontSize)
BEGIN
fontSize:=MAX(MIN(fontSize,7),1);
IF fontSize≠FontSize THEN
FontSize:=fontSize;
Redraw(MIN(Top,MaxTop));
END;
END;
HandleTouch(touch)
BEGIN
IF touch(1)≤#1 THEN
LOCAL y:=B→R(touch(3));
CASE
IF touch(2)≥#300d
THEN MoveTo(y/240*TotalHeight); END;
IF touch(1)=#1
THEN MoveTo(Top+LastTouchY-y); END;
END;
LastTouchY:=y;
END;
END;
HandleKey(code)
BEGIN
CASE
IF code=7 THEN MoveTo(0); END;
IF code=8 THEN MoveTo(MaxTop); END;
IF code=2 THEN MoveTo(Top-80); END;
IF code=12 THEN MoveTo(Top+80); END;
IF code=42 THEN Resize(1); END;
IF code=43 THEN Resize(2); END;
IF code=44 THEN Resize(3); END;
IF code=37 THEN Resize(4); END;
IF code=38 THEN Resize(5); END;
IF code=39 THEN Resize(6); END;
IF code=32 THEN Resize(7); END;
IF code=45 THEN Resize(FontSize-1); END;
IF code=50 THEN Resize(FontSize+1); END;
END;
END;
// Clear the terminal buffer.
EXPORT CLEAR()
BEGIN
Buffer:={};
IF LiveView THEN Redraw(0); END;
END;
// Add a single line or a list of lines to terminal buffer.
EXPORT OUT(data)
BEGIN
LOCAL s:=SIZE(Buffer)+
IFTE(TYPE(data)=6,SIZE(data),1);
IF s>Capacity THEN
Buffer:=SUB(Buffer,s-Capacity+1,Capacity);
END;
Buffer:=CONCAT(Buffer,data);
IF LiveView THEN Redraw(MaxTop); END;
END;
// Show the terminal buffer contents.
EXPORT SHOW()
BEGIN
Redraw(MIN(Top,MaxTop));
LOCAL inp;
REPEAT
IF TYPE(inp:=WAIT(-1))=6
THEN HandleTouch(inp); inp:=-1;
ELSE HandleKey(inp); END;
UNTIL inp=30 OR inp=4; // leave on [Enter] or [Esc]
END;
Usage:
Replace "PRINT()" by "TERM.CLEAR()", "PRINT(data)" by "TERM.OUT(data)", and call "TERM.SHOW()" to view the buffer. (Omit the prefix "TERM." if "CLEAR", "OUT", "SHOW" don't collide with other function names).
If "TERM.LiveView" is set to 0 the program won't display anything until "SHOW()"ed.
Scroll to top/bottom by cursoring left/right, or otherwise 1/3-page up/down.
Keys [1],...,[7],[+],[-] will change font size.
Test program "TERMTEST" for comparing builtin terminal vs. "TERM":
Code:
EXPORT TERMTEST1()
BEGIN
PRINT();
LOCAL n:=0,s;
REPEAT
s:=STRINGFROMID(n:=n+1);
PRINT(n+": "+s);
UNTIL s="LASTSTRING";
END;
EXPORT TERMTEST2()
BEGIN
CLEAR();
LOCAL n:=0,s;
REPEAT
s:=STRINGFROMID(n:=n+1);
OUT(n+": "+s);
UNTIL s="LASTSTRING";
SHOW();
END;
Any improvements are very welcome. Ideas: handle line breaks, long lines, tabulators, highlight numbers, better type handling in general etc.
This program might become obsolete eventually, when the Prime's builtin terminal is upgraded.
Greetings
[EDIT] Thread renamed to not disrupt the sequence of "HP Prime: ..." articles by E. W. Shore when alphabetically sorted.
RE: Terminal alternative - Freire - 06-04-2017 06:33 PM
Althought this is an old post, this Terminal is very good.
Suggestions to code:
-Scroll bar a bit larger and bit more precision by moving it through it's midpoint instead of top point.
-Change in OUT(data) to deal with strings that are larger than a Line, to be printed in 2 lines.
-Fancy Header.
PS: This is not the most elegant and is a bit imprecise but works better than before.
The way of cutting strings into two lines is far from good.
New Code:
Code:
//==========================================
// Author: Snorre
// Version: 1.01
// Update: 04 June 2017
// Firmware: 10637 -> 29/08/2016
//==========================================
EXPORT LiveView:=1; // Visible while outputting?
BackColor:=RGB(0,0,0);
TextColor:=RGB(0,255,0);
BarBColor:=RGB(0,128,0);
BarFColor:=RGB(64,255,64);
Capacity:=9999; // = max list size
FontSize:=2;
Buffer:={};
LastTouchY,Top;
LineHeight()
BEGIN 2*FontSize+10; END;
LineWidth()
BEGIN IP(-15.5*LN(FontSize)+63.9); END;
TotalHeight()
BEGIN SIZE(Buffer)*LineHeight; END;
ScrollHeight()
BEGIN 240²/TotalHeight; END;
MaxTop()
BEGIN MAX(TotalHeight-240,0); END;
Redraw(top)
BEGIN
// Draw buffered lines
LOCAL h:=LineHeight;
LOCAL n:=SIZE(Buffer),
k:=IP(top/h),
y:=-(top MOD h);
DIMGROB_P(G9,320,240,BackColor);
WHILE k<n AND y<240 DO
TEXTOUT_P(Buffer(k:=k+1),G9,0,y,
FontSize,TextColor);
y:=y+h;
END;
// Draw scrollbar
LOCAL t:=TotalHeight;
IF t≥240 THEN
y:=240*top/t;
RECT_P(G9,316,0,319,239,BarBColor);
RECT_P(G9,316,y,319,y+240²/t,BarFColor);
END;
// Show
BLIT(G9);
Top:=top;
END;
MoveTo(top)
BEGIN
top:=MAX(MIN(top,MaxTop),0);
IF top≠Top THEN Redraw(top); END;
END;
Resize(fontSize)
BEGIN
fontSize:=MAX(MIN(fontSize,7),1);
IF fontSize≠FontSize THEN
FontSize:=fontSize;
Redraw(MIN(Top,MaxTop));
END;
END;
HandleTouch(touch)
BEGIN
IF touch(1)≤#1 THEN
LOCAL y:=B→R(touch(3));
CASE
IF touch(2)≥#300d
THEN MoveTo((y-ScrollHeight/2)/240*TotalHeight); END;
IF touch(1)=#1
THEN MoveTo(Top+LastTouchY-y); END;
END;
LastTouchY:=y;
END;
END;
HandleKey(code)
BEGIN
CASE
IF code=7 THEN MoveTo(0); END;
IF code=8 THEN MoveTo(MaxTop); END;
IF code=2 THEN MoveTo(Top-80); END;
IF code=12 THEN MoveTo(Top+80); END;
IF code=42 THEN Resize(1); END;
IF code=43 THEN Resize(2); END;
IF code=44 THEN Resize(3); END;
IF code=37 THEN Resize(4); END;
IF code=38 THEN Resize(5); END;
IF code=39 THEN Resize(6); END;
IF code=32 THEN Resize(7); END;
IF code=45 THEN Resize(FontSize-1); END;
IF code=50 THEN Resize(FontSize+1); END;
END;
END;
// Clear the terminal buffer.
EXPORT CLEAR()
BEGIN
Buffer:={};
IF LiveView THEN Redraw(0); END;
END;
// Add a single line or a list of lines to terminal buffer.
EXPORT OUT(data)
BEGIN
LOCAL w:=LineWidth;
LOCAL temp_data,temp_datas;
IF TYPE(data)==6 THEN
FOR i FROM 1 TO SIZE(data) DO
IF (DIM(data(i))>w) THEN
temp_data:=SUB(data,i+1,SIZE(data));
temp_datas:=data(i);
data(i):=LEFT(data(i),w);
data:=CONCAT(SUB(data,1,i),RIGHT(temp_datas,DIM(temp_datas)-w));
data:=CONCAT(data,temp_data);
END;
END;
ELSE
IF (DIM(data)>w) THEN
temp_datas:=data;
data:={};
data:=CONCAT(data,LEFT(temp_datas,w));
data:=CONCAT(data,RIGHT(temp_datas,DIM(temp_datas)-w));
END;
END;
LOCAL s:=SIZE(Buffer)+
IFTE(TYPE(data)=6,SIZE(data),1);
IF s>Capacity THEN
Buffer:=SUB(Buffer,s-Capacity+1,Capacity);
END;
Buffer:=CONCAT(Buffer,data);
IF LiveView THEN Redraw(MaxTop); END;
END;
// Show the terminal buffer contents.
EXPORT SHOW()
BEGIN
Redraw(MIN(Top,MaxTop));
LOCAL inp;
REPEAT
IF TYPE(inp:=WAIT(-1))=6
THEN HandleTouch(inp); inp:=-1;
ELSE HandleKey(inp); END;
UNTIL inp=30 OR inp=4; // leave on [Enter] or [Esc]
END;
Changed Parts:
Code:
//==========================================
// Author: Snorre
// Version: 1.01
// Update: 04 June 2017
// Firmware: 10637 -> 29/08/2016
//==========================================
[...]
LineWidth()
BEGIN IP(-15.5*LN(FontSize)+63.9); END;
[...]
ScrollHeight()
BEGIN 240²/TotalHeight; END;
[...]
RECT_P(G9,316,0,319,239,BarBColor);
RECT_P(G9,316,y,319,y+240²/t,BarFColor);
[...]
THEN MoveTo((y-ScrollHeight/2)/240*TotalHeight); END;
[...]
LOCAL w:=LineWidth;
LOCAL temp_data,temp_datas;
IF TYPE(data)==6 THEN
FOR i FROM 1 TO SIZE(data) DO
IF (DIM(data(i))>w) THEN
temp_data:=SUB(data,i+1,SIZE(data));
temp_datas:=data(i);
data(i):=LEFT(data(i),w);
data:=CONCAT(SUB(data,1,i),RIGHT(temp_datas,DIM(temp_datas)-w));
data:=CONCAT(data,temp_data);
END;
END;
ELSE
IF (DIM(data)>w) THEN
temp_datas:=data;
data:={};
data:=CONCAT(data,LEFT(temp_datas,w));
data:=CONCAT(data,RIGHT(temp_datas,DIM(temp_datas)-w));
END;
END;
[...]
RE: Terminal alternative - compsystems - 06-06-2017 07:58 PM
2 new cmds
PHP Code:
//========================================== // File: TERM.hpprgm // Author: Snorre // Version: 1.02 // Update: 04 June 2017 // Firmware: 10637 -> 29/08/2016 //========================================== EXPORT LiveView:=0; // Visible EXPORT FontSize:=3;
BackColor:=RGB(0,0,0); TextColor:=RGB(0,255,0); BarBColor:=RGB(0,128,0); BarFColor:=RGB(64,255,64);
Capacity:=9999; // = max list size
Buffer:={}; LastTouchY,Top;
LineHeight() BEGIN 2*FontSize+10; END;
LineWidth() BEGIN IP(-15.5*LN(FontSize)+63.9); END;
TotalHeight() BEGIN SIZE(Buffer)*LineHeight; END;
ScrollHeight() BEGIN 240²/TotalHeight; END;
MaxTop() BEGIN MAX(TotalHeight-240,0); END;
Redraw(top) BEGIN // Draw buffered lines LOCAL h:=LineHeight; LOCAL n:=SIZE(Buffer), k:=IP(top/h), y:=-(top MOD h); DIMGROB_P(G9,320,240,BackColor); WHILE k<n AND y<240 DO TEXTOUT_P(Buffer(k:=k+1),G9,0,y, FontSize,TextColor); y:=y+h; END; // Draw scrollbar LOCAL t:=TotalHeight; IF t≥240 THEN y:=240*top/t; RECT_P(G9,316,0,319,239,BarBColor); RECT_P(G9,316,y,319,y+240²/t,BarFColor); END; // Show BLIT(G9); Top:=top; END;
MoveTo(top) BEGIN top:=MAX(MIN(top,MaxTop),0); IF top≠Top THEN Redraw(top); END; END;
Resize(fontSize) BEGIN fontSize:=MAX(MIN(fontSize,7),1); IF fontSize≠FontSize THEN FontSize:=fontSize; Redraw(MIN(Top,MaxTop)); END; END;
HandleTouch(touch) BEGIN IF touch(1)≤#1 THEN LOCAL y:=B→R(touch(3)); CASE IF touch(2)≥#300d THEN MoveTo((y-ScrollHeight/2)/240*TotalHeight); END; IF touch(1)=#1 THEN MoveTo(Top+LastTouchY-y); END; END; LastTouchY:=y; END; END;
HandleKey(code) BEGIN CASE IF code=7 THEN MoveTo(0); END; IF code=8 THEN MoveTo(MaxTop); END; IF code=2 THEN MoveTo(Top-80); END; IF code=12 THEN MoveTo(Top+80); END; IF code=42 THEN Resize(1); END; IF code=43 THEN Resize(2); END; IF code=44 THEN Resize(3); END; IF code=37 THEN Resize(4); END; IF code=38 THEN Resize(5); END; IF code=39 THEN Resize(6); END; IF code=32 THEN Resize(7); END; IF code=45 THEN Resize(FontSize-1); END; IF code=50 THEN Resize(FontSize+1); END; END; END;
// Clear the terminal buffer. EXPORT CLEAR() BEGIN Buffer:={}; IF LiveView THEN Redraw(0); END; END;
// Add a single line or a list of lines to terminal buffer. EXPORT OUT(data) BEGIN LOCAL w:=LineWidth; LOCAL temp_data,temp_datas; IF TYPE(data)==6 THEN FOR i FROM 1 TO SIZE(data) DO IF (DIM(data(i))>w) THEN temp_data:=SUB(data,i+1,SIZE(data)); temp_datas:=data(i); data(i):=LEFT(data(i),w); data:=CONCAT(SUB(data,1,i),RIGHT(temp_datas,DIM(temp_datas)-w)); data:=CONCAT(data,temp_data); END; END; ELSE IF (DIM(data)>w) THEN temp_datas:=data; data:={}; data:=CONCAT(data,LEFT(temp_datas,w)); data:=CONCAT(data,RIGHT(temp_datas,DIM(temp_datas)-w)); END; END; LOCAL s:=SIZE(Buffer)+ IFTE(TYPE(data)=6,SIZE(data),1); IF s>Capacity THEN Buffer:=SUB(Buffer,s-Capacity+1,Capacity); END; Buffer:=CONCAT(Buffer,data); IF LiveView THEN Redraw(MaxTop); END; END;
// Show the terminal buffer contents. EXPORT SHOW() BEGIN Redraw(MIN(Top,MaxTop)); LOCAL inp; REPEAT IF TYPE(inp:=WAIT(-1))=6 THEN HandleTouch(inp); inp:=-1; ELSE HandleKey(inp); END; UNTIL inp=30 OR inp=4; // leave on [Enter] or [Esc] END;
// Set EXPORT SET_VISIBLE_TERM(flag) BEGIN IF flag=1 THEN LiveView:=1; ELSE LiveView:=0; END; END;
// Set EXPORT SET_FONTSIZE_TERM(size_f) BEGIN FontSize:=size_f; END;
file: testTerm.hpprgm
PHP Code:
//file: testTerm.hpprgm EXPORT TERMTEST1() BEGIN PRINT(); LOCAL n:=0,s; REPEAT s:=STRINGFROMID(n:=n+1); PRINT(n+": "+s); //wait(0.1); UNTIL n=2995; //return {s,n}; return "Done"; END;
EXPORT TERMTEST2() BEGIN TERM.CLEAR(); LOCAL n:=0,s; TERM.SET_VISIBLE_TERM(1); TERM.SET_FONTSIZE_TERM(3); REPEAT s:=STRINGFROMID(n:=n+1); TERM.OUT(n+": "+s); //wait(0.1); UNTIL n=2995; TERM.SHOW(); //return {s,n}; return "Done"; END;
|