1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 05:47:35 +00:00

GamesSettings: Port GamesSettings to GML compilation

Co-Authored-By: Tim Schumacher <timschumi@gmx.de>
This commit is contained in:
tetektoza 2023-09-28 17:06:49 +02:00 committed by Tim Schumacher
parent 935aaab757
commit e26548989a
10 changed files with 281 additions and 233 deletions

View file

@ -4,19 +4,16 @@ serenity_component(
TARGETS GamesSettings TARGETS GamesSettings
) )
stringify_gml(CardSettingsWidget.gml CardSettingsWidgetGML.h card_settings_widget_gml) compile_gml(CardSettingsWidget.gml CardSettingsWidgetGML.cpp)
stringify_gml(ChessSettingsWidget.gml ChessSettingsWidgetGML.h chess_settings_widget_gml) compile_gml(ChessSettingsWidget.gml ChessSettingsWidgetGML.cpp)
set(SOURCES set(SOURCES
main.cpp main.cpp
CardSettingsWidget.cpp CardSettingsWidget.cpp
CardSettingsWidgetGML.cpp
ChessSettingsWidgetGML.cpp
ChessSettingsWidget.cpp ChessSettingsWidget.cpp
) )
set(GENERATED_SOURCES
CardSettingsWidgetGML.h
ChessSettingsWidgetGML.h
)
serenity_app(GamesSettings ICON games) serenity_app(GamesSettings ICON games)
target_link_libraries(GamesSettings PRIVATE LibConfig LibCore LibGfx LibGUI LibMain LibCards LibChess) target_link_libraries(GamesSettings PRIVATE LibConfig LibCore LibGfx LibGUI LibMain LibCards LibChess)

View file

