Skip to content
Snippets Groups Projects
Commit 00f66ccf authored by Richard Linden's avatar Richard Linden
Browse files

EXP-1239 WIP make toolbars wrap when there is not enough room

added more toolbars to floater_test_toolbar.xml
removed layout stack and got basic wrapping working
reviewed by Leslie
parent e70714fc
No related branches found
No related tags found
No related merge requests found
...@@ -57,8 +57,8 @@ LLToolBar::Params::Params() ...@@ -57,8 +57,8 @@ LLToolBar::Params::Params()
button_icon("button_icon"), button_icon("button_icon"),
button_icon_and_text("button_icon_and_text"), button_icon_and_text("button_icon_and_text"),
wrap("wrap", true), wrap("wrap", true),
min_width("min_width", 0), min_button_width("min_button_width", 0),
max_width("max_width", S32_MAX), max_button_width("max_button_width", S32_MAX),
background_image("background_image") background_image("background_image")
{} {}
...@@ -70,8 +70,8 @@ LLToolBar::LLToolBar(const Params& p) ...@@ -70,8 +70,8 @@ LLToolBar::LLToolBar(const Params& p)
mNeedsLayout(false), mNeedsLayout(false),
mCenterPanel(NULL), mCenterPanel(NULL),
mCenteringStack(NULL), mCenteringStack(NULL),
mMinWidth(p.min_width), mMinButtonWidth(p.min_button_width),
mMaxWidth(p.max_width), mMaxButtonWidth(p.max_button_width),
mBackgroundImage(p.background_image) mBackgroundImage(p.background_image)
{ {
} }
...@@ -108,120 +108,148 @@ void LLToolBar::initFromParams(const LLToolBar::Params& p) ...@@ -108,120 +108,148 @@ void LLToolBar::initFromParams(const LLToolBar::Params& p)
mCenteringStack->addChild(LLUICtrlFactory::create<LLLayoutPanel>(border_panel_p)); mCenteringStack->addChild(LLUICtrlFactory::create<LLLayoutPanel>(border_panel_p));
addRow();
BOOST_FOREACH (LLToolBarButton::Params button_p, p.buttons) BOOST_FOREACH (LLToolBarButton::Params button_p, p.buttons)
{ {
// buttons always follow left and top, for all orientations
button_p.follows.flags = FOLLOWS_LEFT|FOLLOWS_TOP;
button_p.fillFrom((mButtonType == BTNTYPE_ICONS_ONLY)
? p.button_icon // icon only
: p.button_icon_and_text); // icon + text
LLRect button_rect(button_p.rect); LLRect button_rect(button_p.rect);
{ // remove any offset from button { // remove any offset from button
if (orientation == LLLayoutStack::HORIZONTAL) if (orientation == LLLayoutStack::HORIZONTAL)
{ {
button_rect.setOriginAndSize(0, 0, mMinWidth, getRect().getHeight()); button_rect.setOriginAndSize(0, 0, mMinButtonWidth, button_rect.getHeight());
} }
else // VERTICAL else // VERTICAL
{ {
button_rect.setOriginAndSize(0, 0, mMinWidth, button_rect.getHeight()); button_rect.setOriginAndSize(0, 0, mMinButtonWidth, button_rect.getHeight());
} }
} }
button_p.fillFrom((mButtonType == BTNTYPE_ICONS_ONLY) // use our calculated rect
? p.button_icon // icon only button_p.rect = button_rect;
: p.button_icon_and_text); // icon + text LLToolBarButton* buttonp = LLUICtrlFactory::create<LLToolBarButton>(button_p);
mButtons.push_back(buttonp);
mCenterPanel->addChild(buttonp);
mButtons.push_back(LLUICtrlFactory::create<LLToolBarButton>(button_p));
mNeedsLayout = true; mNeedsLayout = true;
} }
updateLayout();
} }
void LLToolBar::addButton(LLToolBarButton* buttonp) void LLToolBar::updateLayoutAsNeeded()
{ {
LLLayoutPanel::Params panel_p; if (!mNeedsLayout) return;
panel_p.name = buttonp->getName() + "_panel";
panel_p.user_resize = false;
panel_p.auto_resize= false;
panel_p.fit_content = true;
LLLayoutPanel* panel = LLUICtrlFactory::create<LLLayoutPanel>(panel_p); LLLayoutStack::ELayoutOrientation orientation = getOrientation(mSideType);
panel->addChild(buttonp);
mStacks.back()->addChild(panel);
}
void LLToolBar::updateLayout() // our terminology for orientation-agnostic layout is that
{ // length refers to a distance in the direction we stack the buttons
mCenteringStack->updateLayout(); // and girth refers to a distance in the direction buttons wrap
S32 total_length = 0;
S32 max_length = (orientation == LLLayoutStack::HORIZONTAL)
? getRect().getWidth()
: getRect().getHeight();
S32 max_row_girth = 0;
S32 cur_start = 0;
S32 cur_row = 0;
if (!mNeedsLayout) return; LLRect panel_rect = mCenterPanel->getLocalRect();
mNeedsLayout = false;
{ // clean up existing rows std::vector<LLToolBarButton*> buttons_in_row;
BOOST_FOREACH(LLToolBarButton* button, mButtons)
{ BOOST_FOREACH(LLToolBarButton* button, mButtons)
if (button->getParent()) {
S32 button_clamped_width = llclamp(button->getRect().getWidth(), mMinButtonWidth, mMaxButtonWidth);
S32 button_length = (orientation == LLLayoutStack::HORIZONTAL)
? button_clamped_width
: button->getRect().getHeight();
S32 button_girth = (orientation == LLLayoutStack::HORIZONTAL)
? button->getRect().getHeight()
: button_clamped_width;
// handle wrapping
if (total_length + button_length > max_length
&& cur_start != 0) // not first button in row
{ // go ahead and wrap
if (orientation == LLLayoutStack::VERTICAL)
{
// row girth is clamped to allowable button widths
max_row_girth = llclamp(max_row_girth, mMinButtonWidth, mMaxButtonWidth);
}
// make buttons in current row all same girth
BOOST_FOREACH(LLToolBarButton* button, buttons_in_row)
{ {
button->getParent()->removeChild(button); if (orientation == LLLayoutStack::HORIZONTAL)
{
button->reshape(llclamp(button->getRect().getWidth(), mMinButtonWidth, mMaxButtonWidth), max_row_girth);
}
else // VERTICAL
{
button->reshape(max_row_girth, button->getRect().getHeight());
}
} }
} buttons_in_row.clear();
BOOST_FOREACH(LLLayoutStack* stack, mStacks) total_length = 0;
{ cur_start = 0;
delete stack; cur_row += max_row_girth;
max_row_girth = 0;
} }
mStacks.clear();
}
// start with one row of buttons
addRow();
S32 total_width = 0, total_height = 0;
S32 max_total_width = 0, max_total_height = 0;
S32 max_width = getRect().getWidth(), max_height = getRect().getHeight();
BOOST_FOREACH(LLToolBarButton* button, mButtons)
{
S32 button_width = button->getRect().getWidth();
S32 button_height = button->getRect().getHeight();
if (getOrientation(mSideType) == LLLayoutStack::HORIZONTAL LLRect button_rect;
&& total_width + button_height > getRect().getWidth()) if (orientation == LLLayoutStack::HORIZONTAL)
{
button_rect.setLeftTopAndSize(cur_start, panel_rect.mTop - cur_row, button_clamped_width, button->getRect().getHeight());
}
else // VERTICAL
{ {
addRow(); button_rect.setLeftTopAndSize(cur_row, panel_rect.mTop - cur_start, button_clamped_width, button->getRect().getHeight());
total_width = 0;
} }
addButton(button); button->setShape(button_rect);
total_width += button_width; buttons_in_row.push_back(button);
total_height += button_height;
max_total_width = llmax(max_total_width, total_width); total_length += button_length;
max_total_height = llmax(max_total_height, total_height); cur_start = total_length;
max_width = llmax(button->getRect().getWidth(), max_width); max_row_girth = llmax(button_girth, max_row_girth);
max_height = llmax(button->getRect().getHeight(), max_height);
} }
if (getOrientation(mSideType) == LLLayoutStack::HORIZONTAL) // final resizing in "girth" direction
S32 total_girth = cur_row + max_row_girth; // increment by size of final row
// grow and optionally shift toolbar to accomodate buttons
if (orientation == LLLayoutStack::HORIZONTAL)
{ {
BOOST_FOREACH(LLLayoutStack* stack, mStacks) if (mSideType == SIDE_TOP)
{ { // shift down to maintain top edge
stack->reshape(max_total_width, stack->getParent()->getRect().getHeight()); translate(0, getRect().getHeight() - total_girth);
stack->updateLayout();
} }
reshape(getRect().getWidth(), total_girth);
} }
else else // VERTICAL
{ {
BOOST_FOREACH(LLLayoutStack* stack, mStacks) if (mSideType == SIDE_RIGHT)
{ { // shift left to maintain right edge
stack->reshape(stack->getParent()->getRect().getWidth(), max_total_height); translate(getRect().getWidth() - total_girth, 0);
stack->updateLayout();
} }
reshape(total_girth, getRect().getHeight());
reshape(max_total_width, getRect().getHeight());
} }
// recenter toolbar buttons
mCenteringStack->updateLayout();
// don't clear flag until after we've resized ourselves, to avoid laying out every frame
mNeedsLayout = false;
} }
void LLToolBar::draw() void LLToolBar::draw()
{ {
updateLayout(); updateLayoutAsNeeded();
{ // draw background { // draw background
LLRect bg_rect; LLRect bg_rect;
...@@ -231,22 +259,6 @@ void LLToolBar::draw() ...@@ -231,22 +259,6 @@ void LLToolBar::draw()
LLUICtrl::draw(); LLUICtrl::draw();
} }
void LLToolBar::addRow()
{
LLLayoutStack::ELayoutOrientation orientation = getOrientation(mSideType);
LLLayoutStack::Params stack_p;
stack_p.rect = getLocalRect();
stack_p.name = llformat("button_stack_%d", mStacks.size());
stack_p.orientation = orientation;
stack_p.follows.flags = (orientation == LLLayoutStack::HORIZONTAL)
? (FOLLOWS_TOP|FOLLOWS_BOTTOM) // horizontal
: (FOLLOWS_LEFT|FOLLOWS_RIGHT); // vertical
mStacks.push_back(LLUICtrlFactory::create<LLLayoutStack>(stack_p));
mCenterPanel->addChild(mStacks.back());
}
void LLToolBar::reshape(S32 width, S32 height, BOOL called_from_parent) void LLToolBar::reshape(S32 width, S32 height, BOOL called_from_parent)
{ {
LLUICtrl::reshape(width, height, called_from_parent); LLUICtrl::reshape(width, height, called_from_parent);
......
...@@ -93,8 +93,8 @@ class LLToolBar ...@@ -93,8 +93,8 @@ class LLToolBar
button_icon_and_text; button_icon_and_text;
Optional<bool> wrap; Optional<bool> wrap;
Optional<S32> min_width, Optional<S32> min_button_width,
max_width; max_button_width;
// get rid of this // get rid of this
Multiple<LLToolBarButton::Params> buttons; Multiple<LLToolBarButton::Params> buttons;
...@@ -112,11 +112,9 @@ class LLToolBar ...@@ -112,11 +112,9 @@ class LLToolBar
LLToolBar(const Params&); LLToolBar(const Params&);
void initFromParams(const Params&); void initFromParams(const Params&);
void addButton(LLToolBarButton* buttonp);
void updateLayout();
private: private:
void addRow(); void updateLayoutAsNeeded();
std::list<LLToolBarButton*> mButtons; std::list<LLToolBarButton*> mButtons;
LLToolBarEnums::ButtonType mButtonType; LLToolBarEnums::ButtonType mButtonType;
...@@ -125,11 +123,10 @@ class LLToolBar ...@@ -125,11 +123,10 @@ class LLToolBar
LLLayoutPanel* mCenterPanel; LLLayoutPanel* mCenterPanel;
LLToolBarEnums::SideType mSideType; LLToolBarEnums::SideType mSideType;
std::vector<LLLayoutStack*> mStacks;
bool mWrap; bool mWrap;
bool mNeedsLayout; bool mNeedsLayout;
S32 mMinWidth, S32 mMinButtonWidth,
mMaxWidth; mMaxButtonWidth;
LLUIImagePtr mBackgroundImage; LLUIImagePtr mBackgroundImage;
}; };
......
...@@ -31,16 +31,9 @@ ...@@ -31,16 +31,9 @@
static LLDefaultChildRegistry::Register<LLDragAndDropButton> r("dnd_button"); static LLDefaultChildRegistry::Register<LLDragAndDropButton> r("dnd_button");
LLDragAndDropButton::Params::Params()
{
}
LLDragAndDropButton::LLDragAndDropButton(const Params& params) LLDragAndDropButton::LLDragAndDropButton(const Params& params)
: LLButton(params) : LLButton(params)
{ {}
}
BOOL LLDragAndDropButton::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept, std::string& tooltip_msg) BOOL LLDragAndDropButton::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept, std::string& tooltip_msg)
{ {
......
...@@ -43,10 +43,7 @@ ...@@ -43,10 +43,7 @@
class LLDragAndDropButton : public LLButton class LLDragAndDropButton : public LLButton
{ {
public: public:
struct Params : public LLInitParam::Block<Params, LLButton::Params> struct Params : public LLInitParam::Block<Params, LLButton::Params> {};
{
Params();
};
LLDragAndDropButton(const Params& params); LLDragAndDropButton(const Params& params);
......
...@@ -7,33 +7,64 @@ ...@@ -7,33 +7,64 @@
name="floater_test_toolbar" name="floater_test_toolbar"
translate="false" translate="false"
width="500"> width="500">
<toolbar name="test_toolbar_horizontal" <toolbar name="test_toolbar_top"
follows="left|right|top" follows="left|right|top"
height="50" height="50"
width="500" width="500"
left="0" left="0"
top="20" top="20"
min_width="100"
side="top"> side="top">
<button auto_resize="true" <button auto_resize="true"
label="Button 1"/> label="Button"/>
<button auto_resize="true" <button auto_resize="true"
label="Button with long label"/> label="Button with long label"/>
<button auto_resize="true" <button auto_resize="true"
label="Button with longest label of all"/> label="Button with longest label of all"/>
</toolbar> </toolbar>
<toolbar name="test_toolbar_vertical" <toolbar name="test_toolbar_left"
follows="left|bottom|top" follows="left|bottom|top"
height="430" height="380"
width="100" width="100"
left="0" left="0"
top="70" top="70"
min_width="100"
side="left"> side="left">
<button height="30" <button height="30"
label="Button 1"/> label="Button"/>
<button height="50" <button height="50"
label="Button 2"/> label="Button with long label"/>
<button height="60" <button height="60"
label="Button 3"/> label="Button with longest label of all"/>
</toolbar>
<toolbar name="test_toolbar_right"
follows="right|bottom|top"
height="380"
width="100"
right="500"
top="70"
min_width="100"
side="right">
<button auto_resize="true"
label="Button 1"/>
<button auto_resize="true"
label="Button with long label"/>
<button auto_resize="true"
label="Button with longest label of all"/>
</toolbar>
<toolbar name="test_toolbar_bottom"
follows="left|right|bottom"
height="50"
width="500"
left="0"
bottom="500"
min_width="100"
side="bottom">
<button auto_resize="true"
label="Button"/>
<button auto_resize="true"
label="Button with long label"/>
<button auto_resize="true"
label="Button with longest label of all"/>
</toolbar> </toolbar>
</floater> </floater>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment