MyGUI_MultiListBox.cpp
Go to the documentation of this file.
/*
* This source file is part of MyGUI. For the latest info, see http://mygui.info/
* Distributed under the MIT License
* (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT)
*/
#include "MyGUI_Precompiled.h"
#include "MyGUI_MultiListBox.h"
#include "MyGUI_MultiListItem.h"
#include "MyGUI_ResourceSkin.h"
#include "MyGUI_Button.h"
#include "MyGUI_ImageBox.h"
#include "MyGUI_ListBox.h"
#include "MyGUI_Gui.h"
#include "MyGUI_WidgetManager.h"
namespace MyGUI
{
void MultiListBox::initialiseOverride()
{
Base::initialiseOverride();
if (isUserString("SkinButton"))
mSkinButton = getUserString("SkinButton");
if (isUserString("SkinList"))
mSkinList = getUserString("SkinList");
if (isUserString("SkinSeparator"))
mSkinSeparator = getUserString("SkinSeparator");
if (isUserString("WidthSeparator"))
mWidthSeparator = utility::parseValue<int>(getUserString("WidthSeparator"));
// OBSOLETE
if (isUserString("HeightButton"))
mHeightButton = utility::parseValue<int>(getUserString("HeightButton"));
if (mHeightButton < 0)
mHeightButton = 0;
assignWidget(mHeaderPlace, "HeaderPlace");
assignWidget(mWidgetEmpty, "Empty");
if (mWidgetEmpty == nullptr)
{
std::string_view skinButtonEmpty;
if (isUserString("SkinButtonEmpty"))
skinButtonEmpty = getUserString("SkinButtonEmpty");
if (!skinButtonEmpty.empty())
mWidgetEmpty = _getClientWidget()->createWidget<Widget>(
skinButtonEmpty,
IntCoord(0, 0, _getClientWidget()->getWidth(), getButtonHeight()),
Align::Default);
}
if (getUpdateByResize())
updateColumns();
}
void MultiListBox::shutdownOverride()
{
Base::shutdownOverride();
}
void MultiListBox::setColumnNameAt(size_t _column, const UString& _name)
{
MYGUI_ASSERT_RANGE(_column, mVectorColumnInfo.size(), "MultiListBox::setColumnNameAt");
mVectorColumnInfo[_column].name = _name;
// обновляем кэпшен сначала
redrawButtons();
updateColumns();
}
void MultiListBox::setColumnWidthAt(size_t _column, int _width)
{
MYGUI_ASSERT_RANGE(_column, mVectorColumnInfo.size(), "MultiListBox::setColumnWidthAt");
mVectorColumnInfo[_column].width = _width;
updateColumns();
}
const UString& MultiListBox::getColumnNameAt(size_t _column) const
{
MYGUI_ASSERT_RANGE(_column, mVectorColumnInfo.size(), "MultiListBox::getColumnNameAt");
return mVectorColumnInfo[_column].name;
}
int MultiListBox::getColumnWidthAt(size_t _column) const
{
MYGUI_ASSERT_RANGE(_column, mVectorColumnInfo.size(), "MultiListBox::getColumnWidthAt");
return mVectorColumnInfo[_column].width;
}
void MultiListBox::removeAllColumns()
{
while (!mVectorColumnInfo.empty())
removeColumnAt(0);
}
void MultiListBox::sortByColumn(size_t _column, bool _backward)
{
mSortColumnIndex = _column;
if (_backward)
{
mSortUp = !mSortUp;
redrawButtons();
// если было недосортированно то сортируем
if (mFrameAdvise)
sortList();
flipList();
}
else
{
mSortUp = true;
redrawButtons();
sortList();
}
}
size_t MultiListBox::getItemCount() const
{
if (mVectorColumnInfo.empty())
return 0;
return mVectorColumnInfo.front().list->getItemCount();
}
void MultiListBox::removeAllItems()
{
BiIndexBase::removeAllItems();
for (auto& iter : mVectorColumnInfo)
{
iter.list->removeAllItems();
}
mItemSelected = ITEM_NONE;
}
void MultiListBox::updateBackSelected(size_t _index)
{
if (_index == ITEM_NONE)
{
for (auto& iter : mVectorColumnInfo)
{
iter.list->clearIndexSelected();
}
}
else
{
for (auto& iter : mVectorColumnInfo)
{
iter.list->setIndexSelected(_index);
}
}
}
void MultiListBox::setIndexSelected(size_t _index)
{
if (_index == mItemSelected)
return;
MYGUI_ASSERT(!mVectorColumnInfo.empty(), "MultiListBox::setIndexSelected");
MYGUI_ASSERT_RANGE_AND_NONE(
_index,
mVectorColumnInfo.begin()->list->getItemCount(),
"MultiListBox::setIndexSelected");
mItemSelected = _index;
updateBackSelected(BiIndexBase::convertToBack(mItemSelected));
}
void MultiListBox::setSubItemNameAt(size_t _column, size_t _index, const UString& _name)
{
MYGUI_ASSERT_RANGE(_index, mVectorColumnInfo.begin()->list->getItemCount(), "MultiListBox::setSubItemAt");
size_t index = BiIndexBase::convertToBack(_index);
getSubItemAt(_column)->setItemNameAt(index, _name);
// если мы попортили список с активным сортом, надо пересчитывать
if (_column == mSortColumnIndex)
frameAdvise(true);
}
const UString& MultiListBox::getSubItemNameAt(size_t _column, size_t _index) const
{
MYGUI_ASSERT_RANGE(_index, mVectorColumnInfo.begin()->list->getItemCount(), "MultiListBox::getSubItemNameAt");
size_t index = BiIndexBase::convertToBack(_index);
return getSubItemAt(_column)->getItemNameAt(index);
}
size_t MultiListBox::findSubItemWith(size_t _column, const UString& _name)
{
size_t index = getSubItemAt(_column)->findItemIndexWith(_name);
return BiIndexBase::convertToFace(index);
}
int MultiListBox::getButtonHeight() const
{
if (mHeaderPlace != nullptr)
return mHeaderPlace->getHeight();
return mHeightButton;
}
void MultiListBox::updateOnlyEmpty()
{
if (nullptr == mWidgetEmpty)
return;
// кнопка, для заполнения пустоты
if (mWidthBar >= _getClientWidget()->getWidth())
mWidgetEmpty->setVisible(false);
else
{
mWidgetEmpty->setCoord(mWidthBar, 0, _getClientWidget()->getWidth() - mWidthBar, getButtonHeight());
mWidgetEmpty->setVisible(true);
}
}
void MultiListBox::notifyListChangePosition(ListBox* _sender, size_t _position)
{
for (auto& iter : mVectorColumnInfo)
{
if (_sender != iter.list)
iter.list->setIndexSelected(_position);
}
updateBackSelected(_position);
mItemSelected = BiIndexBase::convertToFace(_position);
// наш евент
eventListChangePosition(this, mItemSelected);
}
void MultiListBox::notifyListSelectAccept(ListBox* _sender, size_t _position)
{
// наш евент
eventListSelectAccept(this, BiIndexBase::convertToFace(_position));
}
void MultiListBox::notifyListNotifyItem(ListBox* _sender, const MyGUI::IBNotifyItemData& _info)
{
IBNotifyItemData infoConvertedIndex(_info);
infoConvertedIndex.index = BiIndexBase::convertToFace(_info.index);
eventNotifyItem(this, infoConvertedIndex);
}
void MultiListBox::notifyListChangeFocus(ListBox* _sender, size_t _position)
{
for (auto& iter : mVectorColumnInfo)
{
if (_sender != iter.list)
{
if (ITEM_NONE != mLastMouseFocusIndex)
iter.list->_setItemFocus(mLastMouseFocusIndex, false);
if (ITEM_NONE != _position)
iter.list->_setItemFocus(_position, true);
}
}
mLastMouseFocusIndex = _position;
}
void MultiListBox::notifyListChangeScrollPosition(ListBox* _sender, size_t _position)
{
for (auto& iter : mVectorColumnInfo)
{
if (_sender != iter.list)
iter.list->setScrollPosition(_position);
}
}
void MultiListBox::notifyButtonClick(MyGUI::Widget* _sender)
{
size_t index = *_sender->_getInternalData<size_t>();
sortByColumn(index, index == mSortColumnIndex);
}
void MultiListBox::redrawButtons()
{
size_t pos = 0;
for (auto& iter : mVectorColumnInfo)
{
if (pos == mSortColumnIndex)
{
if (mSortUp)
iter.button->setImageName("Up");
else
iter.button->setImageName("Down");
}
else
iter.button->setImageName("None");
iter.button->setCaption(iter.name);
pos++;
}
}
void MultiListBox::frameEntered(float _frame)
{
sortList();
}
void MultiListBox::frameAdvise(bool _advise)
{
if (_advise)
{
if (!mFrameAdvise)
{
MyGUI::Gui::getInstance().eventFrameStart += MyGUI::newDelegate(this, &MultiListBox::frameEntered);
mFrameAdvise = true;
}
}
else
{
if (mFrameAdvise)
{
MyGUI::Gui::getInstance().eventFrameStart -= MyGUI::newDelegate(this, &MultiListBox::frameEntered);
mFrameAdvise = false;
}
}
}
Widget* MultiListBox::getOrCreateSeparator(size_t _index)
{
if (!mWidthSeparator || mSkinSeparator.empty())
return nullptr;
// последний столбик
if (_index == mVectorColumnInfo.size() - 1)
return nullptr;
while (_index >= mSeparators.size())
{
Widget* separator = _getClientWidget()->createWidget<Widget>(mSkinSeparator, IntCoord(), Align::Default);
mSeparators.push_back(separator);
}
return mSeparators[_index];
}
void MultiListBox::flipList()
{
if (ITEM_NONE == mSortColumnIndex)
return;
size_t last = mVectorColumnInfo.front().list->getItemCount();
if (0 == last)
return;
last--;
size_t first = 0;
while (first < last)
{
BiIndexBase::swapItemsBackAt(first, last);
for (auto& iter : mVectorColumnInfo)
{
iter.list->swapItemsAt(first, last);
}
first++;
last--;
}
updateBackSelected(BiIndexBase::convertToBack(mItemSelected));
}
bool MultiListBox::compare(ListBox* _list, size_t _left, size_t _right)
{
bool result = false;
if (mSortUp)
std::swap(_left, _right);
if (requestOperatorLess.empty())
{
result = _list->getItemNameAt(_left) < _list->getItemNameAt(_right);
}
else
{
#ifndef MYGUI_DONT_USE_OBSOLETE
requestOperatorLess.m_eventObsolete(
this,
mSortColumnIndex,
_list->getItemNameAt(_left),
_list->getItemNameAt(_right),
result);
requestOperatorLess.m_event(
this,
mSortColumnIndex,
BiIndexBase::convertToFace(_left),
BiIndexBase::convertToFace(_right),
result);
#else
requestOperatorLess(
this,
mSortColumnIndex,
BiIndexBase::convertToFace(_left),
BiIndexBase::convertToFace(_right),
result);
#endif
}
return result;
}
void MultiListBox::sortList()
{
if (ITEM_NONE == mSortColumnIndex)
return;
ListBox* list = mVectorColumnInfo[mSortColumnIndex].list;
size_t count = list->getItemCount();
if (0 == count)
return;
// shell sort
int first;
size_t last;
for (size_t step = count >> 1; step > 0; step >>= 1)
{
for (size_t i = 0; i < (count - step); i++)
{
first = (int)i;
while (first >= 0)
{
last = first + step;
if (compare(list, first, last))
{
BiIndexBase::swapItemsBackAt(first, last);
for (auto& iter : mVectorColumnInfo)
{
iter.list->swapItemsAt(first, last);
}
}
first--;
}
}
}
frameAdvise(false);
updateBackSelected(BiIndexBase::convertToBack(mItemSelected));
}
void MultiListBox::insertItemAt(size_t _index, const UString& _name, Any _data)
{
MYGUI_ASSERT(!mVectorColumnInfo.empty(), "MultiListBox::insertItemAt");
MYGUI_ASSERT_RANGE_INSERT(_index, mVectorColumnInfo.front().list->getItemCount(), "MultiListBox::insertItemAt");
if (ITEM_NONE == _index)
_index = mVectorColumnInfo.front().list->getItemCount();
// если надо, то меняем выделенный элемент
// при сортировке, обновится
if ((mItemSelected != ITEM_NONE) && (_index <= mItemSelected))
mItemSelected++;
size_t index = BiIndexBase::insertItemAt(_index);
// вставляем во все поля пустые, а потом присваиваем первому
for (auto& iter : mVectorColumnInfo)
{
iter.list->insertItemAt(index, UString());
}
mVectorColumnInfo.front().list->setItemNameAt(index, _name);
mVectorColumnInfo.front().list->setItemDataAt(index, _data);
frameAdvise(true);
}
void MultiListBox::removeItemAt(size_t _index)
{
MYGUI_ASSERT(!mVectorColumnInfo.empty(), "MultiListBox::removeItemAt");
MYGUI_ASSERT_RANGE(_index, mVectorColumnInfo.begin()->list->getItemCount(), "MultiListBox::removeItemAt");
size_t index = BiIndexBase::removeItemAt(_index);
for (auto& iter : mVectorColumnInfo)
{
iter.list->removeItemAt(index);
}
// если надо, то меняем выделенный элемент
size_t count = mVectorColumnInfo.begin()->list->getItemCount();
if (count == 0)
mItemSelected = ITEM_NONE;
else if (mItemSelected != ITEM_NONE)
{
if (_index < mItemSelected)
mItemSelected--;
else if ((_index == mItemSelected) && (mItemSelected == count))
mItemSelected--;
}
updateBackSelected(BiIndexBase::convertToBack(mItemSelected));
}
void MultiListBox::swapItemsAt(size_t _index1, size_t _index2)
{
MYGUI_ASSERT(!mVectorColumnInfo.empty(), "MultiListBox::removeItemAt");
MYGUI_ASSERT_RANGE(_index1, mVectorColumnInfo.begin()->list->getItemCount(), "MultiListBox::swapItemsAt");
MYGUI_ASSERT_RANGE(_index2, mVectorColumnInfo.begin()->list->getItemCount(), "MultiListBox::swapItemsAt");
// при сортированном, меняем только индексы
BiIndexBase::swapItemsFaceAt(_index1, _index2);
// при несортированном, нужно наоборот, поменять только данные
// FIXME
}
void MultiListBox::setColumnDataAt(size_t _index, Any _data)
{
MYGUI_ASSERT_RANGE(_index, mVectorColumnInfo.size(), "MultiListBox::setColumnDataAt");
mVectorColumnInfo[_index].data = std::move(_data);
}
void MultiListBox::setSubItemDataAt(size_t _column, size_t _index, Any _data)
{
MYGUI_ASSERT_RANGE(_index, mVectorColumnInfo.begin()->list->getItemCount(), "MultiListBox::setSubItemDataAt");
size_t index = BiIndexBase::convertToBack(_index);
getSubItemAt(_column)->setItemDataAt(index, _data);
}
size_t MultiListBox::getColumnCount() const
{
return mVectorColumnInfo.size();
}
void MultiListBox::addColumn(const UString& _name, int _width, Any _data)
{
insertColumnAt(ITEM_NONE, _name, _width, _data);
}
void MultiListBox::clearColumnDataAt(size_t _index)
{
setColumnDataAt(_index, Any::Null);
}
void MultiListBox::addItem(const UString& _name, Any _data)
{
insertItemAt(ITEM_NONE, _name, _data);
}
void MultiListBox::setItemNameAt(size_t _index, const UString& _name)
{
setSubItemNameAt(0, _index, _name);
}
const UString& MultiListBox::getItemNameAt(size_t _index) const
{
return getSubItemNameAt(0, _index);
}
size_t MultiListBox::getIndexSelected() const
{
return mItemSelected;
}
void MultiListBox::clearIndexSelected()
{
setIndexSelected(ITEM_NONE);
}
void MultiListBox::setItemDataAt(size_t _index, Any _data)
{
setSubItemDataAt(0, _index, _data);
}
void MultiListBox::clearItemDataAt(size_t _index)
{
setItemDataAt(_index, Any::Null);
}
void MultiListBox::clearSubItemDataAt(size_t _column, size_t _index)
{
setSubItemDataAt(_column, _index, Any::Null);
}
ListBox* MultiListBox::getSubItemAt(size_t _column) const
{
MYGUI_ASSERT_RANGE(_column, mVectorColumnInfo.size(), "MultiListBox::getSubItemAt");
return mVectorColumnInfo[_column].list;
}
size_t MultiListBox::_getItemCount() const
{
return getColumnCount();
}
void MultiListBox::_addItem(const MyGUI::UString& _name)
{
addColumn(_name);
setColumnResizingPolicyAt(getColumnCount() - 1, ResizingPolicy::Auto);
}
void MultiListBox::_removeItemAt(size_t _index)
{
removeColumnAt(_index);
}
void MultiListBox::_setItemNameAt(size_t _index, const UString& _name)
{
setColumnNameAt(_index, _name);
}
const UString& MultiListBox::_getItemNameAt(size_t _index) const
{
return getColumnNameAt(_index);
}
void MultiListBox::insertColumnAt(size_t _column, const UString& _name, int _width, Any _data)
{
MYGUI_ASSERT_RANGE_INSERT(_column, mVectorColumnInfo.size(), "MultiListBox::insertColumnAt");
if (_column == ITEM_NONE)
_column = mVectorColumnInfo.size();
createWidget<MultiListItem>(std::string_view{}, IntCoord(), Align::Default);
mVectorColumnInfo.back().width = _width;
mVectorColumnInfo.back().sizeType = ResizingPolicy::Fixed;
mVectorColumnInfo.back().name = _name;
mVectorColumnInfo.back().data = std::move(_data);
mVectorColumnInfo.back().button->setCaption(_name);
if (_column == (mVectorColumnInfo.size() - 1))
{
updateColumns();
mVectorColumnInfo.back().list->setScrollVisible(true);
}
else
{
_swapColumnsAt(_column, mVectorColumnInfo.size() - 1);
}
}
void MultiListBox::removeColumnAt(size_t _column)
{
MYGUI_ASSERT_RANGE(_column, mVectorColumnInfo.size(), "MultiListBox::removeColumnAt");
ColumnInfo& info = mVectorColumnInfo[_column];
WidgetManager::getInstance().destroyWidget(info.item);
}
void MultiListBox::swapColumnsAt(size_t _index1, size_t _index2)
{
MYGUI_ASSERT_RANGE(_index1, mVectorColumnInfo.size(), "MultiListBox::swapColumnsAt");
MYGUI_ASSERT_RANGE(_index2, mVectorColumnInfo.size(), "MultiListBox::swapColumnsAt");
_swapColumnsAt(_index1, _index2);
}
void MultiListBox::_swapColumnsAt(size_t _index1, size_t _index2)
{
if (_index1 == _index2)
return;
mVectorColumnInfo[_index1].list->setScrollVisible(false);
mVectorColumnInfo[_index2].list->setScrollVisible(false);
std::swap(mVectorColumnInfo[_index1], mVectorColumnInfo[_index2]);
updateColumns();
mVectorColumnInfo.back().list->setScrollVisible(true);
}
void MultiListBox::onWidgetCreated(Widget* _widget)
{
Base::onWidgetCreated(_widget);
MultiListItem* child = _widget->castType<MultiListItem>(false);
if (child != nullptr)
{
_wrapItem(child);
}
}
void MultiListBox::onWidgetDestroy(Widget* _widget)
{
Base::onWidgetDestroy(_widget);
MultiListItem* child = _widget->castType<MultiListItem>(false);
if (child != nullptr)
{
_unwrapItem(child);
}
else
{
for (auto& item : mVectorColumnInfo)
{
if (item.button == _widget)
item.button = nullptr;
}
}
}
void MultiListBox::_wrapItem(MultiListItem* _item)
{
// скрываем у крайнего скролл
if (!mVectorColumnInfo.empty())
mVectorColumnInfo.back().list->setScrollVisible(false);
else
mSortColumnIndex = ITEM_NONE;
ColumnInfo column;
column.width = 0;
column.realWidth = 0;
column.sizeType = ResizingPolicy::Auto;
column.item = _item;
column.list = _item->createWidget<ListBox>(
mSkinList,
IntCoord(0, 0, _item->getWidth(), _item->getHeight()),
Align::Stretch);
column.list->eventListChangePosition += newDelegate(this, &MultiListBox::notifyListChangePosition);
column.list->eventListMouseItemFocus += newDelegate(this, &MultiListBox::notifyListChangeFocus);
column.list->eventListChangeScroll += newDelegate(this, &MultiListBox::notifyListChangeScrollPosition);
column.list->eventListSelectAccept += newDelegate(this, &MultiListBox::notifyListSelectAccept);
column.list->eventNotifyItem += newDelegate(this, &MultiListBox::notifyListNotifyItem);
if (mHeaderPlace != nullptr)
column.button = mHeaderPlace->createWidget<Button>(mSkinButton, IntCoord(), Align::Default);
else
column.button = _getClientWidget()->createWidget<Button>(mSkinButton, IntCoord(), Align::Default);
column.button->eventMouseButtonClick += newDelegate(this, &MultiListBox::notifyButtonClick);
// если уже были столбики, то делаем то же колличество полей
if (!mVectorColumnInfo.empty())
{
size_t count = mVectorColumnInfo.front().list->getItemCount();
for (size_t pos = 0; pos < count; ++pos)
column.list->addItem(UString());
}
mVectorColumnInfo.push_back(column);
updateColumns();
// показываем скролл нового крайнего
mVectorColumnInfo.back().list->setScrollVisible(true);
}
void MultiListBox::_unwrapItem(MultiListItem* _item)
{
for (VectorColumnInfo::iterator item = mVectorColumnInfo.begin(); item != mVectorColumnInfo.end(); ++item)
{
if ((*item).item == _item)
{
if ((*item).button != nullptr)
WidgetManager::getInstance().destroyWidget((*item).button);
mVectorColumnInfo.erase(item);
break;
}
}
if (mVectorColumnInfo.empty())
{
mSortColumnIndex = ITEM_NONE;
mItemSelected = ITEM_NONE;
}
else
{
mSortColumnIndex = ITEM_NONE;
mSortUp = true;
sortList();
}
updateColumns();
if (!mVectorColumnInfo.empty())
mVectorColumnInfo.back().list->setScrollVisible(true);
}
Widget* MultiListBox::_getItemAt(size_t _index) const
{
MYGUI_ASSERT_RANGE(_index, mVectorColumnInfo.size(), "MultiListBox::_getItemAt");
return mVectorColumnInfo[_index].item;
}
void MultiListBox::setColumnName(MultiListItem* _item, const UString& _name)
{
setColumnNameAt(getColumnIndex(_item), _name);
}
const UString& MultiListBox::getColumnName(const MultiListItem* _item) const
{
return getColumnNameAt(getColumnIndex(_item));
}
size_t MultiListBox::getColumnIndex(const MultiListItem* _item) const
{
for (size_t index = 0; index < mVectorColumnInfo.size(); ++index)
{
if (mVectorColumnInfo[index].item == _item)
return index;
}
return ITEM_NONE;
}
void MultiListBox::setColumnResizingPolicy(MultiListItem* _item, ResizingPolicy _value)
{
setColumnResizingPolicyAt(getColumnIndex(_item), _value);
}
void MultiListBox::setColumnResizingPolicyAt(size_t _index, ResizingPolicy _value)
{
MYGUI_ASSERT_RANGE(_index, mVectorColumnInfo.size(), "MultiListBox::setColumnWidthAt");
mVectorColumnInfo[_index].sizeType = _value;
updateColumns();
}
void MultiListBox::setColumnWidth(MultiListItem* _item, int _width)
{
setColumnWidthAt(getColumnIndex(_item), _width);
}
void MultiListBox::setPosition(const IntPoint& _point)
{
Base::setPosition(_point);
}
void MultiListBox::setSize(const IntSize& _size)
{
Base::setSize(_size);
if (getUpdateByResize())
updateColumns();
}
void MultiListBox::setCoord(const IntCoord& _coord)
{
Base::setCoord(_coord);
if (getUpdateByResize())
updateColumns();
}
bool MultiListBox::getUpdateByResize() const
{
if (mWidgetEmpty != nullptr)
return true;
for (const auto& info : mVectorColumnInfo)
{
if (info.sizeType == ResizingPolicy::Fill)
return true;
}
return false;
}
int MultiListBox::getColumnWidth(
size_t _index,
int _freeSpace,
size_t _countStars,
size_t _lastIndexStar,
int _starWidth) const
{
const ColumnInfo& info = mVectorColumnInfo[_index];
if (info.sizeType == ResizingPolicy::Auto)
{
return info.realWidth;
}
if (info.sizeType == ResizingPolicy::Fixed)
{
return info.realWidth;
}
if (info.sizeType == ResizingPolicy::Fill)
{
if (_lastIndexStar == _index)
{
return _starWidth + _freeSpace - (_starWidth * _countStars);
}
return _starWidth;
}
return 0;
}
int MultiListBox::updateWidthColumns(size_t& _countStars, size_t& _lastIndexStar)
{
_countStars = 0;
_lastIndexStar = ITEM_NONE;
int width = 0;
for (size_t index = 0; index < mVectorColumnInfo.size(); ++index)
{
ColumnInfo& info = mVectorColumnInfo[index];
if (info.sizeType == ResizingPolicy::Auto)
{
info.realWidth =
info.button->getWidth() - info.button->getTextRegion().width + info.button->getTextSize().width;
}
else if (info.sizeType == ResizingPolicy::Fixed)
{
info.realWidth = info.width < 0 ? 0 : info.width;
}
else if (info.sizeType == ResizingPolicy::Fill)
{
info.realWidth = 0;
_countStars++;
_lastIndexStar = index;
}
else
{
info.realWidth = 0;
}
width += info.realWidth;
}
return width;
}
void MultiListBox::updateColumns()
{
size_t countStars = 0;
size_t lastIndexStar = ITEM_NONE;
int allColumnsWidth = updateWidthColumns(countStars, lastIndexStar);
int clientWidth = _getClientWidget()->getWidth();
int separatorsWidth = mVectorColumnInfo.empty() ? 0 : (mVectorColumnInfo.size() - 1) * mWidthSeparator;
int freeSpace = clientWidth - separatorsWidth - allColumnsWidth;
int starWidth = (countStars != 0 && freeSpace > 0) ? (freeSpace / countStars) : 0;
mWidthBar = 0;
for (size_t index = 0; index < mVectorColumnInfo.size(); ++index)
{
ColumnInfo& info = mVectorColumnInfo[index];
int columnWidth = getColumnWidth(index, freeSpace, countStars, lastIndexStar, starWidth);
if (mHeaderPlace != nullptr)
{
info.item->setCoord(mWidthBar, 0, columnWidth, _getClientWidget()->getHeight());
}
else
{
info.item
->setCoord(mWidthBar, mHeightButton, columnWidth, _getClientWidget()->getHeight() - mHeightButton);
}
info.button->setCoord(mWidthBar, 0, columnWidth, getButtonHeight());
info.button->_setInternalData(index);
mWidthBar += columnWidth;
// промежуток между листами
Widget* separator = getOrCreateSeparator(index);
if (separator)
{
separator->setCoord(mWidthBar, 0, mWidthSeparator, _getClientWidget()->getHeight());
}
mWidthBar += mWidthSeparator;
}
redrawButtons();
updateOnlyEmpty();
}
} // namespace MyGUI
MyGUI_Button.h
MYGUI_ASSERT
#define MYGUI_ASSERT(exp, dest)
Definition MyGUI_Diagnostic.h:31
MYGUI_ASSERT_RANGE_INSERT
#define MYGUI_ASSERT_RANGE_INSERT(index, size, owner)
Definition MyGUI_Diagnostic.h:50
MYGUI_ASSERT_RANGE
#define MYGUI_ASSERT_RANGE(index, size, owner)
Definition MyGUI_Diagnostic.h:44
MYGUI_ASSERT_RANGE_AND_NONE
#define MYGUI_ASSERT_RANGE_AND_NONE(index, size, owner)
Definition MyGUI_Diagnostic.h:46
MyGUI_Gui.h
MyGUI_ImageBox.h
MyGUI_ListBox.h
MyGUI_MultiListBox.h
MyGUI_MultiListItem.h
MyGUI_Precompiled.h
MyGUI_ResourceSkin.h
MyGUI_WidgetManager.h
MyGUI::Any
Definition MyGUI_Any.h:56
MyGUI::Any::Null
static const Any Null
Definition MyGUI_Any.h:58
MyGUI::BiIndexBase::removeAllItems
void removeAllItems()
Definition MyGUI_BiIndexBase.cpp:94
MyGUI::BiIndexBase::swapItemsBackAt
void swapItemsBackAt(size_t _index1, size_t _index2)
Definition MyGUI_BiIndexBase.cpp:131
MyGUI::BiIndexBase::removeItemAt
size_t removeItemAt(size_t _index)
Definition MyGUI_BiIndexBase.cpp:66
MyGUI::BiIndexBase::insertItemAt
size_t insertItemAt(size_t _index)
Definition MyGUI_BiIndexBase.cpp:18
MyGUI::BiIndexBase::convertToBack
size_t convertToBack(size_t _index) const
Definition MyGUI_BiIndexBase.cpp:101
MyGUI::BiIndexBase::convertToFace
size_t convertToFace(size_t _index) const
Definition MyGUI_BiIndexBase.cpp:110
MyGUI::BiIndexBase::swapItemsFaceAt
void swapItemsFaceAt(size_t _index1, size_t _index2)
Definition MyGUI_BiIndexBase.cpp:119
MyGUI::Button
widget description should be here.
Definition MyGUI_Button.h:20
MyGUI::Gui::getInstance
static Gui & getInstance()
Definition MyGUI_Gui.cpp:34
MyGUI::Gui::eventFrameStart
EventHandle_FrameEventDelegate eventFrameStart
Definition MyGUI_Gui.h:215
MyGUI::ICroppedRectangle::getWidth
int getWidth() const
Definition MyGUI_ICroppedRectangle.h:113
MyGUI::ICroppedRectangle::getHeight
int getHeight() const
Definition MyGUI_ICroppedRectangle.h:118
MyGUI::IObject::castType
Type * castType(bool _throw=true)
Definition MyGUI_IObject.h:18
MyGUI::ListBox
widget description should be here.
Definition MyGUI_ListBox.h:28
MyGUI::ListBox::eventListChangePosition
EventPair< EventHandle_WidgetSizeT, EventHandle_ListPtrSizeT > eventListChangePosition
Definition MyGUI_ListBox.h:198
MyGUI::MultiListBox::_getItemCount
size_t _getItemCount() const override
Definition MyGUI_MultiListBox.cpp:586
MyGUI::MultiListBox::removeAllItems
void removeAllItems()
Definition MyGUI_MultiListBox.cpp:132
MyGUI::MultiListBox::setColumnWidthAt
void setColumnWidthAt(size_t _column, int _width)
Definition MyGUI_MultiListBox.cpp:79
MyGUI::MultiListBox::addItem
void addItem(const UString &_name, Any _data=Any::Null)
Definition MyGUI_MultiListBox.cpp:540
MyGUI::MultiListBox::onWidgetDestroy
void onWidgetDestroy(Widget *_widget) override
Definition MyGUI_MultiListBox.cpp:681
MyGUI::MultiListBox::_removeItemAt
void _removeItemAt(size_t _index) override
Definition MyGUI_MultiListBox.cpp:597
MyGUI::MultiListBox::insertItemAt
void insertItemAt(size_t _index, const UString &_name, Any _data=Any::Null)
Definition MyGUI_MultiListBox.cpp:447
MyGUI::MultiListBox::setColumnResizingPolicyAt
void setColumnResizingPolicyAt(size_t _index, ResizingPolicy _value)
Definition MyGUI_MultiListBox.cpp:811
MyGUI::MultiListBox::setColumnWidth
void setColumnWidth(MultiListItem *_item, int _width)
Definition MyGUI_MultiListBox.cpp:818
MyGUI::MultiListBox::_setItemNameAt
void _setItemNameAt(size_t _index, const UString &_name) override
Definition MyGUI_MultiListBox.cpp:602
MyGUI::MultiListBox::removeItemAt
void removeItemAt(size_t _index)
Remove item at a specified position.
Definition MyGUI_MultiListBox.cpp:472
MyGUI::MultiListBox::setCoord
void setCoord(const IntCoord &_coord) override
Definition MyGUI_MultiListBox.cpp:836
MyGUI::MultiListBox::requestOperatorLess
EventPair< EventHandle_MultiListPtrSizeTCUTFStringRefCUTFStringRefBoolRef, EventHandle_MultiListPtrSizeTSizeTSizeTBoolRef > requestOperatorLess
Definition MyGUI_MultiListBox.h:295
MyGUI::MultiListBox::getItemNameAt
const UString & getItemNameAt(size_t _index) const
Get item name from specified position.
Definition MyGUI_MultiListBox.cpp:550
MyGUI::MultiListBox::setColumnDataAt
void setColumnDataAt(size_t _index, Any _data)
Replace an item data at a specified position.
Definition MyGUI_MultiListBox.cpp:511
MyGUI::MultiListBox::eventListChangePosition
EventPair< EventHandle_WidgetSizeT, EventHandle_MultiListPtrSizeT > eventListChangePosition
Definition MyGUI_MultiListBox.h:282
MyGUI::MultiListBox::sortByColumn
void sortByColumn(size_t _column, bool _backward=false)
Definition MyGUI_MultiListBox.cpp:104
MyGUI::MultiListBox::_getItemNameAt
const UString & _getItemNameAt(size_t _index) const override
Definition MyGUI_MultiListBox.cpp:607
MyGUI::MultiListBox::insertColumnAt
void insertColumnAt(size_t _column, const UString &_name, int _width=0, Any _data=Any::Null)
Definition MyGUI_MultiListBox.cpp:612
MyGUI::MultiListBox::setItemNameAt
void setItemNameAt(size_t _index, const UString &_name)
Replace an item name.
Definition MyGUI_MultiListBox.cpp:545
MyGUI::MultiListBox::getColumnWidthAt
int getColumnWidthAt(size_t _column) const
Definition MyGUI_MultiListBox.cpp:92
MyGUI::MultiListBox::setSize
void setSize(const IntSize &_size) override
Definition MyGUI_MultiListBox.cpp:828
MyGUI::MultiListBox::eventListSelectAccept
EventPair< EventHandle_WidgetSizeT, EventHandle_MultiListPtrSizeT > eventListSelectAccept
Definition MyGUI_MultiListBox.h:275
MyGUI::MultiListBox::getColumnCount
size_t getColumnCount() const
Get number of columns.
Definition MyGUI_MultiListBox.cpp:525
MyGUI::MultiListBox::setSubItemDataAt
void setSubItemDataAt(size_t _column, size_t _index, Any _data)
Replace an item data at a specified position.
Definition MyGUI_MultiListBox.cpp:517
MyGUI::MultiListBox::swapItemsAt
void swapItemsAt(size_t _index1, size_t _index2)
Swap items at a specified positions.
Definition MyGUI_MultiListBox.cpp:498
MyGUI::MultiListBox::setSubItemNameAt
void setSubItemNameAt(size_t _column, size_t _index, const UString &_name)
Definition MyGUI_MultiListBox.cpp:176
MyGUI::MultiListBox::onWidgetCreated
void onWidgetCreated(Widget *_widget) override
Definition MyGUI_MultiListBox.cpp:670
MyGUI::MultiListBox::removeColumnAt
void removeColumnAt(size_t _column)
Definition MyGUI_MultiListBox.cpp:638
MyGUI::MultiListBox::_getItemAt
Widget * _getItemAt(size_t _index) const override
Definition MyGUI_MultiListBox.cpp:779
MyGUI::MultiListBox::setPosition
void setPosition(const IntPoint &_point) override
Definition MyGUI_MultiListBox.cpp:823
MyGUI::MultiListBox::clearItemDataAt
void clearItemDataAt(size_t _index)
Clear an item data at a specified position.
Definition MyGUI_MultiListBox.cpp:570
MyGUI::MultiListBox::findSubItemWith
size_t findSubItemWith(size_t _column, const UString &_name)
Definition MyGUI_MultiListBox.cpp:196
MyGUI::MultiListBox::_addItem
void _addItem(const MyGUI::UString &_name) override
Definition MyGUI_MultiListBox.cpp:591
MyGUI::MultiListBox::clearColumnDataAt
void clearColumnDataAt(size_t _index)
Clear an item data at a specified position.
Definition MyGUI_MultiListBox.cpp:535
MyGUI::MultiListBox::setItemDataAt
void setItemDataAt(size_t _index, Any _data)
Replace an item data at a specified position.
Definition MyGUI_MultiListBox.cpp:565
MyGUI::MultiListBox::shutdownOverride
void shutdownOverride() override
Definition MyGUI_MultiListBox.cpp:65
MyGUI::MultiListBox::eventNotifyItem
EventHandle_MultiListPtrCIBNotifyCellDataRef eventNotifyItem
Definition MyGUI_MultiListBox.h:302
MyGUI::MultiListBox::initialiseOverride
void initialiseOverride() override
Definition MyGUI_MultiListBox.cpp:20
MyGUI::MultiListBox::getColumnIndex
size_t getColumnIndex(const MultiListItem *_item) const
Get column index.
Definition MyGUI_MultiListBox.cpp:795
MyGUI::MultiListBox::setColumnNameAt
void setColumnNameAt(size_t _column, const UString &_name)
Definition MyGUI_MultiListBox.cpp:70
MyGUI::MultiListBox::addColumn
void addColumn(const UString &_name, int _width=0, Any _data=Any::Null)
Definition MyGUI_MultiListBox.cpp:530
MyGUI::MultiListBox::getSubItemNameAt
const UString & getSubItemNameAt(size_t _column, size_t _index) const
Definition MyGUI_MultiListBox.cpp:188
MyGUI::MultiListBox::getIndexSelected
size_t getIndexSelected() const
Definition MyGUI_MultiListBox.cpp:555
MyGUI::MultiListBox::setColumnName
void setColumnName(MultiListItem *_item, const UString &_name)
Definition MyGUI_MultiListBox.cpp:785
MyGUI::MultiListBox::setColumnResizingPolicy
void setColumnResizingPolicy(MultiListItem *_item, ResizingPolicy _value)
Definition MyGUI_MultiListBox.cpp:806
MyGUI::MultiListBox::clearSubItemDataAt
void clearSubItemDataAt(size_t _column, size_t _index)
Clear an item data at a specified position.
Definition MyGUI_MultiListBox.cpp:575
MyGUI::MultiListBox::clearIndexSelected
void clearIndexSelected()
Definition MyGUI_MultiListBox.cpp:560
MyGUI::MultiListBox::setIndexSelected
void setIndexSelected(size_t _index)
Definition MyGUI_MultiListBox.cpp:161
MyGUI::MultiListBox::getItemCount
size_t getItemCount() const
Definition MyGUI_MultiListBox.cpp:125
MyGUI::MultiListBox::getColumnNameAt
const UString & getColumnNameAt(size_t _column) const
Definition MyGUI_MultiListBox.cpp:86
MyGUI::MultiListBox::removeAllColumns
void removeAllColumns()
Definition MyGUI_MultiListBox.cpp:98
MyGUI::MultiListBox::swapColumnsAt
void swapColumnsAt(size_t _index1, size_t _index2)
Swap columns at a specified positions.
Definition MyGUI_MultiListBox.cpp:647
MyGUI::MultiListBox::getColumnName
const UString & getColumnName(const MultiListItem *_item) const
Definition MyGUI_MultiListBox.cpp:790
MyGUI::MultiListItem
widget description should be here.
Definition MyGUI_MultiListItem.h:22
MyGUI::UString
A UTF-16 string with implicit conversion to/from std::string and std::wstring.
Definition MyGUI_UString.h:144
MyGUI::UString::data
const code_point * data() const
returns a pointer to the first character in the current string
Definition MyGUI_UString.cpp:609
MyGUI::UserData::isUserString
bool isUserString(std::string_view _key) const
Definition MyGUI_WidgetUserData.cpp:44
MyGUI::UserData::getUserString
std::string_view getUserString(std::string_view _key) const
Definition MyGUI_WidgetUserData.cpp:20
MyGUI::UserData::_getInternalData
ValueType * _getInternalData(bool _throw=true) const
Definition MyGUI_WidgetUserData.h:54
MyGUI::Widget
widget description should be here.
Definition MyGUI_Widget.h:40
MyGUI::Widget::setVisible
virtual void setVisible(bool _value)
Definition MyGUI_Widget.cpp:1022
MyGUI::Widget::assignWidget
void assignWidget(T *&_widget, std::string_view _name)
Definition MyGUI_Widget.h:413
MyGUI::Widget::createWidget
T * createWidget(std::string_view _skin, const IntCoord &_coord, Align _align, std::string_view _name={})
Definition MyGUI_Widget.h:94
MyGUI::Widget::setCoord
void setCoord(const IntCoord &_coord) override
Definition MyGUI_Widget.cpp:730
MyGUI::Widget::_getClientWidget
Widget * _getClientWidget()
If there is client widget return it, otherwise return this.
Definition MyGUI_Widget.cpp:1196
MyGUI::WidgetInput::eventMouseButtonClick
EventHandle_WidgetVoid eventMouseButtonClick
Definition MyGUI_WidgetInput.h:168
MyGUI::WidgetManager::getInstance
static WidgetManager & getInstance()
MyGUI::WidgetManager::destroyWidget
void destroyWidget(Widget *_widget)
Definition MyGUI_WidgetManager.cpp:123
MyGUI::utility::parseValue
T parseValue(std::string_view _value)
Definition MyGUI_StringUtility.h:60
MyGUI
Definition MyGUI_ActionController.h:15
MyGUI::IntPoint
types::TPoint< int > IntPoint
Definition MyGUI_Types.h:27
MyGUI::ITEM_NONE
constexpr size_t ITEM_NONE
Definition MyGUI_Macros.h:19
MyGUI::IntCoord
types::TCoord< int > IntCoord
Definition MyGUI_Types.h:36
MyGUI::IntSize
types::TSize< int > IntSize
Definition MyGUI_Types.h:30
MyGUI::newDelegate
delegates::DelegateFunction< Args... > * newDelegate(void(*_func)(Args... args))
Definition MyGUI_Delegate.h:100
MyGUI::Align::Default
@ Default
Definition MyGUI_Align.h:36
MyGUI::Align::Stretch
@ Stretch
Definition MyGUI_Align.h:35
MyGUI::IBNotifyItemData::index
size_t index
Definition MyGUI_IBItemInfo.h:111
MyGUI::ResizingPolicy
Definition MyGUI_ResizingPolicy.h:16
MyGUI::ResizingPolicy::Auto
@ Auto
Definition MyGUI_ResizingPolicy.h:19
MyGUI::ResizingPolicy::Fixed
@ Fixed
Definition MyGUI_ResizingPolicy.h:20
MyGUI::ResizingPolicy::Fill
@ Fill
Definition MyGUI_ResizingPolicy.h:21