1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-10-19 20:16:37 +00:00

Allow navigating journal indices with a controller

This commit is contained in:
Andrew Lanzone 2025-06-01 01:49:57 -07:00
parent 63a533cd51
commit 95ed6b51da
6 changed files with 159 additions and 9 deletions

View file

@ -105,6 +105,18 @@ namespace MWGui
Styles mStyles; Styles mStyles;
MyGUI::IntRect mRect; MyGUI::IntRect mRect;
void setColour(int section, int line, int run, MyGUI::Colour colour) const override
{
if (section < 0 || section >= mSections.size())
return;
if (line < 0 || line >= mSections[section].mLines.size())
return;
if (run < 0 || run >= mSections[section].mLines[line].mRuns.size())
return;
mSections[section].mLines[line].mRuns[run].mStyle->mNormalColour = colour;
}
virtual ~TypesetBookImpl() {} virtual ~TypesetBookImpl() {}
Range addContent(const BookTypesetter::Utf8Span& text) Range addContent(const BookTypesetter::Utf8Span& text)

View file

@ -31,6 +31,9 @@ namespace MWGui
/// text combined prior to pagination. /// text combined prior to pagination.
virtual std::pair<unsigned int, unsigned int> getSize() const = 0; virtual std::pair<unsigned int, unsigned int> getSize() const = 0;
/// Used to highlight journal indices
virtual void setColour(int section, int line, int run, MyGUI::Colour colour) const = 0;
virtual ~TypesetBook() = default; virtual ~TypesetBook() = default;
}; };

View file

