Add the possibility to scroll text up and down in a virtual window

This commit is contained in:
Markus Gans 2016-10-08 02:54:32 +02:00
parent 605194b69e
commit 8328af4132
11 changed files with 209 additions and 68 deletions

View File

@ -1,4 +1,8 @@
2016-10-02 Markus Gans <guru.mail@muenster.de> 2016-10-08 Markus Gans <guru.mail@muenster.de>
* Add the possibility to scroll text up and down
in a virtual window
2016-10-06 Markus Gans <guru.mail@muenster.de>
* The input cursor is now controlled by the virtual terminal * The input cursor is now controlled by the virtual terminal
2016-10-02 Markus Gans <guru.mail@muenster.de> 2016-10-02 Markus Gans <guru.mail@muenster.de>

View File

@ -567,7 +567,7 @@ void FDialog::draw()
if ( isMonochron() ) if ( isMonochron() )
setReverse(true); setReverse(true);
clearArea(); clearArea (vwin);
drawBorder(); drawBorder();
drawTitleBar(); drawTitleBar();
setCursorPos(2, getHeight() - 1); setCursorPos(2, getHeight() - 1);

View File

@ -591,7 +591,7 @@ void FMenu::draw()
if ( isMonochron() ) if ( isMonochron() )
setReverse(true); setReverse(true);
clearArea(); clearArea (vwin);
drawBorder(); drawBorder();
drawItems(); drawItems();
drawShadow(); drawShadow();

View File

@ -60,6 +60,8 @@ static tcap_map tcap[] =
{ 0, "RI" }, // parm_right_cursor -> move #1 characters to the right (P*) { 0, "RI" }, // parm_right_cursor -> move #1 characters to the right (P*)
{ 0, "sc" }, // save_cursor -> save current cursor position (P) { 0, "sc" }, // save_cursor -> save current cursor position (P)
{ 0, "rc" }, // restore_cursor -> restore cursor to save_cursor { 0, "rc" }, // restore_cursor -> restore cursor to save_cursor
{ 0, "sf" }, // scroll_forward -> scroll text up (P)
{ 0, "sr" }, // scroll_reverse -> scroll text down (P)
{ 0, "ti" }, // enter_ca_mode -> string to start programs using cup { 0, "ti" }, // enter_ca_mode -> string to start programs using cup
{ 0, "te" }, // exit_ca_mode -> strings to end programs using cup { 0, "te" }, // exit_ca_mode -> strings to end programs using cup
{ 0, "eA" }, // enable_acs -> enable alternate char set { 0, "eA" }, // enable_acs -> enable alternate char set
@ -151,6 +153,8 @@ enum termcaps
t_parm_right_cursor, t_parm_right_cursor,
t_save_cursor, t_save_cursor,
t_restore_cursor, t_restore_cursor,
t_scroll_forward,
t_scroll_reverse,
t_enter_ca_mode, t_enter_ca_mode,
t_exit_ca_mode, t_exit_ca_mode,
t_enable_acs, t_enable_acs,

View File

