39 if (mHeightButton < 0)
48 if (mWidgetEmpty ==
nullptr)
50 std::string_view skinButtonEmpty;
54 if (!skinButtonEmpty.empty())
61 if (getUpdateByResize())
72 MYGUI_ASSERT_RANGE(_column, mVectorColumnInfo.size(),
"MultiListBox::setColumnNameAt");
73 mVectorColumnInfo[_column].name = _name;
81 MYGUI_ASSERT_RANGE(_column, mVectorColumnInfo.size(),
"MultiListBox::setColumnWidthAt");
82 mVectorColumnInfo[_column].width = _width;
88 MYGUI_ASSERT_RANGE(_column, mVectorColumnInfo.size(),
"MultiListBox::getColumnNameAt");
89 return mVectorColumnInfo[_column].name;
94 MYGUI_ASSERT_RANGE(_column, mVectorColumnInfo.size(),
"MultiListBox::getColumnWidthAt");
95 return mVectorColumnInfo[_column].width;
100 while (!mVectorColumnInfo.empty())
106 mSortColumnIndex = _column;
127 if (mVectorColumnInfo.empty())
129 return mVectorColumnInfo.front().list->getItemCount();
135 for (
auto& iter : mVectorColumnInfo)
137 iter.list->removeAllItems();
143 void MultiListBox::updateBackSelected(
size_t _index)
147 for (
auto& iter : mVectorColumnInfo)
149 iter.list->clearIndexSelected();
154 for (
auto& iter : mVectorColumnInfo)
156 iter.list->setIndexSelected(_index);
163 if (_index == mItemSelected)
166 MYGUI_ASSERT(!mVectorColumnInfo.empty(),
"MultiListBox::setIndexSelected");
169 mVectorColumnInfo.begin()->list->getItemCount(),
170 "MultiListBox::setIndexSelected");
172 mItemSelected = _index;
178 MYGUI_ASSERT_RANGE(_index, mVectorColumnInfo.begin()->list->getItemCount(),
"MultiListBox::setSubItemAt");
181 getSubItemAt(_column)->setItemNameAt(index, _name);
184 if (_column == mSortColumnIndex)
190 MYGUI_ASSERT_RANGE(_index, mVectorColumnInfo.begin()->list->getItemCount(),
"MultiListBox::getSubItemNameAt");
193 return getSubItemAt(_column)->getItemNameAt(index);
198 size_t index = getSubItemAt(_column)->findItemIndexWith(_name);
202 int MultiListBox::getButtonHeight()
const
204 if (mHeaderPlace !=
nullptr)
206 return mHeightButton;
209 void MultiListBox::updateOnlyEmpty()
211 if (
nullptr == mWidgetEmpty)
224 void MultiListBox::notifyListChangePosition(
ListBox* _sender,
size_t _position)
226 for (
auto& iter : mVectorColumnInfo)
228 if (_sender != iter.list)
229 iter.list->setIndexSelected(_position);
232 updateBackSelected(_position);
240 void MultiListBox::notifyListSelectAccept(
ListBox* _sender,
size_t _position)
246 void MultiListBox::notifyListNotifyItem(
ListBox* _sender,
const MyGUI::IBNotifyItemData& _info)
248 IBNotifyItemData infoConvertedIndex(_info);
253 void MultiListBox::notifyListChangeFocus(
ListBox* _sender,
size_t _position)
255 for (
auto& iter : mVectorColumnInfo)
257 if (_sender != iter.list)
260 iter.list->_setItemFocus(mLastMouseFocusIndex,
false);
262 iter.list->_setItemFocus(_position,
true);
265 mLastMouseFocusIndex = _position;
268 void MultiListBox::notifyListChangeScrollPosition(
ListBox* _sender,
size_t _position)
270 for (
auto& iter : mVectorColumnInfo)
272 if (_sender != iter.list)
273 iter.list->setScrollPosition(_position);
277 void MultiListBox::notifyButtonClick(MyGUI::Widget* _sender)
283 void MultiListBox::redrawButtons()
286 for (
auto& iter : mVectorColumnInfo)
288 if (pos == mSortColumnIndex)
291 iter.button->setImageName(
"Up");
293 iter.button->setImageName(
"Down");
296 iter.button->setImageName(
"None");
298 iter.button->setCaption(iter.name);
303 void MultiListBox::frameEntered(
float _frame)
308 void MultiListBox::frameAdvise(
bool _advise)
323 mFrameAdvise =
false;
328 Widget* MultiListBox::getOrCreateSeparator(
size_t _index)
330 if (!mWidthSeparator || mSkinSeparator.empty())
333 if (_index == mVectorColumnInfo.size() - 1)
336 while (_index >= mSeparators.size())
339 mSeparators.push_back(separator);
342 return mSeparators[_index];
345 void MultiListBox::flipList()
350 size_t last = mVectorColumnInfo.front().list->getItemCount();
359 for (
auto& iter : mVectorColumnInfo)
361 iter.list->swapItemsAt(first, last);
371 bool MultiListBox::compare(
ListBox* _list,
size_t _left,
size_t _right)
375 std::swap(_left, _right);
378 result = _list->getItemNameAt(_left) < _list->getItemNameAt(_right);
382#ifndef MYGUI_DONT_USE_OBSOLETE
386 _list->getItemNameAt(_left),
387 _list->getItemNameAt(_right),
407 void MultiListBox::sortList()
412 ListBox* list = mVectorColumnInfo[mSortColumnIndex].list;
414 size_t count = list->getItemCount();
421 for (
size_t step = count >> 1; step > 0; step >>= 1)
423 for (
size_t i = 0; i < (count - step); i++)
429 if (compare(list, first, last))
432 for (
auto& iter : mVectorColumnInfo)
434 iter.list->swapItemsAt(first, last);
449 MYGUI_ASSERT(!mVectorColumnInfo.empty(),
"MultiListBox::insertItemAt");
452 _index = mVectorColumnInfo.front().list->getItemCount();
456 if ((mItemSelected !=
ITEM_NONE) && (_index <= mItemSelected))
462 for (
auto& iter : mVectorColumnInfo)
464 iter.list->insertItemAt(index,
UString());
466 mVectorColumnInfo.front().list->setItemNameAt(index, _name);
467 mVectorColumnInfo.front().list->setItemDataAt(index, _data);
474 MYGUI_ASSERT(!mVectorColumnInfo.empty(),
"MultiListBox::removeItemAt");
475 MYGUI_ASSERT_RANGE(_index, mVectorColumnInfo.begin()->list->getItemCount(),
"MultiListBox::removeItemAt");
479 for (
auto& iter : mVectorColumnInfo)
481 iter.list->removeItemAt(index);
485 size_t count = mVectorColumnInfo.begin()->list->getItemCount();
490 if (_index < mItemSelected)
492 else if ((_index == mItemSelected) && (mItemSelected == count))
500 MYGUI_ASSERT(!mVectorColumnInfo.empty(),
"MultiListBox::removeItemAt");
501 MYGUI_ASSERT_RANGE(_index1, mVectorColumnInfo.begin()->list->getItemCount(),
"MultiListBox::swapItemsAt");
502 MYGUI_ASSERT_RANGE(_index2, mVectorColumnInfo.begin()->list->getItemCount(),
"MultiListBox::swapItemsAt");
513 MYGUI_ASSERT_RANGE(_index, mVectorColumnInfo.size(),
"MultiListBox::setColumnDataAt");
514 mVectorColumnInfo[_index].data = std::move(_data);
519 MYGUI_ASSERT_RANGE(_index, mVectorColumnInfo.begin()->list->getItemCount(),
"MultiListBox::setSubItemDataAt");
522 getSubItemAt(_column)->setItemDataAt(index, _data);
527 return mVectorColumnInfo.size();
557 return mItemSelected;
580 ListBox* MultiListBox::getSubItemAt(
size_t _column)
const
583 return mVectorColumnInfo[_column].list;
616 _column = mVectorColumnInfo.size();
620 mVectorColumnInfo.back().width = _width;
622 mVectorColumnInfo.back().name = _name;
623 mVectorColumnInfo.back().
data = std::move(_data);
624 mVectorColumnInfo.back().button->setCaption(_name);
626 if (_column == (mVectorColumnInfo.size() - 1))
630 mVectorColumnInfo.back().list->setScrollVisible(
true);
634 _swapColumnsAt(_column, mVectorColumnInfo.size() - 1);
640 MYGUI_ASSERT_RANGE(_column, mVectorColumnInfo.size(),
"MultiListBox::removeColumnAt");
642 ColumnInfo& info = mVectorColumnInfo[_column];
652 _swapColumnsAt(_index1, _index2);
655 void MultiListBox::_swapColumnsAt(
size_t _index1,
size_t _index2)
657 if (_index1 == _index2)
660 mVectorColumnInfo[_index1].list->setScrollVisible(
false);
661 mVectorColumnInfo[_index2].list->setScrollVisible(
false);
663 std::swap(mVectorColumnInfo[_index1], mVectorColumnInfo[_index2]);
667 mVectorColumnInfo.back().list->setScrollVisible(
true);
675 if (child !=
nullptr)
686 if (child !=
nullptr)
692 for (
auto& item : mVectorColumnInfo)
694 if (item.button == _widget)
695 item.button =
nullptr;
703 if (!mVectorColumnInfo.empty())
704 mVectorColumnInfo.back().list->setScrollVisible(
false);
710 column.realWidth = 0;
719 column.list->eventListMouseItemFocus +=
newDelegate(
this, &MultiListBox::notifyListChangeFocus);
720 column.list->eventListChangeScroll +=
newDelegate(
this, &MultiListBox::notifyListChangeScrollPosition);
721 column.list->eventListSelectAccept +=
newDelegate(
this, &MultiListBox::notifyListSelectAccept);
722 column.list->eventNotifyItem +=
newDelegate(
this, &MultiListBox::notifyListNotifyItem);
724 if (mHeaderPlace !=
nullptr)
732 if (!mVectorColumnInfo.empty())
734 size_t count = mVectorColumnInfo.front().list->getItemCount();
735 for (
size_t pos = 0; pos < count; ++pos)
736 column.list->addItem(
UString());
739 mVectorColumnInfo.push_back(column);
744 mVectorColumnInfo.back().list->setScrollVisible(
true);
749 for (VectorColumnInfo::iterator item = mVectorColumnInfo.begin(); item != mVectorColumnInfo.end(); ++item)
751 if ((*item).item == _item)
753 if ((*item).button !=
nullptr)
756 mVectorColumnInfo.erase(item);
761 if (mVectorColumnInfo.empty())
775 if (!mVectorColumnInfo.empty())
776 mVectorColumnInfo.back().list->setScrollVisible(
true);
782 return mVectorColumnInfo[_index].item;
797 for (
size_t index = 0; index < mVectorColumnInfo.size(); ++index)
799 if (mVectorColumnInfo[index].item == _item)
813 MYGUI_ASSERT_RANGE(_index, mVectorColumnInfo.size(),
"MultiListBox::setColumnWidthAt");
814 mVectorColumnInfo[_index].sizeType = _value;
832 if (getUpdateByResize())
840 if (getUpdateByResize())
844 bool MultiListBox::getUpdateByResize()
const
846 if (mWidgetEmpty !=
nullptr)
849 for (
const auto& info : mVectorColumnInfo)
857 int MultiListBox::getColumnWidth(
861 size_t _lastIndexStar,
862 int _starWidth)
const
864 const ColumnInfo& info = mVectorColumnInfo[_index];
868 return info.realWidth;
872 return info.realWidth;
876 if (_lastIndexStar == _index)
878 return _starWidth + _freeSpace - (_starWidth * _countStars);
885 int MultiListBox::updateWidthColumns(
size_t& _countStars,
size_t& _lastIndexStar)
892 for (
size_t index = 0; index < mVectorColumnInfo.size(); ++index)
894 ColumnInfo& info = mVectorColumnInfo[index];
899 info.button->getWidth() - info.button->getTextRegion().width + info.button->getTextSize().width;
903 info.realWidth = info.width < 0 ? 0 : info.width;
909 _lastIndexStar = index;
916 width += info.realWidth;
922 void MultiListBox::updateColumns()
924 size_t countStars = 0;
927 int allColumnsWidth = updateWidthColumns(countStars, lastIndexStar);
929 int separatorsWidth = mVectorColumnInfo.empty() ? 0 : (mVectorColumnInfo.size() - 1) * mWidthSeparator;
930 int freeSpace = clientWidth - separatorsWidth - allColumnsWidth;
931 int starWidth = (countStars != 0 && freeSpace > 0) ? (freeSpace / countStars) : 0;
934 for (
size_t index = 0; index < mVectorColumnInfo.size(); ++index)
936 ColumnInfo& info = mVectorColumnInfo[index];
938 int columnWidth = getColumnWidth(index, freeSpace, countStars, lastIndexStar, starWidth);
940 if (mHeaderPlace !=
nullptr)
950 info.button->setCoord(mWidthBar, 0, columnWidth, getButtonHeight());
951 info.button->_setInternalData(index);
953 mWidthBar += columnWidth;
956 Widget* separator = getOrCreateSeparator(index);
962 mWidthBar += mWidthSeparator;
#define MYGUI_ASSERT(exp, dest)
#define MYGUI_ASSERT_RANGE_INSERT(index, size, owner)
#define MYGUI_ASSERT_RANGE(index, size, owner)
#define MYGUI_ASSERT_RANGE_AND_NONE(index, size, owner)
void swapItemsBackAt(size_t _index1, size_t _index2)
size_t removeItemAt(size_t _index)
size_t insertItemAt(size_t _index)
size_t convertToBack(size_t _index) const
size_t convertToFace(size_t _index) const
void swapItemsFaceAt(size_t _index1, size_t _index2)
static Gui & getInstance()
EventHandle_FrameEventDelegate eventFrameStart
Type * castType(bool _throw=true)
widget description should be here.
EventPair< EventHandle_WidgetSizeT, EventHandle_ListPtrSizeT > eventListChangePosition
size_t _getItemCount() const override
void setColumnWidthAt(size_t _column, int _width)
void addItem(const UString &_name, Any _data=Any::Null)
void onWidgetDestroy(Widget *_widget) override
void _removeItemAt(size_t _index) override
void insertItemAt(size_t _index, const UString &_name, Any _data=Any::Null)
void setColumnResizingPolicyAt(size_t _index, ResizingPolicy _value)
void setColumnWidth(MultiListItem *_item, int _width)
void _setItemNameAt(size_t _index, const UString &_name) override
void removeItemAt(size_t _index)
Remove item at a specified position.
void setCoord(const IntCoord &_coord) override
EventPair< EventHandle_MultiListPtrSizeTCUTFStringRefCUTFStringRefBoolRef, EventHandle_MultiListPtrSizeTSizeTSizeTBoolRef > requestOperatorLess
const UString & getItemNameAt(size_t _index) const
Get item name from specified position.
void setColumnDataAt(size_t _index, Any _data)
Replace an item data at a specified position.
EventPair< EventHandle_WidgetSizeT, EventHandle_MultiListPtrSizeT > eventListChangePosition
void sortByColumn(size_t _column, bool _backward=false)
const UString & _getItemNameAt(size_t _index) const override
void insertColumnAt(size_t _column, const UString &_name, int _width=0, Any _data=Any::Null)
void setItemNameAt(size_t _index, const UString &_name)
Replace an item name.
int getColumnWidthAt(size_t _column) const
void setSize(const IntSize &_size) override
EventPair< EventHandle_WidgetSizeT, EventHandle_MultiListPtrSizeT > eventListSelectAccept
size_t getColumnCount() const
Get number of columns.
void setSubItemDataAt(size_t _column, size_t _index, Any _data)
Replace an item data at a specified position.
void swapItemsAt(size_t _index1, size_t _index2)
Swap items at a specified positions.
void setSubItemNameAt(size_t _column, size_t _index, const UString &_name)
void onWidgetCreated(Widget *_widget) override
void removeColumnAt(size_t _column)
Widget * _getItemAt(size_t _index) const override
void setPosition(const IntPoint &_point) override
void clearItemDataAt(size_t _index)
Clear an item data at a specified position.
size_t findSubItemWith(size_t _column, const UString &_name)
void _addItem(const MyGUI::UString &_name) override
void clearColumnDataAt(size_t _index)
Clear an item data at a specified position.
void setItemDataAt(size_t _index, Any _data)
Replace an item data at a specified position.
void shutdownOverride() override
EventHandle_MultiListPtrCIBNotifyCellDataRef eventNotifyItem
void initialiseOverride() override
size_t getColumnIndex(const MultiListItem *_item) const
Get column index.
void setColumnNameAt(size_t _column, const UString &_name)
void addColumn(const UString &_name, int _width=0, Any _data=Any::Null)
const UString & getSubItemNameAt(size_t _column, size_t _index) const
size_t getIndexSelected() const
void setColumnName(MultiListItem *_item, const UString &_name)
void setColumnResizingPolicy(MultiListItem *_item, ResizingPolicy _value)
void clearSubItemDataAt(size_t _column, size_t _index)
Clear an item data at a specified position.
void clearIndexSelected()
void setIndexSelected(size_t _index)
size_t getItemCount() const
const UString & getColumnNameAt(size_t _column) const
void swapColumnsAt(size_t _index1, size_t _index2)
Swap columns at a specified positions.
const UString & getColumnName(const MultiListItem *_item) const
widget description should be here.
A UTF-16 string with implicit conversion to/from std::string and std::wstring.
const code_point * data() const
returns a pointer to the first character in the current string
bool isUserString(std::string_view _key) const
std::string_view getUserString(std::string_view _key) const
ValueType * _getInternalData(bool _throw=true) const
T parseValue(std::string_view _value)
types::TPoint< int > IntPoint
constexpr size_t ITEM_NONE
types::TCoord< int > IntCoord
types::TSize< int > IntSize
delegates::DelegateFunction< Args... > * newDelegate(void(*_func)(Args... args))