diff --git a/changes.txt b/changes.txt index ff7442f2..69c7af5f 100644 --- a/changes.txt +++ b/changes.txt @@ -1,5 +1,9 @@ -------------------------- Changes in 1.9 (not yet released) +- CGUIListbox, CGUITreeView and CGUITable now resize scrollbars when EGDS_SCROLLBAR_SIZE in the skin changes without having to re-create the elements. + This also fixes the problem that drawing looked wrong when this value got changed after the elements were created. + Thanks @LunaRebirth for reporting. (Forum: http://irrlicht.sourceforge.net/forum/viewtopic.php?f=1&t=52297&p=303682#p303682) +- Scrollbar buttons can no longer get larger than half the ScrollBar element to avoid them overlapping. - Add IVideoDriver::swapMaterialRenderers to allow swapping the renderer used to render a certain material. - IMeshManipulator functions createMeshWith1TCoords, createMeshWith2TCoords and createMeshWithTangents no longer weld vertices while converting meshes. Use IMeshManipulator::createMeshWelded if you need that welding. - Add ITerrainSceneNode::setFixedBorderLOD to handle connecting terrain nodes without gaps. Thanks @diho for the bugreport, testcase and a patch proposal (http://irrlicht.sourceforge.net/forum/viewtopic.php?f=9&t=51220). diff --git a/include/IGUISkin.h b/include/IGUISkin.h index d7cadcd4..bd2de6b5 100644 --- a/include/IGUISkin.h +++ b/include/IGUISkin.h @@ -163,7 +163,7 @@ namespace gui EGDS_MESSAGE_BOX_HEIGHT, //! width of a default button EGDS_BUTTON_WIDTH, - //! height of a default button + //! height of a default button (OK and cancel buttons) EGDS_BUTTON_HEIGHT, //! distance for text from background EGDS_TEXT_DISTANCE_X, diff --git a/source/Irrlicht/CGUIListBox.cpp b/source/Irrlicht/CGUIListBox.cpp index 740f3228..fde30e6a 100644 --- a/source/Irrlicht/CGUIListBox.cpp +++ b/source/Irrlicht/CGUIListBox.cpp @@ -25,7 +25,7 @@ CGUIListBox::CGUIListBox(IGUIEnvironment* environment, IGUIElement* parent, bool drawBack, bool moveOverSelect) : IGUIListBox(environment, parent, id, rectangle), Selected(-1), ItemHeight(0),ItemHeightOverride(0), - TotalItemHeight(0), ItemsIconWidth(0), Font(0), IconBank(0), + TotalItemHeight(0), ItemsIconWidth(0), ScrollBarSize(0), Font(0), IconBank(0), ScrollBar(0), selectTime(0), LastKeyTime(0), Selecting(false), DrawBack(drawBack), MoveOverSelect(moveOverSelect), AutoScroll(true), HighlightWhenNotFocused(true) { @@ -34,10 +34,10 @@ CGUIListBox::CGUIListBox(IGUIEnvironment* environment, IGUIElement* parent, #endif IGUISkin* skin = Environment->getSkin(); - const s32 s = skin->getSize(EGDS_SCROLLBAR_SIZE); + ScrollBarSize = skin->getSize(EGDS_SCROLLBAR_SIZE); ScrollBar = new CGUIScrollBar(false, Environment, this, -1, - core::rect(RelativeRect.getWidth() - s, 0, RelativeRect.getWidth(), RelativeRect.getHeight()), + core::rect(RelativeRect.getWidth() - ScrollBarSize, 0, RelativeRect.getWidth(), RelativeRect.getHeight()), !clip); ScrollBar->setSubElement(true); ScrollBar->setTabStop(false); @@ -190,7 +190,6 @@ void CGUIListBox::recalculateItemHeight() ScrollBar->setVisible(true); } - //! returns id of selected item. returns -1 if no item is selected. s32 CGUIListBox::getSelected() const { @@ -498,6 +497,7 @@ void CGUIListBox::draw() recalculateItemHeight(); // if the font changed IGUISkin* skin = Environment->getSkin(); + updateScrollBarSize(skin->getSize(EGDS_SCROLLBAR_SIZE)); core::rect* clipRect = 0; @@ -510,7 +510,7 @@ void CGUIListBox::draw() clientClip.UpperLeftCorner.Y += 1; clientClip.UpperLeftCorner.X += 1; if (ScrollBar->isVisible()) - clientClip.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X - skin->getSize(EGDS_SCROLLBAR_SIZE); + clientClip.LowerRightCorner.X -= ScrollBarSize; clientClip.LowerRightCorner.Y -= 1; clientClip.clipAgainst(AbsoluteClippingRect); @@ -523,7 +523,7 @@ void CGUIListBox::draw() frameRect = AbsoluteRect; frameRect.UpperLeftCorner.X += 1; if (ScrollBar->isVisible()) - frameRect.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X - skin->getSize(EGDS_SCROLLBAR_SIZE); + frameRect.LowerRightCorner.X -= ScrollBarSize; frameRect.LowerRightCorner.Y = AbsoluteRect.UpperLeftCorner.Y + ItemHeight; @@ -640,6 +640,15 @@ void CGUIListBox::recalculateScrollPos() } } +void CGUIListBox::updateScrollBarSize(s32 size) +{ + if ( size != ScrollBarSize ) + { + ScrollBarSize = size; + core::recti r(RelativeRect.getWidth() - ScrollBarSize, 0, RelativeRect.getWidth(), RelativeRect.getHeight()); + ScrollBar->setRelativePosition(r); + } +} void CGUIListBox::setAutoScrollEnabled(bool scroll) { diff --git a/source/Irrlicht/CGUIListBox.h b/source/Irrlicht/CGUIListBox.h index a94b7932..6219325a 100644 --- a/source/Irrlicht/CGUIListBox.h +++ b/source/Irrlicht/CGUIListBox.h @@ -157,6 +157,7 @@ namespace gui void recalculateItemHeight(); void selectNew(s32 ypos, bool onlyHover=false); void recalculateScrollPos(); + void updateScrollBarSize(s32 size); // extracted that function to avoid copy&paste code void recalculateItemWidth(s32 icon); @@ -170,6 +171,7 @@ namespace gui s32 ItemHeightOverride; s32 TotalItemHeight; s32 ItemsIconWidth; + s32 ScrollBarSize; gui::IGUIFont* Font; gui::IGUISpriteBank* IconBank; gui::IGUIScrollBar* ScrollBar; diff --git a/source/Irrlicht/CGUITable.cpp b/source/Irrlicht/CGUITable.cpp index fac733b6..a0f1ced8 100644 --- a/source/Irrlicht/CGUITable.cpp +++ b/source/Irrlicht/CGUITable.cpp @@ -33,6 +33,7 @@ CGUITable::CGUITable(IGUIEnvironment* environment, IGUIElement* parent, ItemHeight(0), TotalItemHeight(0), TotalItemWidth(0), Selected(-1), CellHeightPadding(2), CellWidthPadding(5), ActiveTab(-1), CurrentOrdering(EGOM_NONE), DrawFlags(EGTDF_ROWS | EGTDF_COLUMNS | EGTDF_ACTIVE_ROW ), + ScrollBarSize(0), OverrideFont(0) { #ifdef _DEBUG @@ -436,7 +437,8 @@ void CGUITable::checkScrollbars() if ( !HorizontalScrollBar || !VerticalScrollBar || !skin) return; - s32 scrollBarSize = skin->getSize(EGDS_SCROLLBAR_SIZE); + ScrollBarSize = skin->getSize(EGDS_SCROLLBAR_SIZE); + bool wasHorizontalScrollBarVisible = HorizontalScrollBar->isVisible(); bool wasVerticalScrollBarVisible = VerticalScrollBar->isVisible(); HorizontalScrollBar->setVisible(false); @@ -456,7 +458,7 @@ void CGUITable::checkScrollbars() // needs horizontal scroll be visible? if( TotalItemWidth > clientClip.getWidth() ) { - clientClip.LowerRightCorner.Y -= scrollBarSize; + clientClip.LowerRightCorner.Y -= ScrollBarSize; HorizontalScrollBar->setVisible(true); HorizontalScrollBar->setMax(core::max_(0,TotalItemWidth - clientClip.getWidth())); } @@ -464,7 +466,7 @@ void CGUITable::checkScrollbars() // needs vertical scroll be visible? if( TotalItemHeight > clientClip.getHeight() ) { - clientClip.LowerRightCorner.X -= scrollBarSize; + clientClip.LowerRightCorner.X -= ScrollBarSize; VerticalScrollBar->setVisible(true); VerticalScrollBar->setMax(core::max_(0,TotalItemHeight - clientClip.getHeight())); @@ -473,7 +475,7 @@ void CGUITable::checkScrollbars() { if( TotalItemWidth > clientClip.getWidth() ) { - clientClip.LowerRightCorner.Y -= scrollBarSize; + clientClip.LowerRightCorner.Y -= ScrollBarSize; HorizontalScrollBar->setVisible(true); HorizontalScrollBar->setMax(core::max_(0,TotalItemWidth - clientClip.getWidth())); } @@ -489,13 +491,13 @@ void CGUITable::checkScrollbars() if ( HorizontalScrollBar->isVisible() ) { VerticalScrollBar->setRelativePosition( - core::rect(RelativeRect.getWidth() - scrollBarSize, 1, - RelativeRect.getWidth()-1, RelativeRect.getHeight()-(1+scrollBarSize) ) ); + core::rect(RelativeRect.getWidth() - ScrollBarSize, 1, + RelativeRect.getWidth()-1, RelativeRect.getHeight()-(1+ScrollBarSize) ) ); } else { VerticalScrollBar->setRelativePosition( - core::rect(RelativeRect.getWidth() - scrollBarSize, 1, + core::rect(RelativeRect.getWidth() - ScrollBarSize, 1, RelativeRect.getWidth()-1, RelativeRect.getHeight()-1) ); } } @@ -508,11 +510,11 @@ void CGUITable::checkScrollbars() if ( VerticalScrollBar->isVisible() ) { - HorizontalScrollBar->setRelativePosition( core::rect(1, RelativeRect.getHeight() - scrollBarSize, RelativeRect.getWidth()-(1+scrollBarSize), RelativeRect.getHeight()-1) ); + HorizontalScrollBar->setRelativePosition( core::rect(1, RelativeRect.getHeight() - ScrollBarSize, RelativeRect.getWidth()-(1+ScrollBarSize), RelativeRect.getHeight()-1) ); } else { - HorizontalScrollBar->setRelativePosition( core::rect(1, RelativeRect.getHeight() - scrollBarSize, RelativeRect.getWidth()-1, RelativeRect.getHeight()-1) ); + HorizontalScrollBar->setRelativePosition( core::rect(1, RelativeRect.getHeight() - ScrollBarSize, RelativeRect.getWidth()-1, RelativeRect.getHeight()-1) ); } } } @@ -864,15 +866,18 @@ void CGUITable::draw() if (!font) return; + if ( ScrollBarSize != skin->getSize(EGDS_SCROLLBAR_SIZE) ) + checkScrollbars(); + // CAREFUL: near identical calculations for tableRect and clientClip are also done in checkScrollbars and selectColumnHeader // Area of table used for drawing without scrollbars core::rect tableRect(AbsoluteRect); tableRect.UpperLeftCorner.X += 1; tableRect.UpperLeftCorner.Y += 1; if ( VerticalScrollBar && VerticalScrollBar->isVisible() ) - tableRect.LowerRightCorner.X -= skin->getSize(EGDS_SCROLLBAR_SIZE); + tableRect.LowerRightCorner.X -= ScrollBarSize; if ( HorizontalScrollBar && HorizontalScrollBar->isVisible() ) - tableRect.LowerRightCorner.Y -= skin->getSize(EGDS_SCROLLBAR_SIZE); + tableRect.LowerRightCorner.Y -= ScrollBarSize; s32 headerBottom = tableRect.UpperLeftCorner.Y + ItemHeight; @@ -910,7 +915,7 @@ void CGUITable::draw() if (rowRect.LowerRightCorner.Y >= AbsoluteRect.UpperLeftCorner.Y && rowRect.UpperLeftCorner.Y <= AbsoluteRect.LowerRightCorner.Y) { - // draw row seperator + // draw row separator if ( DrawFlags & EGTDF_ROWS ) { core::rect lineRect(rowRect); @@ -966,7 +971,7 @@ void CGUITable::draw() // draw column background skin->draw3DButtonPaneStandard(this, columnrect, &tableClip); - // draw column seperator + // draw column separator if ( DrawFlags & EGTDF_COLUMNS ) { columnSeparator.UpperLeftCorner.X = pos; diff --git a/source/Irrlicht/CGUITable.h b/source/Irrlicht/CGUITable.h index 29e66133..f325f49f 100644 --- a/source/Irrlicht/CGUITable.h +++ b/source/Irrlicht/CGUITable.h @@ -179,8 +179,8 @@ namespace gui virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) _IRR_OVERRIDE_; protected: - virtual void refreshControls(); - virtual void checkScrollbars(); + void refreshControls(); + void checkScrollbars(); private: @@ -240,6 +240,7 @@ namespace gui s32 ActiveTab; EGUI_ORDERING_MODE CurrentOrdering; s32 DrawFlags; + s32 ScrollBarSize; gui::IGUIFont* OverrideFont; }; diff --git a/source/Irrlicht/CGUITreeView.cpp b/source/Irrlicht/CGUITreeView.cpp index 7a7accf5..f6d7743a 100644 --- a/source/Irrlicht/CGUITreeView.cpp +++ b/source/Irrlicht/CGUITreeView.cpp @@ -432,6 +432,7 @@ CGUITreeView::CGUITreeView(IGUIEnvironment* environment, IGUIElement* parent, IndentWidth( 0 ), TotalItemHeight( 0 ), TotalItemWidth ( 0 ), + ScrollBarSize( 0 ), Font( 0 ), OverrideFont( 0 ), IconFont( 0 ), @@ -450,15 +451,15 @@ CGUITreeView::CGUITreeView(IGUIEnvironment* environment, IGUIElement* parent, #endif IGUISkin* skin = Environment->getSkin(); - s32 s = skin->getSize( EGDS_SCROLLBAR_SIZE ); + ScrollBarSize = skin->getSize( EGDS_SCROLLBAR_SIZE ); if ( scrollBarVertical ) { ScrollBarV = new CGUIScrollBar( false, Environment, this, -1, - core::rect( RelativeRect.getWidth() - s, + core::rect( RelativeRect.getWidth() - ScrollBarSize, 0, RelativeRect.getWidth(), - RelativeRect.getHeight() - s + RelativeRect.getHeight() - ScrollBarSize ), !clip ); ScrollBarV->drop(); @@ -471,8 +472,8 @@ CGUITreeView::CGUITreeView(IGUIEnvironment* environment, IGUIElement* parent, { ScrollBarH = new CGUIScrollBar( true, Environment, this, -1, core::rect( 0, - RelativeRect.getHeight() - s, - RelativeRect.getWidth() - s, + RelativeRect.getHeight() - ScrollBarSize, + RelativeRect.getWidth() - ScrollBarSize, RelativeRect.getHeight() ), !clip ); ScrollBarH->drop(); @@ -640,6 +641,28 @@ void CGUITreeView::recalculateItemHeight() } +void CGUITreeView::updateScrollBarSize(s32 size) +{ + if ( size != ScrollBarSize ) + { + ScrollBarSize = size; + + if ( ScrollBarV ) + { + core::recti r(RelativeRect.getWidth() - ScrollBarSize, 0, + RelativeRect.getWidth(), RelativeRect.getHeight() - ScrollBarSize); + ScrollBarV->setRelativePosition(r); + } + + if ( ScrollBarH ) + { + core::recti r(0, RelativeRect.getHeight() - ScrollBarSize, + RelativeRect.getWidth() - ScrollBarSize, RelativeRect.getHeight()); + ScrollBarH->setRelativePosition(r); + } + } +} + //! called if an event happened. bool CGUITreeView::OnEvent( const SEvent &event ) { @@ -829,9 +852,11 @@ void CGUITreeView::draw() return; } + IGUISkin* skin = Environment->getSkin(); + + updateScrollBarSize(skin->getSize(EGDS_SCROLLBAR_SIZE)); recalculateItemHeight(); // if the font changed - IGUISkin* skin = Environment->getSkin(); irr::video::IVideoDriver* driver = Environment->getVideoDriver(); core::rect* clipRect = 0; @@ -876,9 +901,9 @@ void CGUITreeView::draw() clientClip.LowerRightCorner.Y -= 1; if ( ScrollBarV ) - clientClip.LowerRightCorner.X -= skin->getSize( EGDS_SCROLLBAR_SIZE ); + clientClip.LowerRightCorner.X -= ScrollBarSize; if ( ScrollBarH ) - clientClip.LowerRightCorner.Y -= skin->getSize( EGDS_SCROLLBAR_SIZE ); + clientClip.LowerRightCorner.Y -= ScrollBarSize; if( clipRect ) { @@ -886,7 +911,7 @@ void CGUITreeView::draw() } frameRect = AbsoluteRect; - frameRect.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X - skin->getSize( EGDS_SCROLLBAR_SIZE ); + frameRect.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X - ScrollBarSize; frameRect.LowerRightCorner.Y = AbsoluteRect.UpperLeftCorner.Y + ItemHeight; if ( ScrollBarV ) diff --git a/source/Irrlicht/CGUITreeView.h b/source/Irrlicht/CGUITreeView.h index 65cb21a1..bdcf035e 100644 --- a/source/Irrlicht/CGUITreeView.h +++ b/source/Irrlicht/CGUITreeView.h @@ -320,6 +320,9 @@ namespace gui //! calculates the heigth of an node and of all visible nodes. void recalculateItemHeight(); + //! Resize scrollbars when their size in the skin has changed + void updateScrollBarSize(s32 size); + //! executes an mouse action (like selectNew of CGUIListBox) void mouseAction( s32 xpos, s32 ypos, bool onlyHover = false ); @@ -329,6 +332,7 @@ namespace gui s32 IndentWidth; s32 TotalItemHeight; s32 TotalItemWidth; + s32 ScrollBarSize; IGUIFont* Font; gui::IGUIFont* OverrideFont; IGUIFont* IconFont;