@ -1752,6 +1752,7 @@ void FTerm::init()
// create virtual desktop area // create virtual desktop area
createArea (vdesktop); createArea (vdesktop);
vdesktop->visible = true; vdesktop->visible = true;
active_area = vdesktop;
// make stdin non-blocking // make stdin non-blocking
setNonBlockingInput(); setNonBlockingInput();
@ -2683,8 +2684,8 @@ bool FTerm::updateVTermCursor (FTerm::term_area* area)
ax = area->widget->getTermX() - 1; ax = area->widget->getTermX() - 1;
ay = area->widget->getTermY() - 1; ay = area->widget->getTermY() - 1;
// area position // area position
x = ax + cx - 1; x = ax + cx;
y = ay + cy - 1; y = ay + cy;
if ( isInsideArea(cx, cy, area) if ( isInsideArea(cx, cy, area)
&& isInsideTerminal(x+1, y+1) && isInsideTerminal(x+1, y+1)
@ -2724,8 +2725,8 @@ void FTerm::setAreaCursor (int x, int y, bool visible, FTerm::term_area* area)
if ( ! area ) if ( ! area )
return; return;
area->input_cursor_x = x; area->input_cursor_x = x - 1;
area->input_cursor_y = y; area->input_cursor_y = y - 1;
area->input_cursor_visible = visible; area->input_cursor_visible = visible;
updateVTerm (area); updateVTerm (area);
} }
@ -2939,42 +2940,97 @@ void FTerm::putArea (int ax, int ay, FTerm::term_area* area)
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FTerm::clearArea() void FTerm::scrollAreaForward (FTerm::term_area* area)
{ {
term_area* area; int total_width;
FWindow* window; int length;
FWidget* widget; int y_max;
FOptiAttr::char_data default_char; FOptiAttr::char_data nc; // next character
FOptiAttr::char_data* lc; // last character
FOptiAttr::char_data* sc; // source character
FOptiAttr::char_data* dc; // destination character
if ( ! area )
return;
if ( area->height <= 1 )
return;
length = area->width;
total_width = area->width + area->right_shadow;
y_max = area->height - 1;
for (int y=0; y < y_max; y++)
{
int pos1 = y * total_width;
int pos2 = (y+1) * total_width;
sc = &area->text[pos2];
dc = &area->text[pos1];
std::memcpy (dc, sc, sizeof(FOptiAttr::char_data) * unsigned(length));
area->changes[y].xmin = 0;
area->changes[y].xmax = uInt(area->width - 1);
}
// insert a new line below
lc = &area->text[(y_max * total_width) - area->right_shadow - 1];
std::memcpy (&nc, lc, sizeof(FOptiAttr::char_data));
nc.code = ' ';
dc = &area->text[y_max * total_width];
std::fill_n (dc, area->width, nc);
area->changes[y_max].xmin = 0;
area->changes[y_max].xmax = uInt(area->width - 1);
}
//----------------------------------------------------------------------
void FTerm::scrollAreaReverse (FTerm::term_area* area)
{
int total_width;
int length;
FOptiAttr::char_data nc; // next character
FOptiAttr::char_data* lc; // last character
FOptiAttr::char_data* sc; // source character
FOptiAttr::char_data* dc; // destination character
if ( ! area )
return;
if ( area->height <= 1 )
return;
length = area->width;
total_width = area->width + area->right_shadow;
for (int y=area->height-1; y > 0; y--)
{
int pos1 = (y-1) * total_width;
int pos2 = y * total_width;
sc = &area->text[pos1];
dc = &area->text[pos2];
std::memcpy (dc, sc, sizeof(FOptiAttr::char_data) * unsigned(length));
area->changes[y].xmin = 0;
area->changes[y].xmax = uInt(area->width - 1);
}
// insert a new line above
lc = &area->text[total_width];
std::memcpy (&nc, lc, sizeof(FOptiAttr::char_data));
nc.code = ' ';
dc = &area->text[0];
std::fill_n (dc, area->width, nc);
area->changes[0].xmin = 0;
area->changes[0].xmax = uInt(area->width - 1);
}
//----------------------------------------------------------------------
void FTerm::clearArea (FTerm::term_area* area)
{
FOptiAttr::char_data nc; // next character
int total_width; int total_width;
uInt w; uInt w;
default_char.code = ' '; // clear with the current attributes and space characters
default_char.fg_color = next_attribute.fg_color; std::memcpy (&nc, &next_attribute, sizeof(FOptiAttr::char_data));
default_char.bg_color = next_attribute.bg_color; nc.code = ' ';
default_char.bold = next_attribute.bold;
default_char.dim = next_attribute.dim;
default_char.italic = next_attribute.italic;
default_char.underline = next_attribute.underline;
default_char.blink = next_attribute.blink;
default_char.reverse = next_attribute.reverse;
default_char.standout = next_attribute.standout;
default_char.invisible = next_attribute.invisible;
default_char.protect = next_attribute.protect;
default_char.crossed_out = next_attribute.crossed_out;
default_char.dbl_underline = next_attribute.dbl_underline;
default_char.alt_charset = next_attribute.alt_charset;
default_char.pc_charset = next_attribute.pc_charset;
default_char.transparent = next_attribute.transparent;
default_char.trans_shadow = next_attribute.trans_shadow;
default_char.inherit_bg = next_attribute.inherit_bg;
widget = static_cast<FWidget*>(this);
window = FWindow::getWindowWidget(widget);
if ( window )
area = window->getVWin();
else
area = vdesktop;
if ( ! area ) if ( ! area )
return; return;
@ -2985,17 +3041,17 @@ void FTerm::clearArea()
if ( area->right_shadow == 0 ) if ( area->right_shadow == 0 )
{ {
int area_size = area->width * area->height; int area_size = area->width * area->height;
std::fill_n (area->text, area_size, default_char); std::fill_n (area->text, area_size, nc);
} }
else else
{ {
FOptiAttr::char_data t_char = default_char; FOptiAttr::char_data t_char = nc;
t_char.transparent = true; t_char.transparent = true;
for (int y=0; y < area->height; y++) for (int y=0; y < area->height; y++)
{ {
int pos = y * total_width; int pos = y * total_width;
std::fill_n (&area->text[pos], total_width, default_char); std::fill_n (&area->text[pos], total_width, nc);
std::fill_n (&area->text[pos+area->width], area->right_shadow, t_char); std::fill_n (&area->text[pos+area->width], area->right_shadow, t_char);
} }
@ -3012,9 +3068,9 @@ void FTerm::clearArea()
area->changes[i].xmin = 0; area->changes[i].xmin = 0;
area->changes[i].xmax = w - 1; area->changes[i].xmax = w - 1;
if ( default_char.transparent if ( nc.transparent
|| default_char.trans_shadow || nc.trans_shadow
|| default_char.inherit_bg ) || nc.inherit_bg )
area->changes[i].trans_count = w; area->changes[i].trans_count = w;
else if ( area->right_shadow != 0 ) else if ( area->right_shadow != 0 )
area->changes[i].trans_count = uInt(area->right_shadow); area->changes[i].trans_count = uInt(area->right_shadow);
@ -4242,6 +4298,32 @@ bool FTerm::setNonBlockingInput (bool on)
return non_blocking_stdin; return non_blocking_stdin;
} }
//----------------------------------------------------------------------
bool FTerm::scrollTermForward()
{
if ( tcap[t_scroll_forward].string )
{
putstring (tcap[t_scroll_forward].string);
std::fflush(stdout);
return true;
}
return false;
}
//----------------------------------------------------------------------
bool FTerm::scrollTermReverse()
{
if ( tcap[t_scroll_reverse].string )
{
putstring (tcap[t_scroll_reverse].string);
std::fflush(stdout);
return true;
}
return false;
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
bool FTerm::setUTF8 (bool on) // UTF-8 (Unicode) bool FTerm::setUTF8 (bool on) // UTF-8 (Unicode)
{ {

View File

@ -313,7 +313,9 @@ class FTerm
void getArea (int, int, int, int, FTerm::term_area*); void getArea (int, int, int, int, FTerm::term_area*);
void putArea (const FPoint&, FTerm::term_area*); void putArea (const FPoint&, FTerm::term_area*);
void putArea (int, int, FTerm::term_area*); void putArea (int, int, FTerm::term_area*);
void clearArea(); static void scrollAreaForward (FTerm::term_area*);
static void scrollAreaReverse (FTerm::term_area*);
void clearArea (FTerm::term_area*);
FOptiAttr::char_data getCharacter (int, const FPoint&, FTerm*); FOptiAttr::char_data getCharacter (int, const FPoint&, FTerm*);
FOptiAttr::char_data getCharacter (int, int, int, FTerm*); FOptiAttr::char_data getCharacter (int, int, int, FTerm*);
FOptiAttr::char_data getCoveredCharacter (const FPoint&, FTerm*); FOptiAttr::char_data getCoveredCharacter (const FPoint&, FTerm*);
@ -413,6 +415,9 @@ class FTerm
static bool setNonBlockingInput(); static bool setNonBlockingInput();
static bool unsetNonBlockingInput(); static bool unsetNonBlockingInput();
static bool scrollTermForward();
static bool scrollTermReverse();
static bool setUTF8 (bool); static bool setUTF8 (bool);
static bool setUTF8(); static bool setUTF8();
static bool unsetUTF8(); static bool unsetUTF8();
@ -424,6 +429,7 @@ class FTerm
static bool unsetRawMode(); static bool unsetRawMode();
static bool setCookedMode(); static bool setCookedMode();
static bool isRaw(); static bool isRaw();
static FString getAnswerbackMsg(); static FString getAnswerbackMsg();
static FString getSecDA(); static FString getSecDA();

View File

@ -130,7 +130,7 @@ void FToolTip::draw()
if ( getMaxColor() < 16 ) if ( getMaxColor() < 16 )
setBold(); setBold();
clearArea(); clearArea (vwin);
drawBorder(); drawBorder();
for (int i=0; i < int(text_num_lines); i++) for (int i=0; i < int(text_num_lines); i++)

View File

@ -143,7 +143,7 @@ void FWidget::init()
foreground_color = wc.term_fg; foreground_color = wc.term_fg;
background_color = wc.term_bg; background_color = wc.term_bg;
setColor(); setColor();
clearArea(); clearArea(vdesktop);
accelerator_list = new Accelerators(); accelerator_list = new Accelerators();
} }
@ -369,29 +369,31 @@ void FWidget::setColorTheme()
//---------------------------------------------------------------------- //----------------------------------------------------------------------
FTerm::term_area* FWidget::getPrintArea() FTerm::term_area* FWidget::getPrintArea()
{ {
// returns the print area of this object
if ( print_area ) if ( print_area )
return print_area; return print_area;
else else
{ {
FWidget* window = FWindow::getWindowWidget(this); FWidget* obj = static_cast<FWidget*>(this);
FWidget* p_obj = static_cast<FWidget*>(obj->getParent());
if ( window ) while ( ! obj->vwin && p_obj )
{ {
term_area* area = window->getVWin(); obj = p_obj;
p_obj = static_cast<FWidget*>(p_obj->getParent());
}
if ( area ) if ( obj->vwin )
{ {
print_area = area; print_area = obj->vwin;
return area; return print_area;
} }
else
return 0;
}
else
return 0;
} }
return vdesktop;
} }
// protected methods of FWidget // protected methods of FWidget
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FWidget::adjustSize() void FWidget::adjustSize()
@ -1227,7 +1229,7 @@ void FWidget::redraw()
terminal_updates = false; terminal_updates = false;
// clean desktop // clean desktop
setColor (wc.term_fg, wc.term_bg); setColor (wc.term_fg, wc.term_bg);
clearArea(); clearArea (vdesktop);
} }
else if ( ! visible ) else if ( ! visible )
return; return;

View File

@ -506,6 +506,7 @@ class FWidget : public FObject, public FTerm
void printPos (const FPoint&); void printPos (const FPoint&);
void printPos (register int, register int); void printPos (register int, register int);
FPoint getPrintPos() const;
static void setNormal(); static void setNormal();
@ -937,6 +938,15 @@ inline void FWidget::printPos (register int x, register int y)
offset.getY1() + adjust_wsize.getY() - 1 + y ); offset.getY1() + adjust_wsize.getY() - 1 + y );
} }
//----------------------------------------------------------------------
inline FPoint FWidget::getPrintPos() const
{
int cx = cursor->getX();
int cy = cursor->getY();
return FPoint ( cx - offset.getX1() - adjust_wsize.getX() + 1
, cy - offset.getY1() - adjust_wsize.getY() + 1 );
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FWidget::setNormal() inline void FWidget::setNormal()
{ {

View File

@ -34,7 +34,23 @@ keyboard::keyboard (FWidget* parent)
void keyboard::onKeyPress (FKeyEvent* ev) void keyboard::onKeyPress (FKeyEvent* ev)
{ {
int key_id = ev->key(); int key_id = ev->key();
std::printf("Key %s (id %d)\n\r", getKeyName(key_id).c_str(), key_id); bool is_last_line = false;
if ( getPrintPos().getY() == getLineNumber() )
is_last_line = true;
printf ("Key %s (id %d)\n", getKeyName(key_id).c_str(), key_id);
if ( is_last_line )
{
scrollAreaForward (vdesktop);
if ( ! scrollTermForward() )
putArea (getTermPos(), vdesktop);
}
setAreaCursor (1, getPrintPos().getY(), true, vdesktop);
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -49,12 +65,12 @@ void keyboard::draw()
{ {
setNormal(); setNormal();
setColor(fc::Default, fc::Default); setColor(fc::Default, fc::Default);
clearArea(); clearArea (vdesktop);
printPosTerm (1,1); printPosTerm (1,1);
print ("---------------\n"); print ("---------------\n");
print ("Press Q to quit\n"); print ("Press Q to quit\n");
print ("---------------\n"); print ("---------------\n");
setCursorPos (1,5); setAreaCursor (1, 4, true, vdesktop);
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------

View File

@ -39,7 +39,24 @@ timer::timer (FWidget* parent)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void timer::onTimer (FTimerEvent* ev) void timer::onTimer (FTimerEvent* ev)
{ {
std::printf("timer event, id %d\n\r", ev->timerId() ); bool is_last_line = false;
int timer_id = ev->timerId();
if ( getPrintPos().getY() == getLineNumber() )
is_last_line = true;
setColor (short(1 + timer_id), fc::Default);
printf ("timer event, id %d\n", timer_id );
if ( is_last_line )
{
scrollAreaForward (vdesktop);
if ( ! scrollTermForward() )
putArea (getTermPos(), vdesktop);
}
setAreaCursor (1, getPrintPos().getY(), true, vdesktop);
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -54,12 +71,12 @@ void timer::draw()
{ {
setNormal(); setNormal();
setColor (fc::Default, fc::Default); setColor (fc::Default, fc::Default);
clearArea(); clearArea (vdesktop);
printPosTerm (1,1); printPosTerm (1,1);
print ("---------------\n"); print ("---------------\n");
print ("Press Q to quit\n"); print ("Press Q to quit\n");
print ("---------------\n"); print ("---------------\n");
setCursorPos (1,4); setAreaCursor (1, 4, true, vdesktop);
} }