Refactoring FListBox::drawList and FListBox::onKeyPress

This commit is contained in:
Markus Gans 2017-12-03 21:06:21 +01:00
parent 8c970c88dd
commit 212172f522
12 changed files with 1025 additions and 783 deletions

View File

@ -1,3 +1,7 @@
2017-12-02 Markus Gans <guru.mail@muenster.de>
* Refactoring FListBox::drawList and FListBox::onKeyPress
* Refactoring FWidget::event
2017-12-02 Markus Gans <guru.mail@muenster.de>
* Refactoring FApplication::linuxModifierKeyCorrection and
FVTerm::updateVTerm

View File

@ -246,11 +246,31 @@ class FListBox : public FWidget
void draw();
void drawLabel();
void drawList();
void drawListLine (int, listBoxItems::iterator, bool);
void drawListBracketsLine (int, listBoxItems::iterator, bool);
void setLineAttributes (int, bool, bool, bool&);
void unsetAttributes();
void updateDrawing (bool, bool);
void recalculateHorizontalBar (int, bool);
void recalculateVerticalBar (int);
void keyUp();
void keyDown();
void keyLeft();
void keyRight();
void keyPgUp();
void keyPgDn();
void keyHome();
void keyEnd();
bool keyEsc();
void keyEnter();
bool keySpace();
bool keyInsert();
bool keyBackspace();
bool keyIncSearchInput (int);
void processClick();
void processSelect();
void processChanged();
void lazyConvert (listBoxItems::iterator, int);
listBoxItems::iterator index2iterator (int);
// Callback methods

View File

@ -319,11 +319,18 @@ class FListView : public FWidget
void drawColumnLabels();
void drawList();
void drawListLine (const FListViewItem*, bool, bool);
void updateDrawing (bool, bool);
void recalculateHorizontalBar (int);
void recalculateVerticalBar (int);
FObjectIterator appendItem (FListViewItem*);
void processClick();
void processChanged();
void keyLeft (int&);
void keyRight (int&);
void keyHome();
void keyEnd();
bool keyPlus();
bool keyMinus();
void setRelativePosition (int);
void stepForward();
void stepBackward();

View File

@ -179,6 +179,27 @@ class FOptiAttr
LightGray = 7
};
enum attr_modes
{
standout_mode = 1,
underline_mode = 2,
reverse_mode = 4,
blink_mode = 8,
dim_mode = 16,
bold_mode = 32,
invisible_mode = 64,
protected_mode = 128,
alt_charset_mode = 256,
horizontal_mode = 512,
left_mode = 1024,
low_mode = 2048,
right_mode = 4096,
top_mode = 8192,
vertical_mode = 16384,
italic_mode = 32768,
no_mode = 65536
};
// Disable copy constructor
FOptiAttr (const FOptiAttr&);

View File

@ -305,6 +305,8 @@ class FVTerm : public FTerm
, int, int, int, int );
static void updateCharacter ( term_area*
, int, int, int, int );
static bool updateVTermCharacter ( term_area*
, int, int, int, int );
static void callPreprocessingHandler (term_area*);
static void updateVTerm();
static void updateVTerm (term_area*);

View File

@ -471,6 +471,8 @@ class FWidget : public FVTerm, public FObject
void init();
void finish();
void insufficientSpaceAdjust();
void KeyPressEvent (FKeyEvent*);
void KeyDownEvent (FKeyEvent*);
void processDestroy();
virtual void draw();
static void setColorTheme();

File diff suppressed because it is too large Load Diff

View File

@ -703,14 +703,11 @@ FObject::FObjectIterator FListView::insert ( const std::vector<long>& cols
//----------------------------------------------------------------------
void FListView::onKeyPress (FKeyEvent* ev)
{
int element_count = int(getCount())
, position_before = current_iter.getPosition()
int position_before = current_iter.getPosition()
, xoffset_before = xoffset
, xoffset_end = max_line_width - getClientWidth()
, first_line_position_before = first_visible_line.getPosition()
, pagesize = getClientHeight() - 1
, key = ev->key();
FListViewItem* item = getCurrentItem();
clicked_expander_pos.setPoint(-1, -1);
switch ( key )
@ -723,142 +720,52 @@ void FListView::onKeyPress (FKeyEvent* ev)
case fc::Fkey_up:
stepBackward();
ev->accept();
break;
case fc::Fkey_down:
stepForward();
ev->accept();
break;
case fc::Fkey_left:
if ( xoffset == 0 )
{
if ( tree_view && item->isExpandable() && item->isExpand() )
{
// Collapse element
item->collapse();
adjustSize();
element_count = int(getCount());
recalculateVerticalBar (element_count);
// Force vertical scrollbar redraw
first_line_position_before = -1;
}
else if ( item->hasParent() )
{
// Jump to parent element
FObject* parent = item->getParent();
if ( parent->isInstanceOf("FListViewItem") )
{
current_iter.parentElement();
if ( current_iter.getPosition() < first_line_position_before )
{
int difference = position_before - current_iter.getPosition();
if ( first_visible_line.getPosition() - difference >= 0 )
{
first_visible_line -= difference;
last_visible_line -= difference;
}
else
{
int d = first_visible_line.getPosition();
first_visible_line -= d;
last_visible_line -= d;
}
}
}
}
}
else
{
// Scroll left
xoffset--;
if ( xoffset < 0 )
xoffset = 0;
}
keyLeft (first_line_position_before);
ev->accept();
break;
case fc::Fkey_right:
if ( tree_view && item->isExpandable() && ! item->isExpand() )
{
// Expand element
item->expand();
adjustSize();
// Force vertical scrollbar redraw
first_line_position_before = -1;
}
else
{
// Scroll right
xoffset++;
if ( xoffset > xoffset_end )
xoffset = xoffset_end;
if ( xoffset < 0 )
xoffset = 0;
}
keyRight(first_line_position_before);
ev->accept();
break;
case fc::Fkey_ppage:
stepBackward(pagesize);
ev->accept();
break;
case fc::Fkey_npage:
stepForward(pagesize);
ev->accept();
break;
case fc::Fkey_home:
{
current_iter -= current_iter.getPosition();
int difference = first_visible_line.getPosition();
first_visible_line -= difference;
last_visible_line -= difference;
}
keyHome();
ev->accept();
break;
case fc::Fkey_end:
{
current_iter += element_count - current_iter.getPosition() - 1;
int difference = element_count - last_visible_line.getPosition() - 1;
first_visible_line += difference;
last_visible_line += difference;
}
keyEnd();
ev->accept();
break;
case int('+'):
if ( tree_view && item->isExpandable() && ! item->isExpand() )
{
item->expand();
adjustSize();
if ( keyPlus() )
ev->accept();
}
break;
case int('-'):
if ( tree_view && item->isExpandable() && item->isExpand() )
{
item->collapse();
adjustSize();
if ( keyMinus() )
ev->accept();
}
break;
default:
@ -870,21 +777,10 @@ void FListView::onKeyPress (FKeyEvent* ev)
if ( ev->isAccepted() )
{
if ( isVisible() )
draw();
vbar->setValue (first_visible_line.getPosition());
if ( vbar->isVisible() && first_line_position_before != first_visible_line.getPosition() )
vbar->drawBar();
hbar->setValue (xoffset);
if ( hbar->isVisible() && xoffset_before != xoffset )
hbar->drawBar();
updateTerminal();
flush_out();
bool draw_vbar = first_line_position_before
!= first_visible_line.getPosition();
bool draw_hbar = xoffset_before != xoffset;
updateDrawing (draw_vbar, draw_hbar);
}
}
@ -1746,6 +1642,26 @@ void FListView::drawListLine ( const FListViewItem* item
print (' ');
}
//----------------------------------------------------------------------
void FListView::updateDrawing (bool draw_vbar, bool draw_hbar)
{
if ( isVisible() )
draw();
vbar->setValue (first_visible_line.getPosition());
if ( vbar->isVisible() && draw_vbar )
vbar->drawBar();
hbar->setValue (xoffset);
if ( hbar->isVisible() && draw_hbar )
hbar->drawBar();
updateTerminal();
flush_out();
}
//----------------------------------------------------------------------
void FListView::recalculateHorizontalBar (int len)
{
@ -1796,6 +1712,139 @@ void FListView::processChanged()
emitCallback("row-changed");
}
//----------------------------------------------------------------------
inline void FListView::keyLeft (int& first_line_position_before)
{
int element_count = int(getCount());
int position_before = current_iter.getPosition();
FListViewItem* item = getCurrentItem();
if ( xoffset == 0 )
{
if ( tree_view && item->isExpandable() && item->isExpand() )
{
// Collapse element
item->collapse();
adjustSize();
element_count = int(getCount());
recalculateVerticalBar (element_count);
// Force vertical scrollbar redraw
first_line_position_before = -1;
}
else if ( item->hasParent() )
{
// Jump to parent element
FObject* parent = item->getParent();
if ( parent->isInstanceOf("FListViewItem") )
{
current_iter.parentElement();
if ( current_iter.getPosition() < first_line_position_before )
{
int difference = position_before - current_iter.getPosition();
if ( first_visible_line.getPosition() - difference >= 0 )
{
first_visible_line -= difference;
last_visible_line -= difference;
}
else
{
int d = first_visible_line.getPosition();
first_visible_line -= d;
last_visible_line -= d;
}
}
}
}
}
else
{
// Scroll left
xoffset--;
if ( xoffset < 0 )
xoffset = 0;
}
}
//----------------------------------------------------------------------
inline void FListView::keyRight (int& first_line_position_before)
{
int xoffset_end = max_line_width - getClientWidth();
FListViewItem* item = getCurrentItem();
if ( tree_view && item->isExpandable() && ! item->isExpand() )
{
// Expand element
item->expand();
adjustSize();
// Force vertical scrollbar redraw
first_line_position_before = -1;
}
else
{
// Scroll right
xoffset++;
if ( xoffset > xoffset_end )
xoffset = xoffset_end;
if ( xoffset < 0 )
xoffset = 0;
}
}
//----------------------------------------------------------------------
inline void FListView::keyHome()
{
current_iter -= current_iter.getPosition();
int difference = first_visible_line.getPosition();
first_visible_line -= difference;
last_visible_line -= difference;
}
//----------------------------------------------------------------------
inline void FListView::keyEnd()
{
int element_count = int(getCount());
current_iter += element_count - current_iter.getPosition() - 1;
int difference = element_count - last_visible_line.getPosition() - 1;
first_visible_line += difference;
last_visible_line += difference;
}
//----------------------------------------------------------------------
inline bool FListView::keyPlus()
{
FListViewItem* item = getCurrentItem();
if ( tree_view && item->isExpandable() && ! item->isExpand() )
{
item->expand();
adjustSize();
return true;
}
return false;
}
//----------------------------------------------------------------------
inline bool FListView::keyMinus()
{
FListViewItem* item = getCurrentItem();
if ( tree_view && item->isExpandable() && item->isExpand() )
{
item->collapse();
adjustSize();
return true;
}
return false;
}
//----------------------------------------------------------------------
void FListView::setRelativePosition (int ry)
{

View File

@ -1204,96 +1204,72 @@ inline void FOptiAttr::resetColor (char_data*& attr)
//----------------------------------------------------------------------
inline void FOptiAttr::prevent_no_color_video_attributes (char_data*& attr)
{
// ignore attributes which can not combined with a color
// Ignore attributes which can not combined with a color
enum attr_modes
{
standout_mode = 1,
underline_mode = 2,
reverse_mode = 4,
blink_mode = 8,
dim_mode = 16,
bold_mode = 32,
invisible_mode = 64,
protected_mode = 128,
alt_charset_mode = 256,
horizontal_mode = 512,
left_mode = 1024,
low_mode = 2048,
right_mode = 4096,
top_mode = 8192,
vertical_mode = 16384,
italic_mode = 32768,
no_mode = 65536
};
if ( ! attr )
if ( ! attr || ! hasColor(attr) || attr_without_color <= 0 )
return;
if ( hasColor(attr) && attr_without_color > 0 )
for (int bit = 1; bit < no_mode; bit <<= 1)
{
for (int bit = 1; bit < no_mode; bit <<= 1)
switch ( bit & attr_without_color )
{
switch ( bit & attr_without_color )
{
case standout_mode:
if ( attr->attr.bit.standout )
attr->attr.bit.standout = false;
break;
case standout_mode:
if ( attr->attr.bit.standout )
attr->attr.bit.standout = false;
break;
case underline_mode:
if ( attr->attr.bit.underline )
attr->attr.bit.underline = false;
break;
case underline_mode:
if ( attr->attr.bit.underline )
attr->attr.bit.underline = false;
break;
case reverse_mode:
if ( attr->attr.bit.reverse )
{
attr->attr.bit.reverse = false;
case reverse_mode:
if ( attr->attr.bit.reverse )
{
attr->attr.bit.reverse = false;
if ( attr->fg_color != attr->bg_color )
fake_reverse = true;
}
break;
if ( attr->fg_color != attr->bg_color )
fake_reverse = true;
}
break;
case blink_mode:
if ( attr->attr.bit.blink )
attr->attr.bit.blink = false;
break;
case blink_mode:
if ( attr->attr.bit.blink )
attr->attr.bit.blink = false;
break;
case dim_mode:
if ( attr->attr.bit.dim )
attr->attr.bit.dim = false;
break;
case dim_mode:
if ( attr->attr.bit.dim )
attr->attr.bit.dim = false;
break;
case bold_mode:
if ( attr->attr.bit.bold )
attr->attr.bit.bold = false;
break;
case bold_mode:
if ( attr->attr.bit.bold )
attr->attr.bit.bold = false;
break;
case invisible_mode:
if ( attr->attr.bit.invisible )
attr->attr.bit.invisible = false;
break;
case invisible_mode:
if ( attr->attr.bit.invisible )
attr->attr.bit.invisible = false;
break;
case protected_mode:
if ( attr->attr.bit.protect )
attr->attr.bit.protect = false;
break;
case protected_mode:
if ( attr->attr.bit.protect )
attr->attr.bit.protect = false;
break;
case alt_charset_mode:
if ( attr->attr.bit.alt_charset )
attr->attr.bit.alt_charset = false;
break;
case alt_charset_mode:
if ( attr->attr.bit.alt_charset )
attr->attr.bit.alt_charset = false;
break;
case italic_mode:
if ( attr->attr.bit.italic )
attr->attr.bit.italic = false;
break;
case italic_mode:
if ( attr->attr.bit.italic )
attr->attr.bit.italic = false;
break;
default:
break;
}
default:
break;
}
}
}

View File

@ -136,7 +136,7 @@ bool FTermcap::no_utf8_acs_chars = false;
int FTermcap::max_color = 1;
int FTermcap::tabstop = 8;
int FTermcap::attr_without_color = 0;
FTerm::initializationValues FTerm::init_values;
FTerm::initializationValues FTerm::init_values;
fc::linuxConsoleCursorStyle FTerm::linux_console_cursor_style;
fc::freebsdConsoleCursorStyle FTerm::freebsd_console_cursor_style;

View File

@ -1256,6 +1256,49 @@ void FVTerm::updateCharacter ( term_area* area
tc->attr.bit.no_changes = false;
}
//----------------------------------------------------------------------
bool FVTerm::updateVTermCharacter ( term_area* area
, int x, int y, int tx, int ty )
{
int& aw = area->width;
int& rsh = area->right_shadow;
int line_len = aw + rsh;
// Area character
char_data* ac = &area->text[y * line_len + x];
// Get covered state
covered_state is_covered = isCovered(tx, ty, area);
if ( is_covered == fully_covered )
return false;
if ( is_covered == half_covered )
{
updateOverlappedColor(area, x, y, tx, ty);
}
else if ( ac->attr.bit.transparent ) // Transparent
{
updateOverlappedCharacter(area, tx, ty);
}
else // Not transparent
{
if ( ac->attr.bit.trans_shadow ) // Transparent shadow
{
updateShadedCharacter (area, x, y, tx, ty);
}
else if ( ac->attr.bit.inherit_bg )
{
updateInheritBackground (area, x, y, tx, ty);
}
else // Default
{
updateCharacter (area, x, y, tx, ty);
}
}
return true;
}
//----------------------------------------------------------------------
void FVTerm::callPreprocessingHandler (term_area* area)
{
@ -1339,26 +1382,21 @@ void FVTerm::updateVTerm (term_area* area)
{
// Update area data on VTerm
char_data* ac; // area character
if ( ! area )
return;
if ( ! area->visible )
return;
// Call the processing handler methods
callPreprocessingHandler(area);
int ax = area->offset_left
, ay = area->offset_top
, aw = area->width
, ah = area->height
, rsh = area->right_shadow
, bsh = area->bottom_shadow
, ol = 0 // outside left
, ol = 0 // Outside left
, y_end;
if ( ! area || ! area->visible )
return;
// Call the processing handler methods
callPreprocessingHandler(area);
if ( ax < 0 )
{
ol = std::abs(ax);
@ -1370,88 +1408,57 @@ void FVTerm::updateVTerm (term_area* area)
else
y_end = ah + bsh;
for (int y = 0; y < y_end; y++) // line loop
for (int y = 0; y < y_end; y++) // Line loop
{
int _xmin, _xmax;
bool modified = false;
int line_xmin = int(area->changes[y].xmin);
int line_xmax = int(area->changes[y].xmax);
if ( line_xmin <= line_xmax )
if ( line_xmin > line_xmax )
continue;
if ( ax == 0 )
line_xmin = ol;
if ( aw + rsh + ax - ol >= vterm->width )
line_xmax = vterm->width + ol - ax - 1;
if ( ax + line_xmin >= vterm->width )
continue;
for (int x = line_xmin; x <= line_xmax; x++) // Column loop
{
int _xmin, _xmax;
bool modified = false;
// Global terminal positions
int tx = ax + x
, ty = ay + y;
if ( ax == 0 )
line_xmin = ol;
if ( aw + rsh + ax - ol >= vterm->width )
line_xmax = vterm->width + ol - ax - 1;
if ( ax + line_xmin >= vterm->width )
if ( tx < 0 || ty < 0 )
continue;
for (int x = line_xmin; x <= line_xmax; x++) // column loop
{
covered_state is_covered;
// global terminal positions
int gx = ax + x
, gy = ay + y;
tx -= ol;
if ( gx < 0 || gy < 0 )
continue;
if ( updateVTermCharacter (area, x, y, tx, ty) )
modified = true;
int line_len = aw + rsh;
ac = &area->text[y * line_len + x];
gx -= ol;
is_covered = isCovered(gx, gy, area); // get covered state
if ( is_covered != fully_covered )
{
if ( is_covered == half_covered )
{
updateOverlappedColor(area, x, y, gx, gy);
}
else if ( ac->attr.bit.transparent ) // transparent
{
updateOverlappedCharacter(area, gx, gy);
}
else // not transparent
{
if ( ac->attr.bit.trans_shadow ) // transparent shadow
{
updateShadedCharacter (area, x, y, gx, gy);
}
else if ( ac->attr.bit.inherit_bg )
{
updateInheritBackground (area, x, y, gx, gy);
}
else // default
{
updateCharacter (area, x, y, gx, gy);
}
}
modified = true;
}
else if ( ! modified )
line_xmin++; // don't update covered character
}
_xmin = ax + line_xmin - ol;
_xmax = ax + line_xmax;
if ( _xmin < short(vterm->changes[ay + y].xmin) )
vterm->changes[ay + y].xmin = uInt(_xmin);
if ( _xmax >= vterm->width )
_xmax = vterm->width - 1;
if ( _xmax > short(vterm->changes[ay + y].xmax) )
vterm->changes[ay + y].xmax = uInt(_xmax);
area->changes[y].xmin = uInt(aw + rsh);
area->changes[y].xmax = 0;
if ( ! modified )
line_xmin++; // Don't update covered character
}
_xmin = ax + line_xmin - ol;
_xmax = ax + line_xmax;
if ( _xmin < short(vterm->changes[ay + y].xmin) )
vterm->changes[ay + y].xmin = uInt(_xmin);
if ( _xmax >= vterm->width )
_xmax = vterm->width - 1;
if ( _xmax > short(vterm->changes[ay + y].xmax) )
vterm->changes[ay + y].xmax = uInt(_xmax);
area->changes[y].xmin = uInt(aw + rsh);
area->changes[y].xmax = 0;
}
updateVTermCursor(area);

View File

@ -2121,43 +2121,7 @@ bool FWidget::event (FEvent* ev)
switch ( ev->type() )
{
case fc::KeyPress_Event:
{
FKeyEvent* kev = static_cast<FKeyEvent*>(ev);
bool accpt_focus = false;
if ( kev->key() == fc::Fkey_tab )
accpt_focus = focusNextChild();
else if ( kev->key() == fc::Fkey_btab )
accpt_focus = focusPrevChild();
if ( accpt_focus )
break;
FWidget* widget = this;
while ( widget )
{
widget->onKeyPress(kev);
if ( ! kev->isAccepted() )
{
if ( kev->key() == fc::Fkey_right
|| kev->key() == fc::Fkey_down )
accpt_focus = focusNextChild();
else if ( kev->key() == fc::Fkey_left
|| kev->key() == fc::Fkey_up )
accpt_focus = focusPrevChild();
if ( accpt_focus )
break;
}
if ( kev->isAccepted() || widget->isRootWidget() )
break;
widget = widget->getParentWidget();
}
}
KeyPressEvent ( static_cast<FKeyEvent*>(ev) );
break;
case fc::KeyUp_Event:
@ -2165,20 +2129,7 @@ bool FWidget::event (FEvent* ev)
break;
case fc::KeyDown_Event:
{
FKeyEvent* kev = static_cast<FKeyEvent*>(ev);
FWidget* widget = this;
while ( widget )
{
widget->onKeyDown(kev);
if ( kev->isAccepted() || widget->isRootWidget() )
break;
widget = widget->getParentWidget();
}
}
KeyDownEvent ( static_cast<FKeyEvent*>(ev) );
break;
case fc::MouseDown_Event:
@ -2244,6 +2195,7 @@ bool FWidget::event (FEvent* ev)
default:
return false;
}
return true;
}
@ -2458,6 +2410,61 @@ inline void FWidget::insufficientSpaceAdjust()
adjust_wsize.setHeight(1);
}
//----------------------------------------------------------------------
void FWidget::KeyPressEvent (FKeyEvent* kev)
{
bool accpt_focus = false;
if ( kev->key() == fc::Fkey_tab )
accpt_focus = focusNextChild();
else if ( kev->key() == fc::Fkey_btab )
accpt_focus = focusPrevChild();
if ( accpt_focus )
return;
FWidget* widget = this;
while ( widget )
{
widget->onKeyPress(kev);
if ( ! kev->isAccepted() )
{
if ( kev->key() == fc::Fkey_right
|| kev->key() == fc::Fkey_down )
accpt_focus = focusNextChild();
else if ( kev->key() == fc::Fkey_left
|| kev->key() == fc::Fkey_up )
accpt_focus = focusPrevChild();
if ( accpt_focus )
return;
}
if ( kev->isAccepted() || widget->isRootWidget() )
return;
widget = widget->getParentWidget();
}
}
//----------------------------------------------------------------------
void FWidget::KeyDownEvent (FKeyEvent* kev)
{
FWidget* widget = this;
while ( widget )
{
widget->onKeyDown(kev);
if ( kev->isAccepted() || widget->isRootWidget() )
break;
widget = widget->getParentWidget();
}
}
//----------------------------------------------------------------------
void FWidget::draw()
{ }