@ -0,0 +1,31 @@
/*
* Copyright (c) 2022-2023, Sam Atkins <atkinssj@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <LibCards/Card.h>
#include <LibCards/CardGame.h>
#include <LibCards/CardPainter.h>
#include <LibCards/CardStack.h>
#include <LibConfig/Client.h>
#include <LibGUI/FileSystemModel.h>
#include <LibGfx/Palette.h>
namespace GamesSettings {
class CardGamePreview final : public Cards::CardGame {
C_OBJECT_ABSTRACT(CardGamePreview)
public:
static ErrorOr<NonnullRefPtr<CardGamePreview>> try_create();
private:
CardGamePreview() = default;
virtual void paint_event(GUI::PaintEvent& event) override;
};
}

View file

@ -5,7 +5,6 @@
*/ */
#include "CardSettingsWidget.h" #include "CardSettingsWidget.h"
#include <Applications/GamesSettings/CardSettingsWidgetGML.h>
#include <LibCards/Card.h> #include <LibCards/Card.h>
#include <LibCards/CardGame.h> #include <LibCards/CardGame.h>
#include <LibCards/CardPainter.h> #include <LibCards/CardPainter.h>
@ -21,66 +20,56 @@ namespace GamesSettings {
static constexpr StringView default_card_back_image_path = "/res/graphics/cards/backs/Red.png"sv; static constexpr StringView default_card_back_image_path = "/res/graphics/cards/backs/Red.png"sv;
static constexpr StringView default_card_front_image_set = "Classic"sv; static constexpr StringView default_card_front_image_set = "Classic"sv;
class CardGamePreview final : public Cards::CardGame { ErrorOr<NonnullRefPtr<CardGamePreview>> CardGamePreview::try_create()
C_OBJECT_ABSTRACT(CardGamePreview)
public:
static ErrorOr<NonnullRefPtr<CardGamePreview>> try_create()
{
auto preview = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) CardGamePreview()));
Gfx::IntPoint point { 25, 24 };
TRY(preview->add_stack(point, Cards::CardStack::Type::Stock));
point.translate_by(Cards::Card::width + 30, 0);
TRY(preview->add_stack(point, Cards::CardStack::Type::Normal));
point.translate_by(Cards::Card::width + 30, 0);
TRY(preview->add_stack(point, Cards::CardStack::Type::Normal));
point.translate_by(20, 10);
TRY(preview->add_stack(point, Cards::CardStack::Type::Normal));
for (size_t i = 0; i < Cards::Card::card_count; ++i)
TRY(preview->stack_at_location(0).push(TRY(Cards::Card::try_create(Cards::Suit::Diamonds, static_cast<Cards::Rank>(i)))));
TRY(preview->stack_at_location(1).push(TRY(Cards::Card::try_create(Cards::Suit::Spades, Cards::Rank::Ace))));
TRY(preview->stack_at_location(2).push(TRY(Cards::Card::try_create(Cards::Suit::Hearts, Cards::Rank::Queen))));
TRY(preview->stack_at_location(3).push(TRY(Cards::Card::try_create(Cards::Suit::Clubs, Cards::Rank::Jack))));
preview->stack_at_location(0).peek().set_upside_down(true);
preview->stack_at_location(2).set_highlighted(true);
return preview;
}
private:
CardGamePreview() = default;
virtual void paint_event(GUI::PaintEvent& event) override
{
Cards::CardGame::paint_event(event);
GUI::Painter painter(*this);
painter.add_clip_rect(frame_inner_rect());
painter.add_clip_rect(event.rect());
auto background_color = this->background_color();
for (auto& stack : stacks())
stack->paint(painter, background_color);
}
};
ErrorOr<NonnullRefPtr<CardSettingsWidget>> CardSettingsWidget::try_create()
{ {
auto card_settings_widget = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) CardSettingsWidget)); auto preview = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) CardGamePreview()));
Gfx::IntPoint point { 25, 24 };
TRY(preview->add_stack(point, Cards::CardStack::Type::Stock));
point.translate_by(Cards::Card::width + 30, 0);
TRY(preview->add_stack(point, Cards::CardStack::Type::Normal));
point.translate_by(Cards::Card::width + 30, 0);
TRY(preview->add_stack(point, Cards::CardStack::Type::Normal));
point.translate_by(20, 10);
TRY(preview->add_stack(point, Cards::CardStack::Type::Normal));
for (size_t i = 0; i < Cards::Card::card_count; ++i)
TRY(preview->stack_at_location(0).push(TRY(Cards::Card::try_create(Cards::Suit::Diamonds, static_cast<Cards::Rank>(i)))));
TRY(preview->stack_at_location(1).push(TRY(Cards::Card::try_create(Cards::Suit::Spades, Cards::Rank::Ace))));
TRY(preview->stack_at_location(2).push(TRY(Cards::Card::try_create(Cards::Suit::Hearts, Cards::Rank::Queen))));
TRY(preview->stack_at_location(3).push(TRY(Cards::Card::try_create(Cards::Suit::Clubs, Cards::Rank::Jack))));
preview->stack_at_location(0).peek().set_upside_down(true);
preview->stack_at_location(2).set_highlighted(true);
return preview;
}
void CardGamePreview::paint_event(GUI::PaintEvent& event)
{
Cards::CardGame::paint_event(event);
GUI::Painter painter(*this);
painter.add_clip_rect(frame_inner_rect());
painter.add_clip_rect(event.rect());
auto background_color = this->background_color();
for (auto& stack : stacks())
stack->paint(painter, background_color);
}
ErrorOr<NonnullRefPtr<CardSettingsWidget>> CardSettingsWidget::create()
{
auto card_settings_widget = TRY(try_create());
TRY(card_settings_widget->initialize()); TRY(card_settings_widget->initialize());
return card_settings_widget; return card_settings_widget;
} }
ErrorOr<void> CardSettingsWidget::initialize() ErrorOr<void> CardSettingsWidget::initialize()
{ {
TRY(load_from_gml(card_settings_widget_gml));
auto background_color = Gfx::Color::from_string(Config::read_string("Games"sv, "Cards"sv, "BackgroundColor"sv)).value_or(Gfx::Color::from_rgb(0x008000)); auto background_color = Gfx::Color::from_string(Config::read_string("Games"sv, "Cards"sv, "BackgroundColor"sv)).value_or(Gfx::Color::from_rgb(0x008000));
m_preview_frame = find_descendant_of_type_named<CardGamePreview>("cards_preview"); m_preview_frame = find_descendant_of_type_named<CardGamePreview>("cards_preview");
@ -179,5 +168,3 @@ String CardSettingsWidget::card_front_images_set_name() const
} }
} }
REGISTER_WIDGET(GamesSettings, CardGamePreview);

