mirror of
https://github.com/izzy2lost/ppsspp.git
synced 2026-03-10 12:43:04 -07:00
Break out ScrollView from ViewGroup.h, and PopupScreens from UIScreen.h
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,388 @@
|
||||
#pragma once
|
||||
|
||||
#include "Common/UI/UIScreen.h"
|
||||
#include "Common/UI/UI.h"
|
||||
#include "Common/UI/View.h"
|
||||
#include "Common/UI/ScrollView.h"
|
||||
|
||||
namespace UI {
|
||||
|
||||
class ListPopupScreen : public PopupScreen {
|
||||
public:
|
||||
ListPopupScreen(std::string title) : PopupScreen(title) {}
|
||||
ListPopupScreen(std::string title, const std::vector<std::string> &items, int selected, std::function<void(int)> callback, bool showButtons = false)
|
||||
: PopupScreen(title, "OK", "Cancel"), adaptor_(items, selected), callback_(callback), showButtons_(showButtons) {
|
||||
}
|
||||
ListPopupScreen(std::string title, const std::vector<std::string> &items, int selected, bool showButtons = false)
|
||||
: PopupScreen(title, "OK", "Cancel"), adaptor_(items, selected), showButtons_(showButtons) {
|
||||
}
|
||||
|
||||
int GetChoice() const {
|
||||
return listView_->GetSelected();
|
||||
}
|
||||
std::string GetChoiceString() const {
|
||||
return adaptor_.GetTitle(listView_->GetSelected());
|
||||
}
|
||||
void SetHiddenChoices(std::set<int> hidden) {
|
||||
hidden_ = hidden;
|
||||
}
|
||||
const char *tag() const override { return "listpopup"; }
|
||||
|
||||
UI::Event OnChoice;
|
||||
|
||||
protected:
|
||||
bool FillVertical() const override { return false; }
|
||||
bool ShowButtons() const override { return showButtons_; }
|
||||
void CreatePopupContents(UI::ViewGroup *parent) override;
|
||||
UI::StringVectorListAdaptor adaptor_;
|
||||
UI::ListView *listView_ = nullptr;
|
||||
|
||||
private:
|
||||
UI::EventReturn OnListChoice(UI::EventParams &e);
|
||||
|
||||
std::function<void(int)> callback_;
|
||||
bool showButtons_ = false;
|
||||
std::set<int> hidden_;
|
||||
};
|
||||
|
||||
class MessagePopupScreen : public PopupScreen {
|
||||
public:
|
||||
MessagePopupScreen(std::string title, std::string message, std::string button1, std::string button2, std::function<void(bool)> callback)
|
||||
: PopupScreen(title, button1, button2), message_(message), callback_(callback) {}
|
||||
UI::Event OnChoice;
|
||||
|
||||
protected:
|
||||
bool FillVertical() const override { return false; }
|
||||
bool ShowButtons() const override { return true; }
|
||||
void CreatePopupContents(UI::ViewGroup *parent) override;
|
||||
|
||||
private:
|
||||
void OnCompleted(DialogResult result) override;
|
||||
std::string message_;
|
||||
std::function<void(bool)> callback_;
|
||||
};
|
||||
|
||||
class SliderPopupScreen : public PopupScreen {
|
||||
public:
|
||||
SliderPopupScreen(int *value, int minValue, int maxValue, const std::string &title, int step = 1, const std::string &units = "")
|
||||
: PopupScreen(title, "OK", "Cancel"), units_(units), value_(value), minValue_(minValue), maxValue_(maxValue), step_(step) {}
|
||||
void CreatePopupContents(ViewGroup *parent) override;
|
||||
|
||||
void SetNegativeDisable(const std::string &str) {
|
||||
negativeLabel_ = str;
|
||||
disabled_ = *value_ < 0;
|
||||
}
|
||||
|
||||
const char *tag() const override { return "SliderPopup"; }
|
||||
|
||||
Event OnChange;
|
||||
|
||||
private:
|
||||
EventReturn OnDecrease(EventParams ¶ms);
|
||||
EventReturn OnIncrease(EventParams ¶ms);
|
||||
EventReturn OnTextChange(EventParams ¶ms);
|
||||
EventReturn OnSliderChange(EventParams ¶ms);
|
||||
void OnCompleted(DialogResult result) override;
|
||||
Slider *slider_ = nullptr;
|
||||
UI::TextEdit *edit_ = nullptr;
|
||||
std::string units_;
|
||||
std::string negativeLabel_;
|
||||
int *value_;
|
||||
int sliderValue_ = 0;
|
||||
int minValue_;
|
||||
int maxValue_;
|
||||
int step_;
|
||||
bool changing_ = false;
|
||||
bool disabled_ = false;
|
||||
};
|
||||
|
||||
class SliderFloatPopupScreen : public PopupScreen {
|
||||
public:
|
||||
SliderFloatPopupScreen(float *value, float minValue, float maxValue, const std::string &title, float step = 1.0f, const std::string &units = "", bool liveUpdate = false)
|
||||
: PopupScreen(title, "OK", "Cancel"), units_(units), value_(value), originalValue_(*value), minValue_(minValue), maxValue_(maxValue), step_(step), changing_(false), liveUpdate_(liveUpdate) {}
|
||||
void CreatePopupContents(UI::ViewGroup *parent) override;
|
||||
|
||||
const char *tag() const override { return "SliderFloatPopup"; }
|
||||
|
||||
Event OnChange;
|
||||
|
||||
private:
|
||||
EventReturn OnIncrease(EventParams ¶ms);
|
||||
EventReturn OnDecrease(EventParams ¶ms);
|
||||
EventReturn OnTextChange(EventParams ¶ms);
|
||||
EventReturn OnSliderChange(EventParams ¶ms);
|
||||
void OnCompleted(DialogResult result) override;
|
||||
UI::SliderFloat *slider_ = nullptr;
|
||||
UI::TextEdit *edit_ = nullptr;
|
||||
std::string units_ = nullptr;
|
||||
float sliderValue_;
|
||||
float originalValue_;
|
||||
float *value_;
|
||||
float minValue_;
|
||||
float maxValue_;
|
||||
float step_;
|
||||
bool changing_;
|
||||
bool liveUpdate_;
|
||||
};
|
||||
|
||||
class TextEditPopupScreen : public PopupScreen {
|
||||
public:
|
||||
TextEditPopupScreen(std::string *value, const std::string &placeholder, const std::string &title, int maxLen)
|
||||
: PopupScreen(title, "OK", "Cancel"), value_(value), placeholder_(placeholder), maxLen_(maxLen) {}
|
||||
void CreatePopupContents(ViewGroup *parent) override;
|
||||
|
||||
const char *tag() const override { return "TextEditPopup"; }
|
||||
|
||||
Event OnChange;
|
||||
|
||||
private:
|
||||
void OnCompleted(DialogResult result) override;
|
||||
TextEdit *edit_ = nullptr;
|
||||
std::string *value_;
|
||||
std::string textEditValue_;
|
||||
std::string placeholder_;
|
||||
int maxLen_;
|
||||
};
|
||||
|
||||
struct ContextMenuItem {
|
||||
const char *text;
|
||||
const char *imageID;
|
||||
};
|
||||
|
||||
// Once a selection has been made,
|
||||
class PopupContextMenuScreen : public PopupScreen {
|
||||
public:
|
||||
PopupContextMenuScreen(const ContextMenuItem *items, size_t itemCount, I18NCategory *category, UI::View *sourceView);
|
||||
void CreatePopupContents(ViewGroup *parent) override;
|
||||
|
||||
const char *tag() const override { return "ContextMenuPopup"; }
|
||||
|
||||
void SetEnabled(size_t index, bool enabled) {
|
||||
enabled_[index] = enabled;
|
||||
}
|
||||
|
||||
UI::Event OnChoice;
|
||||
|
||||
protected:
|
||||
bool HasTitleBar() const override { return false; }
|
||||
|
||||
private:
|
||||
const ContextMenuItem *items_;
|
||||
size_t itemCount_;
|
||||
I18NCategory *category_;
|
||||
UI::View *sourceView_;
|
||||
std::vector<bool> enabled_;
|
||||
};
|
||||
|
||||
class AbstractChoiceWithValueDisplay : public UI::Choice {
|
||||
public:
|
||||
AbstractChoiceWithValueDisplay(const std::string &text, LayoutParams *layoutParams = nullptr)
|
||||
: Choice(text, layoutParams) {
|
||||
}
|
||||
|
||||
void Draw(UIContext &dc) override;
|
||||
void GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert, float &w, float &h) const override;
|
||||
|
||||
protected:
|
||||
virtual std::string ValueText() const = 0;
|
||||
|
||||
float CalculateValueScale(const UIContext &dc, const std::string &valueText, float availWidth) const;
|
||||
};
|
||||
|
||||
// Reads and writes value to determine the current selection.
|
||||
class PopupMultiChoice : public AbstractChoiceWithValueDisplay {
|
||||
public:
|
||||
PopupMultiChoice(int *value, const std::string &text, const char **choices, int minVal, int numChoices,
|
||||
const char *category, ScreenManager *screenManager, UI::LayoutParams *layoutParams = nullptr)
|
||||
: AbstractChoiceWithValueDisplay(text, layoutParams), value_(value), choices_(choices), minVal_(minVal), numChoices_(numChoices),
|
||||
category_(category), screenManager_(screenManager) {
|
||||
if (*value >= numChoices + minVal)
|
||||
*value = numChoices + minVal - 1;
|
||||
if (*value < minVal)
|
||||
*value = minVal;
|
||||
OnClick.Handle(this, &PopupMultiChoice::HandleClick);
|
||||
UpdateText();
|
||||
}
|
||||
|
||||
void Update() override;
|
||||
|
||||
void HideChoice(int c) {
|
||||
hidden_.insert(c);
|
||||
}
|
||||
|
||||
UI::Event OnChoice;
|
||||
|
||||
protected:
|
||||
std::string ValueText() const override;
|
||||
|
||||
int *value_;
|
||||
const char **choices_;
|
||||
int minVal_;
|
||||
int numChoices_;
|
||||
void UpdateText();
|
||||
|
||||
private:
|
||||
UI::EventReturn HandleClick(UI::EventParams &e);
|
||||
|
||||
void ChoiceCallback(int num);
|
||||
virtual void PostChoiceCallback(int num) {}
|
||||
|
||||
const char *category_;
|
||||
ScreenManager *screenManager_;
|
||||
std::string valueText_;
|
||||
bool restoreFocus_ = false;
|
||||
std::set<int> hidden_;
|
||||
};
|
||||
|
||||
// Allows passing in a dynamic vector of strings. Saves the string.
|
||||
class PopupMultiChoiceDynamic : public PopupMultiChoice {
|
||||
public:
|
||||
PopupMultiChoiceDynamic(std::string *value, const std::string &text, std::vector<std::string> choices,
|
||||
const char *category, ScreenManager *screenManager, UI::LayoutParams *layoutParams = nullptr)
|
||||
: UI::PopupMultiChoice(&valueInt_, text, nullptr, 0, (int)choices.size(), category, screenManager, layoutParams),
|
||||
valueStr_(value) {
|
||||
choices_ = new const char *[numChoices_];
|
||||
valueInt_ = 0;
|
||||
for (int i = 0; i < numChoices_; i++) {
|
||||
choices_[i] = new char[choices[i].size() + 1];
|
||||
memcpy((char *)choices_[i], choices[i].c_str(), choices[i].size() + 1);
|
||||
if (*value == choices_[i])
|
||||
valueInt_ = i;
|
||||
}
|
||||
value_ = &valueInt_;
|
||||
UpdateText();
|
||||
}
|
||||
~PopupMultiChoiceDynamic() {
|
||||
for (int i = 0; i < numChoices_; i++) {
|
||||
delete[] choices_[i];
|
||||
}
|
||||
delete[] choices_;
|
||||
}
|
||||
|
||||
protected:
|
||||
void PostChoiceCallback(int num) override {
|
||||
*valueStr_ = choices_[num];
|
||||
}
|
||||
|
||||
private:
|
||||
int valueInt_;
|
||||
std::string *valueStr_;
|
||||
};
|
||||
|
||||
class PopupSliderChoice : public AbstractChoiceWithValueDisplay {
|
||||
public:
|
||||
PopupSliderChoice(int *value, int minValue, int maxValue, const std::string &text, ScreenManager *screenManager, const std::string &units = "", LayoutParams *layoutParams = 0);
|
||||
PopupSliderChoice(int *value, int minValue, int maxValue, const std::string &text, int step, ScreenManager *screenManager, const std::string &units = "", LayoutParams *layoutParams = 0);
|
||||
|
||||
void SetFormat(const char *fmt) {
|
||||
fmt_ = fmt;
|
||||
}
|
||||
void SetZeroLabel(const std::string &str) {
|
||||
zeroLabel_ = str;
|
||||
}
|
||||
void SetNegativeDisable(const std::string &str) {
|
||||
negativeLabel_ = str;
|
||||
}
|
||||
|
||||
Event OnChange;
|
||||
|
||||
protected:
|
||||
std::string ValueText() const override;
|
||||
|
||||
private:
|
||||
EventReturn HandleClick(EventParams &e);
|
||||
EventReturn HandleChange(EventParams &e);
|
||||
|
||||
int *value_;
|
||||
int minValue_;
|
||||
int maxValue_;
|
||||
int step_;
|
||||
const char *fmt_;
|
||||
std::string zeroLabel_;
|
||||
std::string negativeLabel_;
|
||||
std::string units_;
|
||||
ScreenManager *screenManager_;
|
||||
bool restoreFocus_ = false;
|
||||
};
|
||||
|
||||
class PopupSliderChoiceFloat : public AbstractChoiceWithValueDisplay {
|
||||
public:
|
||||
PopupSliderChoiceFloat(float *value, float minValue, float maxValue, const std::string &text, ScreenManager *screenManager, const std::string &units = "", LayoutParams *layoutParams = 0);
|
||||
PopupSliderChoiceFloat(float *value, float minValue, float maxValue, const std::string &text, float step, ScreenManager *screenManager, const std::string &units = "", LayoutParams *layoutParams = 0);
|
||||
|
||||
void SetFormat(const char *fmt) {
|
||||
fmt_ = fmt;
|
||||
}
|
||||
void SetZeroLabel(const std::string &str) {
|
||||
zeroLabel_ = str;
|
||||
}
|
||||
void SetLiveUpdate(bool update) {
|
||||
liveUpdate_ = update;
|
||||
}
|
||||
void SetHasDropShadow(bool has) {
|
||||
hasDropShadow_ = has;
|
||||
}
|
||||
|
||||
Event OnChange;
|
||||
|
||||
protected:
|
||||
std::string ValueText() const override;
|
||||
|
||||
private:
|
||||
EventReturn HandleClick(EventParams &e);
|
||||
EventReturn HandleChange(EventParams &e);
|
||||
float *value_;
|
||||
float minValue_;
|
||||
float maxValue_;
|
||||
float step_;
|
||||
const char *fmt_;
|
||||
std::string zeroLabel_;
|
||||
std::string units_;
|
||||
ScreenManager *screenManager_;
|
||||
bool restoreFocus_ = false;
|
||||
bool liveUpdate_ = false;
|
||||
bool hasDropShadow_ = true;
|
||||
};
|
||||
|
||||
class PopupTextInputChoice : public AbstractChoiceWithValueDisplay {
|
||||
public:
|
||||
PopupTextInputChoice(std::string *value, const std::string &title, const std::string &placeholder, int maxLen, ScreenManager *screenManager, LayoutParams *layoutParams = 0);
|
||||
|
||||
Event OnChange;
|
||||
|
||||
protected:
|
||||
std::string ValueText() const override;
|
||||
|
||||
private:
|
||||
EventReturn HandleClick(EventParams &e);
|
||||
EventReturn HandleChange(EventParams &e);
|
||||
ScreenManager *screenManager_;
|
||||
std::string *value_;
|
||||
std::string placeHolder_;
|
||||
std::string defaultText_;
|
||||
int maxLen_;
|
||||
bool restoreFocus_;
|
||||
};
|
||||
|
||||
class ChoiceWithValueDisplay : public AbstractChoiceWithValueDisplay {
|
||||
public:
|
||||
ChoiceWithValueDisplay(int *value, const std::string &text, LayoutParams *layoutParams = 0)
|
||||
: AbstractChoiceWithValueDisplay(text, layoutParams), iValue_(value) {}
|
||||
|
||||
ChoiceWithValueDisplay(std::string *value, const std::string &text, const char *category, LayoutParams *layoutParams = 0)
|
||||
: AbstractChoiceWithValueDisplay(text, layoutParams), sValue_(value), category_(category) {}
|
||||
|
||||
ChoiceWithValueDisplay(std::string *value, const std::string &text, std::string(*translateCallback)(const char *value), LayoutParams *layoutParams = 0)
|
||||
: AbstractChoiceWithValueDisplay(text, layoutParams), sValue_(value), translateCallback_(translateCallback) {
|
||||
}
|
||||
|
||||
private:
|
||||
std::string ValueText() const override;
|
||||
|
||||
std::string *sValue_ = nullptr;
|
||||
int *iValue_ = nullptr;
|
||||
const char *category_ = nullptr;
|
||||
std::string(*translateCallback_)(const char *value) = nullptr;
|
||||
};
|
||||
|
||||
} // namespace UI
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "Common/Input/InputState.h"
|
||||
#include "Common/UI/Root.h"
|
||||
#include "Common/UI/Screen.h"
|
||||
#include "Common/UI/ScrollView.h"
|
||||
#include "Common/UI/UI.h"
|
||||
#include "Common/UI/View.h"
|
||||
#include "Common/UI/ViewGroup.h"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,133 @@
|
||||
#pragma once
|
||||
|
||||
#include "Common/UI/View.h"
|
||||
#include "Common/UI/ViewGroup.h"
|
||||
|
||||
namespace UI {
|
||||
|
||||
// A scrollview usually contains just a single child - a linear layout or similar.
|
||||
class ScrollView : public ViewGroup {
|
||||
public:
|
||||
ScrollView(Orientation orientation, LayoutParams *layoutParams = 0)
|
||||
: ViewGroup(layoutParams), orientation_(orientation) {}
|
||||
~ScrollView();
|
||||
|
||||
void Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert) override;
|
||||
void Layout() override;
|
||||
|
||||
bool Key(const KeyInput &input) override;
|
||||
bool Touch(const TouchInput &input) override;
|
||||
void Draw(UIContext &dc) override;
|
||||
std::string DescribeLog() const override { return "ScrollView: " + View::DescribeLog(); }
|
||||
|
||||
void ScrollTo(float newScrollPos);
|
||||
void ScrollToBottom();
|
||||
void ScrollRelative(float distance);
|
||||
bool CanScroll() const;
|
||||
void Update() override;
|
||||
|
||||
void RememberPosition(float *pos) {
|
||||
rememberPos_ = pos;
|
||||
ScrollTo(*pos);
|
||||
}
|
||||
|
||||
// Get the last moved scroll view position
|
||||
static void GetLastScrollPosition(float &x, float &y);
|
||||
|
||||
// Override so that we can scroll to the active one after moving the focus.
|
||||
bool SubviewFocused(View *view) override;
|
||||
void PersistData(PersistStatus status, std::string anonId, PersistMap &storage) override;
|
||||
void SetVisibility(Visibility visibility) override;
|
||||
|
||||
// If the view is smaller than the scroll view, sets whether to align to the bottom/right instead of the left.
|
||||
void SetAlignOpposite(bool alignOpposite) {
|
||||
alignOpposite_ = alignOpposite;
|
||||
}
|
||||
|
||||
NeighborResult FindScrollNeighbor(View *view, const Point &target, FocusDirection direction, NeighborResult best) override;
|
||||
|
||||
private:
|
||||
float ClampedScrollPos(float pos);
|
||||
|
||||
GestureDetector gesture_;
|
||||
Orientation orientation_;
|
||||
float scrollPos_ = 0.0f;
|
||||
float scrollStart_ = 0.0f;
|
||||
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;
|
||||
float *rememberPos_ = nullptr;
|
||||
bool alignOpposite_ = false;
|
||||
|
||||
static float lastScrollPosX;
|
||||
static float lastScrollPosY;
|
||||
};
|
||||
|
||||
// Yes, this feels a bit Java-ish...
|
||||
class ListAdaptor {
|
||||
public:
|
||||
virtual ~ListAdaptor() {}
|
||||
virtual View *CreateItemView(int index) = 0;
|
||||
virtual int GetNumItems() = 0;
|
||||
virtual bool AddEventCallback(View *view, std::function<EventReturn(EventParams &)> callback) { return false; }
|
||||
virtual std::string GetTitle(int index) const { return ""; }
|
||||
virtual void SetSelected(int sel) { }
|
||||
virtual int GetSelected() { return -1; }
|
||||
};
|
||||
|
||||
class ChoiceListAdaptor : public ListAdaptor {
|
||||
public:
|
||||
ChoiceListAdaptor(const char *items[], int numItems) : items_(items), numItems_(numItems) {}
|
||||
View *CreateItemView(int index) override;
|
||||
int GetNumItems() override { return numItems_; }
|
||||
bool AddEventCallback(View *view, std::function<EventReturn(EventParams &)> callback) override;
|
||||
|
||||
private:
|
||||
const char **items_;
|
||||
int numItems_;
|
||||
};
|
||||
|
||||
// The "selected" item is what was previously selected (optional). This items will be drawn differently.
|
||||
class StringVectorListAdaptor : public ListAdaptor {
|
||||
public:
|
||||
StringVectorListAdaptor() : selected_(-1) {}
|
||||
StringVectorListAdaptor(const std::vector<std::string> &items, int selected = -1) : items_(items), selected_(selected) {}
|
||||
View *CreateItemView(int index) override;
|
||||
int GetNumItems() override { return (int)items_.size(); }
|
||||
bool AddEventCallback(View *view, std::function<EventReturn(EventParams &)> callback) override;
|
||||
void SetSelected(int sel) override { selected_ = sel; }
|
||||
std::string GetTitle(int index) const override { return items_[index]; }
|
||||
int GetSelected() override { return selected_; }
|
||||
|
||||
private:
|
||||
std::vector<std::string> items_;
|
||||
int selected_;
|
||||
};
|
||||
|
||||
// A list view is a scroll view with autogenerated items.
|
||||
// In the future, it might be smart and load/unload items as they go, but currently not.
|
||||
class ListView : public ScrollView {
|
||||
public:
|
||||
ListView(ListAdaptor *a, std::set<int> hidden = std::set<int>(), LayoutParams *layoutParams = 0);
|
||||
|
||||
int GetSelected() { return adaptor_->GetSelected(); }
|
||||
void Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert) override;
|
||||
virtual void SetMaxHeight(float mh) { maxHeight_ = mh; }
|
||||
Event OnChoice;
|
||||
std::string DescribeLog() const override { return "ListView: " + View::DescribeLog(); }
|
||||
std::string DescribeText() const override;
|
||||
|
||||
private:
|
||||
void CreateAllItems();
|
||||
EventReturn OnItemCallback(int num, EventParams &e);
|
||||
ListAdaptor *adaptor_;
|
||||
LinearLayout *linLayout_;
|
||||
float maxHeight_;
|
||||
std::set<int> hidden_;
|
||||
};
|
||||
|
||||
} // namespace UI
|
||||
File diff suppressed because it is too large
Load Diff
@@ -68,7 +68,6 @@ private:
|
||||
bool finished_;
|
||||
};
|
||||
|
||||
|
||||
class PopupScreen : public UIDialogScreen {
|
||||
public:
|
||||
PopupScreen(std::string title, std::string button1 = "", std::string button2 = "");
|
||||
@@ -118,389 +117,3 @@ private:
|
||||
|
||||
bool hasDropShadow_ = true;
|
||||
};
|
||||
|
||||
class ListPopupScreen : public PopupScreen {
|
||||
public:
|
||||
ListPopupScreen(std::string title) : PopupScreen(title) {}
|
||||
ListPopupScreen(std::string title, const std::vector<std::string> &items, int selected, std::function<void(int)> callback, bool showButtons = false)
|
||||
: PopupScreen(title, "OK", "Cancel"), adaptor_(items, selected), callback_(callback), showButtons_(showButtons) {
|
||||
}
|
||||
ListPopupScreen(std::string title, const std::vector<std::string> &items, int selected, bool showButtons = false)
|
||||
: PopupScreen(title, "OK", "Cancel"), adaptor_(items, selected), showButtons_(showButtons) {
|
||||
}
|
||||
|
||||
int GetChoice() const {
|
||||
return listView_->GetSelected();
|
||||
}
|
||||
std::string GetChoiceString() const {
|
||||
return adaptor_.GetTitle(listView_->GetSelected());
|
||||
}
|
||||
void SetHiddenChoices(std::set<int> hidden) {
|
||||
hidden_ = hidden;
|
||||
}
|
||||
const char *tag() const override { return "listpopup"; }
|
||||
|
||||
UI::Event OnChoice;
|
||||
|
||||
protected:
|
||||
bool FillVertical() const override { return false; }
|
||||
bool ShowButtons() const override { return showButtons_; }
|
||||
void CreatePopupContents(UI::ViewGroup *parent) override;
|
||||
UI::StringVectorListAdaptor adaptor_;
|
||||
UI::ListView *listView_ = nullptr;
|
||||
|
||||
private:
|
||||
UI::EventReturn OnListChoice(UI::EventParams &e);
|
||||
|
||||
std::function<void(int)> callback_;
|
||||
bool showButtons_ = false;
|
||||
std::set<int> hidden_;
|
||||
};
|
||||
|
||||
class MessagePopupScreen : public PopupScreen {
|
||||
public:
|
||||
MessagePopupScreen(std::string title, std::string message, std::string button1, std::string button2, std::function<void(bool)> callback)
|
||||
: PopupScreen(title, button1, button2), message_(message), callback_(callback) {}
|
||||
UI::Event OnChoice;
|
||||
|
||||
protected:
|
||||
bool FillVertical() const override { return false; }
|
||||
bool ShowButtons() const override { return true; }
|
||||
void CreatePopupContents(UI::ViewGroup *parent) override;
|
||||
|
||||
private:
|
||||
void OnCompleted(DialogResult result) override;
|
||||
std::string message_;
|
||||
std::function<void(bool)> callback_;
|
||||
};
|
||||
|
||||
// TODO: Need a way to translate OK and Cancel
|
||||
|
||||
namespace UI {
|
||||
|
||||
class SliderPopupScreen : public PopupScreen {
|
||||
public:
|
||||
SliderPopupScreen(int *value, int minValue, int maxValue, const std::string &title, int step = 1, const std::string &units = "")
|
||||
: PopupScreen(title, "OK", "Cancel"), units_(units), value_(value), minValue_(minValue), maxValue_(maxValue), step_(step) {}
|
||||
void CreatePopupContents(ViewGroup *parent) override;
|
||||
|
||||
void SetNegativeDisable(const std::string &str) {
|
||||
negativeLabel_ = str;
|
||||
disabled_ = *value_ < 0;
|
||||
}
|
||||
|
||||
const char *tag() const override { return "SliderPopup"; }
|
||||
|
||||
Event OnChange;
|
||||
|
||||
private:
|
||||
EventReturn OnDecrease(EventParams ¶ms);
|
||||
EventReturn OnIncrease(EventParams ¶ms);
|
||||
EventReturn OnTextChange(EventParams ¶ms);
|
||||
EventReturn OnSliderChange(EventParams ¶ms);
|
||||
void OnCompleted(DialogResult result) override;
|
||||
Slider *slider_ = nullptr;
|
||||
UI::TextEdit *edit_ = nullptr;
|
||||
std::string units_;
|
||||
std::string negativeLabel_;
|
||||
int *value_;
|
||||
int sliderValue_ = 0;
|
||||
int minValue_;
|
||||
int maxValue_;
|
||||
int step_;
|
||||
bool changing_ = false;
|
||||
bool disabled_ = false;
|
||||
};
|
||||
|
||||
class SliderFloatPopupScreen : public PopupScreen {
|
||||
public:
|
||||
SliderFloatPopupScreen(float *value, float minValue, float maxValue, const std::string &title, float step = 1.0f, const std::string &units = "", bool liveUpdate = false)
|
||||
: PopupScreen(title, "OK", "Cancel"), units_(units), value_(value), originalValue_(*value), minValue_(minValue), maxValue_(maxValue), step_(step), changing_(false), liveUpdate_(liveUpdate) {}
|
||||
void CreatePopupContents(UI::ViewGroup *parent) override;
|
||||
|
||||
const char *tag() const override { return "SliderFloatPopup"; }
|
||||
|
||||
Event OnChange;
|
||||
|
||||
private:
|
||||
EventReturn OnIncrease(EventParams ¶ms);
|
||||
EventReturn OnDecrease(EventParams ¶ms);
|
||||
EventReturn OnTextChange(EventParams ¶ms);
|
||||
EventReturn OnSliderChange(EventParams ¶ms);
|
||||
void OnCompleted(DialogResult result) override;
|
||||
UI::SliderFloat *slider_;
|
||||
UI::TextEdit *edit_;
|
||||
std::string units_;
|
||||
float sliderValue_;
|
||||
float originalValue_;
|
||||
float *value_;
|
||||
float minValue_;
|
||||
float maxValue_;
|
||||
float step_;
|
||||
bool changing_;
|
||||
bool liveUpdate_;
|
||||
};
|
||||
|
||||
class TextEditPopupScreen : public PopupScreen {
|
||||
public:
|
||||
TextEditPopupScreen(std::string *value, const std::string &placeholder, const std::string &title, int maxLen)
|
||||
: PopupScreen(title, "OK", "Cancel"), value_(value), placeholder_(placeholder), maxLen_(maxLen) {}
|
||||
void CreatePopupContents(ViewGroup *parent) override;
|
||||
|
||||
const char *tag() const override { return "TextEditPopup"; }
|
||||
|
||||
Event OnChange;
|
||||
|
||||
private:
|
||||
void OnCompleted(DialogResult result) override;
|
||||
TextEdit *edit_;
|
||||
std::string *value_;
|
||||
std::string textEditValue_;
|
||||
std::string placeholder_;
|
||||
int maxLen_;
|
||||
};
|
||||
|
||||
// TODO: Break out a lot of popup stuff from UIScreen.h.
|
||||
|
||||
struct ContextMenuItem {
|
||||
const char *text;
|
||||
const char *imageID;
|
||||
};
|
||||
|
||||
// Once a selection has been made,
|
||||
class PopupContextMenuScreen : public PopupScreen {
|
||||
public:
|
||||
PopupContextMenuScreen(const ContextMenuItem *items, size_t itemCount, I18NCategory *category, UI::View *sourceView);
|
||||
void CreatePopupContents(ViewGroup *parent) override;
|
||||
|
||||
const char *tag() const override { return "ContextMenuPopup"; }
|
||||
|
||||
void SetEnabled(size_t index, bool enabled) {
|
||||
enabled_[index] = enabled;
|
||||
}
|
||||
|
||||
UI::Event OnChoice;
|
||||
|
||||
protected:
|
||||
bool HasTitleBar() const override { return false; }
|
||||
|
||||
private:
|
||||
const ContextMenuItem *items_;
|
||||
size_t itemCount_;
|
||||
I18NCategory *category_;
|
||||
UI::View *sourceView_;
|
||||
std::vector<bool> enabled_;
|
||||
};
|
||||
|
||||
class AbstractChoiceWithValueDisplay : public UI::Choice {
|
||||
public:
|
||||
AbstractChoiceWithValueDisplay(const std::string &text, LayoutParams *layoutParams = nullptr)
|
||||
: Choice(text, layoutParams) {
|
||||
}
|
||||
|
||||
void Draw(UIContext &dc) override;
|
||||
void GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert, float &w, float &h) const override;
|
||||
|
||||
protected:
|
||||
virtual std::string ValueText() const = 0;
|
||||
|
||||
float CalculateValueScale(const UIContext &dc, const std::string &valueText, float availWidth) const;
|
||||
};
|
||||
|
||||
// Reads and writes value to determine the current selection.
|
||||
class PopupMultiChoice : public AbstractChoiceWithValueDisplay {
|
||||
public:
|
||||
PopupMultiChoice(int *value, const std::string &text, const char **choices, int minVal, int numChoices,
|
||||
const char *category, ScreenManager *screenManager, UI::LayoutParams *layoutParams = nullptr)
|
||||
: AbstractChoiceWithValueDisplay(text, layoutParams), value_(value), choices_(choices), minVal_(minVal), numChoices_(numChoices),
|
||||
category_(category), screenManager_(screenManager) {
|
||||
if (*value >= numChoices + minVal)
|
||||
*value = numChoices + minVal - 1;
|
||||
if (*value < minVal)
|
||||
*value = minVal;
|
||||
OnClick.Handle(this, &PopupMultiChoice::HandleClick);
|
||||
UpdateText();
|
||||
}
|
||||
|
||||
void Update() override;
|
||||
|
||||
void HideChoice(int c) {
|
||||
hidden_.insert(c);
|
||||
}
|
||||
|
||||
UI::Event OnChoice;
|
||||
|
||||
protected:
|
||||
std::string ValueText() const override;
|
||||
|
||||
int *value_;
|
||||
const char **choices_;
|
||||
int minVal_;
|
||||
int numChoices_;
|
||||
void UpdateText();
|
||||
|
||||
private:
|
||||
UI::EventReturn HandleClick(UI::EventParams &e);
|
||||
|
||||
void ChoiceCallback(int num);
|
||||
virtual void PostChoiceCallback(int num) {}
|
||||
|
||||
const char *category_;
|
||||
ScreenManager *screenManager_;
|
||||
std::string valueText_;
|
||||
bool restoreFocus_ = false;
|
||||
std::set<int> hidden_;
|
||||
};
|
||||
|
||||
// Allows passing in a dynamic vector of strings. Saves the string.
|
||||
class PopupMultiChoiceDynamic : public PopupMultiChoice {
|
||||
public:
|
||||
PopupMultiChoiceDynamic(std::string *value, const std::string &text, std::vector<std::string> choices,
|
||||
const char *category, ScreenManager *screenManager, UI::LayoutParams *layoutParams = nullptr)
|
||||
: UI::PopupMultiChoice(&valueInt_, text, nullptr, 0, (int)choices.size(), category, screenManager, layoutParams),
|
||||
valueStr_(value) {
|
||||
choices_ = new const char *[numChoices_];
|
||||
valueInt_ = 0;
|
||||
for (int i = 0; i < numChoices_; i++) {
|
||||
choices_[i] = new char[choices[i].size() + 1];
|
||||
memcpy((char *)choices_[i], choices[i].c_str(), choices[i].size() + 1);
|
||||
if (*value == choices_[i])
|
||||
valueInt_ = i;
|
||||
}
|
||||
value_ = &valueInt_;
|
||||
UpdateText();
|
||||
}
|
||||
~PopupMultiChoiceDynamic() {
|
||||
for (int i = 0; i < numChoices_; i++) {
|
||||
delete[] choices_[i];
|
||||
}
|
||||
delete[] choices_;
|
||||
}
|
||||
|
||||
protected:
|
||||
void PostChoiceCallback(int num) override {
|
||||
*valueStr_ = choices_[num];
|
||||
}
|
||||
|
||||
private:
|
||||
int valueInt_;
|
||||
std::string *valueStr_;
|
||||
};
|
||||
|
||||
class PopupSliderChoice : public AbstractChoiceWithValueDisplay {
|
||||
public:
|
||||
PopupSliderChoice(int *value, int minValue, int maxValue, const std::string &text, ScreenManager *screenManager, const std::string &units = "", LayoutParams *layoutParams = 0);
|
||||
PopupSliderChoice(int *value, int minValue, int maxValue, const std::string &text, int step, ScreenManager *screenManager, const std::string &units = "", LayoutParams *layoutParams = 0);
|
||||
|
||||
void SetFormat(const char *fmt) {
|
||||
fmt_ = fmt;
|
||||
}
|
||||
void SetZeroLabel(const std::string &str) {
|
||||
zeroLabel_ = str;
|
||||
}
|
||||
void SetNegativeDisable(const std::string &str) {
|
||||
negativeLabel_ = str;
|
||||
}
|
||||
|
||||
Event OnChange;
|
||||
|
||||
protected:
|
||||
std::string ValueText() const override;
|
||||
|
||||
private:
|
||||
EventReturn HandleClick(EventParams &e);
|
||||
EventReturn HandleChange(EventParams &e);
|
||||
|
||||
int *value_;
|
||||
int minValue_;
|
||||
int maxValue_;
|
||||
int step_;
|
||||
const char *fmt_;
|
||||
std::string zeroLabel_;
|
||||
std::string negativeLabel_;
|
||||
std::string units_;
|
||||
ScreenManager *screenManager_;
|
||||
bool restoreFocus_ = false;
|
||||
};
|
||||
|
||||
class PopupSliderChoiceFloat : public AbstractChoiceWithValueDisplay {
|
||||
public:
|
||||
PopupSliderChoiceFloat(float *value, float minValue, float maxValue, const std::string &text, ScreenManager *screenManager, const std::string &units = "", LayoutParams *layoutParams = 0);
|
||||
PopupSliderChoiceFloat(float *value, float minValue, float maxValue, const std::string &text, float step, ScreenManager *screenManager, const std::string &units = "", LayoutParams *layoutParams = 0);
|
||||
|
||||
void SetFormat(const char *fmt) {
|
||||
fmt_ = fmt;
|
||||
}
|
||||
void SetZeroLabel(const std::string &str) {
|
||||
zeroLabel_ = str;
|
||||
}
|
||||
void SetLiveUpdate(bool update) {
|
||||
liveUpdate_ = update;
|
||||
}
|
||||
void SetHasDropShadow(bool has) {
|
||||
hasDropShadow_ = has;
|
||||
}
|
||||
|
||||
Event OnChange;
|
||||
|
||||
protected:
|
||||
std::string ValueText() const override;
|
||||
|
||||
private:
|
||||
EventReturn HandleClick(EventParams &e);
|
||||
EventReturn HandleChange(EventParams &e);
|
||||
float *value_;
|
||||
float minValue_;
|
||||
float maxValue_;
|
||||
float step_;
|
||||
const char *fmt_;
|
||||
std::string zeroLabel_;
|
||||
std::string units_;
|
||||
ScreenManager *screenManager_;
|
||||
bool restoreFocus_ = false;
|
||||
bool liveUpdate_ = false;
|
||||
bool hasDropShadow_ = true;
|
||||
};
|
||||
|
||||
class PopupTextInputChoice: public AbstractChoiceWithValueDisplay {
|
||||
public:
|
||||
PopupTextInputChoice(std::string *value, const std::string &title, const std::string &placeholder, int maxLen, ScreenManager *screenManager, LayoutParams *layoutParams = 0);
|
||||
|
||||
Event OnChange;
|
||||
|
||||
protected:
|
||||
std::string ValueText() const override;
|
||||
|
||||
private:
|
||||
EventReturn HandleClick(EventParams &e);
|
||||
EventReturn HandleChange(EventParams &e);
|
||||
ScreenManager *screenManager_;
|
||||
std::string *value_;
|
||||
std::string placeHolder_;
|
||||
std::string defaultText_;
|
||||
int maxLen_;
|
||||
bool restoreFocus_;
|
||||
};
|
||||
|
||||
class ChoiceWithValueDisplay : public AbstractChoiceWithValueDisplay {
|
||||
public:
|
||||
ChoiceWithValueDisplay(int *value, const std::string &text, LayoutParams *layoutParams = 0)
|
||||
: AbstractChoiceWithValueDisplay(text, layoutParams), iValue_(value) {}
|
||||
|
||||
ChoiceWithValueDisplay(std::string *value, const std::string &text, const char *category, LayoutParams *layoutParams = 0)
|
||||
: AbstractChoiceWithValueDisplay(text, layoutParams), sValue_(value), category_(category) {}
|
||||
|
||||
ChoiceWithValueDisplay(std::string *value, const std::string &text, std::string (*translateCallback)(const char *value), LayoutParams *layoutParams = 0)
|
||||
: AbstractChoiceWithValueDisplay(text, layoutParams), sValue_(value), translateCallback_(translateCallback) {
|
||||
}
|
||||
|
||||
private:
|
||||
std::string ValueText() const override;
|
||||
|
||||
std::string *sValue_ = nullptr;
|
||||
int *iValue_ = nullptr;
|
||||
const char *category_ = nullptr;
|
||||
std::string (*translateCallback_)(const char *value) = nullptr;
|
||||
};
|
||||
|
||||
} // namespace UI
|
||||
|
||||
+1
-495
File diff suppressed because it is too large
Load Diff
+1
-126
@@ -12,6 +12,7 @@
|
||||
namespace UI {
|
||||
|
||||
class AnchorTranslateTween;
|
||||
class ScrollView;
|
||||
|
||||
struct NeighborResult {
|
||||
NeighborResult() : view(0), score(0) {}
|
||||
@@ -260,68 +261,6 @@ public:
|
||||
std::string DescribeText() const override;
|
||||
};
|
||||
|
||||
// A scrollview usually contains just a single child - a linear layout or similar.
|
||||
class ScrollView : public ViewGroup {
|
||||
public:
|
||||
ScrollView(Orientation orientation, LayoutParams *layoutParams = 0)
|
||||
: ViewGroup(layoutParams), orientation_(orientation) {}
|
||||
~ScrollView();
|
||||
|
||||
void Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert) override;
|
||||
void Layout() override;
|
||||
|
||||
bool Key(const KeyInput &input) override;
|
||||
bool Touch(const TouchInput &input) override;
|
||||
void Draw(UIContext &dc) override;
|
||||
std::string DescribeLog() const override { return "ScrollView: " + View::DescribeLog(); }
|
||||
|
||||
void ScrollTo(float newScrollPos);
|
||||
void ScrollToBottom();
|
||||
void ScrollRelative(float distance);
|
||||
bool CanScroll() const;
|
||||
void Update() override;
|
||||
|
||||
void RememberPosition(float *pos) {
|
||||
rememberPos_ = pos;
|
||||
ScrollTo(*pos);
|
||||
}
|
||||
|
||||
// Get the last moved scroll view position
|
||||
static void GetLastScrollPosition(float &x, float &y);
|
||||
|
||||
// Override so that we can scroll to the active one after moving the focus.
|
||||
bool SubviewFocused(View *view) override;
|
||||
void PersistData(PersistStatus status, std::string anonId, PersistMap &storage) override;
|
||||
void SetVisibility(Visibility visibility) override;
|
||||
|
||||
// If the view is smaller than the scroll view, sets whether to align to the bottom/right instead of the left.
|
||||
void SetAlignOpposite(bool alignOpposite) {
|
||||
alignOpposite_ = alignOpposite;
|
||||
}
|
||||
|
||||
NeighborResult FindScrollNeighbor(View *view, const Point &target, FocusDirection direction, NeighborResult best) override;
|
||||
|
||||
private:
|
||||
float ClampedScrollPos(float pos);
|
||||
|
||||
GestureDetector gesture_;
|
||||
Orientation orientation_;
|
||||
float scrollPos_ = 0.0f;
|
||||
float scrollStart_ = 0.0f;
|
||||
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;
|
||||
float *rememberPos_ = nullptr;
|
||||
bool alignOpposite_ = false;
|
||||
|
||||
static float lastScrollPosX;
|
||||
static float lastScrollPosY;
|
||||
};
|
||||
|
||||
class ChoiceStrip : public LinearLayout {
|
||||
public:
|
||||
ChoiceStrip(Orientation orientation, LayoutParams *layoutParams = 0);
|
||||
@@ -387,68 +326,4 @@ private:
|
||||
std::vector<AnchorTranslateTween *> tabTweens_;
|
||||
};
|
||||
|
||||
// Yes, this feels a bit Java-ish...
|
||||
class ListAdaptor {
|
||||
public:
|
||||
virtual ~ListAdaptor() {}
|
||||
virtual View *CreateItemView(int index) = 0;
|
||||
virtual int GetNumItems() = 0;
|
||||
virtual bool AddEventCallback(View *view, std::function<EventReturn(EventParams&)> callback) { return false; }
|
||||
virtual std::string GetTitle(int index) const { return ""; }
|
||||
virtual void SetSelected(int sel) { }
|
||||
virtual int GetSelected() { return -1; }
|
||||
};
|
||||
|
||||
class ChoiceListAdaptor : public ListAdaptor {
|
||||
public:
|
||||
ChoiceListAdaptor(const char *items[], int numItems) : items_(items), numItems_(numItems) {}
|
||||
View *CreateItemView(int index) override;
|
||||
int GetNumItems() override { return numItems_; }
|
||||
bool AddEventCallback(View *view, std::function<EventReturn(EventParams&)> callback) override;
|
||||
|
||||
private:
|
||||
const char **items_;
|
||||
int numItems_;
|
||||
};
|
||||
|
||||
|
||||
// The "selected" item is what was previously selected (optional). This items will be drawn differently.
|
||||
class StringVectorListAdaptor : public ListAdaptor {
|
||||
public:
|
||||
StringVectorListAdaptor() : selected_(-1) {}
|
||||
StringVectorListAdaptor(const std::vector<std::string> &items, int selected = -1) : items_(items), selected_(selected) {}
|
||||
View *CreateItemView(int index) override;
|
||||
int GetNumItems() override { return (int)items_.size(); }
|
||||
bool AddEventCallback(View *view, std::function<EventReturn(EventParams&)> callback) override;
|
||||
void SetSelected(int sel) override { selected_ = sel; }
|
||||
std::string GetTitle(int index) const override { return items_[index]; }
|
||||
int GetSelected() override { return selected_; }
|
||||
|
||||
private:
|
||||
std::vector<std::string> items_;
|
||||
int selected_;
|
||||
};
|
||||
|
||||
// A list view is a scroll view with autogenerated items.
|
||||
// In the future, it might be smart and load/unload items as they go, but currently not.
|
||||
class ListView : public ScrollView {
|
||||
public:
|
||||
ListView(ListAdaptor *a, std::set<int> hidden = std::set<int>(), LayoutParams *layoutParams = 0);
|
||||
|
||||
int GetSelected() { return adaptor_->GetSelected(); }
|
||||
void Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert) override;
|
||||
virtual void SetMaxHeight(float mh) { maxHeight_ = mh; }
|
||||
Event OnChoice;
|
||||
std::string DescribeLog() const override { return "ListView: " + View::DescribeLog(); }
|
||||
std::string DescribeText() const override;
|
||||
|
||||
private:
|
||||
void CreateAllItems();
|
||||
EventReturn OnItemCallback(int num, EventParams &e);
|
||||
ListAdaptor *adaptor_;
|
||||
LinearLayout *linLayout_;
|
||||
float maxHeight_;
|
||||
std::set<int> hidden_;
|
||||
};
|
||||
|
||||
} // namespace UI
|
||||
|
||||
Reference in New Issue
Block a user