Commit e78be8e3 authored by NiranV's avatar NiranV
Browse files

Added: Ability for icons to be repeated several times.

Added: Ability for dropdown comboboxes to use the new icon repeat functionality to create a new widget type allowing to select next/previous entries.
Added: Ability for list entries in comboboxes to each have their own separate tooltip.
parent bc6b3a72
......@@ -51,6 +51,8 @@
#include "lluictrlfactory.h"
#include "lltooltip.h"
#include "lliconctrl.h"
// Globals
S32 MAX_COMBO_WIDTH = 500;
......@@ -63,7 +65,8 @@ void LLComboBox::PreferredPositionValues::declareValues()
}
LLComboBox::ItemParams::ItemParams()
: label("label")
: label("label"),
tool_tip("tool_tip")
{
}
......@@ -78,7 +81,11 @@ LLComboBox::Params::Params()
combo_button("combo_button"),
combo_list("combo_list"),
combo_editor("combo_editor"),
drop_down_button("drop_down_button")
drop_down_button("drop_down_button"),
use_ticker("use_ticker", false),
combo_icon("combo_icon"),
combo_next_btn("combo_next_btn"),
combo_previous_btn("combo_previous_btn")
{
addSynonym(items, "combo_item");
}
......@@ -105,6 +112,8 @@ LLComboBox::LLComboBox(const LLComboBox::Params& p)
button_params.mouse_down_callback.function(
boost::bind(&LLComboBox::onButtonMouseDown, this));
button_params.follows.flags(FOLLOWS_LEFT|FOLLOWS_BOTTOM|FOLLOWS_RIGHT);
button_params.font_halign(LLFontGL::HCENTER);
button_params.rect(p.rect);
if(mAllowTextEntry)
......@@ -115,7 +124,6 @@ LLComboBox::LLComboBox(const LLComboBox::Params& p)
mArrowImage = button_params.image_unselected;
mButton = LLUICtrlFactory::create<LLButton>(button_params);
if(mAllowTextEntry)
{
......@@ -146,6 +154,7 @@ LLComboBox::LLComboBox(const LLComboBox::Params& p)
if (it->label.isProvided())
{
item_params.columns.add().value(it->label());
item_params.tool_tip(it->tool_tip());
}
mList->addRow(item_params);
......@@ -153,6 +162,43 @@ LLComboBox::LLComboBox(const LLComboBox::Params& p)
createLineEditor(p);
LLButton::Params prev_btn_params = p.combo_previous_btn;
prev_btn_params.mouse_down_callback.function(boost::bind(&LLComboBox::onPrevBtn, this));
LLRect ticker_btn_rect = getLocalRect();
ticker_btn_rect.mRight = ticker_btn_rect.mLeft + 16;
prev_btn_params.rect(ticker_btn_rect);
mPrevBtn = LLUICtrlFactory::create<LLButton>(prev_btn_params);
addChild(mPrevBtn);
mPrevBtn->setVisible(p.use_ticker);
LLIconCtrl::Params icon_p = p.combo_icon;
icon_p.name = "combo_ticker";
LLRect local_rect = getLocalRect();
local_rect.mTop = local_rect.mBottom + 5;
local_rect.mLeft += 16;
local_rect.mRight -= 16;
icon_p.rect = local_rect;
icon_p.repeats(p.items.size());
mIcon = LLUICtrlFactory::create<LLIconCtrl>(icon_p);
addChild(mIcon);
mIcon->setVisible(p.use_ticker);
LLButton::Params next_btn_params = p.combo_next_btn;
next_btn_params.mouse_down_callback.function(boost::bind(&LLComboBox::onNextBtn, this));
ticker_btn_rect.mLeft = local_rect.mRight;
ticker_btn_rect.mRight = ticker_btn_rect.mLeft + 16;
next_btn_params.rect(ticker_btn_rect);
mNextBtn = LLUICtrlFactory::create<LLButton>(next_btn_params);
addChild(mNextBtn);
mNextBtn->setVisible(p.use_ticker);
if (p.use_ticker)
{
LLRect btn_rect = mButton->getRect();
btn_rect.mBottom = local_rect.mTop;
mButton->setRect(btn_rect);
}
mTopLostSignalConnection = setTopLostCallback(boost::bind(&LLComboBox::hideList, this));
}
......@@ -172,6 +218,7 @@ BOOL LLComboBox::postBuild()
if (mControlVariable)
{
setValue(mControlVariable->getValue()); // selects the appropriate item
mIcon->setSelected(getCurrentIndex());
}
return TRUE;
}
......@@ -206,6 +253,7 @@ void LLComboBox::onCommit()
// the properly capitalized item
mTextEntry->setValue(getSimple());
mTextEntry->setTentative(FALSE);
mIcon->setSelected(getCurrentIndex());
}
setControlValue(getValue());
LLUICtrl::onCommit();
......@@ -252,6 +300,7 @@ LLScrollListItem* LLComboBox::add(const std::string& name, EAddPosition pos, BOO
selectFirstItem();
}
}
mIcon->setRepeats(mList->getChildCount());
return item;
}
......@@ -271,6 +320,7 @@ LLScrollListItem* LLComboBox::add(const std::string& name, const LLUUID& id, EAd
selectFirstItem();
}
}
mIcon->setRepeats(mList->getChildCount());
return item;
}
......@@ -291,6 +341,7 @@ LLScrollListItem* LLComboBox::add(const std::string& name, void* userdata, EAddP
selectFirstItem();
}
}
mIcon->setRepeats(mList->getChildCount());
return item;
}
......@@ -310,6 +361,7 @@ LLScrollListItem* LLComboBox::add(const std::string& name, LLSD value, EAddPosit
selectFirstItem();
}
}
mIcon->setRepeats(mList->getChildCount());
return item;
}
......@@ -351,6 +403,7 @@ void LLComboBox::setValue(const LLSD& value)
updateLabel();
}
mLastSelectedIndex = mList->getFirstSelectedIndex();
mIcon->setSelected(getCurrentIndex());
}
else
{
......@@ -447,7 +500,7 @@ BOOL LLComboBox::remove(const std::string& name)
}
mLastSelectedIndex = mList->getFirstSelectedIndex();
}
mIcon->setRepeats(mList->getChildCount());
return found;
}
......@@ -457,6 +510,7 @@ BOOL LLComboBox::remove(S32 index)
{
mList->deleteSingleItem(index);
setLabel(getSelectedItemLabel());
mIcon->setRepeats(mList->getChildCount());
return TRUE;
}
return FALSE;
......@@ -500,6 +554,7 @@ BOOL LLComboBox::setCurrentByIndex( S32 index )
{
setLabel(getSelectedItemLabel());
mLastSelectedIndex = index;
mIcon->setSelected(index);
}
return found;
}
......@@ -775,21 +830,25 @@ void LLComboBox::onItemSelected(const LLSD& data)
// commit does the reverse, asserting the value in the list
onCommit();
mIcon->setSelected(getCurrentIndex());
}
BOOL LLComboBox::handleToolTip(S32 x, S32 y, MASK mask)
{
std::string tool_tip;
if(LLUICtrl::handleToolTip(x, y, mask))
/*if(LLUICtrl::handleToolTip(x, y, mask))
{
return TRUE;
}
}*/
tool_tip = getToolTip();
if (tool_tip.empty())
{
tool_tip = getSelectedItemLabel();
LLScrollListItem* item = mList->getFirstSelected();
if (item)
tool_tip = item->getToolTip();
}
if( !tool_tip.empty() )
......@@ -821,6 +880,7 @@ BOOL LLComboBox::handleKeyHere(KEY key, MASK mask)
else if (key == KEY_DOWN && mLastSelectedIndex < mList->getItemCount())
++mLastSelectedIndex;
mIcon->setSelected(getCurrentIndex());
//BD - Don't show list when we simply select the next/previous entry.
return mList->handleKeyHere(key, mask);
}
......@@ -1001,6 +1061,7 @@ void LLComboBox::updateSelection()
{
mTextEntry->setTentative(FALSE);
mLastSelectedIndex = mList->getFirstSelectedIndex();
mIcon->setSelected(getCurrentIndex());
}
else if (mList->selectItemByPrefix(left_wstring, FALSE))
{
......@@ -1012,6 +1073,7 @@ void LLComboBox::updateSelection()
mTextEntry->setTentative(FALSE);
mHasAutocompletedText = TRUE;
mLastSelectedIndex = mList->getFirstSelectedIndex();
mIcon->setSelected(getCurrentIndex());
}
else // no matching items found
{
......@@ -1113,7 +1175,7 @@ BOOL LLComboBox::setCurrentByID(const LLUUID& id)
setLabel(getSelectedItemLabel());
mLastSelectedIndex = mList->getFirstSelectedIndex();
}
mIcon->setSelected(getCurrentIndex());
return found;
}
......@@ -1128,6 +1190,7 @@ BOOL LLComboBox::setSelectedByValue(const LLSD& value, BOOL selected)
{
setLabel(getSelectedItemLabel());
}
mIcon->setSelected(getCurrentIndex());
return found;
}
......@@ -1170,6 +1233,7 @@ BOOL LLComboBox::selectItemRange( S32 first, S32 last )
BOOL LLComboBox::handleScrollWheel(S32 x, S32 y, S32 clicks, MASK mask)
{
if (mList->getVisible()) return mList->handleScrollWheel(x, y, clicks, mask);
if (mask != MASK_CONTROL) return false;
if (mAllowTextEntry) // We might be editable
if (!mList->getFirstSelected()) // We aren't in the list, don't kill their text
return false;
......@@ -1209,4 +1273,27 @@ LLScrollListItem* LLComboBox::getItemByLabel(std::string label)
LLScrollListItem* LLComboBox::getItem(const LLSD& sd)
{
return mList->getItem(sd);
}
void LLComboBox::onNextBtn()
{
S32 i = getCurrentIndex();
S32 count = getItemCount() + 1;
++i;
if (i <= count)
selectNthItem(i);
mIcon->setSelected(getCurrentIndex());
onCommit();
}
void LLComboBox::onPrevBtn()
{
S32 i = getCurrentIndex();
--i;
if (i >= 0)
selectNthItem(i);
mIcon->setSelected(getCurrentIndex());
onCommit();
}
\ No newline at end of file
......@@ -38,6 +38,8 @@
#include "lllineeditor.h"
#include <boost/function.hpp>
#include "lliconctrl.h"
// Classes
class LLFontGL;
......@@ -62,6 +64,7 @@ class LLComboBox
struct ItemParams : public LLInitParam::Block<ItemParams, LLScrollListItem::Params>
{
Optional<std::string> label;
Optional<std::string> tool_tip;
ItemParams();
};
......@@ -70,7 +73,8 @@ class LLComboBox
{
Optional<bool> allow_text_entry,
show_text_as_tentative,
allow_new_values;
allow_new_values,
use_ticker;
Optional<S32> max_chars;
Optional<commit_callback_t> prearrange_callback,
text_entry_callback,
......@@ -79,7 +83,10 @@ class LLComboBox
Optional<EPreferredPosition, PreferredPositionValues> list_position;
// components
Optional<LLButton::Params> combo_button;
Optional<LLIconCtrl::Params> combo_icon;
Optional<LLButton::Params> combo_button,
combo_next_btn,
combo_previous_btn;
Optional<LLScrollListCtrl::Params> combo_list;
Optional<LLLineEditor::Params> combo_editor;
......@@ -110,6 +117,9 @@ class LLComboBox
//BD - UI Improvements
BOOL handleScrollWheel(S32 x, S32 y, S32 clicks, MASK mask) final override;
void onNextBtn();
void onPrevBtn();
// LLUICtrl interface
virtual void clear(); // select nothing
virtual void onCommit();
......@@ -228,6 +238,9 @@ class LLComboBox
protected:
LLButton* mButton;
LLButton* mNextBtn;
LLButton* mPrevBtn;
LLIconCtrl* mIcon;
LLLineEditor* mTextEntry;
LLScrollListCtrl* mList;
EPreferredPosition mListPosition;
......
......@@ -39,16 +39,24 @@
static LLDefaultChildRegistry::Register<LLIconCtrl> r("icon");
LLIconCtrl::Params::Params()
: image("image_name"),
: image("image_name"),
color("color"),
use_draw_context_alpha("use_draw_context_alpha", true),
scale_image("scale_image"),
min_width("min_width", 0),
min_height("min_height", 0)
min_height("min_height", 0),
//BD
repeat_image("repeat_image", false),
repeats("repeats", 1),
warn_image("warn_image"),
default_image("default_image"),
warns_index("warns_index", -1),
default_index("default_index", -1),
selected("selected")
{}
LLIconCtrl::LLIconCtrl(const LLIconCtrl::Params& p)
: LLUICtrl(p),
: LLUICtrl(p),
mColor(p.color()),
mImagep(p.image),
mUseDrawContextAlpha(p.use_draw_context_alpha),
......@@ -56,12 +64,87 @@ LLIconCtrl::LLIconCtrl(const LLIconCtrl::Params& p)
mMinWidth(p.min_width),
mMinHeight(p.min_height),
mMaxWidth(0),
mMaxHeight(0)
mMaxHeight(0),
//BD
mDefaultIndex(p.default_index),
mWarnIndex(p.warns_index),
mDefaultImagep(p.default_image),
mWarnImagep(p.warn_image),
mRepeats(p.repeats),
mRepeatImage(p.repeat_image)
{
if (mImagep.notNull())
{
LLUICtrl::setValue(mImagep->getName());
}
if (mDefaultImagep.notNull())
{
LLSD tvalue(mDefaultImagep->getName());
if (tvalue.isString() && LLUUID::validate(tvalue.asString()))
{
//RN: support UUIDs masquerading as strings
tvalue = LLSD(LLUUID(tvalue.asString()));
}
if (tvalue.isUUID())
{
mDefaultImagep = LLUI::getUIImageByID(tvalue.asUUID(), mPriority);
}
else
{
mDefaultImagep = LLUI::getUIImage(tvalue.asString(), mPriority);
}
if (mDefaultImagep.notNull()
&& mDefaultImagep->getImage().notNull()
&& mMinWidth
&& mMinHeight)
{
S32 desired_draw_width = llmax(mMinWidth, mDefaultImagep->getWidth());
S32 desired_draw_height = llmax(mMinHeight, mDefaultImagep->getHeight());
if (mMaxWidth && mMaxHeight)
{
desired_draw_width = llmin(desired_draw_width, mMaxWidth);
desired_draw_height = llmin(desired_draw_height, mMaxHeight);
}
mDefaultImagep->getImage()->setKnownDrawSize(desired_draw_width, desired_draw_height);
}
}
if (mWarnImagep.notNull())
{
LLSD tvalue(mWarnImagep->getName());
if (tvalue.isString() && LLUUID::validate(tvalue.asString()))
{
//RN: support UUIDs masquerading as strings
tvalue = LLSD(LLUUID(tvalue.asString()));
}
if (tvalue.isUUID())
{
mWarnImagep = LLUI::getUIImageByID(tvalue.asUUID(), mPriority);
}
else
{
mWarnImagep = LLUI::getUIImage(tvalue.asString(), mPriority);
}
if (mWarnImagep.notNull()
&& mWarnImagep->getImage().notNull()
&& mMinWidth
&& mMinHeight)
{
S32 desired_draw_width = llmax(mMinWidth, mWarnImagep->getWidth());
S32 desired_draw_height = llmax(mMinHeight, mWarnImagep->getHeight());
if (mMaxWidth && mMaxHeight)
{
desired_draw_width = llmin(desired_draw_width, mMaxWidth);
desired_draw_height = llmin(desired_draw_height, mMaxHeight);
}
mWarnImagep->getImage()->setKnownDrawSize(desired_draw_width, desired_draw_height);
}
}
}
LLIconCtrl::~LLIconCtrl()
......@@ -74,8 +157,43 @@ void LLIconCtrl::draw()
{
if( mImagep.notNull() )
{
const F32 alpha = mUseDrawContextAlpha ? getDrawContext().mAlpha : getCurrentTransparency();
mImagep->draw(getLocalRect(), mColor.get() % alpha );
F32 alpha = mUseDrawContextAlpha ? getDrawContext().mAlpha : getCurrentTransparency();
LLRect local_rect = getLocalRect();
if (mRepeatImage)
{
S32 available_width = getRect().getWidth();
S32 leftover_width = available_width % mRepeats;
S32 repeat_width = local_rect.getWidth() / mRepeats;
S32 last_left = 0;
F32 new_alpha = alpha * 0.6;
S32 i = 0;
while (i < mRepeats)
{
S32 consistent_width = llfloor(available_width / mRepeats);
if (leftover_width > 0)
{
++consistent_width;
--leftover_width;
}
LLRect new_rect = local_rect;
new_rect.mLeft = last_left;
new_rect.mRight = new_rect.mLeft + consistent_width - 1;
last_left += consistent_width;
if (i == mDefaultIndex)
mDefaultImagep->draw(new_rect, mColor.get() % (i != mSelected ? new_alpha : alpha));
else if(i >= mWarnIndex)
mWarnImagep->draw(new_rect, mColor.get() % (i != mSelected ? new_alpha : alpha));
else
mImagep->draw(new_rect, mColor.get() % (i != mSelected ? new_alpha : alpha));
++i;
}
}
else
{
mImagep->draw(local_rect, mColor.get() % alpha);
}
}
LLUICtrl::draw();
......
......@@ -46,11 +46,21 @@ class LLIconCtrl
public:
struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
{
Optional<LLUIImage*> image;
Optional<LLUIImage*> image,
//BD
warn_image,
default_image;
Optional<LLUIColor> color;
Optional<bool> use_draw_context_alpha;
Optional<bool> use_draw_context_alpha,
//BD
repeat_image;
Optional<S32> min_width,
min_height;
min_height,
//BD
repeats,
selected,
warns_index,
default_index;
Ignored scale_image;
Params();
......@@ -75,6 +85,8 @@ class LLIconCtrl
void setColor(const LLColor4& color) { mColor = color; }
void setImage(LLPointer<LLUIImage> image) { mImagep = image; }
const LLPointer<LLUIImage> getImage() { return mImagep; }
void setRepeats(S32 repeats) { mRepeats = repeats; }
void setSelected(S32 selected) { mSelected = selected; }
protected:
S32 mPriority;
......@@ -85,6 +97,15 @@ class LLIconCtrl
mMaxWidth,
mMaxHeight;
//BD
S32 mRepeats;
S32 mSelected;
S32 mWarnIndex;
S32 mDefaultIndex;
LLPointer<LLUIImage> mWarnImagep;
LLPointer<LLUIImage> mDefaultImagep;
bool mRepeatImage;
// If set to true (default), use the draw context transparency.
// If false, will use transparency returned by getCurrentTransparency(). See STORM-698.
bool mUseDrawContextAlpha;
......
......@@ -73,6 +73,7 @@ class LLScrollListItem
Ignored length;
Multiple<LLScrollListCell::Params> columns;
Optional<std::string> tool_tip;
//BD - Cells ~ Thanks to Liru
Optional<Contents> contents;
......@@ -83,6 +84,7 @@ class LLScrollListItem
type("type"),
length("length"),
columns("columns"),
tool_tip("tool_tip"),
//BD - Cells ~ Thanks to Liru
contents("contents")
{
......@@ -102,6 +104,9 @@ class LLScrollListItem
void setHighlighted( BOOL b ) { mHighlighted = b; }
BOOL getHighlighted() const { return mHighlighted; }
void setToolTip(std::string str) { mToolTip = str; }
std::string getToolTip() const { return mToolTip; }
//BD
void setFlagged(bool b) { mFlagged = b; }
bool getFlagged() const { return mFlagged; }
......@@ -146,6 +151,7 @@ class LLScrollListItem
void* mUserdata;
LLSD mItemValue;
std::string mToolTip;
std::vector<LLScrollListCell *> mColumns;
LLRect mRectangle;
};
......
......@@ -807,6 +807,10 @@ with the same filename but different name
<texture name="Blogger_Icon" file_name="blogger_gr.png" preload="true"/>
<texture name="FMOD_Logo" file_name="fmod.png" preload="true"/>
<texture name="Ticker" file_name="widgets/Ticker.png" preload="true" scale.left="4" scale.top="13" scale.right="27" scale.bottom="2" />
<texture name="Ticker_Warn" file_name="widgets/Ticker_Warn.png" preload="true" scale.left="4" scale.top="13" scale.right="27" scale.bottom="2"/>
<texture name="Ticker_Default" file_name="widgets/Ticker_Default.png" preload="true" scale.left="4" scale.top="3" scale.right="27" scale.bottom="2"/>
<texture name="Command_Machinima_Icon" file_name="toolbar_icons/machinima.png" preload="true" />
<texture name="Command_Script_Limits_Icon" file_name="toolbar_icons/script.png" preload="true" />
<texture name="Command_PF_Linksets_Icon" file_name="toolbar_icons/linksets.png" preload="true" />
......
......@@ -2,6 +2,7 @@
<combo_box font="SansSerifSmall"
list_position="below"
max_chars="20"
use_ticker="false"
height="23"
follows="right|top">
<combo_box.combo_button name="Combobox Button"
......@@ -34,4 +35,24 @@
select_on_focus="true"
font="SansSerifSmall"
text_tentative_color="TextFgColor" />
<combo_box.combo_icon
image_name="Ticker"
warn_image="Ticker_Warn"
default_image="Ticker_Default"
follows="left|bottom|right"
default_index="99"
warns_index="99"
repeat_image="true"/>
<combo_box.combo_next_btn
follows="left|bottom|top"
image_overlay="Arrow_Right"
image_unselected="Transparent"
image_selected="Transparent"
image_disabled="Transparent" />
<combo_box.combo_previous_btn
follows="left|bottom|top"
image_overlay="Arrow_Left"
image_unselected="Transparent"
image_selected="Transparent"
image_disabled="Transparent" />
</combo_box>