View file

@ -1,4 +1,4 @@
@GUI::Frame { @GamesSettings::CardSettingsWidget {
fill_with_background_color: true fill_with_background_color: true
layout: @GUI::VerticalBoxLayout { layout: @GUI::VerticalBoxLayout {
margins: [8] margins: [8]
@ -19,7 +19,7 @@
@GUI::ColorInput { @GUI::ColorInput {
name: "cards_background_color" name: "cards_background_color"
has_alpha_channel: false color_has_alpha_channel: false
} }
} }
@ -42,7 +42,7 @@
@GUI::ComboBox { @GUI::ComboBox {
name: "cards_front_image_set" name: "cards_front_image_set"
model_only: true only_allow_values_from_model: true
} }
} }

View file

@ -6,6 +6,7 @@
#pragma once #pragma once
#include "CardGamePreview.h"
#include <LibGUI/ColorInput.h> #include <LibGUI/ColorInput.h>
#include <LibGUI/ComboBox.h> #include <LibGUI/ComboBox.h>
#include <LibGUI/Frame.h> #include <LibGUI/Frame.h>
@ -16,12 +17,11 @@
namespace GamesSettings { namespace GamesSettings {
class CardGamePreview;
class CardSettingsWidget final : public GUI::SettingsWindow::Tab { class CardSettingsWidget final : public GUI::SettingsWindow::Tab {
C_OBJECT_ABSTRACT(CardSettingsWidget) C_OBJECT_ABSTRACT(CardSettingsWidget)
public: public:
static ErrorOr<NonnullRefPtr<CardSettingsWidget>> try_create(); static ErrorOr<NonnullRefPtr<CardSettingsWidget>> try_create();
static ErrorOr<NonnullRefPtr<CardSettingsWidget>> create();
virtual ~CardSettingsWidget() override = default; virtual ~CardSettingsWidget() override = default;
virtual void apply_settings() override; virtual void apply_settings() override;

View file

@ -0,0 +1,47 @@
/*
* Copyright (c) 2022-2023, Sam Atkins <atkinssj@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <LibChess/Chess.h>
#include <LibConfig/Client.h>
#include <LibCore/Directory.h>
#include <LibGUI/CheckBox.h>
#include <LibGUI/ComboBox.h>
#include <LibGUI/Frame.h>
#include <LibGUI/ItemListModel.h>
#include <LibGUI/Painter.h>
namespace GamesSettings {
class ChessGamePreview final : public GUI::Frame {
C_OBJECT_ABSTRACT(ChessGamePreview)
public:
static ErrorOr<NonnullRefPtr<ChessGamePreview>> try_create();
virtual ~ChessGamePreview() = default;
void set_piece_set_name(String piece_set_name);
void set_dark_square_color(Gfx::Color dark_square_color);
void set_light_square_color(Gfx::Color light_square_color);
void set_show_coordinates(bool show_coordinates);
private:
ChessGamePreview();
virtual void paint_event(GUI::PaintEvent& event) override;
HashMap<Chess::Piece, RefPtr<Gfx::Bitmap>> m_piece_images;
bool m_any_piece_images_are_missing { false };
Gfx::Color m_dark_square_color;
Gfx::Color m_light_square_color;
bool m_show_coordinates { true };
String m_piece_set_name;
};
}

View file

@ -5,7 +5,7 @@
*/ */
#include "ChessSettingsWidget.h" #include "ChessSettingsWidget.h"
#include <Applications/GamesSettings/ChessSettingsWidgetGML.h> #include "ChessGamePreview.h"
#include <LibChess/Chess.h> #include <LibChess/Chess.h>
#include <LibConfig/Client.h> #include <LibConfig/Client.h>
#include <LibCore/Directory.h> #include <LibCore/Directory.h>
@ -75,185 +75,171 @@ private:
} }
}; };
class ChessGamePreview final : public GUI::Frame { ChessGamePreview::ChessGamePreview()
C_OBJECT_ABSTRACT(ChessGamePreview) : m_dark_square_color { s_board_themes[0].dark_square_color }
, m_light_square_color { s_board_themes[0].light_square_color }
{
}
public: ErrorOr<NonnullRefPtr<ChessGamePreview>> ChessGamePreview::try_create()
static ErrorOr<NonnullRefPtr<ChessGamePreview>> try_create() {
{ auto preview = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) ChessGamePreview()));
auto preview = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) ChessGamePreview())); return preview;
return preview; }
}
virtual ~ChessGamePreview() = default; void ChessGamePreview::set_piece_set_name(String piece_set_name)
{
if (m_piece_set_name == piece_set_name)
return;
void set_piece_set_name(String piece_set_name) m_piece_set_name = move(piece_set_name);
{ m_piece_images.clear();
if (m_piece_set_name == piece_set_name) m_any_piece_images_are_missing = false;
auto load_piece_image = [&](Chess::Color color, Chess::Type piece, StringView filename) {
auto path = MUST(String::formatted("/res/graphics/chess/sets/{}/{}", m_piece_set_name, filename));
auto image = Gfx::Bitmap::load_from_file(path.bytes_as_string_view());
if (image.is_error()) {
m_any_piece_images_are_missing = true;
return; return;
}
m_piece_images.set({ color, piece }, image.release_value());
};
m_piece_set_name = move(piece_set_name); load_piece_image(Chess::Color::White, Chess::Type::Pawn, "white-pawn.png"sv);
m_piece_images.clear(); load_piece_image(Chess::Color::Black, Chess::Type::Pawn, "black-pawn.png"sv);
m_any_piece_images_are_missing = false; load_piece_image(Chess::Color::White, Chess::Type::Knight, "white-knight.png"sv);
load_piece_image(Chess::Color::Black, Chess::Type::Knight, "black-knight.png"sv);
load_piece_image(Chess::Color::White, Chess::Type::Bishop, "white-bishop.png"sv);
load_piece_image(Chess::Color::Black, Chess::Type::Bishop, "black-bishop.png"sv);
load_piece_image(Chess::Color::White, Chess::Type::Rook, "white-rook.png"sv);
load_piece_image(Chess::Color::Black, Chess::Type::Rook, "black-rook.png"sv);
load_piece_image(Chess::Color::White, Chess::Type::Queen, "white-queen.png"sv);
load_piece_image(Chess::Color::Black, Chess::Type::Queen, "black-queen.png"sv);
load_piece_image(Chess::Color::White, Chess::Type::King, "white-king.png"sv);
load_piece_image(Chess::Color::Black, Chess::Type::King, "black-king.png"sv);
auto load_piece_image = [&](Chess::Color color, Chess::Type piece, StringView filename) { update();
auto path = MUST(String::formatted("/res/graphics/chess/sets/{}/{}", m_piece_set_name, filename)); }
auto image = Gfx::Bitmap::load_from_file(path.bytes_as_string_view());
if (image.is_error()) { void ChessGamePreview::set_dark_square_color(Gfx::Color dark_square_color)
m_any_piece_images_are_missing = true; {
return; if (m_dark_square_color == dark_square_color)
} return;
m_piece_images.set({ color, piece }, image.release_value());
m_dark_square_color = dark_square_color;
update();
}
void ChessGamePreview::set_light_square_color(Gfx::Color light_square_color)
{
if (m_light_square_color == light_square_color)
return;
m_light_square_color = light_square_color;
update();
}
void ChessGamePreview::set_show_coordinates(bool show_coordinates)
{
if (m_show_coordinates == show_coordinates)
return;
m_show_coordinates = show_coordinates;
update();
}
void ChessGamePreview::paint_event(GUI::PaintEvent& event)
{
GUI::Frame::paint_event(event);
GUI::Painter painter(*this);
painter.add_clip_rect(event.rect());
painter.add_clip_rect(frame_inner_rect());
auto& coordinate_font = Gfx::FontDatabase::default_font().bold_variant();
// To show all the piece graphics, we need at least 12 squares visible.
// With the same preview size as we use for card games, a nice fit is 2 ranks of 6.
// There are definitely better ways of doing this, but it'll do. ;^)
auto square_size = 61;
auto square_margin = square_size / 10;
auto rect_for_square = [&](Chess::Square const& square) {
return Gfx::IntRect {
frame_inner_rect().left() + square.file * square_size,
frame_inner_rect().bottom() - (square.rank + 1) * square_size,
square_size,
square_size
}; };
};
load_piece_image(Chess::Color::White, Chess::Type::Pawn, "white-pawn.png"sv); for (int rank = 0; rank < 3; ++rank) {
load_piece_image(Chess::Color::Black, Chess::Type::Pawn, "black-pawn.png"sv); for (int file = 0; file < 8; ++file) {
load_piece_image(Chess::Color::White, Chess::Type::Knight, "white-knight.png"sv); Chess::Square square { rank, file };
load_piece_image(Chess::Color::Black, Chess::Type::Knight, "black-knight.png"sv); auto square_rect = rect_for_square(square);
load_piece_image(Chess::Color::White, Chess::Type::Bishop, "white-bishop.png"sv); painter.fill_rect(square_rect, square.is_light() ? m_light_square_color : m_dark_square_color);
load_piece_image(Chess::Color::Black, Chess::Type::Bishop, "black-bishop.png"sv);
load_piece_image(Chess::Color::White, Chess::Type::Rook, "white-rook.png"sv);
load_piece_image(Chess::Color::Black, Chess::Type::Rook, "black-rook.png"sv);
load_piece_image(Chess::Color::White, Chess::Type::Queen, "white-queen.png"sv);
load_piece_image(Chess::Color::Black, Chess::Type::Queen, "black-queen.png"sv);
load_piece_image(Chess::Color::White, Chess::Type::King, "white-king.png"sv);
load_piece_image(Chess::Color::Black, Chess::Type::King, "black-king.png"sv);
update(); if (m_show_coordinates) {
} auto text_color = square.is_light() ? m_dark_square_color : m_light_square_color;
auto shrunken_rect = square_rect.shrunken(4, 4);
void set_dark_square_color(Gfx::Color dark_square_color) if (square.rank == 0) {
{ auto file_char = square.file_char();
if (m_dark_square_color == dark_square_color) painter.draw_text(shrunken_rect, { &file_char, 1 }, coordinate_font, Gfx::TextAlignment::BottomRight, text_color);
return; }
m_dark_square_color = dark_square_color; if (square.file == 0) {
update(); auto rank_char = square.rank_char();
} painter.draw_text(shrunken_rect, { &rank_char, 1 }, coordinate_font, Gfx::TextAlignment::TopLeft, text_color);
void set_light_square_color(Gfx::Color light_square_color)
{
if (m_light_square_color == light_square_color)
return;
m_light_square_color = light_square_color;
update();
}
void set_show_coordinates(bool show_coordinates)
{
if (m_show_coordinates == show_coordinates)
return;
m_show_coordinates = show_coordinates;
update();
}
private:
ChessGamePreview() = default;
virtual void paint_event(GUI::PaintEvent& event) override
{
GUI::Frame::paint_event(event);
GUI::Painter painter(*this);
painter.add_clip_rect(event.rect());
painter.add_clip_rect(frame_inner_rect());
auto& coordinate_font = Gfx::FontDatabase::default_font().bold_variant();
// To show all the piece graphics, we need at least 12 squares visible.
// With the same preview size as we use for card games, a nice fit is 2 ranks of 6.
// There are definitely better ways of doing this, but it'll do. ;^)
auto square_size = 61;
auto square_margin = square_size / 10;
auto rect_for_square = [&](Chess::Square const& square) {
return Gfx::IntRect {
frame_inner_rect().left() + square.file * square_size,
frame_inner_rect().bottom() - (square.rank + 1) * square_size,
square_size,
square_size
};
};
for (int rank = 0; rank < 3; ++rank) {
for (int file = 0; file < 8; ++file) {
Chess::Square square { rank, file };
auto square_rect = rect_for_square(square);
painter.fill_rect(square_rect, square.is_light() ? m_light_square_color : m_dark_square_color);
if (m_show_coordinates) {
auto text_color = square.is_light() ? m_dark_square_color : m_light_square_color;
auto shrunken_rect = square_rect.shrunken(4, 4);
if (square.rank == 0) {
auto file_char = square.file_char();
painter.draw_text(shrunken_rect, { &file_char, 1 }, coordinate_font, Gfx::TextAlignment::BottomRight, text_color);
}
if (square.file == 0) {
auto rank_char = square.rank_char();
painter.draw_text(shrunken_rect, { &rank_char, 1 }, coordinate_font, Gfx::TextAlignment::TopLeft, text_color);
}
} }
} }
} }
auto draw_piece = [&](Chess::Piece const& piece, Chess::Square const& square) {
auto maybe_bitmap = m_piece_images.get(piece);
if (!maybe_bitmap.has_value())
return;
auto& bitmap = *maybe_bitmap.value();
painter.draw_scaled_bitmap(
rect_for_square(square).shrunken(square_margin, square_margin, square_margin, square_margin),
bitmap,
bitmap.rect(),
1.0f,
Gfx::Painter::ScalingMode::BilinearBlend);
};
draw_piece({ Chess::Color::White, Chess::Type::King }, { 0, 0 });
draw_piece({ Chess::Color::Black, Chess::Type::King }, { 1, 0 });
draw_piece({ Chess::Color::White, Chess::Type::Queen }, { 0, 1 });
draw_piece({ Chess::Color::Black, Chess::Type::Queen }, { 1, 1 });
draw_piece({ Chess::Color::White, Chess::Type::Rook }, { 0, 2 });
draw_piece({ Chess::Color::Black, Chess::Type::Rook }, { 1, 2 });
draw_piece({ Chess::Color::White, Chess::Type::Bishop }, { 0, 3 });
draw_piece({ Chess::Color::Black, Chess::Type::Bishop }, { 1, 3 });
draw_piece({ Chess::Color::White, Chess::Type::Knight }, { 0, 4 });
draw_piece({ Chess::Color::Black, Chess::Type::Knight }, { 1, 4 });
draw_piece({ Chess::Color::White, Chess::Type::Pawn }, { 0, 5 });
draw_piece({ Chess::Color::Black, Chess::Type::Pawn }, { 1, 5 });
if (m_any_piece_images_are_missing) {
auto warning_rect = frame_inner_rect();
warning_rect.set_height(coordinate_font.preferred_line_height() + 4);
painter.fill_rect(warning_rect, palette().base());
painter.draw_text(warning_rect.shrunken(4, 4), "Warning: This set is missing images for some pieces!"sv, coordinate_font, Gfx::TextAlignment::CenterLeft, palette().base_text());
}
} }
HashMap<Chess::Piece, RefPtr<Gfx::Bitmap>> m_piece_images; auto draw_piece = [&](Chess::Piece const& piece, Chess::Square const& square) {
bool m_any_piece_images_are_missing { false }; auto maybe_bitmap = m_piece_images.get(piece);
if (!maybe_bitmap.has_value())
return;
auto& bitmap = *maybe_bitmap.value();
painter.draw_scaled_bitmap(
rect_for_square(square).shrunken(square_margin, square_margin, square_margin, square_margin),
bitmap,
bitmap.rect(),
1.0f,
Gfx::Painter::ScalingMode::BilinearBlend);
};
Gfx::Color m_dark_square_color { s_board_themes[0].dark_square_color }; draw_piece({ Chess::Color::White, Chess::Type::King }, { 0, 0 });
Gfx::Color m_light_square_color { s_board_themes[0].light_square_color }; draw_piece({ Chess::Color::Black, Chess::Type::King }, { 1, 0 });
bool m_show_coordinates { true }; draw_piece({ Chess::Color::White, Chess::Type::Queen }, { 0, 1 });
String m_piece_set_name; draw_piece({ Chess::Color::Black, Chess::Type::Queen }, { 1, 1 });
}; draw_piece({ Chess::Color::White, Chess::Type::Rook }, { 0, 2 });
draw_piece({ Chess::Color::Black, Chess::Type::Rook }, { 1, 2 });
draw_piece({ Chess::Color::White, Chess::Type::Bishop }, { 0, 3 });
draw_piece({ Chess::Color::Black, Chess::Type::Bishop }, { 1, 3 });
draw_piece({ Chess::Color::White, Chess::Type::Knight }, { 0, 4 });
draw_piece({ Chess::Color::Black, Chess::Type::Knight }, { 1, 4 });
draw_piece({ Chess::Color::White, Chess::Type::Pawn }, { 0, 5 });
draw_piece({ Chess::Color::Black, Chess::Type::Pawn }, { 1, 5 });
ErrorOr<NonnullRefPtr<ChessSettingsWidget>> ChessSettingsWidget::try_create() if (m_any_piece_images_are_missing) {
auto warning_rect = frame_inner_rect();
warning_rect.set_height(coordinate_font.preferred_line_height() + 4);
painter.fill_rect(warning_rect, palette().base());
painter.draw_text(warning_rect.shrunken(4, 4), "Warning: This set is missing images for some pieces!"sv, coordinate_font, Gfx::TextAlignment::CenterLeft, palette().base_text());
}
}
ErrorOr<NonnullRefPtr<ChessSettingsWidget>> ChessSettingsWidget::create()
{ {
auto chess_settings_widget = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) ChessSettingsWidget)); auto chess_settings_widget = TRY(try_create());
TRY(chess_settings_widget->initialize()); TRY(chess_settings_widget->initialize());
return chess_settings_widget; return chess_settings_widget;
} }
ErrorOr<void> ChessSettingsWidget::initialize() ErrorOr<void> ChessSettingsWidget::initialize()
{ {
TRY(load_from_gml(chess_settings_widget_gml));
auto piece_set_name = Config::read_string("Games"sv, "Chess"sv, "PieceSet"sv, "Classic"sv); auto piece_set_name = Config::read_string("Games"sv, "Chess"sv, "PieceSet"sv, "Classic"sv);
auto board_theme = get_board_theme(Config::read_string("Games"sv, "Chess"sv, "BoardTheme"sv, "Beige"sv)); auto board_theme = get_board_theme(Config::read_string("Games"sv, "Chess"sv, "BoardTheme"sv, "Beige"sv));
auto show_coordinates = Config::read_bool("Games"sv, "Chess"sv, "ShowCoordinates"sv, true); auto show_coordinates = Config::read_bool("Games"sv, "Chess"sv, "ShowCoordinates"sv, true);
@ -328,5 +314,3 @@ void ChessSettingsWidget::reset_default_values()
} }
} }
REGISTER_WIDGET(GamesSettings, ChessGamePreview);

