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();

View File

@ -423,280 +423,85 @@ void FListBox::clear()
//----------------------------------------------------------------------
void FListBox::onKeyPress (FKeyEvent* ev)
{
static const int padding_space = 2; // 1 leading space + 1 tailing space
int element_count = int(getCount())
, current_before = current
int current_before = current
, xoffset_before = xoffset
, xoffset_end = max_line_width - getClientWidth() + padding_space
, yoffset_before = yoffset
, yoffset_end = element_count - getClientHeight()
, pagesize = getClientHeight() - 1
, key = ev->key();
switch ( key )
{
case fc::Fkey_return:
case fc::Fkey_enter:
processClick();
inc_search.clear();
keyEnter();
ev->accept();
break;
case fc::Fkey_up:
current--;
if ( current < 1 )
current = 1;
if ( current <= yoffset )
yoffset--;
inc_search.clear();
keyUp();
ev->accept();
break;
case fc::Fkey_down:
current++;
if ( current > element_count )
current = element_count;
if ( current - yoffset > getClientHeight() )
yoffset++;
inc_search.clear();
keyDown();
ev->accept();
break;
case fc::Fkey_left:
xoffset--;
if ( xoffset < 0 )
xoffset = 0;
inc_search.clear();
keyLeft();
ev->accept();
break;
case fc::Fkey_right:
xoffset++;
if ( xoffset > xoffset_end )
xoffset = xoffset_end;
if ( xoffset < 0 )
xoffset = 0;
inc_search.clear();
keyRight();
ev->accept();
break;
case fc::Fkey_ppage:
current -= pagesize;
if ( current < 1 )
current = 1;
if ( current <= yoffset )
{
yoffset -= pagesize;
if ( yoffset < 0 )
yoffset = 0;
}
inc_search.clear();
keyPgUp();
ev->accept();
break;
case fc::Fkey_npage:
current += pagesize;
if ( current > element_count )
current = element_count;
if ( current - yoffset > getClientHeight() )
{
yoffset += pagesize;
if ( yoffset > yoffset_end )
yoffset = yoffset_end;
}
inc_search.clear();
keyPgDn();
ev->accept();
break;
case fc::Fkey_home:
current = 1;
yoffset = 0;
inc_search.clear();
keyHome();
ev->accept();
break;
case fc::Fkey_end:
current = element_count;
if ( current > getClientHeight() )
yoffset = yoffset_end;
inc_search.clear();
keyEnd();
ev->accept();
break;
case fc::Fkey_ic: // insert key
if ( isMultiSelection() )
{
if ( isSelected(current) )
unselectItem(current);
else
selectItem(current);
processSelect();
current++;
if ( current > element_count )
current = element_count;
if ( current - yoffset >= getHeight() - 1 )
yoffset++;
if ( keyInsert() )
ev->accept();
}
inc_search.clear();
break;
case fc::Fkey_space:
{
uInt inc_len = inc_search.getLength();
if ( inc_len > 0 )
{
inc_search += L' ';
bool inc_found = false;
listBoxItems::iterator iter = itemlist.begin();
while ( iter != itemlist.end() )
{
if ( ! inc_found
&& inc_search.toLower()
== iter->getText().left(inc_len + 1).toLower() )
{
setCurrentItem(iter);
inc_found = true;
break;
}
++iter;
}
if ( ! inc_found )
{
inc_search.remove(inc_len, 1);
ev->ignore();
}
else
if ( keySpace() )
ev->accept();
}
else if ( isMultiSelection() )
{
if ( isSelected(current) )
unselectItem(current);
else
selectItem(current);
processSelect();
inc_search.clear();
ev->accept();
}
}
break;
case fc::Fkey_erase:
case fc::Fkey_backspace:
{
uInt inc_len = inc_search.getLength();
if ( inc_len > 0 )
{
inc_search.remove(inc_len - 1, 1);
if ( inc_len > 1 )
{
listBoxItems::iterator iter = itemlist.begin();
while ( iter != itemlist.end() )
{
if ( inc_search.toLower()
== iter->getText().left(inc_len - 1).toLower() )
{
setCurrentItem(iter);
break;
}
++iter;
}
}
if ( keyBackspace() )
ev->accept();
}
else
ev->ignore();
}
break;
case fc::Fkey_escape:
case fc::Fkey_escape_mintty:
if ( inc_search.getLength() > 0 )
{
inc_search.clear();
if ( keyEsc() )
ev->accept();
}
break;
default:
if ( key > 0x20 && key <= 0x10fff )
{
// incremental search
if ( inc_search.getLength() == 0 )
inc_search = wchar_t(key);
else
inc_search += wchar_t(key);
uInt inc_len = inc_search.getLength();
bool inc_found = false;
listBoxItems::iterator iter = itemlist.begin();
while ( iter != itemlist.end() )
{
if ( ! inc_found
&& inc_search.toLower()
== iter->getText().left(inc_len).toLower() )
{
setCurrentItem(iter);
inc_found = true;
break;
}
++iter;
}
if ( ! inc_found )
{
inc_search.remove(inc_len - 1, 1);
if ( inc_len == 1 )
ev->ignore();
else
if ( keyIncSearchInput(key) )
ev->accept();
}
else
ev->accept();
}
else
ev->ignore();
}
if ( current_before != current )
{
@ -708,21 +513,9 @@ void FListBox::onKeyPress (FKeyEvent* ev)
if ( ev->isAccepted() )
{
if ( isVisible() )
drawList();
vbar->setValue (yoffset);
if ( vbar->isVisible() && yoffset_before != yoffset )
vbar->drawBar();
hbar->setValue (xoffset);
if ( hbar->isVisible() && xoffset_before != xoffset )
hbar->drawBar();
updateTerminal();
flush_out();
bool draw_vbar = yoffset_before != yoffset;
bool draw_hbar = xoffset_before != xoffset;
updateDrawing (draw_vbar, draw_hbar);
}
}
@ -1402,18 +1195,14 @@ void FListBox::drawLabel()
//----------------------------------------------------------------------
void FListBox::drawList()
{
FString element;
uInt start, num, inc_len;
bool isFocus;
uInt start, num;
listBoxItems::iterator iter;
if ( itemlist.empty() || getHeight() <= 2 || getWidth() <= 4 )
return;
isFocus = ((flags & fc::focus) != 0);
start = 0;
num = uInt(getHeight() - 2);
inc_len = inc_search.getLength();
if ( num > getCount() )
num = getCount();
@ -1433,104 +1222,91 @@ void FListBox::drawList()
for (uInt y = start; y < num && iter != itemlist.end() ; y++)
{
bool serach_mark = false
, lineHasBrackets = hasBrackets(iter)
, isLineSelected = isSelected(iter)
, isCurrentLine = bool(y + uInt(yoffset) + 1 == uInt(current));
bool serach_mark = false;
bool lineHasBrackets = hasBrackets(iter);
if ( conv_type == lazy_convert && iter->getText().isNull() )
{
convertToItem (*iter, source_container, int(y) + yoffset);
int len = int(iter->text.getLength());
recalculateHorizontalBar (len, lineHasBrackets);
// Import data via lazy conversion
lazyConvert (iter, int(y));
if ( hbar->isVisible() )
hbar->redraw();
}
setPrintPos (2, 2 + int(y));
if ( isLineSelected )
{
if ( isMonochron() )
setBold();
else
setColor (wc.selected_list_fg, wc.selected_list_bg);
}
else
{
if ( isMonochron() )
unsetBold();
else
setColor (wc.list_fg, wc.list_bg);
}
if ( isCurrentLine )
{
if ( isFocus && getMaxColor() < 16 )
setBold();
if ( isLineSelected )
{
if ( isMonochron() )
setBold();
else if ( isFocus )
setColor ( wc.selected_current_element_focus_fg
, wc.selected_current_element_focus_bg );
else
setColor ( wc.selected_current_element_fg
, wc.selected_current_element_bg );
setCursorPos (3, 2 + int(y)); // first character
}
else
{
if ( isMonochron() )
unsetBold();
if ( isFocus )
{
setColor ( wc.current_element_focus_fg
, wc.current_element_focus_bg );
int b = ( lineHasBrackets ) ? 1: 0;
if ( inc_len > 0 ) // incremental search
{
serach_mark = true;
// Place the cursor on the last found character
setCursorPos (2 + b + int(inc_len), 2 + int(y));
}
else // only highlighted
setCursorPos (3 + b, 2 + int(y)); // first character
}
else
setColor ( wc.current_element_fg
, wc.current_element_bg );
}
if ( isMonochron() )
setReverse(false);
}
else
{
if ( isMonochron() )
setReverse(true);
else if ( isFocus && getMaxColor() < 16 )
unsetBold();
}
// Set screen position and attributes
setLineAttributes ( int(y), isSelected(iter), lineHasBrackets
, serach_mark );
// print the entry
if ( lineHasBrackets )
{
drawListBracketsLine (int(y), iter, serach_mark);
}
else // line has no brackets
{
drawListLine (int(y), iter, serach_mark);
}
++iter;
}
unsetAttributes();
last_yoffset = yoffset;
last_current = current;
}
//----------------------------------------------------------------------
inline void FListBox::drawListLine ( int y, listBoxItems::iterator iter
, bool serach_mark )
{
uInt i, len;
uInt inc_len = inc_search.getLength();
bool isCurrentLine = bool(y + uInt(yoffset) + 1 == uInt(current));
FString element;
element = getString(iter).mid ( uInt(1 + xoffset)
, uInt(getWidth() - nf_offset - 4) );
const wchar_t* const& element_str = element.wc_str();
len = element.getLength();
if ( isMonochron() && isCurrentLine )
print ('>');
else
print (' ');
if ( lineHasBrackets )
if ( serach_mark )
setColor ( wc.current_inc_search_element_fg
, wc.current_element_focus_bg );
for (i = 0; i < len; i++)
{
if ( serach_mark && i == inc_len )
setColor ( wc.current_element_focus_fg
, wc.current_element_focus_bg );
print (element_str[i]);
}
if ( isMonochron() && isCurrentLine )
{
print ('<');
i++;
}
for (; i < uInt(getWidth() - nf_offset - 3); i++)
print (' ');
}
//----------------------------------------------------------------------
inline void FListBox::drawListBracketsLine ( int y, listBoxItems::iterator iter
, bool serach_mark )
{
int full_length;
FString element;
uInt len
, inc_len = inc_search.getLength()
, i = 0
, b = 0;
bool isCurrentLine = bool(y + uInt(yoffset) + 1 == uInt(current));
if ( isMonochron() && isCurrentLine )
print ('>');
else
print (' ');
if ( xoffset == 0 )
{
@ -1623,47 +1399,117 @@ void FListBox::drawList()
for (; b + i < uInt(getWidth() - nf_offset - 3); i++)
print (' ');
}
//----------------------------------------------------------------------
inline void FListBox::setLineAttributes ( int y
, bool isLineSelected
, bool lineHasBrackets
, bool& serach_mark )
{
bool isFocus = ((flags & fc::focus) != 0)
, isCurrentLine = bool(y + uInt(yoffset) + 1 == uInt(current));
uInt inc_len = inc_search.getLength();
setPrintPos (2, 2 + int(y));
if ( isLineSelected )
{
if ( isMonochron() )
setBold();
else
setColor (wc.selected_list_fg, wc.selected_list_bg);
}
else // line has no brackets
else
{
uInt i, len;
element = getString(iter).mid ( uInt(1 + xoffset)
, uInt(getWidth() - nf_offset - 4) );
const wchar_t* const& element_str = element.wc_str();
len = element.getLength();
if ( isMonochron() )
unsetBold();
else
setColor (wc.list_fg, wc.list_bg);
}
if ( serach_mark )
setColor ( wc.current_inc_search_element_fg
, wc.current_element_focus_bg );
for (i = 0; i < len; i++)
if ( isCurrentLine )
{
if ( isFocus && getMaxColor() < 16 )
setBold();
if ( isLineSelected )
{
if ( isMonochron() )
setBold();
else if ( isFocus )
setColor ( wc.selected_current_element_focus_fg
, wc.selected_current_element_focus_bg );
else
setColor ( wc.selected_current_element_fg
, wc.selected_current_element_bg );
setCursorPos (3, 2 + int(y)); // first character
}
else
{
if ( isMonochron() )
unsetBold();
if ( isFocus )
{
if ( serach_mark && i == inc_len )
setColor ( wc.current_element_focus_fg
, wc.current_element_focus_bg );
int b = ( lineHasBrackets ) ? 1: 0;
print (element_str[i]);
}
if ( isMonochron() && isCurrentLine )
if ( inc_len > 0 ) // incremental search
{
print ('<');
i++;
serach_mark = true;
// Place the cursor on the last found character
setCursorPos (2 + b + int(inc_len), 2 + int(y));
}
else // only highlighted
setCursorPos (3 + b, 2 + int(y)); // first character
}
else
setColor ( wc.current_element_fg
, wc.current_element_bg );
}
for (; i < uInt(getWidth() - nf_offset - 3); i++)
print (' ');
if ( isMonochron() )
setReverse(false);
}
++iter;
else
{
if ( isMonochron() )
setReverse(true);
else if ( isFocus && getMaxColor() < 16 )
unsetBold();
}
}
//----------------------------------------------------------------------
inline void FListBox::unsetAttributes()
{
if ( isMonochron() ) // unset for the last element
setReverse(false);
unsetBold();
last_yoffset = yoffset;
last_current = current;
}
//----------------------------------------------------------------------
inline void FListBox::updateDrawing (bool draw_vbar, bool draw_hbar)
{
if ( isVisible() )
drawList();
vbar->setValue (yoffset);
if ( vbar->isVisible() && draw_vbar )
vbar->drawBar();
hbar->setValue (xoffset);
if ( hbar->isVisible() && draw_hbar )
hbar->drawBar();
updateTerminal();
flush_out();
}
//----------------------------------------------------------------------
@ -1672,8 +1518,9 @@ void FListBox::recalculateHorizontalBar (int len, bool has_brackets)
if ( has_brackets )
len += 2;
if ( len > max_line_width )
{
if ( len <= max_line_width )
return;
max_line_width = len;
if ( len >= getWidth() - nf_offset - 3 )
@ -1685,7 +1532,7 @@ void FListBox::recalculateHorizontalBar (int len, bool has_brackets)
if ( ! hbar->isVisible() )
hbar->setVisible();
}
}
}
//----------------------------------------------------------------------
@ -1699,6 +1546,292 @@ void FListBox::recalculateVerticalBar (int element_count)
vbar->setVisible();
}
//----------------------------------------------------------------------
inline void FListBox::keyUp()
{
current--;
if ( current < 1 )
current = 1;
if ( current <= yoffset )
yoffset--;
inc_search.clear();
}
//----------------------------------------------------------------------
inline void FListBox::keyDown()
{
int element_count = int(getCount());
current++;
if ( current > element_count )
current = element_count;
if ( current - yoffset > getClientHeight() )
yoffset++;
inc_search.clear();
}
//----------------------------------------------------------------------
inline void FListBox::keyLeft()
{
xoffset--;
if ( xoffset < 0 )
xoffset = 0;
inc_search.clear();
}
//----------------------------------------------------------------------
inline void FListBox::keyRight()
{
static const int padding_space = 2; // 1 leading space + 1 tailing space
int xoffset_end = max_line_width - getClientWidth() + padding_space;
xoffset++;
if ( xoffset > xoffset_end )
xoffset = xoffset_end;
if ( xoffset < 0 )
xoffset = 0;
inc_search.clear();
}
//----------------------------------------------------------------------
inline void FListBox::keyPgUp()
{
int pagesize = getClientHeight() - 1;
current -= pagesize;
if ( current < 1 )
current = 1;
if ( current <= yoffset )
{
yoffset -= pagesize;
if ( yoffset < 0 )
yoffset = 0;
}
inc_search.clear();
}
//----------------------------------------------------------------------
inline void FListBox::keyPgDn()
{
int element_count = int(getCount());
int yoffset_end = element_count - getClientHeight();
int pagesize = getClientHeight() - 1;
current += pagesize;
if ( current > element_count )
current = element_count;
if ( current - yoffset > getClientHeight() )
{
yoffset += pagesize;
if ( yoffset > yoffset_end )
yoffset = yoffset_end;
}
inc_search.clear();
}
//----------------------------------------------------------------------
inline void FListBox::keyHome()
{
current = 1;
yoffset = 0;
inc_search.clear();
}
//----------------------------------------------------------------------
inline void FListBox::keyEnd()
{
int element_count = int(getCount());
int yoffset_end = element_count - getClientHeight();
current = element_count;
if ( current > getClientHeight() )
yoffset = yoffset_end;
inc_search.clear();
}
//----------------------------------------------------------------------
inline bool FListBox::keyEsc()
{
if ( inc_search.getLength() > 0 )
{
inc_search.clear();
return true;
}
return false;
}
//----------------------------------------------------------------------
inline void FListBox::keyEnter()
{
processClick();
inc_search.clear();
}
//----------------------------------------------------------------------
inline bool FListBox::keySpace()
{
uInt inc_len = inc_search.getLength();
if ( inc_len > 0 )
{
inc_search += L' ';
bool inc_found = false;
listBoxItems::iterator iter = itemlist.begin();
while ( iter != itemlist.end() )
{
if ( ! inc_found
&& inc_search.toLower()
== iter->getText().left(inc_len + 1).toLower() )
{
setCurrentItem(iter);
inc_found = true;
break;
}
++iter;
}
if ( ! inc_found )
{
inc_search.remove(inc_len, 1);
return false;
}
}
else if ( isMultiSelection() )
{
if ( isSelected(current) )
unselectItem(current);
else
selectItem(current);
processSelect();
inc_search.clear();
}
return true;
}
//----------------------------------------------------------------------
inline bool FListBox::keyInsert()
{
if ( isMultiSelection() )
{
int element_count = int(getCount());
if ( isSelected(current) )
unselectItem(current);
else
selectItem(current);
processSelect();
current++;
if ( current > element_count )
current = element_count;
if ( current - yoffset >= getHeight() - 1 )
yoffset++;
return true;
}
inc_search.clear();
return false;
}
//----------------------------------------------------------------------
inline bool FListBox::keyBackspace()
{
uInt inc_len = inc_search.getLength();
if ( inc_len > 0 )
{
inc_search.remove(inc_len - 1, 1);
if ( inc_len > 1 )
{
listBoxItems::iterator iter = itemlist.begin();
while ( iter != itemlist.end() )
{
if ( inc_search.toLower()
== iter->getText().left(inc_len - 1).toLower() )
{
setCurrentItem(iter);
break;
}
++iter;
}
}
return true;
}
return false;
}
//----------------------------------------------------------------------
inline bool FListBox::keyIncSearchInput (int key)
{
if ( key <= 0x20 || key > 0x10fff )
return false;
// incremental search
if ( inc_search.getLength() == 0 )
inc_search = wchar_t(key);
else
inc_search += wchar_t(key);
uInt inc_len = inc_search.getLength();
bool inc_found = false;
listBoxItems::iterator iter = itemlist.begin();
while ( iter != itemlist.end() )
{
if ( ! inc_found
&& inc_search.toLower()
== iter->getText().left(inc_len).toLower() )
{
setCurrentItem(iter);
inc_found = true;
break;
}
++iter;
}
if ( ! inc_found )
{
inc_search.remove(inc_len - 1, 1);
if ( inc_len == 1 )
return false;
else
return true;
}
return true;
}
//----------------------------------------------------------------------
void FListBox::processClick()
{
@ -1717,6 +1850,20 @@ void FListBox::processChanged()
emitCallback("row-changed");
}
//----------------------------------------------------------------------
void FListBox::lazyConvert(listBoxItems::iterator iter, int y)
{
if ( conv_type != lazy_convert || ! iter->getText().isNull() )
return;
convertToItem (*iter, source_container, y + yoffset);
int len = int(iter->text.getLength());
recalculateHorizontalBar (len, hasBrackets(iter));
if ( hbar->isVisible() )
hbar->redraw();
}
//----------------------------------------------------------------------
void FListBox::cb_VBarChange (FWidget*, data_ptr)
{

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,34 +1204,11 @@ 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)
{
switch ( bit & attr_without_color )
@ -1295,7 +1272,6 @@ inline void FOptiAttr::prevent_no_color_video_attributes (char_data*& attr)
break;
}
}
}
}
//----------------------------------------------------------------------

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,15 +1408,15 @@ void FVTerm::updateVTerm (term_area* area)
else
y_end = ah + bsh;
for (int y = 0; y < y_end; y++) // line loop
{
int line_xmin = int(area->changes[y].xmin);
int line_xmax = int(area->changes[y].xmax);
if ( line_xmin <= line_xmax )
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 )
continue;
if ( ax == 0 )
line_xmin = ol;
@ -1389,52 +1427,22 @@ void FVTerm::updateVTerm (term_area* area)
if ( ax + line_xmin >= vterm->width )
continue;
for (int x = line_xmin; x <= line_xmax; x++) // column loop
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;
// Global terminal positions
int tx = ax + x
, ty = ay + y;
if ( gx < 0 || gy < 0 )
if ( tx < 0 || ty < 0 )
continue;
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);
}
}
tx -= ol;
if ( updateVTermCharacter (area, x, y, tx, ty) )
modified = true;
}
else if ( ! modified )
line_xmin++; // don't update covered character
if ( ! modified )
line_xmin++; // Don't update covered character
}
_xmin = ax + line_xmin - ol;
@ -1452,7 +1460,6 @@ void FVTerm::updateVTerm (term_area* area)
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()
{ }