Change the Settings toggle to a specially styled checkbox

This commit is contained in:
Henrik Rydgård 2022-12-07 11:12:10 +01:00
parent 59c4ff6af4
commit 241dd4093b
5 changed files with 79 additions and 20 deletions

View File

@ -16,3 +16,9 @@ typedef unsigned int Color;
inline Color darkenColor(Color color) {
return (color & 0xFF000000) | ((color >> 1) & 0x7F7F7F);
}
inline Color lightenColor(Color color) {
color = ~color;
color = (color & 0xFF000000) | ((color >> 1) & 0x7F7F7F);
return ~color;
}

View File

@ -700,28 +700,55 @@ void CheckBox::Draw(UIContext &dc) {
if (!IsEnabled()) {
style = dc.theme->itemDisabledStyle;
}
if (HasFocus()) {
style = dc.theme->itemFocusedStyle;
}
if (down_) {
style = dc.theme->itemDownStyle;
ImageID image = Toggled() ? dc.theme->checkOn : dc.theme->checkOff;
// In image mode, light up instead of showing a checkbox.
if (imageID_.isValid()) {
image = imageID_;
if (Toggled()) {
if (HasFocus()) {
style = dc.theme->itemDownStyle;
} else {
style = dc.theme->itemFocusedStyle;
}
} else {
if (HasFocus()) {
style = dc.theme->itemDownStyle;
} else {
style = dc.theme->itemStyle;
}
}
if (down_) {
style.background.color = lightenColor(style.background.color);
}
} else {
if (HasFocus()) {
style = dc.theme->itemFocusedStyle;
}
if (down_) {
style = dc.theme->itemDownStyle;
}
}
dc.SetFontStyle(dc.theme->uiFont);
ClickableItem::Draw(dc);
DrawBG(dc, style);
ImageID image = Toggled() ? dc.theme->checkOn : dc.theme->checkOff;
float imageW, imageH;
dc.Draw()->MeasureImage(image, &imageW, &imageH);
const int paddingX = 12;
// Padding right of the checkbox image too.
const float availWidth = bounds_.w - paddingX * 2 - imageW - paddingX;
float scale = CalculateTextScale(dc, availWidth);
dc.SetFontScale(scale, scale);
Bounds textBounds(bounds_.x + paddingX, bounds_.y, availWidth, bounds_.h);
dc.DrawTextRect(text_.c_str(), textBounds, style.fgColor, ALIGN_VCENTER | FLAG_WRAP_TEXT);
if (!text_.empty()) {
float scale = CalculateTextScale(dc, availWidth);
dc.SetFontScale(scale, scale);
Bounds textBounds(bounds_.x + paddingX, bounds_.y, availWidth, bounds_.h);
dc.DrawTextRect(text_.c_str(), textBounds, style.fgColor, ALIGN_VCENTER | FLAG_WRAP_TEXT);
}
dc.Draw()->DrawImage(image, bounds_.x2() - paddingX, bounds_.centerY(), 1.0f, style.fgColor, ALIGN_RIGHT | ALIGN_VCENTER);
dc.SetFontScale(1.0f, 1.0f);
}
@ -747,24 +774,41 @@ float CheckBox::CalculateTextScale(const UIContext &dc, float availWidth) const
void CheckBox::GetContentDimensions(const UIContext &dc, float &w, float &h) const {
ImageID image = Toggled() ? dc.theme->checkOn : dc.theme->checkOff;
if (imageID_.isValid()) {
image = imageID_;
}
float imageW, imageH;
dc.Draw()->MeasureImage(image, &imageW, &imageH);
const int paddingX = 12;
if (imageID_.isValid()) {
w = imageW + paddingX * 2;
h = std::max(imageH, ITEM_HEIGHT);
return;
}
// The below code is kinda wacky, we shouldn't involve bounds_ here.
// Padding right of the checkbox image too.
float availWidth = bounds_.w - paddingX * 2 - imageW - paddingX;
if (availWidth < 0.0f) {
// Let it have as much space as it needs.
availWidth = MAX_ITEM_SIZE;
}
float scale = CalculateTextScale(dc, availWidth);
float actualWidth, actualHeight;
Bounds availBounds(0, 0, availWidth, bounds_.h);
dc.MeasureTextRect(dc.theme->uiFont, scale, scale, text_.c_str(), (int)text_.size(), availBounds, &actualWidth, &actualHeight, ALIGN_VCENTER | FLAG_WRAP_TEXT);
if (!text_.empty()) {
float scale = CalculateTextScale(dc, availWidth);
float actualWidth, actualHeight;
Bounds availBounds(0, 0, availWidth, bounds_.h);
dc.MeasureTextRect(dc.theme->uiFont, scale, scale, text_.c_str(), (int)text_.size(), availBounds, &actualWidth, &actualHeight, ALIGN_VCENTER | FLAG_WRAP_TEXT);
h = std::max(actualHeight, ITEM_HEIGHT);
} else {
h = std::max(imageH, ITEM_HEIGHT);
}
w = bounds_.w;
h = std::max(actualHeight, ITEM_HEIGHT);
}
void BitCheckBox::Toggle() {

View File

@ -827,11 +827,17 @@ private:
class CheckBox : public ClickableItem {
public:
CheckBox(bool *toggle, const std::string &text, const std::string &smallText = "", LayoutParams *layoutParams = 0)
CheckBox(bool *toggle, const std::string &text, const std::string &smallText = "", LayoutParams *layoutParams = nullptr)
: ClickableItem(layoutParams), toggle_(toggle), text_(text), smallText_(smallText) {
OnClick.Handle(this, &CheckBox::OnClicked);
}
// Image-only "checkbox", lights up instead of showing a checkmark.
CheckBox(bool *toggle, ImageID imageID, LayoutParams *layoutParams = nullptr)
: ClickableItem(layoutParams), toggle_(toggle), imageID_(imageID) {
OnClick.Handle(this, &CheckBox::OnClicked);
}
void Draw(UIContext &dc) override;
std::string DescribeText() const override;
void GetContentDimensions(const UIContext &dc, float &w, float &h) const override;
@ -846,6 +852,7 @@ private:
bool *toggle_;
std::string text_;
std::string smallText_;
ImageID imageID_;
};
class BitCheckBox : public CheckBox {

View File

@ -310,9 +310,9 @@ void DisplayLayoutScreen::CreateViews() {
}
}
if (hasSettings) {
auto settingsButton = shaderRow->Add(new Choice(ImageID("I_SLIDERS"), new LinearLayoutParams(0.0f)));
CheckBox *checkBox = new CheckBox(&settingsVisible_[i], ImageID("I_SLIDERS"), new LinearLayoutParams(0.0f));
auto settingsButton = shaderRow->Add(checkBox);
settingsButton->OnClick.Add([=](EventParams &e) {
settingsVisible_[i] = !settingsVisible_[i];
RecreateViews();
return UI::EVENT_DONE;
});

View File

@ -17,6 +17,8 @@
#pragma once
#include <deque>
#include "Common/UI/View.h"
#include "Common/UI/ViewGroup.h"
#include "GPU/Common/PostShader.h"
@ -47,7 +49,7 @@ private:
UI::ChoiceStrip *mode_ = nullptr;
UI::Choice *postProcChoice_ = nullptr;
std::string shaderNames_[256];
std::vector<bool> settingsVisible_;
std::deque<bool> settingsVisible_; // vector<bool> is an insane bitpacked specialization!
};
class PostProcScreen : public ListPopupScreen {