Fix overrunning array
This commit is contained in:
parent
0e4ba28544
commit
37f8ee81c9
|
@ -26,8 +26,17 @@ FListViewItem::FListViewItem (const FListViewItem& item)
|
|||
{
|
||||
FObject* parent = getParent();
|
||||
|
||||
if ( parent && parent->isInstanceOf("FListView") )
|
||||
if ( ! parent )
|
||||
return;
|
||||
|
||||
if ( parent->isInstanceOf("FListView") )
|
||||
{
|
||||
static_cast<FListView*>(parent)->insert (this);
|
||||
}
|
||||
else if ( parent->isInstanceOf("FListViewItem") )
|
||||
{
|
||||
static_cast<FListViewItem*>(parent)->insert (this);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -39,23 +48,7 @@ FListViewItem::FListViewItem (FObjectIterator parent_iter)
|
|||
, expandable(false)
|
||||
, is_expand(false)
|
||||
{
|
||||
if ( *parent_iter )
|
||||
{
|
||||
if ( (*parent_iter)->isInstanceOf("FListView") )
|
||||
{
|
||||
// Add FListViewItem to a FListView parent
|
||||
FListView* parent = static_cast<FListView*>(*parent_iter);
|
||||
parent->addChild (this);
|
||||
parent->insert (this);
|
||||
}
|
||||
else if ( (*parent_iter)->isInstanceOf("FListViewItem") )
|
||||
{
|
||||
// Add FListViewItem to a FListViewItem parent
|
||||
FListViewItem* parent = static_cast<FListViewItem*>(*parent_iter);
|
||||
parent->addChild (this);
|
||||
parent->expandable = true;
|
||||
}
|
||||
}
|
||||
insert (this, parent_iter);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -72,35 +65,8 @@ FListViewItem::FListViewItem ( const std::vector<FString>& cols
|
|||
if ( cols.empty() )
|
||||
return;
|
||||
|
||||
// Replace the control codes characters
|
||||
std::vector<FString>::iterator iter = column_list.begin();
|
||||
|
||||
while ( iter != column_list.end() )
|
||||
{
|
||||
*iter = iter->replaceControlCodes();
|
||||
++iter;
|
||||
}
|
||||
|
||||
if ( parent_iter == FObjectIterator(0) )
|
||||
return;
|
||||
|
||||
if ( *parent_iter )
|
||||
{
|
||||
if ( (*parent_iter)->isInstanceOf("FListView") )
|
||||
{
|
||||
// Add FListViewItem to a FListView parent
|
||||
FListView* parent = static_cast<FListView*>(*parent_iter);
|
||||
parent->addChild (this);
|
||||
parent->insert (this);
|
||||
}
|
||||
else if ( (*parent_iter)->isInstanceOf("FListViewItem") )
|
||||
{
|
||||
// Add FListViewItem to a FListViewItem parent
|
||||
FListViewItem* parent = static_cast<FListViewItem*>(*parent_iter);
|
||||
parent->addChild (this);
|
||||
parent->expandable = true;
|
||||
}
|
||||
}
|
||||
replaceControlCodes();
|
||||
insert (this, parent_iter);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -149,14 +115,39 @@ void FListViewItem::setText (int column, const FString& text)
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FListViewItem::insert (FListViewItem* child)
|
||||
FObject::FObjectIterator FListViewItem::insert (FListViewItem* child)
|
||||
{
|
||||
// Add a FListViewItem as child element
|
||||
if ( ! child || ! hasChildren() )
|
||||
return;
|
||||
return FObjectIterator(0);
|
||||
|
||||
addChild (child);
|
||||
expandable = true;
|
||||
return appendItem(child);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
FObject::FObjectIterator FListViewItem::insert ( FListViewItem* child
|
||||
, FObjectIterator parent_iter )
|
||||
{
|
||||
if ( parent_iter == FObjectIterator(0) )
|
||||
return FObjectIterator(0);
|
||||
|
||||
if ( *parent_iter )
|
||||
{
|
||||
if ( (*parent_iter)->isInstanceOf("FListView") )
|
||||
{
|
||||
// Add FListViewItem to a FListView parent
|
||||
FListView* parent = static_cast<FListView*>(*parent_iter);
|
||||
return parent->insert (child);
|
||||
}
|
||||
else if ( (*parent_iter)->isInstanceOf("FListViewItem") )
|
||||
{
|
||||
// Add FListViewItem to a FListViewItem parent
|
||||
FListViewItem* parent = static_cast<FListViewItem*>(*parent_iter);
|
||||
return parent->insert (child);
|
||||
}
|
||||
}
|
||||
|
||||
return FObjectIterator(0);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -177,6 +168,29 @@ void FListViewItem::collapse()
|
|||
is_expand = false;
|
||||
}
|
||||
|
||||
// private methods of FListView
|
||||
//----------------------------------------------------------------------
|
||||
FObject::FObjectIterator FListViewItem::appendItem (FListViewItem* child)
|
||||
{
|
||||
expandable = true;
|
||||
addChild (child);
|
||||
FObjectList children = getChildren();
|
||||
return --children.end();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FListViewItem::replaceControlCodes()
|
||||
{
|
||||
// Replace the control codes characters
|
||||
std::vector<FString>::iterator iter = column_list.begin();
|
||||
|
||||
while ( iter != column_list.end() )
|
||||
{
|
||||
*iter = iter->replaceControlCodes();
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
int FListViewItem::getVisibleLines()
|
||||
{
|
||||
|
@ -379,32 +393,25 @@ FObject::FObjectIterator FListView::insert ( FListViewItem* item
|
|||
|
||||
if ( parent_iter == root )
|
||||
{
|
||||
addChild (item);
|
||||
itemlist.push_back (item);
|
||||
item_iter = --itemlist.end();
|
||||
item_iter = appendItem (item);
|
||||
}
|
||||
else if ( *parent_iter )
|
||||
{
|
||||
if ( (*parent_iter)->isInstanceOf("FListView") )
|
||||
{
|
||||
// Add FListViewItem to a FListView parent
|
||||
addChild (item);
|
||||
FListView* parent = static_cast<FListView*>(*parent_iter);
|
||||
parent->itemlist.push_back (item);
|
||||
item_iter = --parent->itemlist.end();
|
||||
item_iter = parent->appendItem (item);
|
||||
}
|
||||
else if ( (*parent_iter)->isInstanceOf("FListViewItem") )
|
||||
{
|
||||
// Add FListViewItem to a FListViewItem parent
|
||||
FListViewItem* parent = static_cast<FListViewItem*>(*parent_iter);
|
||||
parent->expandable = true;
|
||||
parent->addChild (item);
|
||||
FObjectList parent_obj = parent->getChildren();
|
||||
item_iter = --parent_obj.end();
|
||||
item_iter = parent->appendItem (item);
|
||||
}
|
||||
}
|
||||
|
||||
int element_count = int(itemlist.size());
|
||||
int element_count = int(getCount());
|
||||
recalculateVerticalBar (element_count);
|
||||
return item_iter;
|
||||
}
|
||||
|
@ -416,6 +423,9 @@ FObject::FObjectIterator FListView::insert ( const std::vector<FString>& cols
|
|||
{
|
||||
FListViewItem* item;
|
||||
|
||||
if ( cols.empty() || parent_iter == FObjectIterator(0) )
|
||||
return FObjectIterator(0);
|
||||
|
||||
if ( ! *parent_iter )
|
||||
parent_iter = root;
|
||||
|
||||
|
@ -429,6 +439,7 @@ FObject::FObjectIterator FListView::insert ( const std::vector<FString>& cols
|
|||
return FObjectIterator(0);
|
||||
}
|
||||
|
||||
item->replaceControlCodes();
|
||||
return insert(item, parent_iter);
|
||||
}
|
||||
|
||||
|
@ -454,7 +465,7 @@ FObject::FObjectIterator FListView::insert ( const std::vector<long>& cols
|
|||
//----------------------------------------------------------------------
|
||||
void FListView::onKeyPress (FKeyEvent* ev)
|
||||
{
|
||||
int element_count = int(itemlist.size());
|
||||
int element_count = int(getCount());
|
||||
int current_before = current;
|
||||
int xoffset_before = xoffset;
|
||||
int xoffset_end = max_line_width - getClientWidth();
|
||||
|
@ -564,6 +575,22 @@ void FListView::onKeyPress (FKeyEvent* ev)
|
|||
ev->accept();
|
||||
break;
|
||||
|
||||
case int('+'):
|
||||
{
|
||||
FListViewItem* item = getCurrentItem();
|
||||
item->expand();
|
||||
ev->accept();
|
||||
}
|
||||
break;
|
||||
|
||||
case int('-'):
|
||||
{
|
||||
FListViewItem* item = getCurrentItem();
|
||||
item->collapse();
|
||||
ev->accept();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ev->ignore();
|
||||
}
|
||||
|
@ -631,8 +658,8 @@ void FListView::onMouseDown (FMouseEvent* ev)
|
|||
{
|
||||
current = yoffset + mouse_y - 1;
|
||||
|
||||
if ( current > int(itemlist.size()) )
|
||||
current = int(itemlist.size());
|
||||
if ( current > int(getCount()) )
|
||||
current = int(getCount());
|
||||
|
||||
if ( isVisible() )
|
||||
drawList();
|
||||
|
@ -694,8 +721,8 @@ void FListView::onMouseMove (FMouseEvent* ev)
|
|||
{
|
||||
current = yoffset + mouse_y - 1;
|
||||
|
||||
if ( current > int(itemlist.size()) )
|
||||
current = int(itemlist.size());
|
||||
if ( current > int(getCount()) )
|
||||
current = int(getCount());
|
||||
|
||||
if ( isVisible() )
|
||||
drawList();
|
||||
|
@ -741,7 +768,7 @@ void FListView::onMouseMove (FMouseEvent* ev)
|
|||
&& scroll_distance < getClientHeight() )
|
||||
scroll_distance++;
|
||||
|
||||
if ( ! scroll_timer && current < int(itemlist.size()) )
|
||||
if ( ! scroll_timer && current < int(getCount()) )
|
||||
{
|
||||
scroll_timer = true;
|
||||
addTimer(scroll_repeat);
|
||||
|
@ -752,7 +779,7 @@ void FListView::onMouseMove (FMouseEvent* ev)
|
|||
drag_scroll = fc::scrollDown;
|
||||
}
|
||||
|
||||
if ( current == int(itemlist.size()) )
|
||||
if ( current == int(getCount()) )
|
||||
{
|
||||
delOwnTimer();
|
||||
drag_scroll = fc::noScroll;
|
||||
|
@ -782,7 +809,7 @@ void FListView::onMouseDoubleClick (FMouseEvent* ev)
|
|||
if ( mouse_x > 1 && mouse_x < getWidth()
|
||||
&& mouse_y > 1 && mouse_y < getHeight() )
|
||||
{
|
||||
if ( yoffset + mouse_y - 1 > int(itemlist.size()) )
|
||||
if ( yoffset + mouse_y - 1 > int(getCount()) )
|
||||
return;
|
||||
|
||||
processClick();
|
||||
|
@ -792,7 +819,7 @@ void FListView::onMouseDoubleClick (FMouseEvent* ev)
|
|||
//----------------------------------------------------------------------
|
||||
void FListView::onTimer (FTimerEvent*)
|
||||
{
|
||||
int element_count = int(itemlist.size());
|
||||
int element_count = int(getCount());
|
||||
int current_before = current;
|
||||
int yoffset_before = yoffset;
|
||||
int yoffset_end = element_count - getClientHeight();
|
||||
|
@ -863,7 +890,7 @@ void FListView::onTimer (FTimerEvent*)
|
|||
void FListView::onWheel (FWheelEvent* ev)
|
||||
{
|
||||
int element_count, current_before, yoffset_before, yoffset_end, wheel;
|
||||
element_count = int(itemlist.size());
|
||||
element_count = int(getCount());
|
||||
current_before = current;
|
||||
yoffset_before = yoffset;
|
||||
yoffset_end = element_count - getClientHeight();
|
||||
|
@ -964,7 +991,7 @@ void FListView::onFocusOut (FFocusEvent*)
|
|||
//----------------------------------------------------------------------
|
||||
void FListView::adjustYOffset()
|
||||
{
|
||||
int element_count = int(itemlist.size());
|
||||
int element_count = int(getCount());
|
||||
|
||||
if ( yoffset > element_count - getClientHeight() )
|
||||
yoffset = element_count - getClientHeight();
|
||||
|
@ -986,7 +1013,7 @@ void FListView::adjustSize()
|
|||
FWidget::adjustSize();
|
||||
adjustYOffset();
|
||||
|
||||
element_count = int(itemlist.size());
|
||||
element_count = int(getCount());
|
||||
vbar->setMaximum (element_count - getClientHeight());
|
||||
vbar->setPageSize (element_count, getClientHeight());
|
||||
vbar->setX (getWidth());
|
||||
|
@ -1235,42 +1262,54 @@ void FListView::drawColumnLabels()
|
|||
//----------------------------------------------------------------------
|
||||
void FListView::drawList()
|
||||
{
|
||||
uInt start, end;
|
||||
bool isFocus;
|
||||
constFObjectIterator iter;
|
||||
uInt page_height, y;
|
||||
bool is_focus;
|
||||
FObjectIterator iter;
|
||||
|
||||
if ( itemlist.empty() || getHeight() <= 2 || getWidth() <= 4 )
|
||||
return;
|
||||
|
||||
isFocus = ((flags & fc::focus) != 0);
|
||||
start = 0;
|
||||
end = uInt(getHeight() - 2);
|
||||
y = 0;
|
||||
page_height = uInt(getHeight() - 2);
|
||||
is_focus = ((flags & fc::focus) != 0);
|
||||
iter = index2iterator(yoffset);
|
||||
|
||||
if ( end > itemlist.size() )
|
||||
end = uInt(itemlist.size());
|
||||
|
||||
iter = index2iterator(int(start) + yoffset);
|
||||
|
||||
for (uInt y = start; y < end; y++)
|
||||
while ( iter != itemlist.end() && y < page_height )
|
||||
{
|
||||
bool isCurrentLine = bool( y + uInt(yoffset) + 1 == uInt(current) );
|
||||
bool is_current_line = bool( y + uInt(yoffset) + 1 == uInt(current) );
|
||||
const FListViewItem* item = static_cast<FListViewItem*>(*iter);
|
||||
setPrintPos (2, 2 + int(y));
|
||||
setColor (wc.list_fg, wc.list_bg);
|
||||
FListViewItem* item = static_cast<FListViewItem*>(*iter);
|
||||
|
||||
if ( isCurrentLine )
|
||||
// Draw one FListViewItem
|
||||
drawListLine (item, is_focus, is_current_line);
|
||||
|
||||
if ( is_focus && is_current_line )
|
||||
setCursorPos (3, 2 + int(y)); // first character
|
||||
|
||||
y++;
|
||||
nextElement(iter);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FListView::drawListLine ( const FListViewItem* item
|
||||
, bool is_focus
|
||||
, bool is_current )
|
||||
{
|
||||
setColor (wc.list_fg, wc.list_bg);
|
||||
|
||||
if ( is_current )
|
||||
{
|
||||
if ( isFocus && getMaxColor() < 16 )
|
||||
if ( is_focus && getMaxColor() < 16 )
|
||||
setBold();
|
||||
|
||||
if ( isMonochron() )
|
||||
unsetBold();
|
||||
|
||||
if ( isFocus )
|
||||
if ( is_focus )
|
||||
{
|
||||
setColor ( wc.current_element_focus_fg
|
||||
, wc.current_element_focus_bg );
|
||||
setCursorPos (3, 2 + int(y)); // first character
|
||||
}
|
||||
else
|
||||
setColor ( wc.current_element_fg
|
||||
|
@ -1283,7 +1322,7 @@ void FListView::drawList()
|
|||
{
|
||||
if ( isMonochron() )
|
||||
setReverse(true);
|
||||
else if ( isFocus && getMaxColor() < 16 )
|
||||
else if ( is_focus && getMaxColor() < 16 )
|
||||
unsetBold();
|
||||
}
|
||||
|
||||
|
@ -1363,9 +1402,6 @@ void FListView::drawList()
|
|||
|
||||
for (; i < uInt(getWidth() - nf_offset - 2); i++)
|
||||
print (' ');
|
||||
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -1398,6 +1434,14 @@ void FListView::recalculateVerticalBar (int element_count)
|
|||
vbar->setVisible();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
FObject::FObjectIterator FListView::appendItem (FListViewItem* item)
|
||||
{
|
||||
addChild (item);
|
||||
itemlist.push_back (item);
|
||||
return --itemlist.end();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FListView::processClick()
|
||||
{
|
||||
|
@ -1415,7 +1459,7 @@ void FListView::cb_VBarChange (FWidget*, data_ptr)
|
|||
{
|
||||
FScrollbar::sType scrollType;
|
||||
int distance = 1;
|
||||
int element_count = int(itemlist.size());
|
||||
int element_count = int(getCount());
|
||||
int yoffset_before = yoffset;
|
||||
int yoffset_end = element_count - getClientHeight();
|
||||
scrollType = vbar->getScrollType();
|
||||
|
|
|
@ -17,11 +17,11 @@
|
|||
// ▕▁▁▁▁▁▁▁▁▏
|
||||
// ▲
|
||||
// │
|
||||
// ▕▔▔▔▔▔▔▔▔▔▏
|
||||
// ▕ FWidget ▏
|
||||
// ▕▁▁▁▁▁▁▁▁▁▏
|
||||
// ▲
|
||||
// │
|
||||
// ▕▔▔▔▔▔▔▔▔▔▏ ▕▔▔▔▔▔▔▔▔▔▏
|
||||
// ▕ FWidget ▏ ▕ FObject ▏
|
||||
// ▕▁▁▁▁▁▁▁▁▁▏ ▕▁▁▁▁▁▁▁▁▁▏
|
||||
// ▲ ▲
|
||||
// │ │
|
||||
// ▕▔▔▔▔▔▔▔▔▔▔▔▏1 *▕▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▏
|
||||
// ▕ FListView ▏- - - -▕ FListViewItem ▏
|
||||
// ▕▁▁▁▁▁▁▁▁▁▁▁▏ ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▏
|
||||
|
@ -77,7 +77,8 @@ class FListViewItem : public FObject
|
|||
bool isExpand();
|
||||
|
||||
// Methods
|
||||
void insert (FListViewItem*);
|
||||
FObjectIterator insert (FListViewItem*);
|
||||
FObjectIterator insert (FListViewItem*, FObjectIterator);
|
||||
void expand();
|
||||
void collapse();
|
||||
|
||||
|
@ -86,6 +87,8 @@ class FListViewItem : public FObject
|
|||
bool isExpandable();
|
||||
|
||||
// Methods
|
||||
FObjectIterator appendItem (FListViewItem*);
|
||||
void replaceControlCodes();
|
||||
int getVisibleLines();
|
||||
|
||||
// Data Member
|
||||
|
@ -140,6 +143,7 @@ class FListView : public FWidget
|
|||
|
||||
// Accessors
|
||||
const char* getClassName() const;
|
||||
uInt getCount() const;
|
||||
fc::text_alignment getColumnAlignment (int) const;
|
||||
FString getColumnText (int) const;
|
||||
FListViewItem* getCurrentItem();
|
||||
|
@ -225,11 +229,14 @@ class FListView : public FWidget
|
|||
void draw();
|
||||
void drawColumnLabels();
|
||||
void drawList();
|
||||
void drawListLine (const FListViewItem*, bool, bool);
|
||||
void recalculateHorizontalBar (int);
|
||||
void recalculateVerticalBar (int);
|
||||
FObjectIterator appendItem (FListViewItem*);
|
||||
void processClick();
|
||||
void processChanged();
|
||||
FObjectIterator index2iterator (int);
|
||||
void nextElement (FObjectIterator&);
|
||||
|
||||
// Callback methods
|
||||
void cb_VBarChange (FWidget*, data_ptr);
|
||||
|
@ -265,6 +272,10 @@ class FListView : public FWidget
|
|||
inline const char* FListView::getClassName() const
|
||||
{ return "FListView"; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline uInt FListView::getCount() const
|
||||
{ return uInt(itemlist.size()); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline FListViewItem* FListView::getCurrentItem()
|
||||
{
|
||||
|
@ -319,4 +330,10 @@ inline FObject::FObjectIterator FListView::index2iterator (int index)
|
|||
return iter;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FListView::nextElement (FObjectIterator& iter)
|
||||
{
|
||||
++iter;
|
||||
}
|
||||
|
||||
#endif // FLISTVIEW_H
|
||||
|
|
|
@ -17,11 +17,9 @@ const FString* fc::empty_string = 0;
|
|||
FObject::FObject (FObject* parent)
|
||||
: widget_object(false)
|
||||
, parent_obj(parent)
|
||||
, children_list()
|
||||
, children_list() // no children yet
|
||||
, has_parent(false)
|
||||
{
|
||||
children_list.clear(); // no children yet
|
||||
|
||||
if ( parent_obj ) // add object to parent
|
||||
parent_obj->addChild(this);
|
||||
|
||||
|
|
|
@ -999,7 +999,7 @@ void FVTerm::resizeArea ( int offset_left, int offset_top
|
|||
default_char.bg_color = fc::Default;
|
||||
default_char.attr.byte[0] = 0;
|
||||
default_char.attr.byte[1] = 0;
|
||||
default_char.attr.byte[3] = 0;
|
||||
default_char.attr.byte[2] = 0;
|
||||
|
||||
std::fill_n (area->text, area_size, default_char);
|
||||
|
||||
|
|
Loading…
Reference in New Issue