From 7d3793ce1d8cb26e7608bf859beca21359cec6e9 Mon Sep 17 00:00:00 2001 From: maxim nikonov Date: Thu, 5 Feb 2026 16:35:56 +0500 Subject: wip --- src/Fl_Group.cxx | 42 ++++++++++++++++------- src/Fl_Table.cxx | 96 ++++++++++++++++++++++++++++++++++++++-------------- src/Fl_Table_Row.cxx | 39 ++++++++++++++------- 3 files changed, 127 insertions(+), 50 deletions(-) (limited to 'src') diff --git a/src/Fl_Group.cxx b/src/Fl_Group.cxx index e256e81ec..31fca05d8 100644 --- a/src/Fl_Group.cxx +++ b/src/Fl_Group.cxx @@ -34,12 +34,9 @@ Fl_Group* Fl_Group::current_; \note This pointer is only valid until the next time a child is added or removed. - - \internal This "array" of children is the storage area of an - internal std::vector. */ Fl_Widget*const* Fl_Group::array() const { - return child_.data(); + return child_; } /** @@ -354,6 +351,9 @@ int Fl_Group::navigation(int key) { Fl_Group::Fl_Group(int X, int Y, int W, int H, const char *L) : Fl_Widget(X, Y, W, H, L) { align(FL_ALIGN_TOP); + child_ = 0; + children_ = 0; + children_alloc_ = 0; savedfocus_ = 0; resizable_ = this; bounds_ = 0; // this is allocated when first resize() is done @@ -437,6 +437,10 @@ Fl_Group::~Fl_Group() { if (current_ == this) end(); clear(); + if (child_) { + free(child_); + child_ = 0; + } } /** @@ -529,10 +533,24 @@ void Fl_Group::insert(Fl_Widget &o, int index) { index = on_insert(&o, index); if (index == -1) return; - if (index >= children()) { // append - child_.push_back(&o); + + // grow array if needed + if (children_ >= children_alloc_) { + int newsize = children_alloc_ ? children_alloc_ * 2 : 4; + Fl_Widget **newarray = (Fl_Widget**)realloc(child_, newsize * sizeof(Fl_Widget*)); + if (!newarray) return; // allocation failed + child_ = newarray; + children_alloc_ = newsize; + } + + if (index >= children_) { // append + child_[children_++] = &o; } else { // insert - child_.insert(child_.begin() + index, &o); + int i; + for (i = children_; i > index; i--) + child_[i] = child_[i - 1]; + child_[index] = &o; + children_++; } o.parent_ = this; init_sizes(); @@ -583,11 +601,11 @@ void Fl_Group::remove(int index) { o.parent_ = 0; } - if (index == children() - 1) { - child_.pop_back(); - } else { - child_.erase(child_.begin() + index); // remove the widget from the group - } + // remove the widget from the group + children_--; + int i; + for (i = index; i < children_; i++) + child_[i] = child_[i + 1]; init_sizes(); } diff --git a/src/Fl_Table.cxx b/src/Fl_Table.cxx index c3fddc5fa..79d152acb 100644 --- a/src/Fl_Table.cxx +++ b/src/Fl_Table.cxx @@ -145,8 +145,12 @@ Fl_Table::Fl_Table(int X, int Y, int W, int H, const char *l) : Fl_Group(X,Y,W,H _scrollbar_size = 0; flags_ = 0; // TABCELLNAV off - _colwidths = new std::vector; // column widths in pixels - _rowheights = new std::vector; // row heights in pixels + _colwidths = 0; + _colwidths_size = 0; + _colwidths_alloc = 0; + _rowheights = 0; + _rowheights_size = 0; + _rowheights_alloc = 0; box(FL_THIN_DOWN_FRAME); @@ -181,8 +185,8 @@ Fl_Table::Fl_Table(int X, int Y, int W, int H, const char *l) : Fl_Group(X,Y,W,H */ Fl_Table::~Fl_Table() { // The parent Fl_Group takes care of destroying scrollbars - delete _colwidths; - delete _rowheights; + if (_colwidths) free(_colwidths); + if (_rowheights) free(_rowheights); } @@ -194,7 +198,7 @@ Fl_Table::~Fl_Table() { \returns Number of columns. */ int Fl_Table::col_size() { - return int(_colwidths->size()); + return _colwidths_size; } /** @@ -205,7 +209,7 @@ int Fl_Table::col_size() { \returns Number of rows. */ int Fl_Table::row_size() { - return int(_rowheights->size()); + return _rowheights_size; } /** @@ -216,15 +220,26 @@ int Fl_Table::row_size() { */ void Fl_Table::row_height(int row, int height) { if ( row < 0 ) return; - if ( row < row_size() && (*_rowheights)[row] == height ) { + if ( row < row_size() && _rowheights[row] == height ) { return; // OPTIMIZATION: no change? avoid redraw } // Add row heights, even if none yet - int now_size = row_size(); - if (row >= now_size) { - _rowheights->resize(row, height); + if (row >= _rowheights_size) { + // Need to grow array + int newsize = row + 1; + if (newsize > _rowheights_alloc) { + int newalloc = _rowheights_alloc ? _rowheights_alloc * 2 : 8; + if (newalloc < newsize) newalloc = newsize; + _rowheights = (int*)realloc(_rowheights, newalloc * sizeof(int)); + _rowheights_alloc = newalloc; + } + // Fill new entries with height + int i; + for (i = _rowheights_size; i < newsize; i++) + _rowheights[i] = height; + _rowheights_size = newsize; } - (*_rowheights)[row] = height; + _rowheights[row] = height; table_resized(); if ( row <= botrow ) { // OPTIMIZATION: only redraw if onscreen or above screen redraw(); @@ -243,15 +258,26 @@ void Fl_Table::row_height(int row, int height) { void Fl_Table::col_width(int col, int width) { if ( col < 0 ) return; - if ( col < col_size() && (*_colwidths)[col] == width ) { + if ( col < col_size() && _colwidths[col] == width ) { return; // OPTIMIZATION: no change? avoid redraw } // Add column widths, even if none yet - int now_size = col_size(); - if ( col >= now_size ) { - _colwidths->resize(col+1, width); + if ( col >= _colwidths_size ) { + // Need to grow array + int newsize = col + 1; + if (newsize > _colwidths_alloc) { + int newalloc = _colwidths_alloc ? _colwidths_alloc * 2 : 8; + if (newalloc < newsize) newalloc = newsize; + _colwidths = (int*)realloc(_colwidths, newalloc * sizeof(int)); + _colwidths_alloc = newalloc; + } + // Fill new entries with width + int i; + for (i = _colwidths_size; i < newsize; i++) + _colwidths[i] = width; + _colwidths_size = newsize; } - (*_colwidths)[col] = width; + _colwidths[col] = width; table_resized(); if ( col <= rightcol ) { // OPTIMIZATION: only redraw if onscreen or to the left redraw(); @@ -660,11 +686,20 @@ void Fl_Table::rows(int val) { int oldrows = _rows; _rows = val; - int default_h = row_size() > 0 ? _rowheights->back() : 25; - int now_size = row_size(); + int default_h = row_size() > 0 ? _rowheights[row_size()-1] : 25; - if (now_size != val) - _rowheights->resize(val, default_h); // enlarge or shrink as needed + if (_rowheights_size != val) { + // resize array + if (val > _rowheights_alloc) { + _rowheights = (int*)realloc(_rowheights, val * sizeof(int)); + _rowheights_alloc = val; + } + // Fill new entries + int i; + for (i = _rowheights_size; i < val; i++) + _rowheights[i] = default_h; + _rowheights_size = val; + } table_resized(); @@ -682,11 +717,20 @@ void Fl_Table::rows(int val) { void Fl_Table::cols(int val) { _cols = val; - int default_w = col_size() > 0 ? (*_colwidths)[col_size()-1] : 80; - int now_size = col_size(); + int default_w = col_size() > 0 ? _colwidths[col_size()-1] : 80; - if (now_size != val) - _colwidths->resize(val, default_w); // enlarge or shrink as needed + if (_colwidths_size != val) { + // resize array + if (val > _colwidths_alloc) { + _colwidths = (int*)realloc(_colwidths, val * sizeof(int)); + _colwidths_alloc = val; + } + // Fill new entries + int i; + for (i = _colwidths_size; i < val; i++) + _colwidths[i] = default_w; + _colwidths_size = val; + } table_resized(); redraw(); @@ -1398,12 +1442,12 @@ void Fl_Table::draw() { Returns the current height of the specified row as a value in pixels. */ int Fl_Table::row_height(int row) { - return((row < 0 || row >= row_size()) ? 0 : (*_rowheights)[row]); + return((row < 0 || row >= row_size()) ? 0 : _rowheights[row]); } /** Returns the current width of the specified column in pixels. */ int Fl_Table::col_width(int col) { - return((col < 0 || col >= col_size()) ? 0 : (*_colwidths)[col]); + return((col < 0 || col >= col_size()) ? 0 : _colwidths[col]); } diff --git a/src/Fl_Table_Row.cxx b/src/Fl_Table_Row.cxx index 849cd0383..d07db7ac7 100644 --- a/src/Fl_Table_Row.cxx +++ b/src/Fl_Table_Row.cxx @@ -63,20 +63,21 @@ int Fl_Table_Row::row_selected(int row) { // Change row selection type void Fl_Table_Row::type(TableRowSelectMode val) { _selectmode = val; + int i; switch ( _selectmode ) { case SELECT_NONE: { - for (auto &sel : _rowselect) { - sel = 0; + for (i = 0; i < _rowselect_size; i++) { + _rowselect[i] = 0; } redraw(); break; } case SELECT_SINGLE: { int count = 0; - for (auto &sel : _rowselect) { - if (sel) { + for (i = 0; i < _rowselect_size; i++) { + if (_rowselect[i]) { if (++count > 1) { // only one allowed - sel = 0; + _rowselect[i] = 0; } } } @@ -149,6 +150,7 @@ int Fl_Table_Row::select_row(int row, int flag) { // Select all rows to a known state void Fl_Table_Row::select_all_rows(int flag) { + int i; switch ( _selectmode ) { case SELECT_NONE: return; @@ -160,14 +162,14 @@ void Fl_Table_Row::select_all_rows(int flag) { case SELECT_MULTI: { char changed = 0; if ( flag == 2 ) { - for (auto &sel : _rowselect) { - sel ^= 1; + for (i = 0; i < _rowselect_size; i++) { + _rowselect[i] ^= 1; } changed = 1; } else { - for (auto &sel : _rowselect) { - changed |= (sel != flag) ? 1 : 0; - sel = flag; + for (i = 0; i < _rowselect_size; i++) { + changed |= (_rowselect[i] != flag) ? 1 : 0; + _rowselect[i] = flag; } } if ( changed ) { @@ -180,9 +182,22 @@ void Fl_Table_Row::select_all_rows(int flag) { // Set number of rows void Fl_Table_Row::rows(int val) { // Note: order of operations below matters, see PR #1187 - if (val > (int)_rowselect.size()) { _rowselect.resize(val, 0); } // enlarge + if (val > _rowselect_size) { + // enlarge + if (val > _rowselect_alloc) { + _rowselect = (unsigned char*)realloc(_rowselect, val); + _rowselect_alloc = val; + } + int i; + for (i = _rowselect_size; i < val; i++) + _rowselect[i] = 0; + _rowselect_size = val; + } Fl_Table::rows(val); - if (val < (int)_rowselect.size()) { _rowselect.resize(val); } // shrink + if (val < _rowselect_size) { + // shrink + _rowselect_size = val; + } } // Handle events -- cgit v1.2.3