mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-12 17:19:28 +01:00
Merge pull request #22933 from hrydgard/more-ui-work
Fix a bunch of UI bugs
This commit is contained in:
29 files changed
+216
-136
No files matched your search
@@ -174,3 +174,16 @@ bool HitAnyAsserts() {
|
||||
void ResetHitAnyAsserts() {
|
||||
hitAnyAsserts = false;
|
||||
}
|
||||
|
||||
void ShowMessageDialog(const char *title, const char *message, bool isError) {
|
||||
#if PPSSPP_PLATFORM(WINDOWS) && !PPSSPP_PLATFORM(UWP)
|
||||
const int msgBoxStyle = MB_ICONINFORMATION | MB_OK;
|
||||
std::string text = message;
|
||||
const char *caption = title;
|
||||
std::wstring wcaption = ConvertUTF8ToWString(std::string(caption));
|
||||
MessageBox(g_dialogParent, ConvertUTF8ToWString(text).c_str(), wcaption.c_str(), msgBoxStyle);
|
||||
#else
|
||||
// Just printf.
|
||||
fprintf(stderr, "%s: %s\n", title, message);
|
||||
#endif
|
||||
}
|
||||
@@ -154,6 +154,7 @@ void SetAssertCancelCallback(AssertNoCallbackFunc callback, void *userdata);
|
||||
void SetCleanExitOnAssert();
|
||||
void BreakIntoPSPDebugger(const char *reason = "(userbreak)");
|
||||
void SetAssertDialogParent(void *handle); // HWND on windows. Ignored on other platforms.
|
||||
void ShowMessageDialog(const char *title, const char *message, bool isError = false);
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
// Tricky macro to get the basename, that also works if *built* on Win32.
|
||||
|
||||
@@ -21,7 +21,8 @@ ENUM_CLASS_BITOPS(FontStyleFlags);
|
||||
|
||||
enum class FontFamily : u8 {
|
||||
SansSerif = 1,
|
||||
Fixed = 2,
|
||||
SansSerifWide = 2,
|
||||
Fixed = 3,
|
||||
};
|
||||
|
||||
struct FontStyle {
|
||||
|
||||
@@ -400,6 +400,10 @@ static const FontDesc g_fontDescs[] = {
|
||||
{FontFamily::SansSerif, FontStyleFlags::Bold, "Roboto Condensed", "Roboto_Condensed-Bold"},
|
||||
{FontFamily::SansSerif, FontStyleFlags::Italic, "Roboto Condensed", "Roboto_Condensed-Italic"},
|
||||
{FontFamily::SansSerif, FontStyleFlags::Light, "Roboto Condensed", "Roboto_Condensed-Light"},
|
||||
{FontFamily::SansSerifWide, FontStyleFlags::Default, "Roboto SemiCondensed", "Roboto_SemiCondensed-Regular"},
|
||||
{FontFamily::SansSerifWide, FontStyleFlags::Bold, "Roboto SemiCondensed", "Roboto_SemiCondensed-Bold"},
|
||||
{FontFamily::SansSerifWide, FontStyleFlags::Italic, "Roboto SemiCondensed", "Roboto_SemiCondensed-Italic"},
|
||||
{FontFamily::SansSerifWide, FontStyleFlags::Light, "Roboto SemiCondensed", "Roboto_SemiCondensed-Light"},
|
||||
{FontFamily::Fixed, FontStyleFlags::Default, "Inconsolata", "Inconsolata-Regular"},
|
||||
};
|
||||
|
||||
|
||||
+12
-17
@@ -153,6 +153,7 @@ void PopupScreen::CreateViews() {
|
||||
using namespace UI;
|
||||
UIContext &dc = *screenManager()->getUIContext();
|
||||
|
||||
// This places the actual popup in the center of the screen.
|
||||
AnchorLayout *anchor = new AnchorLayout(new LayoutParams(FILL_PARENT, FILL_PARENT));
|
||||
anchor->Overflow(false);
|
||||
root_ = anchor;
|
||||
@@ -184,16 +185,16 @@ void PopupScreen::CreateViews() {
|
||||
(layoutBounds.w - RootMargins().horiz()) * 0.5, y, NONE, NONE, vCentering | Centering::Horizontal);
|
||||
}
|
||||
|
||||
box_ = new LinearLayout(ORIENT_VERTICAL, anchorParams);
|
||||
// Box is the actual popup shape.
|
||||
box_ = root_->Add(new LinearLayout(ORIENT_VERTICAL, anchorParams));
|
||||
|
||||
root_->Add(box_);
|
||||
box_->SetBG(dc.GetTheme().popupStyle.background);
|
||||
box_->SetHasDropShadow(hasDropShadow_);
|
||||
box_->SetRadiusFactor(1.44f);
|
||||
// Since we scale a bit, make the dropshadow bleed past the edges.
|
||||
box_->SetDropShadowExpand(std::max(g_display.dp_xres, g_display.dp_yres));
|
||||
box_->SetSpacing(0.0f);
|
||||
box_->SetPadding(Margins(8));
|
||||
box_->SetSpacing(12.0f);
|
||||
box_->SetPadding(Margins(12));
|
||||
|
||||
if (!title_.empty()) {
|
||||
View *title = new PopupHeader(title_);
|
||||
@@ -214,21 +215,19 @@ void PopupScreen::CreateViews() {
|
||||
if (ShowButtons() && !button1_.empty()) {
|
||||
// And the two buttons at the bottom.
|
||||
LinearLayout *buttonRow = new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(200, WRAP_CONTENT));
|
||||
buttonRow->SetSpacing(0);
|
||||
Margins buttonMargins(5, 5);
|
||||
|
||||
buttonRow->SetSpacing(8);
|
||||
// Adjust button order to the platform default.
|
||||
if (System_GetPropertyBool(SYSPROP_OK_BUTTON_LEFT)) {
|
||||
defaultButton_ = buttonRow->Add(new Choice(button1_, button1Image_, new LinearLayoutParams(1.0f, buttonMargins)));
|
||||
defaultButton_ = buttonRow->Add(new Choice(button1_, button1Image_, new LinearLayoutParams(1.0f)));
|
||||
defaultButton_->OnClick.Handle<UIScreen>(this, &UIScreen::OnOK);
|
||||
if (!button2_.empty()) {
|
||||
buttonRow->Add(new Choice(button2_, button2Image_, new LinearLayoutParams(1.0f, buttonMargins)))->OnClick.Handle<UIScreen>(this, &UIScreen::OnCancel);
|
||||
buttonRow->Add(new Choice(button2_, button2Image_, new LinearLayoutParams(1.0f)))->OnClick.Handle<UIScreen>(this, &UIScreen::OnCancel);
|
||||
}
|
||||
} else {
|
||||
if (!button2_.empty()) {
|
||||
buttonRow->Add(new Choice(button2_, button2Image_, new LinearLayoutParams(1.0f, buttonMargins)))->OnClick.Handle<UIScreen>(this, &UIScreen::OnCancel);
|
||||
buttonRow->Add(new Choice(button2_, button2Image_, new LinearLayoutParams(1.0f)))->OnClick.Handle<UIScreen>(this, &UIScreen::OnCancel);
|
||||
}
|
||||
defaultButton_ = buttonRow->Add(new Choice(button1_, button1Image_, new LinearLayoutParams(1.0f, buttonMargins)));
|
||||
defaultButton_ = buttonRow->Add(new Choice(button1_, button1Image_, new LinearLayoutParams(1.0f)));
|
||||
defaultButton_->OnClick.Handle<UIScreen>(this, &UIScreen::OnOK);
|
||||
}
|
||||
|
||||
@@ -256,12 +255,8 @@ void MessagePopupScreen::CreatePopupContents(UI::ViewGroup *parent) {
|
||||
}
|
||||
|
||||
void MessagePopupScreen::OnCompleted(DialogResult result) {
|
||||
if (result == DR_OK) {
|
||||
if (callback_)
|
||||
callback_(true);
|
||||
} else {
|
||||
if (callback_)
|
||||
callback_(false);
|
||||
if (callback_) {
|
||||
callback_(result == DR_OK);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+53
-38
@@ -641,6 +641,59 @@ std::string ItemHeader::DescribeText() const {
|
||||
return ApplySafeSubstitutions(u->T("%1 heading"), text_);
|
||||
}
|
||||
|
||||
PopupHeader::PopupHeader(std::string_view text, LayoutParams *layoutParams)
|
||||
: Item(layoutParams), text_(text) {
|
||||
layoutParams_->width = FILL_PARENT;
|
||||
layoutParams_->height = 44;
|
||||
}
|
||||
|
||||
void PopupHeader::GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert, float &w, float &h) const {
|
||||
float availWidth = layoutParams_->width;
|
||||
if (availWidth < 0) {
|
||||
// If there's no size, let's grow as big as we want.
|
||||
availWidth = horiz.size == 0 ? MAX_ITEM_SIZE : horiz.size;
|
||||
}
|
||||
ApplyBoundBySpec(availWidth, horiz);
|
||||
dc.MeasureTextRect(dc.GetTheme().uiFontBig, 1.0f, 1.0f, text_, availWidth, &w, &h, ALIGN_LEFT | ALIGN_VCENTER);
|
||||
}
|
||||
|
||||
void PopupHeader::Draw(UIContext &dc) {
|
||||
const float availableWidth = bounds_.w;
|
||||
|
||||
float tw, th;
|
||||
dc.SetFontStyle(dc.GetTheme().uiFontBig);
|
||||
dc.MeasureText(dc.GetFontStyle(), 1.0f, 1.0f, text_, &tw, &th, 0);
|
||||
|
||||
float sineWidth = std::max(0.0f, (tw - availableWidth)) / 2.0f;
|
||||
|
||||
float tx = 0;
|
||||
if (availableWidth < tw) {
|
||||
float overageRatio = 1.5f * availableWidth * 1.0f / tw;
|
||||
tx -= (1.0f + sin(time_now_d() * overageRatio)) * sineWidth;
|
||||
Bounds tb = bounds_;
|
||||
tb.x = bounds_.x;
|
||||
tb.w = bounds_.w;
|
||||
dc.PushScissor(tb);
|
||||
}
|
||||
|
||||
// Header background
|
||||
dc.FillRoundRect(dc.GetTheme().popupTitleStyle.background, bounds_, dc.GetTheme().choiceRoundRadius, roundCorners_);
|
||||
// Header title text
|
||||
dc.DrawText(text_, bounds_.x + tx, bounds_.centerY(), dc.GetTheme().popupTitleStyle.fgColor, ALIGN_LEFT | ALIGN_VCENTER);
|
||||
|
||||
// Underline. Skipping it with the new style.
|
||||
// dc.Draw()->DrawImageCenterTexel(dc.GetTheme().whiteImage, bounds_.x, bounds_.y2()-2, bounds_.x2(), bounds_.y2(), dc.GetTheme().popupTitleStyle.fgColor);
|
||||
|
||||
if (availableWidth < tw) {
|
||||
dc.PopScissor();
|
||||
}
|
||||
}
|
||||
|
||||
std::string PopupHeader::DescribeText() const {
|
||||
auto u = GetI18NCategory(I18NCat::UI_ELEMENTS);
|
||||
return ApplySafeSubstitutions(u->T("%1 heading"), text_);
|
||||
}
|
||||
|
||||
CollapsibleHeader::CollapsibleHeader(bool *toggle, std::string_view text, LayoutParams *layoutParams)
|
||||
: CheckBox(toggle, text, "", layoutParams) {
|
||||
layoutParams_->width = FILL_PARENT;
|
||||
@@ -713,44 +766,6 @@ void BorderView::GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec hor
|
||||
h = (borderFlags_ & BORDER_HORIZ) != 0 ? bounds.h : 0;
|
||||
}
|
||||
|
||||
void PopupHeader::Draw(UIContext &dc) {
|
||||
const float paddingHorizontal = 12;
|
||||
const float availableWidth = bounds_.w - paddingHorizontal * 2;
|
||||
|
||||
float tw, th;
|
||||
dc.SetFontStyle(dc.GetTheme().uiFont);
|
||||
dc.MeasureText(dc.GetFontStyle(), 1.0f, 1.0f, text_, &tw, &th, 0);
|
||||
|
||||
float sineWidth = std::max(0.0f, (tw - availableWidth)) / 2.0f;
|
||||
|
||||
float tx = paddingHorizontal;
|
||||
if (availableWidth < tw) {
|
||||
float overageRatio = 1.5f * availableWidth * 1.0f / tw;
|
||||
tx -= (1.0f + sin(time_now_d() * overageRatio)) * sineWidth;
|
||||
Bounds tb = bounds_;
|
||||
tb.x = bounds_.x + paddingHorizontal;
|
||||
tb.w = bounds_.w - paddingHorizontal * 2;
|
||||
dc.PushScissor(tb);
|
||||
}
|
||||
|
||||
// Header background
|
||||
dc.FillRoundRect(dc.GetTheme().popupTitleStyle.background, bounds_, dc.GetTheme().choiceRoundRadius, roundCorners_);
|
||||
// Header title text
|
||||
dc.DrawText(text_, bounds_.x + tx, bounds_.centerY(), dc.GetTheme().popupTitleStyle.fgColor, ALIGN_LEFT | ALIGN_VCENTER);
|
||||
|
||||
// Underline. Skipping it with the new style.
|
||||
// dc.Draw()->DrawImageCenterTexel(dc.GetTheme().whiteImage, bounds_.x, bounds_.y2()-2, bounds_.x2(), bounds_.y2(), dc.GetTheme().popupTitleStyle.fgColor);
|
||||
|
||||
if (availableWidth < tw) {
|
||||
dc.PopScissor();
|
||||
}
|
||||
}
|
||||
|
||||
std::string PopupHeader::DescribeText() const {
|
||||
auto u = GetI18NCategory(I18NCat::UI_ELEMENTS);
|
||||
return ApplySafeSubstitutions(u->T("%1 heading"), text_);
|
||||
}
|
||||
|
||||
void CheckBox::Toggle() {
|
||||
if (toggle_) {
|
||||
*toggle_ = !(*toggle_);
|
||||
|
||||
+2
-5
@@ -939,12 +939,9 @@ private:
|
||||
|
||||
class PopupHeader : public Item {
|
||||
public:
|
||||
PopupHeader(std::string_view text, LayoutParams *layoutParams = 0)
|
||||
: Item(layoutParams), text_(text) {
|
||||
layoutParams_->width = FILL_PARENT;
|
||||
layoutParams_->height = 64;
|
||||
}
|
||||
PopupHeader(std::string_view text, LayoutParams *layoutParams = 0);
|
||||
void Draw(UIContext &dc) override;
|
||||
void GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert, float &w, float &h) const override;
|
||||
std::string DescribeText() const override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -885,7 +885,14 @@ ChoiceGroup::ChoiceGroup(std::string_view title, LayoutParams *layoutParams)
|
||||
|
||||
ChoiceGroupList::ChoiceGroupList(LayoutParams *layoutParams)
|
||||
: LinearLayoutList(ORIENT_VERTICAL, layoutParams ? layoutParams : new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)) {
|
||||
SetPadding(Margins(12, 12, 8, 12));
|
||||
SetPadding(Margins(12, 12, 12, 12));
|
||||
SetSpacing(24.0f);
|
||||
}
|
||||
|
||||
PopupChoiceGroupList::PopupChoiceGroupList(LayoutParams *layoutParams)
|
||||
: LinearLayoutList(ORIENT_VERTICAL, layoutParams ? layoutParams : new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)) {
|
||||
// Padding is already present in the popup itself. Just add a little more.
|
||||
SetPadding(Margins(0));
|
||||
SetSpacing(24.0f);
|
||||
}
|
||||
|
||||
|
||||
@@ -276,6 +276,13 @@ public:
|
||||
ChoiceGroupList(LayoutParams *layoutParams = nullptr);
|
||||
};
|
||||
|
||||
// A vertical list that spaces out the ChoiceGroups in it and keeps them off its edges.
|
||||
// This one is adjusted for popups (i.e. smaller margins and spacing).
|
||||
class PopupChoiceGroupList : public LinearLayoutList {
|
||||
public:
|
||||
PopupChoiceGroupList(LayoutParams *layoutParams = nullptr);
|
||||
};
|
||||
|
||||
// GridLayout is a little different from the Android layout. This one has fixed size
|
||||
// rows and columns, filled row by row. Items are not allowed to deviate from the set sizes.
|
||||
struct GridLayoutSettings {
|
||||
|
||||
@@ -557,6 +557,17 @@ CommandLineParseResult CommandLineOptions::Parse(int argc, const char *argv[], C
|
||||
}
|
||||
} else if (startsWith(argv[i], "--")) {
|
||||
PRINT_STDERR("Error: Unknown parameter: %s\n", argv[i]);
|
||||
if (mode == CmdLineMode::Application) {
|
||||
// Ignore bad parameters - but inform the user in the Windows debug output at least.
|
||||
OutputDebugStringUTF8("Warning: Unknown parameter: ");
|
||||
OutputDebugStringUTF8(argv[i]);
|
||||
OutputDebugStringUTF8("\n");
|
||||
|
||||
std::string msg = StringFromFormat("Unknown command line parameter: %s\n\nProceeding anyway.", argv[i]);
|
||||
ShowMessageDialog("Unknown Parameter", msg.c_str(), true);
|
||||
|
||||
return CommandLineParseResult::Continue;
|
||||
}
|
||||
return CommandLineParseResult::Error;
|
||||
}
|
||||
// To the next argument.
|
||||
|
||||
@@ -342,6 +342,8 @@ void GameButton::Draw(UIContext &dc) {
|
||||
dc.PopScissor();
|
||||
}
|
||||
} else {
|
||||
// The two list view modes, compat and large.
|
||||
|
||||
Bounds bounds = bounds_;
|
||||
|
||||
std::string_view rightText = g_Config.bShowIDOnGameIcon ? std::string_view(id_version) : std::string_view();
|
||||
|
||||
+14
-5
@@ -396,17 +396,26 @@ bool GameInfo::DeleteAllSaveData() const {
|
||||
|
||||
void GameInfo::ParseParamSFO(IdentifiedFileType type) {
|
||||
title = paramSFO.GetValueString("TITLE");
|
||||
if (type != IdentifiedFileType::PSP_UMD_VIDEO_ISO) {
|
||||
switch (type) {
|
||||
case IdentifiedFileType::PSP_UMD_VIDEO_ISO:
|
||||
id.clear();
|
||||
id_version.clear();
|
||||
region = GameRegion::UNKNOWN;
|
||||
break;
|
||||
case IdentifiedFileType::PSP_SAVEDATA_DIRECTORY:
|
||||
// Sniff the ID from the folder name.
|
||||
id = paramSFO.GetValueString("SAVEDATA_DIRECTORY").substr(0, 9);
|
||||
id_version = id;
|
||||
region = DetectGameRegionFromID(id);
|
||||
break;
|
||||
default:
|
||||
id = paramSFO.GetValueString("DISC_ID");
|
||||
id_version = id + "_" + paramSFO.GetValueString("DISC_VERSION");
|
||||
disc_total = paramSFO.GetValueInt("DISC_TOTAL");
|
||||
disc_number = paramSFO.GetValueInt("DISC_NUMBER");
|
||||
// region = paramSFO.GetValueInt("REGION"); // Always seems to be 32768?
|
||||
region = DetectGameRegionFromID(id);
|
||||
} else {
|
||||
id.clear();
|
||||
id_version.clear();
|
||||
region = GameRegion::UNKNOWN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -135,7 +135,7 @@ static const PageDef pageDefs[] = {
|
||||
{ "GameSettingsNetworking", "Networking", "I_WIFI", "network", I18NCat::NETWORKING, &BuildNetworkingSettings },
|
||||
{ "GameSettingsTools", "Tools", "I_TOOLS", "tools", I18NCat::MAINSETTINGS, &BuildToolsSettings },
|
||||
{ "GameSettingsSystem", "System", "I_PSP", "system", I18NCat::SYSTEM, nullptr, &BuildSystemSettings },
|
||||
{ "GameSettingsVR", "VR", nullptr, nullptr, I18NCat::VR, &BuildVRSettings },
|
||||
{ "GameSettingsVR", "VR", "I_VR", nullptr, I18NCat::VR, &BuildVRSettings},
|
||||
};
|
||||
|
||||
void GameSettingsScreen::CreateTabs() {
|
||||
|
||||
@@ -1949,7 +1949,7 @@ static const char *VoiceTypeToString(VoiceType type) {
|
||||
}
|
||||
}
|
||||
|
||||
void DrawSasAudio(ImConfig &cfg) {
|
||||
static void DrawSasAudio(ImConfig &cfg, ImControl &control) {
|
||||
if (!ImGui::Begin("sasAudio", &cfg.sasAudioOpen)) {
|
||||
ImGui::End();
|
||||
return;
|
||||
@@ -2012,8 +2012,8 @@ void DrawSasAudio(ImConfig &cfg) {
|
||||
ImGui::TableNextColumn();
|
||||
switch (voice.type) {
|
||||
case VOICETYPE_OFF: ImGui::TextUnformatted("(off)"); break;
|
||||
case VOICETYPE_VAG: ImGui::Text("%08x", voice.vagAddr); break;
|
||||
case VOICETYPE_PCM: ImGui::Text("%08x", voice.pcmAddr); break;
|
||||
case VOICETYPE_VAG: ImClickableValue("vagaddr", voice.vagAddr, control, ImCmd::SHOW_IN_MEMORY_VIEWER); break;
|
||||
case VOICETYPE_PCM: ImClickableValue("pcmaddr", voice.pcmAddr, control, ImCmd::SHOW_IN_MEMORY_VIEWER); break;
|
||||
case VOICETYPE_ATRAC3: ImGui::Text("atrac: %d", voice.atrac3.AtracID()); break;
|
||||
default:
|
||||
ImGui::TextUnformatted("N/A");
|
||||
@@ -2022,8 +2022,8 @@ void DrawSasAudio(ImConfig &cfg) {
|
||||
ImGui::TableNextColumn();
|
||||
switch (voice.type) {
|
||||
case VOICETYPE_OFF: ImGui::TextUnformatted("(off)"); break;
|
||||
case VOICETYPE_VAG: ImGui::Text("%08x", voice.vagSize); break;
|
||||
case VOICETYPE_PCM: ImGui::Text("%08x", voice.pcmSize); break;
|
||||
case VOICETYPE_VAG: ImGui::Text("%x", voice.vagSize); break;
|
||||
case VOICETYPE_PCM: ImGui::Text("%x", voice.pcmSize); break;
|
||||
case VOICETYPE_ATRAC3: ImGui::Text("atrac: n/a"); break;
|
||||
default:
|
||||
ImGui::TextUnformatted("N/A");
|
||||
@@ -3165,7 +3165,7 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUCommon *gpuDebug, Draw:
|
||||
}
|
||||
|
||||
if (cfg_.sasAudioOpen) {
|
||||
DrawSasAudio(cfg_);
|
||||
DrawSasAudio(cfg_, control);
|
||||
}
|
||||
|
||||
if (cfg_.kernelObjectsOpen) {
|
||||
|
||||
@@ -1434,7 +1434,7 @@ void ImGeDebuggerWindow::Draw(ImConfig &cfg, ImControl &control, GPUCommon *gpuD
|
||||
if (gstate.isModeClear()) {
|
||||
ImGui::Text("(clear mode - texturing not used)");
|
||||
} else if (!gstate.isTextureMapEnabled()) {
|
||||
ImGui::Text("(texturing not enabled");
|
||||
ImGui::Text("(texturing not enabled)");
|
||||
} else if (TextureCacheCommon *texcache = gpuDebug->GetTextureCacheCommon()) { // We don't bother with the texture if previewCmd is BOUNDING_BOX - no texturing happens there.
|
||||
TextureApplyResult result = texcache->ApplyTexture(false);
|
||||
if (TexCacheEntry *tex = result.texCacheEntry) {
|
||||
|
||||
+28
-35
@@ -145,7 +145,7 @@ static void LaunchFile(ScreenManager *screenManager, Screen *currentScreen, cons
|
||||
// Show the savedata popup, why not?
|
||||
waitForParamSFO();
|
||||
std::string title = SanitizeString(info->GetTitle(), StringRestriction::NoLineBreaksOrSpecials, 0, 200);
|
||||
screenManager->push(new SavedataPopupScreen(Path(), path, title));
|
||||
screenManager->push(new SavedataPopupScreen(Path(), path, true, title));
|
||||
return;
|
||||
}
|
||||
case IdentifiedFileType::PSP_PBP:
|
||||
@@ -992,7 +992,9 @@ void UmdReplaceScreen::CreateViews() {
|
||||
|
||||
rightColumnItems->Add(new Choice(di->T("Cancel")))->OnClick.Handle<UIScreen>(this, &UIScreen::OnCancel);
|
||||
rightColumnItems->Add(new Spacer());
|
||||
rightColumnItems->Add(new Choice(mm->T("Game Settings")))->OnClick.Handle(this, &UmdReplaceScreen::OnGameSettings);
|
||||
rightColumnItems->Add(new Choice(mm->T("Game Settings")))->OnClick.Add([this](UI::EventParams &e) {
|
||||
screenManager()->push(new GameSettingsScreen(Path()));
|
||||
});
|
||||
|
||||
if (g_recentFiles.HasAny()) {
|
||||
leftColumn->SetCurrentTab(0, true);
|
||||
@@ -1026,10 +1028,6 @@ void UmdReplaceScreen::UseDisc(const Path &path) {
|
||||
}
|
||||
}
|
||||
|
||||
void UmdReplaceScreen::OnGameSettings(UI::EventParams &e) {
|
||||
screenManager()->push(new GameSettingsScreen(Path()));
|
||||
}
|
||||
|
||||
void GridSettingsPopupScreen::CreatePopupContents(UI::ViewGroup *parent) {
|
||||
using namespace UI;
|
||||
|
||||
@@ -1037,41 +1035,36 @@ void GridSettingsPopupScreen::CreatePopupContents(UI::ViewGroup *parent) {
|
||||
auto sy = GetI18NCategory(I18NCat::SYSTEM);
|
||||
auto mm = GetI18NCategory(I18NCat::MAINMENU);
|
||||
|
||||
ScrollView *scroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT, 1.0f));
|
||||
LinearLayout *items = new LinearLayoutList(ORIENT_VERTICAL);
|
||||
items->SetSpacing(0.0f);
|
||||
ScrollView *scroll = parent->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT, 1.0f)));
|
||||
|
||||
PopupChoiceGroupList *groupList = scroll->Add(new PopupChoiceGroupList());
|
||||
|
||||
ChoiceGroup *group = groupList->Add(new ChoiceGroup());
|
||||
|
||||
// Same order as GameBrowserViewMode.
|
||||
static const char *defaultTabs[] = { "Recent", "Games", "Homebrew & Demos" };
|
||||
items->Add(new PopupMultiChoice(&g_Config.iDefaultTab, sy->T("Default tab"), defaultTabs, 0, ARRAY_SIZE(defaultTabs), I18NCat::MAINMENU, screenManager()));
|
||||
group->Add(new PopupMultiChoice(&g_Config.iDefaultTab, sy->T("Default tab"), defaultTabs, 0, ARRAY_SIZE(defaultTabs), I18NCat::MAINMENU, screenManager()));
|
||||
|
||||
items->Add(new ItemHeader(sy->T("Icon size")));
|
||||
items->Add(new Choice(sy->T("Increase size")))->OnClick.Handle(this, &GridSettingsPopupScreen::GridPlusClick);
|
||||
items->Add(new Choice(sy->T("Decrease size")))->OnClick.Handle(this, &GridSettingsPopupScreen::GridMinusClick);
|
||||
ChoiceGroup *iconSizeGroup = groupList->Add(new ChoiceGroup(sy->T("Icon size")));
|
||||
iconSizeGroup->Add(new Choice(sy->T("Increase size")))->OnClick.Add([this](UI::EventParams &e) {
|
||||
g_Config.fGameGridScale = std::min(g_Config.fGameGridScale * 1.25f, MAX_GAME_GRID_SCALE);
|
||||
screenManager()->RecreateAllViews();
|
||||
});
|
||||
iconSizeGroup->Add(new Choice(sy->T("Decrease size")))->OnClick.Add([this](UI::EventParams &e) {
|
||||
g_Config.fGameGridScale = std::max(g_Config.fGameGridScale / 1.25f, MIN_GAME_GRID_SCALE);
|
||||
screenManager()->RecreateAllViews();
|
||||
});
|
||||
|
||||
items->Add(new ItemHeader(sy->T("Display Extra Info")));
|
||||
items->Add(new CheckBox(&g_Config.bShowIDOnGameIcon, sy->T("Show ID")));
|
||||
items->Add(new CheckBox(&g_Config.bShowRegionOnGameIcon, sy->T("Show region flag")));
|
||||
ChoiceGroup *extraInfoGroup = groupList->Add(new ChoiceGroup(sy->T("Display Extra Info")));
|
||||
extraInfoGroup->Add(new CheckBox(&g_Config.bShowIDOnGameIcon, sy->T("Show ID")));
|
||||
extraInfoGroup->Add(new CheckBox(&g_Config.bShowRegionOnGameIcon, sy->T("Show region flag")));
|
||||
|
||||
if (g_Config.iMaxRecent > 0) {
|
||||
items->Add(new ItemHeader(sy->T("Clear Recent")));
|
||||
items->Add(new Choice(sy->T("Clear Recent Games List")))->OnClick.Handle(this, &GridSettingsPopupScreen::OnRecentClearClick);
|
||||
ChoiceGroup *recentGroup = groupList->Add(new ChoiceGroup(sy->T("Clear Recent")));
|
||||
recentGroup->Add(new Choice(sy->T("Clear Recent Games List")))->OnClick.Add([this](UI::EventParams &e) {
|
||||
g_recentFiles.Clear();
|
||||
OnRecentChanged.Trigger(e);
|
||||
TriggerFinish(DR_OK);
|
||||
});
|
||||
}
|
||||
|
||||
scroll->Add(items);
|
||||
parent->Add(scroll);
|
||||
}
|
||||
|
||||
void GridSettingsPopupScreen::GridPlusClick(UI::EventParams &e) {
|
||||
g_Config.fGameGridScale = std::min(g_Config.fGameGridScale*1.25f, MAX_GAME_GRID_SCALE);
|
||||
}
|
||||
|
||||
void GridSettingsPopupScreen::GridMinusClick(UI::EventParams &e) {
|
||||
g_Config.fGameGridScale = std::max(g_Config.fGameGridScale/1.25f, MIN_GAME_GRID_SCALE);
|
||||
}
|
||||
|
||||
void GridSettingsPopupScreen::OnRecentClearClick(UI::EventParams &e) {
|
||||
g_recentFiles.Clear();
|
||||
OnRecentChanged.Trigger(e);
|
||||
TriggerFinish(DR_OK);
|
||||
}
|
||||
@@ -115,7 +115,6 @@ protected:
|
||||
|
||||
private:
|
||||
void OnGameSelected(UI::EventParams &e);
|
||||
void OnGameSettings(UI::EventParams &e);
|
||||
void UseDisc(const Path &path);
|
||||
|
||||
bool insert_;
|
||||
@@ -130,9 +129,6 @@ public:
|
||||
const char *tag() const override { return "GridSettings"; }
|
||||
|
||||
private:
|
||||
void GridPlusClick(UI::EventParams &e);
|
||||
void GridMinusClick(UI::EventParams &e);
|
||||
void OnRecentClearClick(UI::EventParams &e);
|
||||
const float MAX_GAME_GRID_SCALE = 3.0f;
|
||||
const float MIN_GAME_GRID_SCALE = 0.8f;
|
||||
};
|
||||
|
||||
@@ -192,7 +192,7 @@ void MemStickScreen::CreateViews() {
|
||||
ViewGroup *leftColumn = new LinearLayoutList(ORIENT_VERTICAL, new LinearLayoutParams(1.0));
|
||||
subColumns->Add(leftColumn);
|
||||
|
||||
ViewGroup *rightColumnItems = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(250, FILL_PARENT, actionMenuMargins));
|
||||
LinearLayout *rightColumnItems = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(250, FILL_PARENT, actionMenuMargins));
|
||||
subColumns->Add(rightColumnItems);
|
||||
|
||||
// For legacy Android systems, so you can switch back to the old ways if you move to SD or something.
|
||||
@@ -276,6 +276,8 @@ void MemStickScreen::CreateViews() {
|
||||
rightColumnItems->Add(new UI::Choice(ms->T("WhatsThis", "What's this?"), ImageID("I_LINK_OUT_QUESTION")))->OnClick.Handle<MemStickScreen>(this, &MemStickScreen::OnHelp);
|
||||
}
|
||||
|
||||
rightColumnItems->ApplyRoundCorners();
|
||||
|
||||
INFO_LOG(Log::System, "MemStickScreen: initialSetup=%d", (int)initialSetup_);
|
||||
}
|
||||
|
||||
|
||||
@@ -167,3 +167,15 @@ private:
|
||||
int width_ = 0;
|
||||
int height_ = 0;
|
||||
};
|
||||
|
||||
class HintView : public UI::TextView {
|
||||
public:
|
||||
HintView(std::string_view str, UI::LayoutParams *layoutParams = nullptr) : TextView(str, FLAG_WRAP_TEXT, false, layoutParams) {
|
||||
using namespace UI;
|
||||
layoutParams_->width = FILL_PARENT;
|
||||
layoutParams_->height = WRAP_CONTENT;
|
||||
SetTextSize(TextSize::Small);
|
||||
SetPadding(Margins(12));
|
||||
SetFrame(true);
|
||||
}
|
||||
};
|
||||
+4
-1
@@ -373,7 +373,7 @@ void runImDebugger(Draw::DrawContext *draw) {
|
||||
|
||||
// Read the TTF font
|
||||
size_t propSize = 0;
|
||||
const uint8_t *propFontData = g_VFS.ReadFile("Roboto-Regular.ttf", &propSize);
|
||||
const uint8_t *propFontData = g_VFS.ReadFile("Roboto_Condensed-Regular.ttf", &propSize);
|
||||
size_t fixedSize = 0;
|
||||
const uint8_t *fixedFontData = g_VFS.ReadFile("Inconsolata-Regular.ttf", &fixedSize);
|
||||
// This call works even if fontData is nullptr, in which case the font just won't get loaded.
|
||||
@@ -904,6 +904,9 @@ void NativeInit(int argc, const char *argv[], const CommandLineOptions &cmdLineO
|
||||
} else if (equals(cmdLineOptions.startScreen.value(), "firmware")) {
|
||||
g_screenManager->switchScreen(new MainScreen());
|
||||
g_screenManager->push(new FirmwareScreen(Path()));
|
||||
} else if (equals(cmdLineOptions.startScreen.value(), "memsticksetup")) {
|
||||
g_screenManager->switchScreen(new MainScreen());
|
||||
g_screenManager->push(new MemStickScreen(true));
|
||||
} else {
|
||||
WARN_LOG(Log::System, "Unknown start screen '%s'", cmdLineOptions.startScreen.value().c_str());
|
||||
g_screenManager->switchScreen(new LogoScreen(AfterLogoScreen::DEFAULT));
|
||||
|
||||
+6
-6
@@ -497,14 +497,14 @@ void GamePauseScreen::CreateSavestateControls(UI::LinearLayout *leftColumnItems,
|
||||
|
||||
LinearLayout *buttonRow = new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(Margins(10, 0, 0, 10)));
|
||||
if (g_Config.bEnableStateUndo && !Achievements::HardcoreModeActive() && NetworkAllowSaveState()) {
|
||||
UI::Choice *saveUndoButton = buttonRow->Add(new Choice(pa->T("Undo last save"), ImageID("I_NAVIGATE_BACK"), new LinearLayoutParams(WRAP_CONTENT, WRAP_CONTENT)));
|
||||
UI::Button *saveUndoButton = buttonRow->Add(new Button(pa->T("Undo last save"), ImageID("I_NAVIGATE_BACK"), new LinearLayoutParams(WRAP_CONTENT, ITEM_HEIGHT)));
|
||||
saveUndoButton->SetEnabled(SaveState::HasUndoLastSave(saveStatePrefix_));
|
||||
saveUndoButton->OnClick.Add([this](UI::EventParams &e) {
|
||||
SaveState::UndoLastSave(saveStatePrefix_);
|
||||
RecreateViews();
|
||||
});
|
||||
|
||||
UI::Choice *loadUndoButton = buttonRow->Add(new Choice(pa->T("Undo last load"), ImageID("I_NAVIGATE_BACK"), new LinearLayoutParams(WRAP_CONTENT, WRAP_CONTENT)));
|
||||
UI::Button *loadUndoButton = buttonRow->Add(new Button(pa->T("Undo last load"), ImageID("I_NAVIGATE_BACK"), new LinearLayoutParams(WRAP_CONTENT, ITEM_HEIGHT)));
|
||||
loadUndoButton->SetEnabled(SaveState::HasUndoLoad(saveStatePrefix_));
|
||||
loadUndoButton->OnClick.Add([this](UI::EventParams &e) {
|
||||
CloseAfterStateLoad([this](SaveState::Callback callback) {
|
||||
@@ -514,7 +514,7 @@ void GamePauseScreen::CreateSavestateControls(UI::LinearLayout *leftColumnItems,
|
||||
}
|
||||
|
||||
if (g_Config.iRewindSnapshotInterval > 0 && !Achievements::HardcoreModeActive() && NetworkAllowSaveState()) {
|
||||
UI::Choice *rewindButton = buttonRow->Add(new Choice(pa->T("Rewind"), ImageID("I_REWIND"), new LinearLayoutParams(WRAP_CONTENT, WRAP_CONTENT)));
|
||||
UI::Button *rewindButton = buttonRow->Add(new Button(pa->T("Rewind"), ImageID("I_REWIND"), new LinearLayoutParams(WRAP_CONTENT, ITEM_HEIGHT)));
|
||||
rewindButton->SetEnabled(SaveState::CanRewind());
|
||||
rewindButton->OnClick.Add([this](UI::EventParams &e) {
|
||||
CloseAfterStateLoad([](SaveState::Callback callback) {
|
||||
@@ -661,12 +661,12 @@ void GamePauseScreen::CreateViews() {
|
||||
|
||||
if (showSavestateControls) {
|
||||
if (PSP_CoreParameter().compat.flags().SaveStatesNotRecommended) {
|
||||
LinearLayout *horiz = new LinearLayout(ORIENT_HORIZONTAL);
|
||||
saveDataScrollItems->Add(horiz);
|
||||
LinearLayout *horiz = saveDataScrollItems->Add(new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)));
|
||||
horiz->Add(new NoticeView(NoticeLevel::WARN, pa->T("Using save states is not recommended in this game"), "", new LinearLayoutParams(1.0f)));
|
||||
horiz->Add(new Button(di->T("More info")))->OnClick.Add([](UI::EventParams &e) {
|
||||
horiz->Add(new Choice(di->T("More info"), ImageID("I_LINK_OUT_QUESTION"), new LinearLayoutParams(WRAP_CONTENT, WRAP_CONTENT)))->OnClick.Add([](UI::EventParams &e) {
|
||||
System_LaunchUrl(LaunchUrlType::BROWSER_URL, "https://www.ppsspp.org/docs/troubleshooting/save-state-time-warps");
|
||||
});
|
||||
horiz->ApplyRoundCorners();
|
||||
}
|
||||
LinearLayout *extraRow = nullptr;
|
||||
CreateSavestateControls(saveDataScrollItems, &extraRow);
|
||||
|
||||
+15
-8
@@ -132,7 +132,7 @@ SavedataView::SavedataView(UIContext &dc, GameInfo *ginfo, IdentifiedFileType ty
|
||||
}
|
||||
}
|
||||
|
||||
SavedataPopupScreen::SavedataPopupScreen(Path gamePath, Path savePath, std::string_view title) : PopupScreen(StripSpaces(title)), savePath_(savePath), gamePath_(gamePath) {}
|
||||
SavedataPopupScreen::SavedataPopupScreen(Path gamePath, Path savePath, bool showHint, std::string_view title) : PopupScreen(StripSpaces(title)), savePath_(savePath), gamePath_(gamePath), showHint_(showHint) {}
|
||||
|
||||
void SavedataPopupScreen::update() {
|
||||
PopupScreen::update();
|
||||
@@ -158,17 +158,23 @@ void SavedataPopupScreen::CreatePopupContents(UI::ViewGroup *parent) {
|
||||
ScrollView *contentScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT, 1.0f, UI::Margins(0, 3)));
|
||||
parent->Add(contentScroll);
|
||||
|
||||
LinearLayout *content = contentScroll->Add(new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)));
|
||||
|
||||
if (showHint_) {
|
||||
auto g = GetI18NCategory(I18NCat::GAME);
|
||||
content->Add(new HintView(g->T("SaveData")));
|
||||
}
|
||||
|
||||
// TODO: If the game info wasn't already loaded, we'll get a bogus fileType here.
|
||||
savedataView_ = contentScroll->Add(new SavedataView(dc, ginfo.get(), ginfo->fileType, true));
|
||||
savedataView_ = content->Add(new SavedataView(dc, ginfo.get(), ginfo->fileType, true));
|
||||
|
||||
auto di = GetI18NCategory(I18NCat::DIALOG);
|
||||
|
||||
LinearLayout *buttonRow = new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT));
|
||||
buttonRow->SetSpacing(0);
|
||||
Margins buttonMargins(5, 5, 5, 13); // not sure why we need more at the bottom to make it look right
|
||||
buttonRow->SetSpacing(12);
|
||||
|
||||
buttonRow->Add(new Choice(di->T("Back"), ImageID("I_NAVIGATE_BACK"), new LinearLayoutParams(1.0f, buttonMargins)))->OnClick.Handle<UIScreen>(this, &UIScreen::OnBack);
|
||||
buttonRow->Add(new Choice(di->T("Delete"), ImageID("I_TRASHCAN"), new LinearLayoutParams(1.0f, buttonMargins)))->OnClick.Add([this](UI::EventParams &e) {
|
||||
buttonRow->Add(new Choice(di->T("Back"), ImageID("I_NAVIGATE_BACK"), new LinearLayoutParams(1.0f)))->OnClick.Handle<UIScreen>(this, &UIScreen::OnBack);
|
||||
buttonRow->Add(new Choice(di->T("Delete"), ImageID("I_TRASHCAN"), new LinearLayoutParams(1.0f)))->OnClick.Add([this](UI::EventParams &e) {
|
||||
auto di = GetI18NCategory(I18NCat::DIALOG);
|
||||
std::shared_ptr<GameInfo> ginfo = g_gameInfoCache->GetInfo(nullptr, savePath_, GameInfoFlags::PARAM_SFO);
|
||||
|
||||
@@ -183,10 +189,11 @@ void SavedataPopupScreen::CreatePopupContents(UI::ViewGroup *parent) {
|
||||
}));
|
||||
});
|
||||
if (System_GetPropertyBool(SYSPROP_CAN_SHOW_FILE)) {
|
||||
buttonRow->Add(new Choice(di->T("Show in folder"), ImageID("I_FOLDER"), new LinearLayoutParams(1.0f, buttonMargins)))->OnClick.Add([this](UI::EventParams &e) {
|
||||
buttonRow->Add(new Choice(di->T("Show in folder"), ImageID("I_FOLDER"), new LinearLayoutParams(1.0f)))->OnClick.Add([this](UI::EventParams &e) {
|
||||
System_ShowFileInFolder(savePath_);
|
||||
});
|
||||
}
|
||||
buttonRow->ApplyRoundCorners();
|
||||
parent->Add(buttonRow);
|
||||
}
|
||||
|
||||
@@ -690,7 +697,7 @@ void SavedataScreen::OnSavedataButtonClick(UI::EventParams &e) {
|
||||
|
||||
// Sanitize the title.
|
||||
std::string title = SanitizeString(ginfo->GetTitle(), StringRestriction::NoLineBreaksOrSpecials, 0, 200);
|
||||
SavedataPopupScreen *popupScreen = new SavedataPopupScreen(gamePath_, Path(e.s), title);
|
||||
SavedataPopupScreen *popupScreen = new SavedataPopupScreen(gamePath_, Path(e.s), false, title);
|
||||
if (e.v) {
|
||||
popupScreen->SetPopupOrigin(e.v);
|
||||
}
|
||||
|
||||
+2
-1
@@ -71,7 +71,7 @@ class SavedataView;
|
||||
|
||||
class SavedataPopupScreen : public UI::PopupScreen {
|
||||
public:
|
||||
SavedataPopupScreen(Path gamePath, Path savePath, std::string_view title);
|
||||
SavedataPopupScreen(Path gamePath, Path savePath, bool showHint, std::string_view title);
|
||||
|
||||
const char *tag() const override { return "SavedataPopup"; }
|
||||
void update() override;
|
||||
@@ -84,6 +84,7 @@ private:
|
||||
SavedataView *savedataView_ = nullptr;
|
||||
Path savePath_;
|
||||
Path gamePath_;
|
||||
bool showHint_ = false;
|
||||
};
|
||||
|
||||
class SavedataScreen : public UITabbedBaseDialogScreen {
|
||||
|
||||
@@ -208,6 +208,7 @@ static const ImageMeta g_uiImageIDs[] = {
|
||||
{"I_DOWNLOAD", false},
|
||||
{"I_NETWORK", false},
|
||||
{"I_LANGUAGE", false},
|
||||
{"I_VR", false},
|
||||
};
|
||||
|
||||
static std::string PNGNameFromID(std::string_view id) {
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -23,9 +23,9 @@
|
||||
inkscape:pagecheckerboard="true"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="px"
|
||||
inkscape:zoom="5.6568544"
|
||||
inkscape:cx="181.63805"
|
||||
inkscape:cy="75.041705"
|
||||
inkscape:zoom="4.0000001"
|
||||
inkscape:cx="234.87499"
|
||||
inkscape:cy="537.87499"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2071"
|
||||
inkscape:window-x="-9"
|
||||
@@ -985,7 +985,7 @@
|
||||
style="fill:#ffffff;stroke-width:4.93273"
|
||||
d="m 94.191649,3.89538 a 2.5724686,2.5724686 0 0 1 2.57247,-2.57246 2.5724686,2.5724686 0 0 1 2.57247,2.57246 2.5724686,2.5724686 0 0 1 -2.57247,2.57247 2.5724686,2.5724686 0 0 1 -2.57247,-2.57247 z" /><g
|
||||
id="I_DISPLAY"
|
||||
transform="matrix(1.7225478,0,0,1.7225478,-109.02695,4.9970217)">
|
||||
transform="matrix(1.8233708,0,0,1.8233708,-118.84776,-1.0582382)">
|
||||
|
||||
<path
|
||||
d="m 94.898083,57.771045 h 5.016673 0.116084 v 0.116081 3.861938 0.116081 h -0.116084 -1.630619 v 0.193005 h 0.406285 v 0.287413 H 96.069104 V 62.05815 h 0.406285 v -0.193005 h -1.577306 -0.116082 v -0.116081 -3.861938 -0.116081 z m 4.694422,0.330476 H 95.2473 v 3.44158 h 4.344643 z"
|
||||
@@ -1613,7 +1613,10 @@
|
||||
sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccc" /><path
|
||||
id="I_CHEVRON_LEFT"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none"
|
||||
d="m 49.998024,36.583735 -3.7171,3.7172 3.7171,3.7172 -0.5656,0.5656 -4.2829,-4.2828 4.2829,-4.2828 z" /></g><style
|
||||
d="m 49.998024,36.583735 -3.7171,3.7172 3.7171,3.7172 -0.5656,0.5656 -4.2829,-4.2828 4.2829,-4.2828 z" /><path
|
||||
id="I_VR"
|
||||
style="baseline-shift:baseline;display:inline;overflow:visible;vector-effect:none;fill:#ffffff;fill-opacity:1;stroke-width:0.622078;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;enable-background:accumulate;stop-color:#000000"
|
||||
d="M 19.158394 183.69988 C 18.364409 183.69988 17.622057 184.09765 17.181632 184.75829 L 16.76199 185.38724 A 0.31107067 0.31107067 0 0 0 16.710309 185.53504 C 16.396114 185.78176 16.193509 186.16449 16.193509 186.5919 L 16.193509 190.20537 C 16.193509 190.94364 16.798938 191.54905 17.53719 191.54905 L 19.533591 191.54905 C 20.005017 191.54905 20.442989 191.30109 20.68554 190.89685 L 21.491232 189.5542 C 21.578042 189.40951 21.755333 189.40951 21.84214 189.5542 L 22.647832 190.89685 C 22.89037 191.30113 23.328361 191.54905 23.79978 191.54905 L 25.796181 191.54905 C 26.534444 191.54905 27.139863 190.94363 27.139863 190.20537 L 27.139863 186.5919 C 27.139863 186.16449 26.937259 185.78176 26.623062 185.53504 A 0.31107067 0.31107067 0 0 0 26.571382 185.38724 L 26.152257 184.75829 C 25.711819 184.09766 24.968954 183.69988 24.174978 183.69988 L 19.158394 183.69988 z M 19.158394 184.32263 L 24.174978 184.32263 C 24.761687 184.32263 25.308432 184.61481 25.633906 185.103 L 25.730548 185.24822 L 17.602824 185.24822 L 17.699466 185.103 C 18.024922 184.61482 18.571672 184.32263 19.158394 184.32263 z M 17.53719 185.87148 L 25.796181 185.87148 C 26.198263 185.87148 26.517118 186.18983 26.517118 186.5919 L 26.517118 190.20537 C 26.517118 190.60745 26.198269 190.9263 25.796181 190.9263 L 23.79978 190.9263 C 23.545964 190.9263 23.311729 190.79406 23.18117 190.57643 L 22.376511 189.2343 C 22.062347 188.71064 21.271024 188.71064 20.95686 189.2343 L 20.152202 190.57643 C 20.021604 190.79409 19.787421 190.9263 19.533591 190.9263 L 17.53719 190.9263 C 17.135122 190.9263 16.816254 190.60745 16.816254 190.20537 L 16.816254 186.5919 C 16.816254 186.18984 17.135128 185.87148 17.53719 185.87148 z " /></g><style
|
||||
type="text/css"
|
||||
id="style1">
|
||||
.st0{fill:#000000;}
|
||||
|
||||
|
Before Width: | Height: | Size: 173 KiB After Width: | Height: | Size: 175 KiB |
Reference in new issue
Block a user