diff options
Diffstat (limited to 'src/ui/previewholder.cpp')
| -rw-r--r-- | src/ui/previewholder.cpp | 228 |
1 files changed, 113 insertions, 115 deletions
diff --git a/src/ui/previewholder.cpp b/src/ui/previewholder.cpp index 3d5290712..faf98d725 100644 --- a/src/ui/previewholder.cpp +++ b/src/ui/previewholder.cpp @@ -55,7 +55,7 @@ PreviewHolder::PreviewHolder() : _scroller->set_hexpand(); _scroller->set_vexpand(); _scroller->add( *_insides ); - + pack_start(*_scroller, Gtk::PACK_EXPAND_WIDGET); } @@ -127,15 +127,22 @@ void PreviewHolder::addPreview( Previewable* preview ) int ncols = 1; int nrows = 1; - calcGridSize( item, items.size(), ncols, nrows ); - - // Column and row for the new widget - int col = i % ncols; - int row = i / ncols; + int col = 0; + int row = 0; + // To get size auto kids = _insides->get_children(); int childCount = (int)kids.size(); - // g_message(" %3d resize from %d to %d (r:%d, c:%d) with %d children", i, oldWidth, width, row, col, childCount ); + if (childCount > 0 ) { + + // Need already shown widget + calcGridSize( kids[0], items.size()+1, ncols, nrows ); + + // Column and row for the new widget + col = i % ncols; + row = i / ncols; + + } // Loop through the existing widgets and move them to new location for ( int j = 1; j < childCount; j++ ) { @@ -217,7 +224,7 @@ void PreviewHolder::setOrientation(SPAnchorType anchor) void PreviewHolder::setWrap( bool wrap ) { - if (_wrap != wrap ) { + if (_wrap != wrap) { _wrap = wrap; switch ( _anchor ) { @@ -242,42 +249,40 @@ void PreviewHolder::setColumnPref( int cols ) _prefCols = cols; } -void PreviewHolder::on_size_allocate( Gtk::Allocation& allocation ) +void PreviewHolder::get_preferred_height_vfunc(int& minimum_height, int& natural_height) const { -// g_message( "on_size_allocate(%d, %d) (%d, %d)", allocation.get_x(), allocation.get_y(), allocation.get_width(), allocation.get_height() ); -// g_message(" anchor:%d", _anchor); - Gtk::Box::on_size_allocate( allocation ); - -/* if ( _insides && !_wrap && (_view != VIEW_TYPE_LIST) && (_anchor == SP_ANCHOR_NORTH || _anchor == SP_ANCHOR_SOUTH) ) { - Gtk::Requisition req; - Gtk::Requisition req_natural; - _insides->get_preferred_size(req, req_natural); - gint delta = allocation.get_width() - req.width; - - if ( (delta > 4) && req.height < allocation.get_height() ) { - _scroller->set_policy( Gtk::POLICY_NEVER, Gtk::POLICY_NEVER ); - } else { - _scroller->set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_NEVER ); - } - }*/ -} + // If we have a child (swatch), use that to get it's height. + auto children = _insides->get_children(); + int minimum_height_child = 0; + int natural_height_child = 0; + if (children.size() > 0) { + children[0]->get_preferred_height(minimum_height_child, natural_height_child); + } + + if (_wrap) { + // If wrapped, make height three times child height (seems reasonable). + minimum_height = 3 * minimum_height_child; + natural_height = 3 * natural_height_child; + } else { + // If not wrapped, height is sum of child height and scrollbar height. -//void PreviewHolder::on_size_request( Gtk::Requisition* requisition ) -//{ -// g_message( "on_size_request(%d, %d)", requisition->width, requisition->height ); -// Gtk::VBox::on_size_request( requisition ); -// g_message( " super (%d, %d)", requisition->width, requisition->height ); -// g_message(" anchor:%d", _anchor); -// g_message(" items:%d", (int)items.size()); -//} + // Get horizontal scrollbar height. + int minimum_height_scrollbar = 0; + int natural_height_scrollbar = 0; + _scroller->get_hscrollbar()->get_preferred_height(minimum_height_scrollbar, natural_height_scrollbar); + + minimum_height = minimum_height_child + minimum_height_scrollbar; + natural_height = natural_height_child + natural_height_scrollbar; + } +} /** * Calculate the grid side of a preview holder * - * \param[in] item + * \param[in] item A sample preview widget. * \param[in] itemCount The number of items to pack into the grid. * \param[out] ncols The number of columns in grid. - * \param[out] height The number of rows in grid. + * \param[out] nrows The number of rows in grid. */ void PreviewHolder::calcGridSize( const Gtk::Widget* item, int itemCount, int& ncols, int& nrows ) { @@ -287,42 +292,38 @@ void PreviewHolder::calcGridSize( const Gtk::Widget* item, int itemCount, int& n #if GTK_CHECK_VERSION(3,16,0) // Disable overlay scrolling as the scrollbar covers up swatches. - // For some reason this also makes the height 55px. - ((Gtk::ScrolledWindow *)_scroller)->set_overlay_scrolling(false); + _scroller->set_overlay_scrolling(false); #endif if ( _anchor == SP_ANCHOR_SOUTH || _anchor == SP_ANCHOR_NORTH ) { - Gtk::Requisition req; - Gtk::Requisition req_natural; - _scroller->get_preferred_size(req, req_natural); - int currW = _scroller->get_width(); - if ( currW > req.width ) { - req.width = currW; - } + // Horizontal layout, long bar. - auto hs = _scroller->get_hscrollbar(); + if (_wrap && item != NULL) { - if ( hs ) { - Gtk::Requisition scrollReq; - Gtk::Requisition scrollReq_natural; - hs->get_preferred_size(scrollReq, scrollReq_natural); + // Get width of bar. + int width_scroller = _scroller->get_width(); - // the +8 is a temporary hack - req.height -= scrollReq.height + 8; - } + // Get width of one item (must be visible). + int minimum_width_item = 0; + int natural_width_item = 0; + item->get_preferred_width(minimum_width_item, natural_width_item); - Gtk::Requisition req2; - Gtk::Requisition req2_natural; - const_cast<Gtk::Widget*>(item)->get_preferred_size(req2, req2_natural); + // Calculate columns and rows. + if (natural_width_item < 1) { + natural_width_item = 1; + } + ncols = width_scroller / natural_width_item - 1; + nrows = itemCount / ncols; - int h2 = ((req2.height > 0) && (req.height > req2.height)) ? (req.height / req2.height) : 1; - int w2 = ((req2.width > 0) && (req.width > req2.width)) ? (req.width / req2.width) : 1; - ncols = (itemCount + (h2 - 1)) / h2; - if ( ncols < w2 ) { - ncols = w2; + // On first run, scroller width is not set correct... so we need to fudge it: + if (ncols < 2) { + ncols = itemCount/2; + nrows = 2; + } } } else { - ncols = (_baseSize == PREVIEW_SIZE_SMALL || _baseSize == PREVIEW_SIZE_TINY) ? COLUMNS_FOR_SMALL : COLUMNS_FOR_LARGE; + ncols = (_baseSize == PREVIEW_SIZE_SMALL || _baseSize == PREVIEW_SIZE_TINY) ? + COLUMNS_FOR_SMALL : COLUMNS_FOR_LARGE; if ( _prefCols > 0 ) { ncols = _prefCols; } @@ -335,76 +336,73 @@ void PreviewHolder::calcGridSize( const Gtk::Widget* item, int itemCount, int& n void PreviewHolder::rebuildUI() { - _scroller->remove(); - _insides = 0; // remove() call should have deleted the Gtk::Table. - - switch(_view) { - case VIEW_TYPE_LIST: - { - _insides = Gtk::manage(new Gtk::Grid()); - _insides->set_column_spacing(8); + auto children = _insides->get_children(); + for (auto child : children) { + _insides->remove(*child); + } - if (_border == BORDER_WIDE) { - _insides->set_row_spacing(1); - } + _insides->set_column_spacing(0); + _insides->set_row_spacing(0); + if (_border == BORDER_WIDE) { + _insides->set_column_spacing(1); + _insides->set_row_spacing(1); + } - for ( unsigned int i = 0; i < items.size(); i++ ) { - Gtk::Widget* label = Gtk::manage(items[i]->getPreview(PREVIEW_STYLE_BLURB, _view, _baseSize, _ratio, _border)); - //label->set_alignment(Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER); + switch (_view) { + case VIEW_TYPE_LIST: + { + _insides->set_column_spacing(8); - Gtk::Widget* item = Gtk::manage(items[i]->getPreview(PREVIEW_STYLE_PREVIEW, _view, _baseSize, _ratio, _border)); + for ( unsigned int i = 0; i < items.size(); i++ ) { + Gtk::Widget* label = Gtk::manage(items[i]->getPreview(PREVIEW_STYLE_BLURB, _view, _baseSize, _ratio, _border)); + //label->set_alignment(Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER); - item->set_hexpand(); - item->set_vexpand(); - _insides->attach(*item, 0, i, 1, 1); + Gtk::Widget* item = Gtk::manage(items[i]->getPreview(PREVIEW_STYLE_PREVIEW, _view, _baseSize, _ratio, _border)); - label->set_hexpand(); - label->set_valign(Gtk::ALIGN_CENTER); - _insides->attach(*label, 1, i, 1, 1); - } + item->set_hexpand(); + item->set_vexpand(); + _insides->attach(*item, 0, i, 1, 1); - _scroller->add( *_insides ); + label->set_hexpand(); + label->set_valign(Gtk::ALIGN_CENTER); + _insides->attach(*label, 1, i, 1, 1); } - break; + } + break; case VIEW_TYPE_GRID: - { - int col = 0; - int row = 0; - int ncols = 2; - int nrows = 1; - - for ( unsigned int i = 0; i < items.size(); i++ ) { + { + int col = 0; + int row = 0; + int ncols = 2; + int nrows = 1; - // If this is the last row, flag so the previews can draw a bottom - ::BorderStyle border = ((row == nrows -1) && (_border == BORDER_SOLID)) ? BORDER_SOLID_LAST_ROW : _border; - Gtk::Widget* item = Gtk::manage(items[i]->getPreview(PREVIEW_STYLE_PREVIEW, _view, _baseSize, _ratio, border)); + for ( unsigned int i = 0; i < items.size(); i++ ) { - if ( !_insides ) { - calcGridSize( item, items.size(), ncols, nrows ); + // If this is the last row, flag so the previews can draw a bottom + ::BorderStyle border = ((row == nrows -1) && (_border == BORDER_SOLID)) ? + BORDER_SOLID_LAST_ROW : _border; - _insides = Gtk::manage(new Gtk::Grid()); - if (_border == BORDER_WIDE) { - _insides->set_column_spacing(1); - _insides->set_row_spacing(1); - } - } + Gtk::Widget* item = Gtk::manage(items[i]->getPreview(PREVIEW_STYLE_PREVIEW, _view, _baseSize, _ratio, border)); + item->set_hexpand(false); + item->set_vexpand(false); - item->set_hexpand(); - item->set_vexpand(); + if (i == 0) { + // We need one item shown before we can call calcGridSize()... + _insides->attach( *item, 0, 0, 1, 1); + _scroller->show_all_children(); + calcGridSize( item, items.size(), ncols, nrows ); + } else { + // We've already calculated grid size. _insides->attach( *item, col, row, 1, 1); - - if ( ++col >= ncols ) { - col = 0; - row++; - } - } - if ( !_insides ) { - _insides = Gtk::manage(new Gtk::Grid()); } - _scroller->add( *_insides ); + if ( ++col >= ncols ) { + col = 0; + row++; + } } + } } _scroller->show_all_children(); |
