Post Reply 
Terminal alternative
12-19-2014, 05:13 PM (This post was last modified: 12-25-2014 04:24 PM by Snorre.)
Post: #1
Terminal alternative
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.
Find all posts by this user
Quote this message in a reply
06-04-2017, 06:33 PM (This post was last modified: 06-04-2017 06:57 PM by Freire.)
Post: #2
RE: Terminal alternative
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;
[...]
Find all posts by this user
Quote this message in a reply
06-06-2017, 07:58 PM (This post was last modified: 06-06-2017 08:05 PM by compsystems.)
Post: #3
RE: Terminal alternative
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+10END;

LineWidth()
BEGIN IP(-15.5*LN(FontSize)+63.9); END;

TotalHeight()
BEGIN SIZE(Buffer)*LineHeightEND;

ScrollHeight()
BEGIN 240²/TotalHeightEND;

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<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))>wTHEN
                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)>wTHEN
            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=
    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
Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: 1 Guest(s)