mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Merge pull request #14781 from unknownbrackets/ui-ctrl-mapping
Fix various focus issues in the control mapping
This commit is contained in:
commit
6fbc73ef69
4 changed files with 78 additions and 69 deletions
|
@ -756,6 +756,8 @@ void ScrollView::Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec ver
|
|||
}
|
||||
views_[0]->Measure(dc, MeasureSpec(UNSPECIFIED, measuredWidth_), v);
|
||||
MeasureBySpec(layoutParams_->height, views_[0]->GetMeasuredHeight(), vert, &measuredHeight_);
|
||||
if (layoutParams_->width == WRAP_CONTENT)
|
||||
MeasureBySpec(layoutParams_->width, views_[0]->GetMeasuredWidth(), horiz, &measuredWidth_);
|
||||
} else {
|
||||
MeasureSpec h = MeasureSpec(AT_MOST, measuredWidth_ - margins.horiz());
|
||||
if (measuredWidth_ == 0.0f && (horiz.type == UNSPECIFIED || layoutParams_->width == WRAP_CONTENT)) {
|
||||
|
@ -763,16 +765,16 @@ void ScrollView::Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec ver
|
|||
}
|
||||
views_[0]->Measure(dc, h, MeasureSpec(UNSPECIFIED, measuredHeight_));
|
||||
MeasureBySpec(layoutParams_->width, views_[0]->GetMeasuredWidth(), horiz, &measuredWidth_);
|
||||
if (layoutParams_->height == WRAP_CONTENT)
|
||||
MeasureBySpec(layoutParams_->height, views_[0]->GetMeasuredHeight(), vert, &measuredHeight_);
|
||||
}
|
||||
if (orientation_ == ORIENT_VERTICAL && vert.type != EXACTLY) {
|
||||
if (measuredHeight_ < views_[0]->GetMeasuredHeight() && layoutParams_->height < 0.0f) {
|
||||
measuredHeight_ = views_[0]->GetMeasuredHeight();
|
||||
}
|
||||
if (measuredHeight_ < views_[0]->GetBounds().h && layoutParams_->height < 0.0f) {
|
||||
measuredHeight_ = views_[0]->GetBounds().h;
|
||||
}
|
||||
if (vert.type == AT_MOST && measuredHeight_ > vert.size) {
|
||||
measuredHeight_ = vert.size;
|
||||
float bestHeight = std::max(views_[0]->GetMeasuredHeight(), views_[0]->GetBounds().h);
|
||||
if (vert.type == AT_MOST)
|
||||
bestHeight = std::min(bestHeight, vert.size);
|
||||
|
||||
if (measuredHeight_ < bestHeight && layoutParams_->height < 0.0f) {
|
||||
measuredHeight_ = bestHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -793,7 +795,7 @@ void ScrollView::Layout() {
|
|||
scrolled.w = views_[0]->GetMeasuredWidth() - margins.horiz();
|
||||
scrolled.h = views_[0]->GetMeasuredHeight() - margins.vert();
|
||||
|
||||
float layoutScrollPos = ClampedScrollPos(scrollPos_);
|
||||
layoutScrollPos_ = ClampedScrollPos(scrollPos_);
|
||||
|
||||
switch (orientation_) {
|
||||
case ORIENT_HORIZONTAL:
|
||||
|
@ -801,7 +803,7 @@ void ScrollView::Layout() {
|
|||
ScrollTo(0.0f);
|
||||
lastViewSize_ = scrolled.w;
|
||||
}
|
||||
scrolled.x = bounds_.x - layoutScrollPos;
|
||||
scrolled.x = bounds_.x - layoutScrollPos_;
|
||||
scrolled.y = bounds_.y + margins.top;
|
||||
break;
|
||||
case ORIENT_VERTICAL:
|
||||
|
@ -810,7 +812,7 @@ void ScrollView::Layout() {
|
|||
lastViewSize_ = scrolled.h;
|
||||
}
|
||||
scrolled.x = bounds_.x + margins.left;
|
||||
scrolled.y = bounds_.y - layoutScrollPos;
|
||||
scrolled.y = bounds_.y - layoutScrollPos_;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -913,25 +915,27 @@ bool ScrollView::SubviewFocused(View *view) {
|
|||
const float overscroll = std::min(view->GetBounds().h / 1.5f, GetBounds().h / 4.0f);
|
||||
|
||||
float pos = ClampedScrollPos(scrollPos_);
|
||||
float visibleSize = orientation_ == ORIENT_VERTICAL ? bounds_.h : bounds_.w;
|
||||
float visibleEnd = scrollPos_ + visibleSize;
|
||||
|
||||
float viewStart, viewEnd;
|
||||
switch (orientation_) {
|
||||
case ORIENT_HORIZONTAL:
|
||||
if (vBounds.x2() > bounds_.x2()) {
|
||||
ScrollTo(pos + vBounds.x2() - bounds_.x2() + overscroll);
|
||||
}
|
||||
if (vBounds.x < bounds_.x) {
|
||||
ScrollTo(pos + (vBounds.x - bounds_.x) - overscroll);
|
||||
}
|
||||
viewStart = layoutScrollPos_ + vBounds.x - bounds_.x;
|
||||
viewEnd = layoutScrollPos_ + vBounds.x2() - bounds_.x;
|
||||
break;
|
||||
case ORIENT_VERTICAL:
|
||||
if (vBounds.y2() > bounds_.y2()) {
|
||||
ScrollTo(pos + vBounds.y2() - bounds_.y2() + overscroll);
|
||||
}
|
||||
if (vBounds.y < bounds_.y) {
|
||||
ScrollTo(pos + (vBounds.y - bounds_.y) - overscroll);
|
||||
}
|
||||
viewStart = layoutScrollPos_ + vBounds.y - bounds_.y;
|
||||
viewEnd = layoutScrollPos_ + vBounds.y2() - bounds_.y;
|
||||
break;
|
||||
}
|
||||
|
||||
if (viewEnd > visibleEnd) {
|
||||
ScrollTo(viewEnd - visibleSize + overscroll);
|
||||
} else if (viewStart < pos) {
|
||||
ScrollTo(viewStart - overscroll);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -300,6 +300,7 @@ private:
|
|||
float scrollTarget_ = 0.0f;
|
||||
int scrollTouchId_ = -1;
|
||||
bool scrollToTarget_ = false;
|
||||
float layoutScrollPos_ = 0.0f;
|
||||
float inertia_ = 0.0f;
|
||||
float pull_ = 0.0f;
|
||||
float lastViewSize_ = 0.0f;
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "Common/Data/Text/I18n.h"
|
||||
#include "Common/Input/KeyCodes.h"
|
||||
#include "Common/Input/InputState.h"
|
||||
#include "Common/StringUtils.h"
|
||||
#include "Common/System/Display.h"
|
||||
#include "Common/System/System.h"
|
||||
#include "Core/KeyMap.h"
|
||||
|
@ -45,10 +46,10 @@
|
|||
|
||||
class SingleControlMapper : public UI::LinearLayout {
|
||||
public:
|
||||
SingleControlMapper(ControlMappingScreen *ctrlScreen, int pspKey, std::string keyName, ScreenManager *scrm, UI::LinearLayoutParams *layoutParams = 0);
|
||||
SingleControlMapper(int pspKey, std::string keyName, ScreenManager *scrm, UI::LinearLayoutParams *layoutParams = nullptr);
|
||||
|
||||
void Update() override;
|
||||
int GetPspKey() const { return pspKey_; }
|
||||
|
||||
private:
|
||||
void Refresh();
|
||||
|
||||
|
@ -67,30 +68,22 @@ private:
|
|||
ADD,
|
||||
};
|
||||
|
||||
ControlMappingScreen *ctrlScreen_;
|
||||
Action action_;
|
||||
UI::Choice *addButton_ = nullptr;
|
||||
UI::Choice *replaceAllButton_ = nullptr;
|
||||
std::vector<UI::View *> rows_;
|
||||
Action action_ = NONE;
|
||||
int actionIndex_;
|
||||
int pspKey_;
|
||||
std::string keyName_;
|
||||
ScreenManager *scrm_;
|
||||
bool refresh_;
|
||||
};
|
||||
|
||||
SingleControlMapper::SingleControlMapper(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) {
|
||||
SingleControlMapper::SingleControlMapper(int pspKey, std::string keyName, ScreenManager *scrm, UI::LinearLayoutParams *layoutParams)
|
||||
: UI::LinearLayout(UI::ORIENT_VERTICAL, layoutParams), pspKey_(pspKey), keyName_(keyName), scrm_(scrm) {
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void SingleControlMapper::Update() {
|
||||
if (refresh_) {
|
||||
refresh_ = false;
|
||||
Refresh();
|
||||
host->UpdateUI();
|
||||
}
|
||||
}
|
||||
|
||||
void SingleControlMapper::Refresh() {
|
||||
bool hasFocus = UI::GetFocusedView() == this;
|
||||
Clear();
|
||||
auto mc = GetI18NCategory("MappableControls");
|
||||
|
||||
|
@ -117,17 +110,16 @@ void SingleControlMapper::Refresh() {
|
|||
auto iter = keyImages.find(keyName_);
|
||||
// First, look among images.
|
||||
if (iter != keyImages.end()) {
|
||||
Choice *c = root->Add(new Choice(iter->second, new LinearLayoutParams(leftColumnWidth, itemH)));
|
||||
c->OnClick.Handle(this, &SingleControlMapper::OnReplaceAll);
|
||||
replaceAllButton_ = new Choice(iter->second, new LinearLayoutParams(leftColumnWidth, itemH));
|
||||
} else {
|
||||
// No image? Let's translate.
|
||||
Choice *c = new Choice(mc->T(keyName_.c_str()), new LinearLayoutParams(leftColumnWidth, itemH));
|
||||
c->SetCentered(true);
|
||||
root->Add(c)->OnClick.Handle(this, &SingleControlMapper::OnReplaceAll);
|
||||
replaceAllButton_ = new Choice(mc->T(keyName_.c_str()), new LinearLayoutParams(leftColumnWidth, itemH));
|
||||
replaceAllButton_->SetCentered(true);
|
||||
}
|
||||
root->Add(replaceAllButton_)->OnClick.Handle(this, &SingleControlMapper::OnReplaceAll);
|
||||
|
||||
Choice *p = root->Add(new Choice(" + ", new LayoutParams(WRAP_CONTENT, itemH)));
|
||||
p->OnClick.Handle(this, &SingleControlMapper::OnAdd);
|
||||
addButton_ = root->Add(new Choice(" + ", new LayoutParams(WRAP_CONTENT, itemH)));
|
||||
addButton_->OnClick.Handle(this, &SingleControlMapper::OnAdd);
|
||||
if (g_Config.bMouseControl) {
|
||||
Choice *p = root->Add(new Choice("M", new LayoutParams(WRAP_CONTENT, itemH)));
|
||||
p->OnClick.Handle(this, &SingleControlMapper::OnAddMouse);
|
||||
|
@ -138,22 +130,21 @@ void SingleControlMapper::Refresh() {
|
|||
std::vector<KeyDef> mappings;
|
||||
KeyMap::KeyFromPspButton(pspKey_, &mappings, false);
|
||||
|
||||
rows_.empty();
|
||||
for (size_t i = 0; i < mappings.size(); i++) {
|
||||
std::string deviceName = GetDeviceName(mappings[i].deviceId);
|
||||
std::string keyName = KeyMap::GetKeyOrAxisName(mappings[i].keyCode);
|
||||
|
||||
LinearLayout *row = rightColumn->Add(new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)));
|
||||
row->SetSpacing(1.0f);
|
||||
|
||||
char tagbuf[16];
|
||||
sprintf(tagbuf, "%d", (int)i);
|
||||
rows_.push_back(row);
|
||||
|
||||
Choice *c = row->Add(new Choice(deviceName + "." + keyName, new LinearLayoutParams(FILL_PARENT, itemH, 1.0f)));
|
||||
c->SetTag(tagbuf);
|
||||
c->SetTag(StringFromFormat("%d_Change%d", (int)i, pspKey_));
|
||||
c->OnClick.Handle(this, &SingleControlMapper::OnReplace);
|
||||
|
||||
Choice *d = row->Add(new Choice(" X ", new LayoutParams(WRAP_CONTENT, itemH)));
|
||||
d->SetTag(tagbuf);
|
||||
d->SetTag(StringFromFormat("%d_Del%d", (int)i, pspKey_));
|
||||
d->OnClick.Handle(this, &SingleControlMapper::OnDelete);
|
||||
}
|
||||
|
||||
|
@ -162,30 +153,31 @@ void SingleControlMapper::Refresh() {
|
|||
Choice *c = rightColumn->Add(new Choice("", new LinearLayoutParams(FILL_PARENT, itemH)));
|
||||
c->OnClick.Handle(this, &SingleControlMapper::OnAdd);
|
||||
}
|
||||
|
||||
if (hasFocus)
|
||||
this->SetFocus();
|
||||
}
|
||||
|
||||
void SingleControlMapper::MappedCallback(KeyDef kdf) {
|
||||
switch (action_) {
|
||||
case ADD:
|
||||
KeyMap::SetKeyMapping(pspKey_, kdf, false);
|
||||
addButton_->SetFocus();
|
||||
break;
|
||||
case REPLACEALL:
|
||||
KeyMap::SetKeyMapping(pspKey_, kdf, true);
|
||||
replaceAllButton_->SetFocus();
|
||||
break;
|
||||
case REPLACEONE:
|
||||
KeyMap::g_controllerMap[pspKey_][actionIndex_] = kdf;
|
||||
KeyMap::g_controllerMapGeneration++;
|
||||
if (actionIndex_ < rows_.size())
|
||||
rows_[actionIndex_]->SetFocus();
|
||||
else
|
||||
SetFocus();
|
||||
break;
|
||||
default:
|
||||
;
|
||||
SetFocus();
|
||||
break;
|
||||
}
|
||||
g_Config.bMapMouse = false;
|
||||
refresh_ = true;
|
||||
ctrlScreen_->KeyMapped(pspKey_);
|
||||
// After this, we do not exist any more. So the refresh_ = true is probably irrelevant.
|
||||
}
|
||||
|
||||
UI::EventReturn SingleControlMapper::OnReplace(UI::EventParams ¶ms) {
|
||||
|
@ -221,7 +213,11 @@ UI::EventReturn SingleControlMapper::OnDelete(UI::EventParams ¶ms) {
|
|||
int index = atoi(params.v->Tag().c_str());
|
||||
KeyMap::g_controllerMap[pspKey_].erase(KeyMap::g_controllerMap[pspKey_].begin() + index);
|
||||
KeyMap::g_controllerMapGeneration++;
|
||||
refresh_ = true;
|
||||
|
||||
if (index + 1 < rows_.size())
|
||||
rows_[index]->SetFocus();
|
||||
else
|
||||
SetFocus();
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
|
@ -260,8 +256,9 @@ void ControlMappingScreen::CreateViews() {
|
|||
std::vector<KeyMap::KeyMap_IntStrPair> mappableKeys = KeyMap::GetMappableKeys();
|
||||
for (size_t i = 0; i < mappableKeys.size(); i++) {
|
||||
SingleControlMapper *mapper = rightColumn->Add(
|
||||
new SingleControlMapper(this, mappableKeys[i].key, mappableKeys[i].name, screenManager(),
|
||||
new SingleControlMapper(mappableKeys[i].key, mappableKeys[i].name, screenManager(),
|
||||
new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)));
|
||||
mapper->SetTag(StringFromFormat("KeyMap%s", mappableKeys[i].name));
|
||||
mappers_.push_back(mapper);
|
||||
}
|
||||
|
||||
|
@ -314,13 +311,6 @@ 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 (size_t i = 0; i < mappers_.size(); i++) {
|
||||
if (mappers_[i]->GetPspKey() == pspkey)
|
||||
SetFocusedView(mappers_[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void KeyMappingNewKeyDialog::CreatePopupContents(UI::ViewGroup *parent) {
|
||||
using namespace UI;
|
||||
|
||||
|
@ -1007,6 +997,7 @@ public:
|
|||
|
||||
MockPSP(UI::LayoutParams *layoutParams = nullptr);
|
||||
void SelectButton(int btn);
|
||||
void FocusButton(int btn);
|
||||
float GetPopupOffset();
|
||||
|
||||
UI::Event ButtonClick;
|
||||
|
@ -1053,6 +1044,12 @@ void MockPSP::SelectButton(int btn) {
|
|||
selectedButton_ = btn;
|
||||
}
|
||||
|
||||
void MockPSP::FocusButton(int btn) {
|
||||
MockButton *view = buttons_[selectedButton_];
|
||||
if (view)
|
||||
view->SetFocus();
|
||||
}
|
||||
|
||||
float MockPSP::GetPopupOffset() {
|
||||
MockButton *view = buttons_[selectedButton_];
|
||||
if (!view)
|
||||
|
@ -1162,8 +1159,13 @@ void VisualMappingScreen::HandleKeyMapping(KeyDef key) {
|
|||
nextKey_ = VIRTKEY_AXIS_X_MIN;
|
||||
else if (nextKey_ == VIRTKEY_AXIS_X_MIN)
|
||||
nextKey_ = VIRTKEY_AXIS_X_MAX;
|
||||
else
|
||||
else {
|
||||
if (nextKey_ == VIRTKEY_AXIS_X_MAX)
|
||||
psp_->FocusButton(VIRTKEY_AXIS_Y_MAX);
|
||||
else
|
||||
psp_->FocusButton(nextKey_);
|
||||
nextKey_ = 0;
|
||||
}
|
||||
} else if ((size_t)bindAll_ + 1 < bindAllOrder.size()) {
|
||||
bindAll_++;
|
||||
nextKey_ = bindAllOrder[bindAll_];
|
||||
|
@ -1177,6 +1179,9 @@ void VisualMappingScreen::dialogFinished(const Screen *dialog, DialogResult resu
|
|||
if (result == DR_YES && nextKey_ != 0) {
|
||||
MapNext();
|
||||
} else {
|
||||
// This means they canceled.
|
||||
if (nextKey_ != 0)
|
||||
psp_->FocusButton(nextKey_);
|
||||
nextKey_ = 0;
|
||||
bindAll_ = -1;
|
||||
psp_->SelectButton(0);
|
||||
|
|
|
@ -35,7 +35,6 @@ class SingleControlMapper;
|
|||
class ControlMappingScreen : public UIDialogScreenWithBackground {
|
||||
public:
|
||||
ControlMappingScreen() {}
|
||||
void KeyMapped(int pspkey); // Notification to let us refocus the same one after recreating views.
|
||||
std::string tag() const override { return "control mapping"; }
|
||||
|
||||
protected:
|
||||
|
|
Loading…
Add table
Reference in a new issue