Don't lose focus after mapping a control.

Makes it a lot less aggravating to remap more than one control using a controller.

Also fixes a race condition.
This commit is contained in:
Henrik Rydgard
2014-06-08 15:38:13 +02:00
parent a31194a877
commit 77c85bccdd
2 changed files with 41 additions and 11 deletions
+32 -9
View File
@@ -35,10 +35,10 @@
class ControlMapper : public UI::LinearLayout {
public:
ControlMapper(int pspKey, std::string keyName, ScreenManager *scrm, UI::LinearLayoutParams *layoutParams = 0);
ControlMapper(ControlMappingScreen *ctrlScreen, int pspKey, std::string keyName, ScreenManager *scrm, UI::LinearLayoutParams *layoutParams = 0);
virtual void Update(const InputState &input);
int GetPspKey() const { return pspKey_; }
private:
void Refresh();
@@ -56,6 +56,7 @@ private:
ADD,
};
ControlMappingScreen *ctrlScreen_;
Action action_;
int actionIndex_;
int pspKey_;
@@ -64,8 +65,8 @@ private:
bool refresh_;
};
ControlMapper::ControlMapper(int pspKey, std::string keyName, ScreenManager *scrm, UI::LinearLayoutParams *layoutParams)
: UI::LinearLayout(UI::ORIENT_VERTICAL, layoutParams), action_(NONE), pspKey_(pspKey), keyName_(keyName), scrm_(scrm), refresh_(false) {
ControlMapper::ControlMapper(ControlMappingScreen *ctrlScreen, int pspKey, std::string keyName, ScreenManager *scrm, UI::LinearLayoutParams *layoutParams)
: UI::LinearLayout(UI::ORIENT_VERTICAL, layoutParams), ctrlScreen_(ctrlScreen), action_(NONE), pspKey_(pspKey), keyName_(keyName), scrm_(scrm), refresh_(false) {
Refresh();
}
@@ -77,6 +78,7 @@ void ControlMapper::Update(const InputState &input) {
}
void ControlMapper::Refresh() {
bool hasFocus = UI::GetFocusedView() == this;
Clear();
I18NCategory *mc = GetI18NCategory("MappableControls");
@@ -143,6 +145,9 @@ void ControlMapper::Refresh() {
Choice *c = rightColumn->Add(new Choice("", new LinearLayoutParams(FILL_PARENT, itemH)));
c->OnClick.Handle(this, &ControlMapper::OnAdd);
}
if (hasFocus)
this->SetFocus();
}
void ControlMapper::MappedCallback(KeyDef kdf) {
@@ -160,6 +165,8 @@ void ControlMapper::MappedCallback(KeyDef kdf) {
;
}
refresh_ = true;
ctrlScreen_->KeyMapped(pspKey_);
// After this, we do not exist any more. So the refresh_ = true is probably irrelevant.
}
UI::EventReturn ControlMapper::OnReplace(UI::EventParams &params) {
@@ -190,6 +197,7 @@ UI::EventReturn ControlMapper::OnDelete(UI::EventParams &params) {
void ControlMappingScreen::CreateViews() {
using namespace UI;
mappers_.clear();
I18NCategory *k = GetI18NCategory("KeyMapping");
I18NCategory *d = GetI18NCategory("Dialog");
@@ -205,17 +213,18 @@ void ControlMappingScreen::CreateViews() {
leftColumn->Add(new Spacer(new LinearLayoutParams(1.0f)));
leftColumn->Add(new Choice(d->T("Back")))->OnClick.Handle<UIScreen>(this, &UIScreen::OnBack);
ScrollView *rightScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0f));
rightScroll->SetScrollToTop(false);
rightScroll_ = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0f));
rightScroll_->SetScrollToTop(false);
LinearLayout *rightColumn = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(1.0f));
rightScroll->Add(rightColumn);
rightScroll_->Add(rightColumn);
root_->Add(leftColumn);
root_->Add(rightScroll);
root_->Add(rightScroll_);
std::vector<KeyMap::KeyMap_IntStrPair> mappableKeys = KeyMap::GetMappableKeys();
for (size_t i = 0; i < mappableKeys.size(); i++) {
rightColumn->Add(new ControlMapper(mappableKeys[i].key, mappableKeys[i].name, screenManager(), new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)));
ControlMapper *mapper = rightColumn->Add(new ControlMapper(this, mappableKeys[i].key, mappableKeys[i].name, screenManager(), new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)));
mappers_.push_back(mapper);
}
}
@@ -261,6 +270,13 @@ void ControlMappingScreen::dialogFinished(const Screen *dialog, DialogResult res
}
}
void ControlMappingScreen::KeyMapped(int pspkey) { // Notification to let us refocus the same one after recreating views.
for (int i = 0; i < mappers_.size(); i++) {
if (mappers_[i]->GetPspKey() == pspkey)
SetFocusedView(mappers_[i]);
}
}
void KeyMappingNewKeyDialog::CreatePopupContents(UI::ViewGroup *parent) {
using namespace UI;
@@ -272,11 +288,14 @@ void KeyMappingNewKeyDialog::CreatePopupContents(UI::ViewGroup *parent) {
}
void KeyMappingNewKeyDialog::key(const KeyInput &key) {
if (mapped_)
return;
if (key.flags & KEY_DOWN) {
if (key.keyCode == NKCODE_EXT_MOUSEBUTTON_1) {
return;
}
mapped_ = true;
KeyDef kdf(key.deviceId, key.keyCode);
screenManager()->finishDialog(this, DR_OK);
if (callback_)
@@ -285,6 +304,8 @@ void KeyMappingNewKeyDialog::key(const KeyInput &key) {
}
void KeyMappingNewKeyDialog::axis(const AxisInput &axis) {
if (mapped_)
return;
switch (axis.axisId) {
// Ignore the accelerometer for mapping for now.
case JOYSTICK_AXIS_ACCELEROMETER_X:
@@ -304,6 +325,7 @@ void KeyMappingNewKeyDialog::axis(const AxisInput &axis) {
}
if (axis.value > AXIS_BIND_THRESHOLD) {
mapped_ = true;
KeyDef kdf(axis.deviceId, KeyMap::TranslateKeyCodeFromAxis(axis.axisId, 1));
screenManager()->finishDialog(this, DR_OK);
if (callback_)
@@ -311,6 +333,7 @@ void KeyMappingNewKeyDialog::axis(const AxisInput &axis) {
}
if (axis.value < -AXIS_BIND_THRESHOLD) {
mapped_ = true;
KeyDef kdf(axis.deviceId, KeyMap::TranslateKeyCodeFromAxis(axis.axisId, -1));
screenManager()->finishDialog(this, DR_OK);
if (callback_)