@ -169,7 +169,7 @@ namespace MWGui
{ {
BookTypesetter::Ptr typesetter = createTypesetter(); BookTypesetter::Ptr typesetter = createTypesetter();
BookTypesetter::Style* header = typesetter->createStyle({}, MyGUI::Colour(0.60f, 0.00f, 0.00f)); BookTypesetter::Style* header = typesetter->createStyle({}, journalHeaderColour);
BookTypesetter::Style* body = typesetter->createStyle({}, MyGUI::Colour::Black); BookTypesetter::Style* body = typesetter->createStyle({}, MyGUI::Colour::Black);
typesetter->write(header, to_utf8_span("You have no journal entries!")); typesetter->write(header, to_utf8_span("You have no journal entries!"));
@ -184,7 +184,7 @@ namespace MWGui
{ {
BookTypesetter::Ptr typesetter = createTypesetter(); BookTypesetter::Ptr typesetter = createTypesetter();
BookTypesetter::Style* header = typesetter->createStyle({}, MyGUI::Colour(0.60f, 0.00f, 0.00f)); BookTypesetter::Style* header = typesetter->createStyle({}, journalHeaderColour);
BookTypesetter::Style* body = typesetter->createStyle({}, MyGUI::Colour::Black); BookTypesetter::Style* body = typesetter->createStyle({}, MyGUI::Colour::Black);
mModel->visitJournalEntries({}, AddJournalEntry(typesetter, body, header, true)); mModel->visitJournalEntries({}, AddJournalEntry(typesetter, body, header, true));
@ -196,7 +196,7 @@ namespace MWGui
{ {
BookTypesetter::Ptr typesetter = createTypesetter(); BookTypesetter::Ptr typesetter = createTypesetter();
BookTypesetter::Style* header = typesetter->createStyle({}, MyGUI::Colour(0.60f, 0.00f, 0.00f)); BookTypesetter::Style* header = typesetter->createStyle({}, journalHeaderColour);
BookTypesetter::Style* body = typesetter->createStyle({}, MyGUI::Colour::Black); BookTypesetter::Style* body = typesetter->createStyle({}, MyGUI::Colour::Black);
mModel->visitTopicName(topicId, AddTopicName(typesetter, header)); mModel->visitTopicName(topicId, AddTopicName(typesetter, header));
@ -212,7 +212,7 @@ namespace MWGui
{ {
BookTypesetter::Ptr typesetter = createTypesetter(); BookTypesetter::Ptr typesetter = createTypesetter();
BookTypesetter::Style* header = typesetter->createStyle({}, MyGUI::Colour(0.60f, 0.00f, 0.00f)); BookTypesetter::Style* header = typesetter->createStyle({}, journalHeaderColour);
BookTypesetter::Style* body = typesetter->createStyle({}, MyGUI::Colour::Black); BookTypesetter::Style* body = typesetter->createStyle({}, MyGUI::Colour::Black);
AddQuestName addName(typesetter, header); AddQuestName addName(typesetter, header);

View file

@ -10,6 +10,8 @@ namespace MWGui
{ {
MWGui::BookTypesetter::Utf8Span to_utf8_span(std::string_view text); MWGui::BookTypesetter::Utf8Span to_utf8_span(std::string_view text);
const MyGUI::Colour journalHeaderColour = MyGUI::Colour(0.60f, 0.00f, 0.00f);
struct JournalBooks struct JournalBooks
{ {
typedef TypesetBook::Ptr Book; typedef TypesetBook::Ptr Book;

View file

@ -474,6 +474,9 @@ namespace
getPage(LeftTopicIndex)->showPage(mTopicIndexBook, 0); getPage(LeftTopicIndex)->showPage(mTopicIndexBook, 0);
getPage(RightTopicIndex)->showPage(mTopicIndexBook, 1); getPage(RightTopicIndex)->showPage(mTopicIndexBook, 1);
} }
if (Settings::gui().mControllerMenus)
setIndexControllerFocus(mSelectedIndex, true);
} }
void notifyJournal(MyGUI::Widget* _sender) void notifyJournal(MyGUI::Widget* _sender)
@ -493,7 +496,7 @@ namespace
MyGUI::Button* listItem = _list->getItemWidget(_list->getItemNameAt(i)); MyGUI::Button* listItem = _list->getItemWidget(_list->getItemNameAt(i));
if (listItem) if (listItem)
{ {
listItem->setStateSelected(mButtons.size() == _selectedIndex); listItem->setTextColour(mButtons.size() == _selectedIndex ? MWGui::journalHeaderColour : MyGUI::Colour::Black);
mButtons.push_back(listItem); mButtons.push_back(listItem);
} }
} }
@ -518,7 +521,10 @@ namespace
list->adjustSize(); list->adjustSize();
if (Settings::gui().mControllerMenus) if (Settings::gui().mControllerMenus)
{
mSelectedQuest = 0;
addControllerButtons(list, mSelectedQuest); addControllerButtons(list, mSelectedQuest);
}
MWBase::Environment::get().getWindowManager()->playSound(ESM::RefId::stringRefId("book page")); MWBase::Environment::get().getWindowManager()->playSound(ESM::RefId::stringRefId("book page"));
MWBase::Environment::get().getWindowManager()->updateControllerButtonsOverlay(); MWBase::Environment::get().getWindowManager()->updateControllerButtonsOverlay();
@ -688,8 +694,30 @@ namespace
return &mControllerButtons; return &mControllerButtons;
} }
void setIndexControllerFocus(int index, bool focused)
{
int col, row;
bool isRussian = (mEncoding == ToUTF8::WINDOWS_1251);
if (isRussian)
{
// Cyrillic = 30 (10 + 10 + 10)
col = index / 10;
row = index % 10;
}
else
{
// Latin = 26 (13 + 13)
col = index / 13;
row = index % 13;
}
mTopicIndexBook->setColour(col, row, 0, focused ? MWGui::journalHeaderColour : MyGUI::Colour::Black);
}
bool onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) override bool onControllerButtonEvent(const SDL_ControllerButtonEvent& arg) override
{ {
bool isRussian = (mEncoding == ToUTF8::WINDOWS_1251);
if (arg.button == SDL_CONTROLLER_BUTTON_A) // A: Mouse click or Select if (arg.button == SDL_CONTROLLER_BUTTON_A) // A: Mouse click or Select
{ {
if (mOptionsMode && mQuestMode) if (mOptionsMode && mQuestMode)
@ -704,6 +732,15 @@ namespace
Gui::MWList* list = getWidget<Gui::MWList>(TopicsList); Gui::MWList* list = getWidget<Gui::MWList>(TopicsList);
notifyTopicSelected(list->getItemNameAt(mSelectedQuest), 0); notifyTopicSelected(list->getItemNameAt(mSelectedQuest), 0);
} }
else if (mOptionsMode)
{
// Choose an index. Cyrillic capital A is a 0xd090 in UTF-8.
// Words can not be started with characters 26 or 28.
int russianOffset = 0xd090;
if (mSelectedIndex >= 26) russianOffset++;
if (mSelectedIndex >= 27) russianOffset++; // 27, not 28, because of skipping char 26
notifyIndexLinkClicked(isRussian ? mSelectedIndex + russianOffset : mSelectedIndex + 'A');
}
return true; return true;
} }
else if (arg.button == SDL_CONTROLLER_BUTTON_B) // B: Back else if (arg.button == SDL_CONTROLLER_BUTTON_B) // B: Back
@ -776,10 +813,41 @@ namespace
{ {
if (mOptionsMode && (mQuestMode || mTopicsMode)) if (mOptionsMode && (mQuestMode || mTopicsMode))
{ {
if (mButtons.size() <= 1)
return true;
// Scroll through the list of quests or topics // Scroll through the list of quests or topics
mButtons[mSelectedQuest]->setStateSelected(false); mButtons[mSelectedQuest]->setTextColour(MyGUI::Colour::Black);
mSelectedQuest = MWGui::wrap(mSelectedQuest - 1, mButtons.size()); mSelectedQuest = MWGui::wrap(mSelectedQuest - 1, mButtons.size());
mButtons[mSelectedQuest]->setStateSelected(true); mButtons[mSelectedQuest]->setTextColour(MWGui::journalHeaderColour);
}
else if (mOptionsMode)
{
setIndexControllerFocus(mSelectedIndex, false);
if (isRussian)
{
// Cyrillic = 30 (10 + 10 + 10)
if (mSelectedIndex == 0)
mSelectedIndex = 9;
else if (mSelectedIndex == 10)
mSelectedIndex = 19;
else if (mSelectedIndex == 20)
mSelectedIndex = 29;
else
mSelectedIndex--;
}
else
{
// Latin = 26 (13 + 13)
if (mSelectedIndex == 0)
mSelectedIndex = 12;
else if (mSelectedIndex == 13)
mSelectedIndex = 25;
else
mSelectedIndex--;
}
setIndexControllerFocus(mSelectedIndex, true);
setText(PageOneNum, 1); // Redraw the list
} }
return true; return true;
} }
@ -787,10 +855,41 @@ namespace
{ {
if (mOptionsMode && (mQuestMode || mTopicsMode)) if (mOptionsMode && (mQuestMode || mTopicsMode))
{ {
if (mButtons.size() <= 1)
return true;
// Scroll through the list of quests or topics // Scroll through the list of quests or topics
mButtons[mSelectedQuest]->setStateSelected(false); mButtons[mSelectedQuest]->setTextColour(MyGUI::Colour::Black);
mSelectedQuest = MWGui::wrap(mSelectedQuest + 1, mButtons.size()); mSelectedQuest = MWGui::wrap(mSelectedQuest + 1, mButtons.size());
mButtons[mSelectedQuest]->setStateSelected(true); mButtons[mSelectedQuest]->setTextColour(MWGui::journalHeaderColour);
}
else if (mOptionsMode)
{
setIndexControllerFocus(mSelectedIndex, false);
if (isRussian)
{
// Cyrillic = 30 (10 + 10 + 10)
if (mSelectedIndex == 9)
mSelectedIndex = 0;
else if (mSelectedIndex == 19)
mSelectedIndex = 10;
else if (mSelectedIndex == 29)
mSelectedIndex = 20;
else
mSelectedIndex++;
}
else
{
// Latin = 26 (13 + 13)
if (mSelectedIndex == 12)
mSelectedIndex = 0;
else if (mSelectedIndex == 25)
mSelectedIndex = 13;
else
mSelectedIndex++;
}
setIndexControllerFocus(mSelectedIndex, true);
setText(PageOneNum, 1); // Redraw the list
} }
return true; return true;
} }
@ -798,12 +897,44 @@ namespace
{ {
if (!mOptionsMode) if (!mOptionsMode)
notifyPrevPage(getWidget<MyGUI::Widget>(PrevPageBTN)); notifyPrevPage(getWidget<MyGUI::Widget>(PrevPageBTN));
else if (mOptionsMode && !mQuestMode && !mTopicsMode)
{
setIndexControllerFocus(mSelectedIndex, false);
if (isRussian)
{
// Cyrillic = 30 (10 + 10 + 10)
mSelectedIndex = (mSelectedIndex + 20) % 30;
}
else
{
// Latin = 26 (13 + 13)
mSelectedIndex = (mSelectedIndex + 13) % 26;
}
setIndexControllerFocus(mSelectedIndex, true);
setText(PageOneNum, 1); // Redraw the list
}
return true; return true;
} }
else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_RIGHT) else if (arg.button == SDL_CONTROLLER_BUTTON_DPAD_RIGHT)
{ {
if (!mOptionsMode) if (!mOptionsMode)
notifyNextPage(getWidget<MyGUI::Widget>(NextPageBTN)); notifyNextPage(getWidget<MyGUI::Widget>(NextPageBTN));
else if (mOptionsMode && !mQuestMode && !mTopicsMode)
{
setIndexControllerFocus(mSelectedIndex, false);
if (isRussian)
{
// Cyrillic = 30 (10 + 10 + 10)
mSelectedIndex = (mSelectedIndex + 10) % 30;
}
else
{
// Latin = 26 (13 + 13)
mSelectedIndex = (mSelectedIndex + 13) % 26;
}
setIndexControllerFocus(mSelectedIndex, true);
setText(PageOneNum, 1); // Redraw the list
}
return true; return true;
} }
else if (arg.button == SDL_CONTROLLER_BUTTON_LEFTSHOULDER) // LB: Previous Page else if (arg.button == SDL_CONTROLLER_BUTTON_LEFTSHOULDER) // LB: Previous Page

View file

@ -34,6 +34,8 @@ namespace MWGui
std::vector<MyGUI::Button*> mButtons; std::vector<MyGUI::Button*> mButtons;
int mSelectedQuest = 0; int mSelectedQuest = 0;
int mSelectedIndex = 0;
void setIndexControllerFocus(int index, bool focused);
}; };
} }