View file

@ -1,4 +1,4 @@
@GUI::Frame { @GamesSettings::ChessSettingsWidget {
fill_with_background_color: true fill_with_background_color: true
layout: @GUI::VerticalBoxLayout { layout: @GUI::VerticalBoxLayout {
margins: [8] margins: [8]
@ -29,7 +29,7 @@
@GUI::ComboBox { @GUI::ComboBox {
name: "piece_set" name: "piece_set"
model_only: true only_allow_values_from_model: true
} }
} }
@ -45,7 +45,7 @@
@GUI::ComboBox { @GUI::ComboBox {
name: "board_theme" name: "board_theme"
model_only: true only_allow_values_from_model: true
} }
} }

View file

@ -6,6 +6,7 @@
#pragma once #pragma once
#include "ChessGamePreview.h"
#include <AK/Array.h> #include <AK/Array.h>
#include <AK/StringView.h> #include <AK/StringView.h>
#include <LibGUI/SettingsWindow.h> #include <LibGUI/SettingsWindow.h>
@ -13,12 +14,11 @@
namespace GamesSettings { namespace GamesSettings {
class ChessGamePreview;
class ChessSettingsWidget final : public GUI::SettingsWindow::Tab { class ChessSettingsWidget final : public GUI::SettingsWindow::Tab {
C_OBJECT_ABSTRACT(ChessSettingsWidget) C_OBJECT_ABSTRACT(ChessSettingsWidget)
public: public:
static ErrorOr<NonnullRefPtr<ChessSettingsWidget>> try_create(); static ErrorOr<NonnullRefPtr<ChessSettingsWidget>> try_create();
static ErrorOr<NonnullRefPtr<ChessSettingsWidget>> create();
virtual ~ChessSettingsWidget() override = default; virtual ~ChessSettingsWidget() override = default;
virtual void apply_settings() override; virtual void apply_settings() override;
@ -30,7 +30,7 @@ private:
Vector<DeprecatedString> m_piece_sets; Vector<DeprecatedString> m_piece_sets;
RefPtr<ChessGamePreview> m_preview; RefPtr<GamesSettings::ChessGamePreview> m_preview;
RefPtr<GUI::ComboBox> m_piece_set_combobox; RefPtr<GUI::ComboBox> m_piece_set_combobox;
RefPtr<GUI::ComboBox> m_board_theme_combobox; RefPtr<GUI::ComboBox> m_board_theme_combobox;
RefPtr<GUI::CheckBox> m_show_coordinates_checkbox; RefPtr<GUI::CheckBox> m_show_coordinates_checkbox;

View file

@ -35,8 +35,10 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
auto window = TRY(GUI::SettingsWindow::create("Games Settings", GUI::SettingsWindow::ShowDefaultsButton::Yes)); auto window = TRY(GUI::SettingsWindow::create("Games Settings", GUI::SettingsWindow::ShowDefaultsButton::Yes));
window->set_icon(app_icon.bitmap_for_size(16)); window->set_icon(app_icon.bitmap_for_size(16));
(void)TRY(window->add_tab<GamesSettings::CardSettingsWidget>("Cards"_string, "cards"sv)); auto widget_cards = TRY(GamesSettings::CardSettingsWidget::create());
(void)TRY(window->add_tab<GamesSettings::ChessSettingsWidget>("Chess"_string, "chess"sv)); auto widget_chess = TRY(GamesSettings::ChessSettingsWidget::create());
(void)TRY(window->add_tab(widget_cards, "Cards"_string, "cards"sv));
(void)TRY(window->add_tab(widget_chess, "Chess"_string, "chess"sv));
window->set_active_tab(selected_tab); window->set_active_tab(selected_tab);
window->show(); window->show();