From 3f63700e993367c45548c995f6bf0fb30d02d737 Mon Sep 17 00:00:00 2001 From: Alexei Kotov Date: Sun, 9 Mar 2025 19:20:24 +0300 Subject: [PATCH] Improve topic and magic effect list padding accuracy This also touches the quest list, but there are bigger problems with the journal than just padding --- apps/openmw/mwgui/dialogue.cpp | 5 ++++- components/widgets/list.cpp | 29 ++++++++++++++++------------- components/widgets/list.hpp | 15 +++++++++++++-- 3 files changed, 33 insertions(+), 16 deletions(-) diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index e14c400978..6b1e007770 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -588,10 +588,13 @@ namespace MWGui if (mTopicsList->getItemCount() > 0) mTopicsList->addSeparator(); + // Morrowind uses 3 px invisible borders for padding topics + constexpr int verticalPadding = 3; + for (const auto& keyword : mKeywords) { std::string topicId = Misc::StringUtils::lowerCase(keyword); - mTopicsList->addItem(keyword); + mTopicsList->addItem(keyword, verticalPadding); auto t = std::make_unique(keyword); mKeywordSearch.seed(topicId, intptr_t(t.get())); diff --git a/components/widgets/list.cpp b/components/widgets/list.cpp index 896057443c..416590ed48 100644 --- a/components/widgets/list.cpp +++ b/components/widgets/list.cpp @@ -29,14 +29,14 @@ namespace Gui MyGUI::Align::Top | MyGUI::Align::Left | MyGUI::Align::Stretch, getName() + "_ScrollView"); } - void MWList::addItem(std::string_view name) + void MWList::addItem(std::string_view name, int verticalPadding) { - mItems.emplace_back(name); + mItems.emplace_back(name, verticalPadding); } void MWList::addSeparator() { - mItems.emplace_back(std::string{}); + addItem({}); } void MWList::adjustSize() @@ -48,7 +48,6 @@ namespace Gui { constexpr int _scrollBarWidth = 20; // fetch this from skin? const int scrollBarWidth = scrollbarShown ? _scrollBarWidth : 0; - constexpr int spacing = 3; int viewPosition = -mScrollView->getViewOffset().top; while (mScrollView->getChildCount()) @@ -60,25 +59,27 @@ namespace Gui int i = 0; for (const auto& item : mItems) { - if (!item.empty()) + mItemHeight += item.mVPadding; + if (!item.mName.empty()) { if (mListItemSkin.empty()) return; MyGUI::Button* button = mScrollView->createWidget(mListItemSkin, MyGUI::IntCoord(0, mItemHeight, mScrollView->getSize().width - scrollBarWidth - 2, 24), - MyGUI::Align::Left | MyGUI::Align::Top, getName() + "_item_" + item); - button->setCaption(item); + MyGUI::Align::Left | MyGUI::Align::Top, getName() + "_item_" + item.mName); + button->setCaption(item.mName); button->getSubWidgetText()->setWordWrap(true); button->getSubWidgetText()->setTextAlign(MyGUI::Align::Left); button->eventMouseWheel += MyGUI::newDelegate(this, &MWList::onMouseWheelMoved); button->eventMouseButtonClick += MyGUI::newDelegate(this, &MWList::onItemSelected); button->setNeedKeyFocus(true); - int height = button->getTextSize().height; + // Morrowind list item text widgets are typically 18 pixels tall + int height = button->getTextSize().height + 2; button->setSize(MyGUI::IntSize(button->getSize().width, height)); button->setUserData(i); - mItemHeight += height + spacing; + mItemHeight += height; } else { @@ -87,8 +88,9 @@ namespace Gui MyGUI::Align::Left | MyGUI::Align::Top | MyGUI::Align::HStretch); separator->setNeedMouseFocus(false); - mItemHeight += 18 + spacing; + mItemHeight += 18; } + mItemHeight += item.mVPadding; ++i; } @@ -123,18 +125,19 @@ namespace Gui const std::string& MWList::getItemNameAt(size_t at) { assert(at < mItems.size() && "List item out of bounds"); - return mItems[at]; + return mItems[at].mName; } void MWList::sort() { // A special case for separators is not needed for now - std::sort(mItems.begin(), mItems.end(), Misc::StringUtils::ciLess); + std::sort(mItems.begin(), mItems.end(), + [](const auto& left, const auto& right) { return Misc::StringUtils::ciLess(left.mName, right.mName); }); } void MWList::removeItem(const std::string& name) { - auto it = std::find(mItems.begin(), mItems.end(), name); + auto it = std::find_if(mItems.begin(), mItems.end(), [&name](const auto& item) { return item.mName == name; }); assert(it != mItems.end()); mItems.erase(it); } diff --git a/components/widgets/list.hpp b/components/widgets/list.hpp index 3d5e320cf7..f67a7da97b 100644 --- a/components/widgets/list.hpp +++ b/components/widgets/list.hpp @@ -36,7 +36,7 @@ namespace Gui void adjustSize(); void sort(); - void addItem(std::string_view name); + void addItem(std::string_view name, int verticalPadding = 0); void addSeparator(); ///< add a seperator between the current and the next item. void removeItem(const std::string& name); size_t getItemCount(); @@ -64,7 +64,18 @@ namespace Gui MyGUI::Widget* mClient; std::string mListItemSkin; - std::vector mItems; + struct ListItemData + { + std::string mName; + int mVPadding; + + ListItemData(std::string_view name, int verticalPadding) + : mName(name) + , mVPadding(verticalPadding) + { + } + }; + std::vector mItems; int mItemHeight; // height of all items };