mirror of
https://github.com/The-Powder-Toy/The-Powder-Toy.git
synced 2025-01-16 13:58:43 +01:00
Add credits UI
Lists all GitHub contributors and moderators, alongside the original credits (which were moved from the intro text to here) The UI itself is controlled with credits.json. This can be regenerated with resources/gencredits.py.
This commit is contained in:
parent
9fa0fc45bc
commit
57593fb212
1
.gitignore
vendored
1
.gitignore
vendored
@ -74,6 +74,7 @@ screenshot_*
|
||||
/.kdev4
|
||||
|
||||
# Other IDEs / misc
|
||||
/.idea
|
||||
.vscode/
|
||||
.vs/
|
||||
*.sublime-*
|
||||
|
1
resources/credits.json
Normal file
1
resources/credits.json
Normal file
@ -0,0 +1 @@
|
||||
{"GitHub": ["simtr", "jacob1", "LBPHacker", "jacksonmj", "Pilihp64", "mniip", "savask", "NoH", "triclops200", "SuperDoxin", "zc00gii", "krawthekrow", "wolfy1339", "QuanTech0", "catsoften", "Catelite", "antb", "moonheart08", "cracker1000", "Huulivoide", "ntoskrnl11", "me4502", "suve", "mmbob", "C7C8", "boxmein", "ief015", "jbot-42", "tridiaq", "perssphere07", "iczero", "SebastianMestre", "nixls", "yareky", "CapacitorSet", "ssccsscc", "JustinShurie", "BlueSyncLine", "Mailaender", "kroq-gar78", "nunom27", "amaank404", "nucular", "jombo23", "gamax92", "Ristovski", "Novocain1", "VelocityRa", "orbitcowboy", "TropicalBastos", "Bowserinator", "n1kolasM", "NoComplaintsEver", "Not-Super-Nova", "Onestay42", "RCAProduction", "SilentSpud", "Rebmiami", "RobertBScott", "ageofadz", "Vgr255", "jebbyk", "avevad", "cppxor2arr", "dxgldotorg", "grufkork", "rfht", "china-richway2", "yangbowen", "dreness", "andrewrk", "super7ramp", "Caeleron", "CanGonenc", "ChromicQuanta", "connor-create", "Departing", "AMDmi3", "EchoHowardLam", "BigWolfy1339", "Jakav-N", "JasonS05", "meyer9", "um3k", "Ksawi999", "Maticzpl", "Mrprocom", "handicraftsman"], "OrigCredits": [{"realname": "Stanislaw K Skowronek", "message": "Designed the original Powder Toy"}, {"realname": "Simon Robertshaw", "message": "Wrote the website, current server owner"}, {"realname": "Skresanov Savely", "message": ""}, {"realname": "Pilihp64", "message": ""}, {"realname": "Catelite", "message": ""}, {"realname": "Victoria Hoyle", "message": ""}, {"realname": "Nathan Cousins", "message": ""}, {"realname": "jacksonmj", "message": ""}, {"realname": "Felix Wallin", "message": ""}, {"realname": "Lieuwe Mosch", "message": ""}, {"realname": "Anthony Boot", "message": ""}, {"realname": "Me4502", "message": ""}, {"realname": "MaksProg", "message": ""}, {"realname": "jacob1", "message": ""}, {"realname": "mniip", "message": ""}, {"realname": "LBPHacker", "message": ""}], "Moderators": [{"username": "jacob1", "role": "Moderator"}, {"username": "LBPHacker", "role": "Moderator"}, {"username": "Sylvi", "role": "Moderator"}, {"username": "CCl2F2", "role": "Moderator"}, {"username": "catsoften", "role": "Moderator"}, {"username": "Denderth", "role": "Moderator"}, {"username": "Simon", "role": "Moderator"}, {"username": "Mrprocom", "role": "Moderator"}, {"username": "jacksonmj", "role": "Former Staff"}, {"username": "Pilihp64", "role": "Former Staff"}, {"username": "Catelite", "role": "Former Staff"}, {"username": "boxmein", "role": "Former Staff"}, {"username": "lolzy", "role": "Former Staff"}, {"username": "Xenocide", "role": "Former Staff"}, {"username": "triclops200", "role": "Former Staff"}, {"username": "devast8a", "role": "Former Staff"}, {"username": "HK6", "role": "Former Staff"}, {"username": "FrankBro", "role": "Former Staff"}, {"username": "doxin", "role": "Former Staff"}, {"username": "ief015", "role": "Former Staff"}, {"username": "ad", "role": "Former Staff"}]}
|
101
resources/gencredits.py
Normal file
101
resources/gencredits.py
Normal file
@ -0,0 +1,101 @@
|
||||
import urllib.error
|
||||
import urllib.request
|
||||
import json
|
||||
|
||||
def get_url(url : str) -> bytes | None:
|
||||
try:
|
||||
req = urllib.request.Request(url)
|
||||
data = urllib.request.urlopen(req, timeout=10)
|
||||
page = data.read()
|
||||
|
||||
return page
|
||||
except urllib.error.URLError as e:
|
||||
print(f"{url} - {e}")
|
||||
return None
|
||||
|
||||
def fetch_gh_contributors() -> list[any]:
|
||||
page = 1
|
||||
ret = []
|
||||
while True:
|
||||
data = get_url(f"https://api.github.com/repos/The-Powder-Toy/The-Powder-Toy/contributors?page={page}")
|
||||
contributors = json.loads(data)
|
||||
if not len(contributors):
|
||||
break
|
||||
ret.extend(contributors)
|
||||
page = page + 1
|
||||
|
||||
return ret
|
||||
|
||||
def get_github_json(github_contributors : list[any]) -> list[str]:
|
||||
ret = []
|
||||
for contributor in github_contributors:
|
||||
ret.append(contributor["login"])
|
||||
|
||||
return ret
|
||||
|
||||
def get_orig_json() -> list[dict[str, str | int]]:
|
||||
"""Credits that appeared in intro text in older versions"""
|
||||
|
||||
return [
|
||||
{ "realname" : "Stanislaw K Skowronek", "message" : "Designed the original Powder Toy"},
|
||||
{ "realname" : "Simon Robertshaw", "message" : "Wrote the website, current server owner"},
|
||||
{ "realname" : "Skresanov Savely", "message" : ""},
|
||||
{ "realname" : "Pilihp64", "message" : ""},
|
||||
{ "realname" : "Catelite", "message" : ""},
|
||||
{ "realname" : "Victoria Hoyle", "message" : ""},
|
||||
{ "realname" : "Nathan Cousins", "message" : ""},
|
||||
{ "realname" : "jacksonmj", "message" : ""},
|
||||
{ "realname" : "Felix Wallin", "message" : ""},
|
||||
{ "realname" : "Lieuwe Mosch", "message" : ""},
|
||||
{ "realname" : "Anthony Boot", "message" : ""},
|
||||
{ "realname" : "Me4502", "message" : ""},
|
||||
{ "realname" : "MaksProg", "message" : ""},
|
||||
{ "realname" : "jacob1", "message" : ""},
|
||||
{ "realname" : "mniip", "message" : ""},
|
||||
{ "realname" : "LBPHacker", "message" : ""},
|
||||
]
|
||||
|
||||
def get_moderator_json() -> list[dict[str, str | int]]:
|
||||
"""Current and former moderators"""
|
||||
|
||||
return [
|
||||
{ "username" : "jacob1", "role" : "Moderator" },
|
||||
{ "username" : "LBPHacker", "role" : "Moderator" },
|
||||
{ "username" : "Sylvi", "role" : "Moderator" },
|
||||
{ "username" : "CCl2F2", "role" : "Moderator" },
|
||||
{ "username" : "catsoften", "role" : "Moderator" },
|
||||
{ "username" : "Denderth", "role" : "Moderator" },
|
||||
{ "username" : "Simon", "role" : "Moderator" },
|
||||
{ "username" : "Mrprocom", "role" : "Moderator" },
|
||||
{ "username" : "jacksonmj", "role" : "Former Staff" },
|
||||
{ "username" : "Pilihp64", "role" : "Former Staff" },
|
||||
{ "username" : "Catelite", "role" : "Former Staff" },
|
||||
{ "username" : "boxmein", "role" : "Former Staff" },
|
||||
{ "username" : "lolzy", "role" : "Former Staff" },
|
||||
{ "username" : "Xenocide", "role" : "Former Staff" },
|
||||
{ "username" : "triclops200", "role" : "Former Staff" },
|
||||
{ "username" : "devast8a", "role" : "Former Staff" },
|
||||
{ "username" : "HK6", "role" : "Former Staff" },
|
||||
{ "username" : "FrankBro", "role" : "Former Staff" },
|
||||
{ "username" : "doxin", "role" : "Former Staff" },
|
||||
{ "username" : "ief015", "role" : "Former Staff" },
|
||||
{ "username" : "ad", "role" : "Former Staff" },
|
||||
]
|
||||
|
||||
def process() -> any:
|
||||
github_contributors = fetch_gh_contributors()
|
||||
github = get_github_json(github_contributors)
|
||||
|
||||
orig = get_orig_json()
|
||||
mods = get_moderator_json()
|
||||
|
||||
data = {
|
||||
"GitHub" : github,
|
||||
"OrigCredits" : orig,
|
||||
"Moderators" : mods,
|
||||
}
|
||||
|
||||
with open("credits.json", "w") as f:
|
||||
json.dump(data, f)
|
||||
|
||||
process()
|
@ -118,3 +118,4 @@ endif
|
||||
data_files += to_array.process('save_local.png', extra_args: 'save_local_png')
|
||||
data_files += to_array.process('save_online.png', extra_args: 'save_online_png')
|
||||
data_files += to_array.process('font.bz2', extra_args: 'compressed_font_data')
|
||||
data_files += to_array.process('credits.json', extra_args: 'credits_json')
|
||||
|
217
src/gui/credits/Credits.cpp
Normal file
217
src/gui/credits/Credits.cpp
Normal file
@ -0,0 +1,217 @@
|
||||
#include "Credits.h"
|
||||
|
||||
#include <json/json.h>
|
||||
|
||||
#include "credits.json.h"
|
||||
#include "gui/Style.h"
|
||||
|
||||
#include "common/platform/Platform.h"
|
||||
#include "gui/interface/AvatarButton.h"
|
||||
#include "gui/interface/Button.h"
|
||||
#include "gui/interface/Engine.h"
|
||||
#include "gui/interface/Label.h"
|
||||
#include "gui/interface/RichLabel.h"
|
||||
#include "gui/interface/ScrollPanel.h"
|
||||
#include "gui/interface/Separator.h"
|
||||
|
||||
Credits::Credits():
|
||||
ui::Window(ui::Point(-1, -1), ui::Point(WINDOWW, WINDOWH))
|
||||
{
|
||||
Json::Value root;
|
||||
Json::Reader reader;
|
||||
auto credits = credits_json.AsCharSpan();
|
||||
if (bool parsed = reader.parse(credits.data(), credits.data() + credits.size(), root, false); !parsed) {
|
||||
// Failure. Shouldn't ever happen.
|
||||
return;
|
||||
}
|
||||
|
||||
auto *scrollPanel = new ui::ScrollPanel(ui::Point(0, 0), ui::Point(Size.X, Size.Y - 12));
|
||||
AddComponent(scrollPanel);
|
||||
|
||||
int xPos = 0, yPos = 0, row = 0;
|
||||
int nextY = 0;
|
||||
|
||||
// Organize blocks of components of equal width into rows, and add them to the scroll panel
|
||||
auto organizeComponents = [&xPos, &yPos, &nextY, &row, &scrollPanel](const auto& components, const int panelWidth) {
|
||||
ui::Point blockSize = { 0, 0 };
|
||||
for (const auto &component : components)
|
||||
{
|
||||
blockSize.X = std::max(blockSize.X, component->Position.X + component->Size.X);
|
||||
blockSize.Y = std::max(blockSize.Y, component->Position.Y + component->Size.Y);
|
||||
}
|
||||
|
||||
// New row, offset x position to ensure entire row is centered
|
||||
if (xPos == 0)
|
||||
xPos = (panelWidth % blockSize.X) / 2;
|
||||
for (const auto &component : components)
|
||||
component->Position += ui::Point({ xPos, yPos });
|
||||
|
||||
xPos += blockSize.X;
|
||||
nextY = std::max(nextY, yPos + blockSize.Y);
|
||||
if (xPos + blockSize.X > panelWidth)
|
||||
{
|
||||
xPos = 0;
|
||||
yPos = nextY + 8;
|
||||
row++;
|
||||
}
|
||||
|
||||
for (const auto &component : components)
|
||||
scrollPanel->AddChild(component);
|
||||
};
|
||||
|
||||
// Add header and separator for each section of credits
|
||||
auto addHeader = [&xPos, &yPos, &nextY, &row, &scrollPanel](const String &text, const bool addSeparator = true) {
|
||||
xPos = 0;
|
||||
yPos = nextY + 10;
|
||||
row = 0;
|
||||
|
||||
if (addSeparator)
|
||||
{
|
||||
auto *separator = new ui::Separator(ui::Point(0, yPos), ui::Point(scrollPanel->Size.X, 1));
|
||||
scrollPanel->AddChild(separator);
|
||||
yPos += 6;
|
||||
}
|
||||
|
||||
auto *label = new ui::RichLabel(ui::Point(4, yPos), ui::Point(scrollPanel->Size.X, 24), text);
|
||||
label->SetTextColour(style::Colour::InformationTitle);
|
||||
label->Appearance.HorizontalAlign = ui::Appearance::AlignCentre;
|
||||
label->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
|
||||
scrollPanel->AddChild(label);
|
||||
yPos += label->Size.Y + 8;
|
||||
};
|
||||
|
||||
|
||||
addHeader("TPT is an open source project, developed by members of the community.\n"
|
||||
"We'd like to thank everyone who contributed to our \bt{a:https://github.com/The-Powder-Toy/The-Powder-Toy|GitHub repo}\x0E:", false);
|
||||
|
||||
auto GitHub = root["GitHub"];
|
||||
int grayscale = 255;
|
||||
for (auto &item : GitHub)
|
||||
{
|
||||
ByteString username = item.asString();
|
||||
auto components = AddCredit(username.FromUtf8(), "", Small, "", false, grayscale);
|
||||
organizeComponents(components, scrollPanel->Size.X);
|
||||
if (grayscale > 180)
|
||||
grayscale--;
|
||||
}
|
||||
|
||||
|
||||
addHeader("Staff - volunteers that run the community and keep the site running");
|
||||
|
||||
auto Moderators = root["Moderators"];
|
||||
for (auto &item : Moderators)
|
||||
{
|
||||
ByteString username = item["username"].asString();
|
||||
ByteString role = item["role"].asString();
|
||||
|
||||
if (role == "Moderator" || role == "HalfMod")
|
||||
{
|
||||
auto components = AddCredit(username.FromUtf8(), "", Large, GetProfileUri(username), true);
|
||||
organizeComponents(components, scrollPanel->Size.X);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
addHeader("Former Staff", false);
|
||||
|
||||
for (auto &item : Moderators)
|
||||
{
|
||||
ByteString username = item["username"].asString();
|
||||
ByteString role = item["role"].asString();
|
||||
|
||||
if (role == "Former Staff")
|
||||
{
|
||||
auto components = AddCredit(username.FromUtf8(), "", Small, "", true);
|
||||
organizeComponents(components, scrollPanel->Size.X);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
addHeader("The following users have been credited in the intro text from the start.\n"
|
||||
"Their contributions to the early beginnings of TPT were invaluable in shaping TPT into what it is today.");
|
||||
|
||||
auto OrigCredits = root["OrigCredits"];
|
||||
for (auto &item : OrigCredits)
|
||||
{
|
||||
ByteString realname = item["realname"].asString();
|
||||
ByteString message = item["message"].asString();
|
||||
|
||||
auto components = AddCredit(realname.FromUtf8(), message.FromUtf8(), row == 0 ? Half : Small, "");
|
||||
organizeComponents(components, scrollPanel->Size.X);
|
||||
}
|
||||
|
||||
|
||||
scrollPanel->InnerSize = ui::Point(scrollPanel->Size.X, nextY);
|
||||
|
||||
auto *closeButton = new ui::Button({ 0, Size.Y - 12 }, { Size.X, 12 }, "Close");
|
||||
closeButton->SetActionCallback({
|
||||
[this] {
|
||||
CloseActiveWindow();
|
||||
} });
|
||||
AddComponent(closeButton);
|
||||
}
|
||||
|
||||
std::vector<ui::Component *> Credits::AddCredit(const String &name, const String &subheader, const CreditSize size,
|
||||
const ByteString &uri, const bool includeAvatar, const int grayscale)
|
||||
{
|
||||
std::vector<ui::Component *> components;
|
||||
int creditBlockWidth = size == Small ? 100 : (size == Large ? 155 : 310);
|
||||
int y = 0;
|
||||
|
||||
if (includeAvatar)
|
||||
{
|
||||
int avatarWidth = size == Small ? 40 : 64;
|
||||
int avatarSize = size == Small ? 40 : 256;
|
||||
auto *avatarButton = new ui::AvatarButton(ui::Point((creditBlockWidth - avatarWidth) / 2, 0), ui::Point(avatarWidth, avatarWidth), name.ToUtf8(), avatarSize);
|
||||
if (!uri.empty())
|
||||
{
|
||||
avatarButton->SetActionCallback({[uri] {
|
||||
Platform::OpenURI(uri);
|
||||
} });
|
||||
}
|
||||
components.push_back(avatarButton);
|
||||
|
||||
y += avatarButton->Size.Y + 2;
|
||||
}
|
||||
|
||||
if (!name.empty())
|
||||
{
|
||||
auto labelText = !uri.empty() ? GetRichLabelText(uri, name) : name;
|
||||
auto *nameLabel = new ui::RichLabel(ui::Point(0, y), ui::Point(creditBlockWidth, 14), labelText);
|
||||
nameLabel->Appearance.HorizontalAlign = ui::Appearance::AlignCentre;
|
||||
nameLabel->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
|
||||
nameLabel->SetTextColour(ui::Colour(grayscale, grayscale, grayscale));
|
||||
components.push_back(nameLabel);
|
||||
|
||||
y += nameLabel->Size.Y + 2;
|
||||
}
|
||||
|
||||
if (!subheader.empty())
|
||||
{
|
||||
auto *subheaderLabel = new ui::Label(ui::Point(0, y), ui::Point(creditBlockWidth, 14), subheader);
|
||||
subheaderLabel->Appearance.HorizontalAlign = ui::Appearance::AlignCentre;
|
||||
subheaderLabel->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
|
||||
int col = (int)((float)grayscale * .67f);
|
||||
subheaderLabel->SetTextColour(ui::Colour(col, col, col));
|
||||
components.push_back(subheaderLabel);
|
||||
}
|
||||
|
||||
return components;
|
||||
}
|
||||
|
||||
ByteString Credits::GetProfileUri(const ByteString &username)
|
||||
{
|
||||
return "https://powdertoy.co.uk/User.html?Name=" + username;
|
||||
}
|
||||
|
||||
String Credits::GetRichLabelText(const ByteString &uri, const String &message)
|
||||
{
|
||||
StringBuilder builder;
|
||||
builder << "{a:" << uri.FromUtf8() << "|" << message << "}";
|
||||
return builder.Build();
|
||||
}
|
||||
|
||||
void Credits::OnTryExit(ExitMethod method)
|
||||
{
|
||||
ui::Engine::Ref().CloseWindow();
|
||||
}
|
23
src/gui/credits/Credits.h
Normal file
23
src/gui/credits/Credits.h
Normal file
@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include "gui/interface/Window.h"
|
||||
|
||||
class Credits : public ui::Window
|
||||
{
|
||||
enum CreditSize
|
||||
{
|
||||
Small,
|
||||
Large,
|
||||
Half,
|
||||
};
|
||||
|
||||
static std::vector<ui::Component *> AddCredit(const String &name, const String &subheader, CreditSize size,
|
||||
const ByteString &uri, bool includeAvatar = false, int grayscale = 255);
|
||||
static ByteString GetProfileUri(const ByteString &username);
|
||||
static ByteString GetTptLabelText(const ByteString &tpt, const ByteString &github);
|
||||
static String GetRichLabelText(const ByteString &uri, const String &message);
|
||||
public:
|
||||
Credits();
|
||||
|
||||
void OnTryExit(ExitMethod method) override;
|
||||
};
|
3
src/gui/credits/meson.build
Normal file
3
src/gui/credits/meson.build
Normal file
@ -0,0 +1,3 @@
|
||||
powder_files += files(
|
||||
'Credits.cpp',
|
||||
)
|
@ -64,10 +64,6 @@ inline ByteString IntroText()
|
||||
"Use 'S' to save parts of the window as 'stamps'. 'L' loads the most recent stamp, 'K' shows a library of stamps you saved.\n"
|
||||
"Use 'P' to take a screenshot and save it into the current directory.\n"
|
||||
"Use 'H' to toggle the HUD. Use 'D' to toggle debug mode in the HUD.\n"
|
||||
"\n"
|
||||
"Contributors: \bgStanislaw K Skowronek (Designed the original Powder Toy),\n"
|
||||
"\bgSimon Robertshaw, Skresanov Savely, Pilihp64, Catelite, Victoria Hoyle, Nathan Cousins, jacksonmj,\n"
|
||||
"\bgFelix Wallin, Lieuwe Mosch, Anthony Boot, Me4502, MaksProg, jacob1, mniip, LBPHacker\n"
|
||||
"\n";
|
||||
if constexpr (BETA)
|
||||
{
|
||||
|
@ -10,9 +10,10 @@
|
||||
|
||||
namespace ui {
|
||||
|
||||
AvatarButton::AvatarButton(Point position, Point size, ByteString username):
|
||||
AvatarButton::AvatarButton(Point position, Point size, ByteString username, int avatarSize):
|
||||
Component(position, size),
|
||||
name(username),
|
||||
avatarSize(avatarSize),
|
||||
tried(false)
|
||||
{
|
||||
|
||||
@ -23,7 +24,14 @@ void AvatarButton::Tick(float dt)
|
||||
if (!avatar && !tried && name.size() > 0)
|
||||
{
|
||||
tried = true;
|
||||
imageRequest = std::make_unique<http::ImageRequest>(ByteString::Build(STATICSERVER, "/avatars/", name, ".png"), Size);
|
||||
ByteStringBuilder urlBuilder;
|
||||
urlBuilder << STATICSERVER << "/avatars/" << name;
|
||||
if (avatarSize)
|
||||
{
|
||||
urlBuilder << "." << avatarSize;
|
||||
}
|
||||
urlBuilder << ".png";
|
||||
imageRequest = std::make_unique<http::ImageRequest>(urlBuilder.Build(), Size);
|
||||
imageRequest->Start();
|
||||
}
|
||||
|
||||
@ -45,7 +53,7 @@ void AvatarButton::Draw(const Point& screenPos)
|
||||
{
|
||||
Graphics * g = GetGraphics();
|
||||
|
||||
if(avatar)
|
||||
if (avatar)
|
||||
{
|
||||
auto *tex = avatar.get();
|
||||
g->BlendImage(tex->Data(), 255, RectSized(screenPos, tex->Size()));
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
#include "Component.h"
|
||||
#include "graphics/Graphics.h"
|
||||
#include "gui/interface/Colour.h"
|
||||
#include "client/http/ImageRequest.h"
|
||||
|
||||
#include <memory>
|
||||
@ -15,6 +14,7 @@ class AvatarButton : public Component
|
||||
{
|
||||
std::unique_ptr<VideoBuffer> avatar;
|
||||
ByteString name;
|
||||
int avatarSize;
|
||||
bool tried;
|
||||
|
||||
struct AvatarButtonAction
|
||||
@ -26,7 +26,7 @@ class AvatarButton : public Component
|
||||
std::unique_ptr<http::ImageRequest> imageRequest;
|
||||
|
||||
public:
|
||||
AvatarButton(Point position, Point size, ByteString username);
|
||||
AvatarButton(Point position, Point size, ByteString username, int avatarSize = 0);
|
||||
virtual ~AvatarButton() = default;
|
||||
|
||||
void OnMouseClick(int x, int y, unsigned int button) override;
|
||||
@ -46,6 +46,6 @@ public:
|
||||
ByteString GetUsername() { return name; }
|
||||
inline void SetActionCallback(AvatarButtonAction const &action) { actionCallback = action; };
|
||||
protected:
|
||||
bool isMouseInside, isButtonDown;
|
||||
bool isMouseInside = false, isButtonDown = false;
|
||||
};
|
||||
}
|
||||
|
12
src/gui/interface/Separator.cpp
Normal file
12
src/gui/interface/Separator.cpp
Normal file
@ -0,0 +1,12 @@
|
||||
#include "Separator.h"
|
||||
#include "graphics/Graphics.h"
|
||||
|
||||
namespace ui
|
||||
{
|
||||
|
||||
void Separator::Draw(const ui::Point& screenPos)
|
||||
{
|
||||
GetGraphics()->BlendRect(RectSized(screenPos, Size), 0xFFFFFF_rgb .WithAlpha(180));
|
||||
}
|
||||
|
||||
}
|
16
src/gui/interface/Separator.h
Normal file
16
src/gui/interface/Separator.h
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
#include "Component.h"
|
||||
|
||||
namespace ui
|
||||
{
|
||||
|
||||
class Separator : public Component
|
||||
{
|
||||
public:
|
||||
Separator(ui::Point position, ui::Point size) : Component(position, size)
|
||||
{ }
|
||||
|
||||
void Draw(const ui::Point& screenPos) override;
|
||||
};
|
||||
|
||||
}
|
@ -23,4 +23,5 @@ powder_files += files(
|
||||
'AvatarButton.cpp',
|
||||
'RichLabel.cpp',
|
||||
'SaveButton.cpp',
|
||||
'Separator.cpp',
|
||||
)
|
||||
|
@ -4,6 +4,7 @@ gui_files = files(
|
||||
|
||||
subdir('colourpicker')
|
||||
subdir('console')
|
||||
subdir('credits')
|
||||
subdir('dialogues')
|
||||
subdir('elementsearch')
|
||||
subdir('filebrowser')
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "simulation/ElementDefs.h"
|
||||
#include "simulation/SimulationSettings.h"
|
||||
#include "client/Client.h"
|
||||
#include "gui/credits/Credits.h"
|
||||
#include "gui/dialogues/ConfirmPrompt.h"
|
||||
#include "gui/dialogues/InformationMessage.h"
|
||||
#include "gui/interface/Button.h"
|
||||
@ -17,6 +18,7 @@
|
||||
#include "gui/interface/DropDown.h"
|
||||
#include "gui/interface/Engine.h"
|
||||
#include "gui/interface/Label.h"
|
||||
#include "gui/interface/Separator.h"
|
||||
#include "gui/interface/Textbox.h"
|
||||
#include "gui/interface/DirectionSelector.h"
|
||||
#include "PowderToySDL.h"
|
||||
@ -41,19 +43,7 @@ OptionsView::OptionsView() : ui::Window(ui::Point(-1, -1), ui::Point(320, 340))
|
||||
AddComponent(label);
|
||||
}
|
||||
|
||||
class Separator : public ui::Component
|
||||
{
|
||||
public:
|
||||
Separator(ui::Point position, ui::Point size) : Component(position, size){}
|
||||
virtual ~Separator(){}
|
||||
|
||||
void Draw(const ui::Point& screenPos) override
|
||||
{
|
||||
GetGraphics()->BlendRect(RectSized(screenPos, Size), 0xFFFFFF_rgb .WithAlpha(180));
|
||||
}
|
||||
};
|
||||
|
||||
Separator *tmpSeparator = new Separator(ui::Point(0, 22), ui::Point(Size.X, 1));
|
||||
auto *tmpSeparator = new ui::Separator(ui::Point(0, 22), ui::Point(Size.X, 1));
|
||||
AddComponent(tmpSeparator);
|
||||
|
||||
scrollPanel = new ui::ScrollPanel(ui::Point(1, 23), ui::Point(Size.X-2, Size.Y-39));
|
||||
@ -103,7 +93,7 @@ OptionsView::OptionsView() : ui::Window(ui::Point(-1, -1), ui::Point(320, 340))
|
||||
};
|
||||
auto addSeparator = [this, ¤tY]() {
|
||||
currentY += 6;
|
||||
auto *separator = new Separator(ui::Point(0, currentY), ui::Point(Size.X, 1));
|
||||
auto *separator = new ui::Separator(ui::Point(0, currentY), ui::Point(Size.X, 1));
|
||||
scrollPanel->AddChild(separator);
|
||||
currentY += 11;
|
||||
};
|
||||
@ -180,7 +170,7 @@ OptionsView::OptionsView() : ui::Window(ui::Point(-1, -1), ui::Point(320, 340))
|
||||
tempLabel->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
|
||||
AddComponent(tempLabel);
|
||||
|
||||
Separator * tempSeparator = new Separator(ui::Point(0, 22), ui::Point(Size.X, 1));
|
||||
auto * tempSeparator = new ui::Separator(ui::Point(0, 22), ui::Point(Size.X, 1));
|
||||
AddComponent(tempSeparator);
|
||||
|
||||
labelValues = new ui::Label(ui::Point(0, (radius * 5 / 2) + 37), ui::Point(Size.X, 16), String::Build(Format::Precision(1), "X:", x, " Y:", y, " Total:", std::hypot(x, y)));
|
||||
@ -364,6 +354,22 @@ OptionsView::OptionsView() : ui::Window(ui::Point(-1, -1), ui::Point(320, 340))
|
||||
}
|
||||
currentY += 26;
|
||||
}
|
||||
|
||||
{
|
||||
addSeparator();
|
||||
|
||||
auto *creditsButton = new ui::Button(ui::Point(10, currentY), ui::Point(90, 16), "Credits");
|
||||
creditsButton->SetActionCallback({ [this] {
|
||||
auto *credits = new Credits();
|
||||
ui::Engine::Ref().ShowWindow(credits);
|
||||
} });
|
||||
scrollPanel->AddChild(creditsButton);
|
||||
|
||||
addLabel(5, " - Find out who contributed to TPT");
|
||||
currentY += 13;
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
ui::Button *ok = new ui::Button(ui::Point(0, Size.Y-16), ui::Point(Size.X, 16), "OK");
|
||||
ok->SetActionCallback({ [this] {
|
||||
|
Loading…
x
Reference in New Issue
Block a user