From e26548989ad73c9fd077d51c88203788ba4645c3 Mon Sep 17 00:00:00 2001 From: tetektoza Date: Thu, 28 Sep 2023 17:06:49 +0200 Subject: [PATCH] GamesSettings: Port GamesSettings to GML compilation Co-Authored-By: Tim Schumacher --- .../Applications/GamesSettings/CMakeLists.txt | 11 +- .../GamesSettings/CardGamePreview.h | 31 ++ .../GamesSettings/CardSettingsWidget.cpp | 99 +++--- .../GamesSettings/CardSettingsWidget.gml | 6 +- .../GamesSettings/CardSettingsWidget.h | 4 +- .../GamesSettings/ChessGamePreview.h | 47 +++ .../GamesSettings/ChessSettingsWidget.cpp | 298 +++++++++--------- .../GamesSettings/ChessSettingsWidget.gml | 6 +- .../GamesSettings/ChessSettingsWidget.h | 6 +- Userland/Applications/GamesSettings/main.cpp | 6 +- 10 files changed, 281 insertions(+), 233 deletions(-) create mode 100644 Userland/Applications/GamesSettings/CardGamePreview.h create mode 100644 Userland/Applications/GamesSettings/ChessGamePreview.h diff --git a/Userland/Applications/GamesSettings/CMakeLists.txt b/Userland/Applications/GamesSettings/CMakeLists.txt index 4b854981f3..9965f7453b 100644 --- a/Userland/Applications/GamesSettings/CMakeLists.txt +++ b/Userland/Applications/GamesSettings/CMakeLists.txt @@ -4,19 +4,16 @@ serenity_component( TARGETS GamesSettings ) -stringify_gml(CardSettingsWidget.gml CardSettingsWidgetGML.h card_settings_widget_gml) -stringify_gml(ChessSettingsWidget.gml ChessSettingsWidgetGML.h chess_settings_widget_gml) +compile_gml(CardSettingsWidget.gml CardSettingsWidgetGML.cpp) +compile_gml(ChessSettingsWidget.gml ChessSettingsWidgetGML.cpp) set(SOURCES main.cpp CardSettingsWidget.cpp + CardSettingsWidgetGML.cpp + ChessSettingsWidgetGML.cpp ChessSettingsWidget.cpp ) -set(GENERATED_SOURCES - CardSettingsWidgetGML.h - ChessSettingsWidgetGML.h -) - serenity_app(GamesSettings ICON games) target_link_libraries(GamesSettings PRIVATE LibConfig LibCore LibGfx LibGUI LibMain LibCards LibChess) diff --git a/Userland/Applications/GamesSettings/CardGamePreview.h b/Userland/Applications/GamesSettings/CardGamePreview.h new file mode 100644 index 0000000000..39ce08f95e --- /dev/null +++ b/Userland/Applications/GamesSettings/CardGamePreview.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022-2023, Sam Atkins + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace GamesSettings { + +class CardGamePreview final : public Cards::CardGame { + C_OBJECT_ABSTRACT(CardGamePreview) + +public: + static ErrorOr> try_create(); + +private: + CardGamePreview() = default; + + virtual void paint_event(GUI::PaintEvent& event) override; +}; + +} diff --git a/Userland/Applications/GamesSettings/CardSettingsWidget.cpp b/Userland/Applications/GamesSettings/CardSettingsWidget.cpp index 34341dfa64..abdf3befd5 100644 --- a/Userland/Applications/GamesSettings/CardSettingsWidget.cpp +++ b/Userland/Applications/GamesSettings/CardSettingsWidget.cpp @@ -5,7 +5,6 @@ */ #include "CardSettingsWidget.h" -#include #include #include #include @@ -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_front_image_set = "Classic"sv; -class CardGamePreview final : public Cards::CardGame { - C_OBJECT_ABSTRACT(CardGamePreview) - -public: - static ErrorOr> 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(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> CardSettingsWidget::try_create() +ErrorOr> CardGamePreview::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(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> CardSettingsWidget::create() +{ + auto card_settings_widget = TRY(try_create()); TRY(card_settings_widget->initialize()); return card_settings_widget; } ErrorOr 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)); m_preview_frame = find_descendant_of_type_named("cards_preview"); @@ -179,5 +168,3 @@ String CardSettingsWidget::card_front_images_set_name() const } } - -REGISTER_WIDGET(GamesSettings, CardGamePreview); diff --git a/Userland/Applications/GamesSettings/CardSettingsWidget.gml b/Userland/Applications/GamesSettings/CardSettingsWidget.gml index 0c8c470f4f..fd0520bdd0 100644 --- a/Userland/Applications/GamesSettings/CardSettingsWidget.gml +++ b/Userland/Applications/GamesSettings/CardSettingsWidget.gml @@ -1,4 +1,4 @@ -@GUI::Frame { +@GamesSettings::CardSettingsWidget { fill_with_background_color: true layout: @GUI::VerticalBoxLayout { margins: [8] @@ -19,7 +19,7 @@ @GUI::ColorInput { name: "cards_background_color" - has_alpha_channel: false + color_has_alpha_channel: false } } @@ -42,7 +42,7 @@ @GUI::ComboBox { name: "cards_front_image_set" - model_only: true + only_allow_values_from_model: true } } diff --git a/Userland/Applications/GamesSettings/CardSettingsWidget.h b/Userland/Applications/GamesSettings/CardSettingsWidget.h index 569edffca9..7308f9e802 100644 --- a/Userland/Applications/GamesSettings/CardSettingsWidget.h +++ b/Userland/Applications/GamesSettings/CardSettingsWidget.h @@ -6,6 +6,7 @@ #pragma once +#include "CardGamePreview.h" #include #include #include @@ -16,12 +17,11 @@ namespace GamesSettings { -class CardGamePreview; - class CardSettingsWidget final : public GUI::SettingsWindow::Tab { C_OBJECT_ABSTRACT(CardSettingsWidget) public: static ErrorOr> try_create(); + static ErrorOr> create(); virtual ~CardSettingsWidget() override = default; virtual void apply_settings() override; diff --git a/Userland/Applications/GamesSettings/ChessGamePreview.h b/Userland/Applications/GamesSettings/ChessGamePreview.h new file mode 100644 index 0000000000..6cb871726b --- /dev/null +++ b/Userland/Applications/GamesSettings/ChessGamePreview.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2022-2023, Sam Atkins + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace GamesSettings { + +class ChessGamePreview final : public GUI::Frame { + C_OBJECT_ABSTRACT(ChessGamePreview) + +public: + static ErrorOr> 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> 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; +}; + +} diff --git a/Userland/Applications/GamesSettings/ChessSettingsWidget.cpp b/Userland/Applications/GamesSettings/ChessSettingsWidget.cpp index 5847bc6009..48177afe37 100644 --- a/Userland/Applications/GamesSettings/ChessSettingsWidget.cpp +++ b/Userland/Applications/GamesSettings/ChessSettingsWidget.cpp @@ -5,7 +5,7 @@ */ #include "ChessSettingsWidget.h" -#include +#include "ChessGamePreview.h" #include #include #include @@ -75,185 +75,171 @@ private: } }; -class ChessGamePreview final : public GUI::Frame { - C_OBJECT_ABSTRACT(ChessGamePreview) +ChessGamePreview::ChessGamePreview() + : m_dark_square_color { s_board_themes[0].dark_square_color } + , m_light_square_color { s_board_themes[0].light_square_color } +{ +} -public: - static ErrorOr> try_create() - { - auto preview = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) ChessGamePreview())); - return preview; - } +ErrorOr> ChessGamePreview::try_create() +{ + auto preview = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) ChessGamePreview())); + 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) - { - if (m_piece_set_name == piece_set_name) + m_piece_set_name = move(piece_set_name); + m_piece_images.clear(); + 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; + } + m_piece_images.set({ color, piece }, image.release_value()); + }; - m_piece_set_name = move(piece_set_name); - m_piece_images.clear(); - m_any_piece_images_are_missing = false; + load_piece_image(Chess::Color::White, Chess::Type::Pawn, "white-pawn.png"sv); + load_piece_image(Chess::Color::Black, Chess::Type::Pawn, "black-pawn.png"sv); + 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) { - 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; - } - m_piece_images.set({ color, piece }, image.release_value()); + update(); +} + +void ChessGamePreview::set_dark_square_color(Gfx::Color dark_square_color) +{ + if (m_dark_square_color == dark_square_color) + return; + + 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); - load_piece_image(Chess::Color::Black, Chess::Type::Pawn, "black-pawn.png"sv); - 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); + 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); - 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 (m_dark_square_color == dark_square_color) - return; + 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); + } - m_dark_square_color = dark_square_color; - update(); - } - - 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); - } + 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> m_piece_images; - bool m_any_piece_images_are_missing { false }; + 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); + }; - Gfx::Color m_dark_square_color { s_board_themes[0].dark_square_color }; - Gfx::Color m_light_square_color { s_board_themes[0].light_square_color }; - bool m_show_coordinates { true }; - String m_piece_set_name; -}; + 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 }); -ErrorOr> 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> 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()); return chess_settings_widget; } ErrorOr 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 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); @@ -328,5 +314,3 @@ void ChessSettingsWidget::reset_default_values() } } - -REGISTER_WIDGET(GamesSettings, ChessGamePreview); diff --git a/Userland/Applications/GamesSettings/ChessSettingsWidget.gml b/Userland/Applications/GamesSettings/ChessSettingsWidget.gml index 67ece20766..9332e1d098 100644 --- a/Userland/Applications/GamesSettings/ChessSettingsWidget.gml +++ b/Userland/Applications/GamesSettings/ChessSettingsWidget.gml @@ -1,4 +1,4 @@ -@GUI::Frame { +@GamesSettings::ChessSettingsWidget { fill_with_background_color: true layout: @GUI::VerticalBoxLayout { margins: [8] @@ -29,7 +29,7 @@ @GUI::ComboBox { name: "piece_set" - model_only: true + only_allow_values_from_model: true } } @@ -45,7 +45,7 @@ @GUI::ComboBox { name: "board_theme" - model_only: true + only_allow_values_from_model: true } } diff --git a/Userland/Applications/GamesSettings/ChessSettingsWidget.h b/Userland/Applications/GamesSettings/ChessSettingsWidget.h index be2fcc6ae6..704823b044 100644 --- a/Userland/Applications/GamesSettings/ChessSettingsWidget.h +++ b/Userland/Applications/GamesSettings/ChessSettingsWidget.h @@ -6,6 +6,7 @@ #pragma once +#include "ChessGamePreview.h" #include #include #include @@ -13,12 +14,11 @@ namespace GamesSettings { -class ChessGamePreview; - class ChessSettingsWidget final : public GUI::SettingsWindow::Tab { C_OBJECT_ABSTRACT(ChessSettingsWidget) public: static ErrorOr> try_create(); + static ErrorOr> create(); virtual ~ChessSettingsWidget() override = default; virtual void apply_settings() override; @@ -30,7 +30,7 @@ private: Vector m_piece_sets; - RefPtr m_preview; + RefPtr m_preview; RefPtr m_piece_set_combobox; RefPtr m_board_theme_combobox; RefPtr m_show_coordinates_checkbox; diff --git a/Userland/Applications/GamesSettings/main.cpp b/Userland/Applications/GamesSettings/main.cpp index 7f4cb56d6d..2b84e785b5 100644 --- a/Userland/Applications/GamesSettings/main.cpp +++ b/Userland/Applications/GamesSettings/main.cpp @@ -35,8 +35,10 @@ ErrorOr serenity_main(Main::Arguments arguments) auto window = TRY(GUI::SettingsWindow::create("Games Settings", GUI::SettingsWindow::ShowDefaultsButton::Yes)); window->set_icon(app_icon.bitmap_for_size(16)); - (void)TRY(window->add_tab("Cards"_string, "cards"sv)); - (void)TRY(window->add_tab("Chess"_string, "chess"sv)); + auto widget_cards = TRY(GamesSettings::CardSettingsWidget::create()); + 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->show();