Implement event filter in InputDialog (resolves #517)

This commit is contained in:
Thomas Jentzsch 2019-08-17 15:42:39 +02:00
parent 82c6b5544d
commit 019f4ae247
7 changed files with 417 additions and 89 deletions

View File

@ -124,6 +124,15 @@ class Event
};
// Event categorizing groups
enum Group
{
Menu, Emulation,
Misc, AudioVideo, States, Console, Joystick, Paddles, Keyboard,
Debug, Combo,
LastGroup
};
// Event list version, update if the id of existing event types changed
static constexpr Int32 VERSION = 3;

View File

@ -1250,6 +1250,80 @@ StringList EventHandler::getActionList(EventMode mode) const
return l;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
StringList EventHandler::getActionList(Event::Group group) const
{
StringList l;
switch(group)
{
case Event::Group::Menu:
return getActionList(EventMode::kMenuMode);
case Event::Group::Emulation:
return getActionList(EventMode::kEmulationMode);
case Event::Group::Misc:
return getActionList(MiscEvents);
case Event::Group::AudioVideo:
return getActionList(AudioVideoEvents);
case Event::Group::States:
return getActionList(StateEvents);
case Event::Group::Console:
return getActionList(ConsoleEvents);
case Event::Group::Joystick:
return getActionList(JoystickEvents);
case Event::Group::Paddles:
return getActionList(PaddlesEvents);
case Event::Group::Keyboard:
return getActionList(KeyboardEvents);
case Event::Group::Debug:
return getActionList(DebugEvents);
case Event::Group::Combo:
return getActionList(ComboEvents);
default:
return l; // ToDo
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
StringList EventHandler::getActionList(const EventList& events, EventMode mode) const
{
StringList l;
switch(mode)
{
case EventMode::kMenuMode:
for(uInt32 i = 0; i < MENU_ACTIONLIST_SIZE; ++i)
for(const auto& event : events)
if(EventHandler::ourMenuActionList[i].event == event)
{
l.push_back(EventHandler::ourMenuActionList[i].action);
break;
}
break;
default:
for(uInt32 i = 0; i < EMUL_ACTIONLIST_SIZE; ++i)
for(const auto& event : events)
if(EventHandler::ourEmulActionList[i].event == event)
{
l.push_back(EventHandler::ourEmulActionList[i].action);
break;
}
}
return l;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
VariantList EventHandler::getComboList(EventMode /**/) const
{
@ -1320,62 +1394,136 @@ void EventHandler::setComboListForEvent(Event::Type event, const StringList& eve
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Event::Type EventHandler::eventAtIndex(int idx, EventMode mode) const
int EventHandler::getEmulActionListIndex(int idx, const EventList& events) const
{
switch(mode)
// idx = index into intersection set of 'events' and 'ourEmulActionList'
// ordered by 'ourEmulActionList'!
Event::Type event = Event::NoType;
for(uInt32 i = 0; i < EMUL_ACTIONLIST_SIZE; ++i)
{
case EventMode::kEmulationMode:
if(idx < 0 || idx >= EMUL_ACTIONLIST_SIZE)
return Event::NoType;
else
return ourEmulActionList[idx].event;
case EventMode::kMenuMode:
if(idx < 0 || idx >= MENU_ACTIONLIST_SIZE)
return Event::NoType;
else
return ourMenuActionList[idx].event;
for(const auto& item : events)
if(EventHandler::ourEmulActionList[i].event == item)
{
idx--;
if(idx < 0)
event = item;
break;
}
if(idx < 0)
break;
}
for(uInt32 i = 0; i < EMUL_ACTIONLIST_SIZE; ++i)
if(EventHandler::ourEmulActionList[i].event == event)
return i;
return -1;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int EventHandler::getActionListIndex(int idx, Event::Group group) const
{
switch(group)
{
case Event::Group::Menu:
return idx;
case Event::Group::Emulation:
return idx;
case Event::Group::Misc:
return getEmulActionListIndex(idx, MiscEvents);
case Event::Group::AudioVideo:
return getEmulActionListIndex(idx, AudioVideoEvents);
case Event::Group::States:
return getEmulActionListIndex(idx, StateEvents);
case Event::Group::Console:
return getEmulActionListIndex(idx, ConsoleEvents);
case Event::Group::Joystick:
return getEmulActionListIndex(idx, JoystickEvents);
case Event::Group::Paddles:
return getEmulActionListIndex(idx, PaddlesEvents);
case Event::Group::Keyboard:
return getEmulActionListIndex(idx, KeyboardEvents);
case Event::Group::Debug:
return getEmulActionListIndex(idx, DebugEvents);
case Event::Group::Combo:
return getEmulActionListIndex(idx, ComboEvents);
default:
return Event::NoType;
return -1;
};
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Event::Type EventHandler::eventAtIndex(int idx, Event::Group group) const
{
int index = getActionListIndex(idx, group);
switch(group)
{
case Event::Group::Menu:
if(index < 0 || index >= MENU_ACTIONLIST_SIZE)
return Event::NoType;
else
return ourMenuActionList[index].event;
default:
if(index < 0 || index >= EMUL_ACTIONLIST_SIZE)
return Event::NoType;
else
return ourEmulActionList[index].event;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string EventHandler::actionAtIndex(int idx, EventMode mode) const
string EventHandler::actionAtIndex(int idx, Event::Group group) const
{
switch(mode)
int index = getActionListIndex(idx, group);
switch(group)
{
case EventMode::kEmulationMode:
if(idx < 0 || idx >= EMUL_ACTIONLIST_SIZE)
case Event::Group::Menu:
if(index < 0 || index >= MENU_ACTIONLIST_SIZE)
return EmptyString;
else
return ourEmulActionList[idx].action;
case EventMode::kMenuMode:
if(idx < 0 || idx >= MENU_ACTIONLIST_SIZE)
return EmptyString;
else
return ourMenuActionList[idx].action;
return ourMenuActionList[index].action;
default:
return EmptyString;
if(index < 0 || index >= EMUL_ACTIONLIST_SIZE)
return EmptyString;
else
return ourEmulActionList[index].action;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string EventHandler::keyAtIndex(int idx, EventMode mode) const
string EventHandler::keyAtIndex(int idx, Event::Group group) const
{
switch(mode)
int index = getActionListIndex(idx, group);
switch(group)
{
case EventMode::kEmulationMode:
if(idx < 0 || idx >= EMUL_ACTIONLIST_SIZE)
case Event::Group::Menu:
if(index < 0 || index >= MENU_ACTIONLIST_SIZE)
return EmptyString;
else
return ourEmulActionList[idx].key;
case EventMode::kMenuMode:
if(idx < 0 || idx >= MENU_ACTIONLIST_SIZE)
return EmptyString;
else
return ourMenuActionList[idx].key;
return ourMenuActionList[index].key;
default:
return EmptyString;
if(index < 0 || index >= EMUL_ACTIONLIST_SIZE)
return EmptyString;
else
return ourEmulActionList[index].key;
}
}
@ -1579,10 +1727,14 @@ void EventHandler::exitEmulation()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
EventHandler::ActionList EventHandler::ourEmulActionList[EMUL_ACTIONLIST_SIZE] = {
{ Event::Quit, "Quit", "" },
{ Event::ReloadConsole, "Reload current ROM/load next game", "" },
{ Event::Fry, "Fry cartridge", "" },
{ Event::ExitMode, "Exit current Stella menu/mode", "" },
{ Event::OptionsMenuMode, "Enter Options menu UI", "" },
{ Event::CmdMenuMode, "Toggle Commands menu UI", "" },
{ Event::DebuggerMode, "Toggle Debugger mode", "" },
{ Event::TogglePauseMode, "Toggle Pause mode", "" },
{ Event::StartPauseMode, "Start Pause mode", "" },
{ Event::ConsoleSelect, "Select", "" },
{ Event::ConsoleReset, "Reset", "" },
@ -1600,9 +1752,11 @@ EventHandler::ActionList EventHandler::ourEmulActionList[EMUL_ACTIONLIST_SIZE] =
{ Event::ChangeState, "Change state slot", "" },
{ Event::ToggleAutoSlot, "Toggle automatic state slot change", "" },
{ Event::LoadState, "Load state", "" },
#ifdef PNG_SUPPORT
{ Event::TakeSnapshot, "Snapshot", "" },
{ Event::TogglePauseMode, "Toggle pause mode", "" },
{ Event::StartPauseMode, "Start pause mode", "" },
{ Event::ToggleContSnapshots, "Save continuous snapsh. (as defined)", "" },
{ Event::ToggleContSnapshotsFrame,"Save continuous snapsh. (every frame)", "" },
#endif
{ Event::JoystickZeroUp, "P0 Joystick Up", "" },
{ Event::JoystickZeroDown, "P0 Joystick Down", "" },
@ -1665,6 +1819,16 @@ EventHandler::ActionList EventHandler::ourEmulActionList[EMUL_ACTIONLIST_SIZE] =
{ Event::KeyboardOneStar, "P1 Keyboard *", "" },
{ Event::KeyboardOne0, "P1 Keyboard 0", "" },
{ Event::KeyboardOnePound, "P1 Keyboard #", "" },
// Video
{ Event::VidmodeDecrease, "Previous zoom level", "" },
{ Event::VidmodeIncrease, "Next zoom level", "" },
{ Event::ToggleFullScreen, "Toggle fullscreen", "" },
{ Event::DecreaseOverscan, "Decrease overscan in fullscreen mode", "" },
{ Event::IncreaseOverScan, "Increase overscan in fullscreen mode", "" },
{ Event::DecreaseFormat, "Decrease display format", "" },
{ Event::IncreaseFormat, "Increase display format", "" },
{ Event::TogglePalette, "Switch palette (Standard/Z26/User)", "" },
// TV effects:
{ Event::VidmodeStd, "Disable TV effects", "" },
{ Event::VidmodeRGB, "Select 'RGB' preset", "" },
@ -1701,14 +1865,6 @@ EventHandler::ActionList EventHandler::ourEmulActionList[EMUL_ACTIONLIST_SIZE] =
{ Event::ToggleColorLoss, "Toggle PAL color-loss effect", "" },
{ Event::ToggleJitter, "Toggle TV 'Jitter' effect", "" },
// Other keys:
{ Event::VidmodeDecrease, "Previous zoom level", "" },
{ Event::VidmodeIncrease, "Next zoom level", "" },
{ Event::ToggleFullScreen, "Toggle fullscreen", "" },
{ Event::DecreaseOverscan, "Decrease overscan in fullscreen mode", "" },
{ Event::IncreaseOverScan, "Increase overscan in fullscreen mode", "" },
{ Event::DecreaseFormat, "Decrease display format", "" },
{ Event::IncreaseFormat, "Increase display format", "" },
{ Event::TogglePalette, "Switch palette (Standard/Z26/User)", "" },
{ Event::SoundToggle, "Toggle sound", "" },
{ Event::VolumeDecrease, "Decrease volume", "" },
{ Event::VolumeIncrease, "Increase volume", "" },
@ -1716,25 +1872,19 @@ EventHandler::ActionList EventHandler::ourEmulActionList[EMUL_ACTIONLIST_SIZE] =
{ Event::HandleMouseControl, "Switch mouse emulation modes", "" },
{ Event::ToggleGrabMouse, "Toggle grab mouse", "" },
{ Event::ToggleSAPortOrder, "Swap Stelladaptor port ordering", "" },
{ Event::ReloadConsole, "Reload current ROM/load next game", "" },
{ Event::Fry, "Fry cartridge", "" },
#ifdef PNG_SUPPORT
{ Event::ToggleContSnapshots, "Save cont. PNG snapsh. (as defined)", "" },
{ Event::ToggleContSnapshotsFrame,"Save cont. PNG snapsh. (every frame)", "" },
#endif
{ Event::SaveAllStates, "Save all TM states of current game", "" },
{ Event::LoadAllStates, "Load saved TM states for current game", "" },
{ Event::ToggleTimeMachine, "Toggle 'Time Machine' mode", "" },
{ Event::TimeMachineMode, "Toggle 'Time Machine' UI", "" },
{ Event::RewindPause, "Rewind one state & enter pause mode", "" },
{ Event::RewindPause, "Rewind one state & enter Pause mode", "" },
{ Event::Rewind1Menu, "Rewind one state & enter TM UI", "" },
{ Event::Rewind10Menu, "Rewind 10 states & enter TM UI", "" },
{ Event::RewindAllMenu, "Rewind all states & enter TM UI", "" },
{ Event::UnwindPause, "Unwind one state & enter pause mode", "" },
{ Event::UnwindPause, "Unwind one state & enter Pause mode", "" },
{ Event::Unwind1Menu, "Unwind one state & enter TM UI", "" },
{ Event::Unwind10Menu, "Unwind 10 states & enter TM UI", "" },
{ Event::UnwindAllMenu, "Unwind all states & enter TM UI", "" },
{ Event::SaveAllStates, "Save all TM states of current game", "" },
{ Event::LoadAllStates, "Load saved TM states for current game", "" },
{ Event::Combo1, "Combo 1", "" },
{ Event::Combo2, "Combo 2", "" },
@ -1779,3 +1929,94 @@ EventHandler::ActionList EventHandler::ourMenuActionList[MENU_ACTIONLIST_SIZE] =
{ Event::ToggleFullScreen, "Toggle fullscreen", "" },
{ Event::Quit, "Quit", "" }
};
// Event groups
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const EventHandler::EventList EventHandler::MiscEvents = {
Event::Quit, Event::ReloadConsole, Event::Fry, Event::StartPauseMode,
Event::TogglePauseMode, Event::OptionsMenuMode, Event::CmdMenuMode, Event::DebuggerMode, Event::ExitMode,
Event::TakeSnapshot, Event::ToggleContSnapshots, Event::ToggleContSnapshotsFrame,
// Event::MouseAxisXValue, Event::MouseAxisYValue,
// Event::MouseButtonLeftValue, Event::MouseButtonRightValue,
Event::HandleMouseControl, Event::ToggleGrabMouse,
Event::ToggleSAPortOrder,
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const EventHandler::EventList EventHandler::AudioVideoEvents = {
Event::VolumeDecrease, Event::VolumeIncrease, Event::SoundToggle,
Event::VidmodeDecrease, Event::VidmodeIncrease,
Event::ToggleFullScreen,
Event::VidmodeStd, Event::VidmodeRGB, Event::VidmodeSVideo, Event::VidModeComposite, Event::VidModeBad, Event::VidModeCustom,
Event::PreviousAttribute, Event::NextAttribute, Event::DecreaseAttribute, Event::IncreaseAttribute,
Event::ScanlinesDecrease, Event::ScanlinesIncrease,
Event::DecreasePhosphor, Event::IncreasePhosphor, Event::TogglePhosphor,
Event::DecreaseFormat, Event::IncreaseFormat,
Event::DecreaseOverscan, Event::IncreaseOverScan,
Event::TogglePalette,
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const EventHandler::EventList EventHandler::StateEvents = {
Event::ChangeState, Event::LoadState, Event::SaveState, Event::TimeMachineMode,
Event::RewindPause, Event::UnwindPause, Event::ToggleTimeMachine,
Event::Rewind1Menu, Event::Rewind10Menu, Event::RewindAllMenu,
Event::Unwind1Menu, Event::Unwind10Menu, Event::UnwindAllMenu,
Event::SaveAllStates, Event::LoadAllStates, Event::ToggleAutoSlot,
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const EventHandler::EventList EventHandler::ConsoleEvents = {
Event::ConsoleOn, Event::ConsoleOff, Event::ConsoleColor, Event::ConsoleBlackWhite,
Event::ConsoleLeftDiffA, Event::ConsoleLeftDiffB,
Event::ConsoleRightDiffA, Event::ConsoleRightDiffB,
Event::ConsoleSelect, Event::ConsoleReset,
Event::ConsoleLeftDiffToggle, Event::ConsoleRightDiffToggle, Event::ConsoleColorToggle,
Event::Console7800Pause,
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const EventHandler::EventList EventHandler::JoystickEvents = {
Event::JoystickZeroUp, Event::JoystickZeroDown, Event::JoystickZeroLeft, Event::JoystickZeroRight,
Event::JoystickZeroFire, Event::JoystickZeroFire5, Event::JoystickZeroFire9,
Event::JoystickOneUp, Event::JoystickOneDown, Event::JoystickOneLeft, Event::JoystickOneRight,
Event::JoystickOneFire, Event::JoystickOneFire5, Event::JoystickOneFire9,
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const EventHandler::EventList EventHandler::PaddlesEvents = {
Event::PaddleZeroDecrease, Event::PaddleZeroIncrease, Event::PaddleZeroAnalog, Event::PaddleZeroFire,
Event::PaddleOneDecrease, Event::PaddleOneIncrease, Event::PaddleOneAnalog, Event::PaddleOneFire,
Event::PaddleTwoDecrease, Event::PaddleTwoIncrease, Event::PaddleTwoAnalog, Event::PaddleTwoFire,
Event::PaddleThreeDecrease, Event::PaddleThreeIncrease, Event::PaddleThreeAnalog, Event::PaddleThreeFire,
};
const EventHandler::EventList EventHandler::KeyboardEvents = {
Event::KeyboardZero1, Event::KeyboardZero2, Event::KeyboardZero3,
Event::KeyboardZero4, Event::KeyboardZero5, Event::KeyboardZero6,
Event::KeyboardZero7, Event::KeyboardZero8, Event::KeyboardZero9,
Event::KeyboardZeroStar, Event::KeyboardZero0, Event::KeyboardZeroPound,
Event::KeyboardOne1, Event::KeyboardOne2, Event::KeyboardOne3,
Event::KeyboardOne4, Event::KeyboardOne5, Event::KeyboardOne6,
Event::KeyboardOne7, Event::KeyboardOne8, Event::KeyboardOne9,
Event::KeyboardOneStar, Event::KeyboardOne0, Event::KeyboardOnePound,
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const EventHandler::EventList EventHandler::DebugEvents = {
Event::ToggleFrameStats,
Event::ToggleP0Collision, Event::ToggleP0Bit, Event::ToggleP1Collision, Event::ToggleP1Bit,
Event::ToggleM0Collision, Event::ToggleM0Bit, Event::ToggleM1Collision, Event::ToggleM1Bit,
Event::ToggleBLCollision, Event::ToggleBLBit, Event::TogglePFCollision, Event::TogglePFBit,
Event::ToggleCollisions, Event::ToggleBits, Event::ToggleFixedColors,
Event::ToggleColorLoss,
Event::ToggleJitter,
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const EventHandler::EventList EventHandler::ComboEvents = {
Event::Combo1, Event::Combo2, Event::Combo3, Event::Combo4, Event::Combo5, Event::Combo6, Event::Combo7, Event::Combo8,
Event::Combo9, Event::Combo10, Event::Combo11, Event::Combo12, Event::Combo13, Event::Combo14, Event::Combo15, Event::Combo16,
};

View File

@ -151,7 +151,7 @@ class EventHandler
bool frying() const { return myFryingFlag; }
StringList getActionList(EventMode mode) const;
StringList getActionList(Event::Group group) const;
VariantList getComboList(EventMode mode) const;
/** Used to access the list of events assigned to a specific combo event. */
@ -177,9 +177,9 @@ class EventHandler
return myPKeyHandler->getMappingDesc(event, mode);
}
Event::Type eventAtIndex(int idx, EventMode mode) const;
string actionAtIndex(int idx, EventMode mode) const;
string keyAtIndex(int idx, EventMode mode) const;
Event::Type eventAtIndex(int idx, Event::Group group) const;
string actionAtIndex(int idx, Event::Group group) const;
string keyAtIndex(int idx, Event::Group group) const;
/**
Bind a key to an event/action and regenerate the mapping array(s).
@ -400,6 +400,18 @@ class EventHandler
MENU_ACTIONLIST_SIZE = 18
;
using EventList = std::vector<Event::Type>;
// Define event groups
static const EventList MiscEvents;
static const EventList StateEvents;
static const EventList AudioVideoEvents;
static const EventList ConsoleEvents;
static const EventList JoystickEvents;
static const EventList PaddlesEvents;
static const EventList KeyboardEvents;
static const EventList DebugEvents;
static const EventList ComboEvents;
/**
The following methods take care of assigning action mappings.
*/
@ -408,6 +420,12 @@ class EventHandler
void setDefaultJoymap(Event::Type, EventMode mode);
void saveComboMapping();
StringList getActionList(EventMode mode) const;
StringList getActionList(const EventList& events, EventMode mode = EventMode::kEmulationMode) const;
// returns the action array index of the index in the provided group
int getEmulActionListIndex(int idx, const EventList& events) const;
int getActionListIndex(int idx, Event::Group group) const;
private:
// Structure used for action menu items
struct ActionList {

View File

@ -21,6 +21,7 @@
#include "OSystem.hxx"
#include "GuiObject.hxx"
#include "PopUpWidget.hxx"
#include "FrameBuffer.hxx"
#include "EventHandler.hxx"
#include "Event.hxx"
@ -36,11 +37,13 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
EventMappingWidget::EventMappingWidget(GuiObject* boss, const GUI::Font& font,
int x, int y, int w, int h,
const StringList& actions, EventMode mode)
EventMode mode)
: Widget(boss, font, x, y, w, h),
CommandSender(boss),
CommandSender(boss),
myFilterPopup(nullptr),
myComboDialog(nullptr),
myEventMode(mode),
myEventGroup(Event::Group::Emulation),
myActionSelected(-1),
myRemapStatus(false),
myLastStick(0),
@ -59,12 +62,37 @@ EventMappingWidget::EventMappingWidget(GuiObject* boss, const GUI::Font& font,
const int VBORDER = 8;
const int ACTION_LINES = 2;
int xpos = HBORDER, ypos = VBORDER;
const int listWidth = _w - buttonWidth - HBORDER * 2 - 8;
int listHeight = _h - (2 + ACTION_LINES) * lineHeight - VBORDER + 2;
myActionsList = new StringListWidget(boss, font, xpos, ypos,
_w - buttonWidth - HBORDER * 2 - 8, _h - (2 + ACTION_LINES) * lineHeight - VBORDER);
if(mode == EventMode::kEmulationMode)
{
VariantList items;
items.clear();
VarList::push_back(items, "All", Event::Group::Emulation);
VarList::push_back(items, "Miscellaneous", Event::Group::Misc);
VarList::push_back(items, "Video & Audio", Event::Group::AudioVideo);
VarList::push_back(items, "States", Event::Group::States);
VarList::push_back(items, "Console", Event::Group::Console);
VarList::push_back(items, "Joystick", Event::Group::Joystick);
VarList::push_back(items, "Paddles", Event::Group::Paddles);
VarList::push_back(items, "Keyboard", Event::Group::Keyboard);
VarList::push_back(items, "Combo", Event::Group::Combo);
VarList::push_back(items, "Debug", Event::Group::Debug);
myFilterPopup = new PopUpWidget(boss, font, xpos, ypos,
listWidth - font.getStringWidth("Events ") - 23, lineHeight,
items, "Events ", 0, kFilterCmd);
myFilterPopup->setTarget(this);
addFocusWidget(myFilterPopup);
ypos += lineHeight + 8;
listHeight -= lineHeight + 8;
}
myActionsList = new StringListWidget(boss, font, xpos, ypos, listWidth, listHeight);
myActionsList->setTarget(this);
myActionsList->setEditable(false);
myActionsList->setList(actions);
addFocusWidget(myActionsList);
// Add remap, erase, cancel and default buttons
@ -113,13 +141,15 @@ EventMappingWidget::EventMappingWidget(GuiObject* boss, const GUI::Font& font,
myComboButton = nullptr;
// Show message for currently selected event
xpos = HBORDER; ypos = VBORDER + myActionsList->getHeight() + 8;
xpos = HBORDER;
ypos = myActionsList->getBottom() + 8;
StaticTextWidget* t;
t = new StaticTextWidget(boss, font, xpos, ypos+2, font.getStringWidth("Action"),
fontHeight, "Action", TextAlign::Left);
myKeyMapping = new EditTextWidget(boss, font, xpos + t->getWidth() + 8, ypos,
_w - xpos - t->getWidth() - 8 - HBORDER, lineHeight * ACTION_LINES, "");
_w - xpos - t->getWidth() - 8 - HBORDER,
lineHeight + font.getFontHeight() * (ACTION_LINES - 1), "");
myKeyMapping->setEditable(false, true);
myKeyMapping->clearFlags(Widget::FLAG_RETAIN_FOCUS);
}
@ -129,17 +159,18 @@ void EventMappingWidget::loadConfig()
{
if(myFirstTime)
{
myActionsList->setSelected(0);
if(myFilterPopup)
myFilterPopup->setSelectedIndex(0);
myFirstTime = false;
}
else
// controller IDs may have changed in between
drawKeyMapping();
// Make sure remapping is turned off, just in case the user didn't properly
// exit last time
if(myRemapStatus)
stopRemapping();
updateActions();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -147,6 +178,20 @@ void EventMappingWidget::saveConfig()
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void EventMappingWidget::updateActions()
{
if(myFilterPopup)
myEventGroup = Event::Group(myFilterPopup->getSelectedTag().toInt());
else
myEventGroup = Event::Group::Menu;
StringList actions = instance().eventHandler().getActionList(myEventGroup);
myActionsList->setList(actions);
myActionSelected = myActionsList->getSelected();
drawKeyMapping();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void EventMappingWidget::setDefaults()
{
@ -180,7 +225,7 @@ void EventMappingWidget::startRemapping()
// And show a message indicating which key is being remapped
ostringstream buf;
buf << "Select action for '"
<< instance().eventHandler().actionAtIndex(myActionSelected, myEventMode)
<< instance().eventHandler().actionAtIndex(myActionSelected, myEventGroup)
<< "' event";
myKeyMapping->setTextColor(kTextColorEm);
myKeyMapping->setText(buf.str());
@ -197,7 +242,7 @@ void EventMappingWidget::eraseRemapping()
return;
Event::Type event =
instance().eventHandler().eventAtIndex(myActionSelected, myEventMode);
instance().eventHandler().eventAtIndex(myActionSelected, myEventGroup);
instance().eventHandler().eraseMapping(event, myEventMode);
drawKeyMapping();
@ -210,7 +255,7 @@ void EventMappingWidget::resetRemapping()
return;
Event::Type event =
instance().eventHandler().eventAtIndex(myActionSelected, myEventMode);
instance().eventHandler().eventAtIndex(myActionSelected, myEventGroup);
instance().eventHandler().setDefaultMapping(event, myEventMode);
drawKeyMapping();
@ -246,7 +291,7 @@ void EventMappingWidget::drawKeyMapping()
if(myActionSelected >= 0)
{
myKeyMapping->setTextColor(kTextColor);
myKeyMapping->setText(instance().eventHandler().keyAtIndex(myActionSelected, myEventMode));
myKeyMapping->setText(instance().eventHandler().keyAtIndex(myActionSelected, myEventGroup));
}
}
@ -261,7 +306,7 @@ void EventMappingWidget::enableButtons(bool state)
if(myComboButton)
{
Event::Type e =
instance().eventHandler().eventAtIndex(myActionSelected, myEventMode);
instance().eventHandler().eventAtIndex(myActionSelected, myEventGroup);
myComboButton->setEnabled(state && e >= Event::Combo1 && e <= Event::Combo16);
}
@ -292,7 +337,7 @@ bool EventMappingWidget::handleKeyUp(StellaKey key, StellaMod mod)
&& (mod & (KBDM_CTRL | KBDM_SHIFT | KBDM_ALT | KBDM_GUI)) == 0)
{
Event::Type event =
instance().eventHandler().eventAtIndex(myActionSelected, myEventMode);
instance().eventHandler().eventAtIndex(myActionSelected, myEventGroup);
// if not pressed alone, map left and right modifier keys
if(myLastKey < KBDK_LCTRL || myLastKey > KBDK_RGUI)
@ -332,7 +377,7 @@ void EventMappingWidget::handleJoyUp(int stick, int button)
if (myLastStick == stick && myLastButton == button)
{
EventHandler& eh = instance().eventHandler();
Event::Type event = eh.eventAtIndex(myActionSelected, myEventMode);
Event::Type event = eh.eventAtIndex(myActionSelected, myEventGroup);
// map either button/hat, solo button or button/axis combinations
if(myLastHat != -1)
@ -368,7 +413,7 @@ void EventMappingWidget::handleJoyAxis(int stick, JoyAxis axis, JoyDir adir, int
else if(myLastStick == stick && axis == myLastAxis && adir == JoyDir::NONE)
{
EventHandler& eh = instance().eventHandler();
Event::Type event = eh.eventAtIndex(myActionSelected, myEventMode);
Event::Type event = eh.eventAtIndex(myActionSelected, myEventGroup);
if (eh.addJoyMapping(event, myEventMode, stick, myLastButton, axis, myLastDir))
stopRemapping();
@ -399,7 +444,7 @@ bool EventMappingWidget::handleJoyHat(int stick, int hat, JoyHatDir hdir, int bu
else if(myLastStick == stick && hat == myLastHat && hdir == JoyHatDir::CENTER)
{
EventHandler& eh = instance().eventHandler();
Event::Type event = eh.eventAtIndex(myActionSelected, myEventMode);
Event::Type event = eh.eventAtIndex(myActionSelected, myEventGroup);
if (eh.addJoyHatMapping(event, myEventMode, stick, myLastButton, hat, myLastHatDir))
{
@ -418,6 +463,10 @@ void EventMappingWidget::handleCommand(CommandSender* sender, int cmd,
{
switch(cmd)
{
case kFilterCmd:
updateActions();
break;
case ListWidget::kSelectionChangedCmd:
if(myActionsList->getSelected() >= 0)
{
@ -454,8 +503,8 @@ void EventMappingWidget::handleCommand(CommandSender* sender, int cmd,
case kComboCmd:
if(myComboDialog)
myComboDialog->show(
instance().eventHandler().eventAtIndex(myActionSelected, myEventMode),
instance().eventHandler().actionAtIndex(myActionSelected, myEventMode));
instance().eventHandler().eventAtIndex(myActionSelected, myEventGroup),
instance().eventHandler().actionAtIndex(myActionSelected, myEventGroup));
break;
}
}

View File

@ -40,7 +40,7 @@ class EventMappingWidget : public Widget, public CommandSender
public:
EventMappingWidget(GuiObject* boss, const GUI::Font& font,
int x, int y, int w, int h,
const StringList& actions, EventMode mode);
EventMode mode);
virtual ~EventMappingWidget() = default;
bool remapMode() { return myRemapStatus; }
@ -49,6 +49,7 @@ class EventMappingWidget : public Widget, public CommandSender
private:
enum {
kFilterCmd = 'filt',
kStartMapCmd = 'map ',
kStopMapCmd = 'smap',
kEraseCmd = 'eras',
@ -68,6 +69,7 @@ class EventMappingWidget : public Widget, public CommandSender
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
void updateActions();
void startRemapping();
void eraseRemapping();
void resetRemapping();
@ -84,6 +86,7 @@ class EventMappingWidget : public Widget, public CommandSender
ButtonWidget* myEraseButton;
ButtonWidget* myResetButton;
ButtonWidget* myComboButton;
PopUpWidget* myFilterPopup;
StringListWidget* myActionsList;
EditTextWidget* myKeyMapping;
@ -93,6 +96,9 @@ class EventMappingWidget : public Widget, public CommandSender
// we need to specify exactly which group of events we are remapping
EventMode myEventMode;
// Since we can filter events, the event mode is not specific enough
Event::Group myEventGroup;
// Indicates the event that is currently selected
int myActionSelected;

View File

@ -48,7 +48,6 @@ InputDialog::InputDialog(OSystem& osystem, DialogContainer& parent,
buttonHeight = font.getLineHeight() + 4;
const int vBorder = 4;
int xpos, ypos, tabID;
StringList actions;
// Set real dimensions
setSize(51 * fontWidth + 10, 17 * (lineHeight + 4) + 16 + _th, max_w, max_h);
@ -60,21 +59,19 @@ InputDialog::InputDialog(OSystem& osystem, DialogContainer& parent,
// 1) Event mapper for emulation actions
tabID = myTab->addTab(" Emulation Events ", TabWidget::AUTO_WIDTH);
actions = instance().eventHandler().getActionList(EventMode::kEmulationMode);
myEmulEventMapper = new EventMappingWidget(myTab, font, 2, 2,
myTab->getWidth(),
myTab->getHeight() - 4,
actions, EventMode::kEmulationMode);
EventMode::kEmulationMode);
myTab->setParentWidget(tabID, myEmulEventMapper);
addToFocusList(myEmulEventMapper->getFocusList(), myTab, tabID);
// 2) Event mapper for UI actions
tabID = myTab->addTab(" UI Events ", TabWidget::AUTO_WIDTH);
actions = instance().eventHandler().getActionList(EventMode::kMenuMode);
myMenuEventMapper = new EventMappingWidget(myTab, font, 2, 2,
myTab->getWidth(),
myTab->getHeight() - 4,
actions, EventMode::kMenuMode);
EventMode::kMenuMode);
myTab->setParentWidget(tabID, myMenuEventMapper);
addToFocusList(myMenuEventMapper->getFocusList(), myTab, tabID);
@ -642,3 +639,4 @@ void InputDialog::UpdateDejitter()
myDejitterLabel->setLabel(label.str());
}

View File

@ -164,8 +164,13 @@ void ListWidget::recalc()
{
int size = int(_list.size());
if (_currentPos >= size)
_currentPos = size - 1;
if(_currentPos >= size)
{
if(size <= _rows)
_currentPos = 0;
else
_currentPos = size - _rows;
}
if (_currentPos < 0)
_currentPos = 0;
@ -176,6 +181,8 @@ void ListWidget::recalc()
_scrollBar->_numEntries = int(_list.size());
_scrollBar->_entriesPerPage = _rows;
// disable scrollbar if no longer necessary
scrollBarRecalc();
// Reset to normal data entry
abortEditMode();