2022-08-20 14:14:48 +01:00
|
|
|
/*
|
2023-02-01 13:50:10 +00:00
|
|
|
* Copyright (c) 2022-2023, Sam Atkins <atkinssj@serenityos.org>
|
2022-08-20 14:14:48 +01:00
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "CardSettingsWidget.h"
|
2023-01-12 15:07:47 -05:00
|
|
|
#include <LibCards/Card.h>
|
|
|
|
#include <LibCards/CardGame.h>
|
2022-08-21 16:07:46 +01:00
|
|
|
#include <LibCards/CardPainter.h>
|
2023-01-12 15:07:47 -05:00
|
|
|
#include <LibCards/CardStack.h>
|
2022-08-20 14:14:48 +01:00
|
|
|
#include <LibConfig/Client.h>
|
2023-10-03 17:06:54 +01:00
|
|
|
#include <LibCore/Directory.h>
|
2022-08-21 16:02:56 +01:00
|
|
|
#include <LibGUI/FileSystemModel.h>
|
2023-10-03 17:06:54 +01:00
|
|
|
#include <LibGUI/ItemListModel.h>
|
2022-08-21 16:07:46 +01:00
|
|
|
#include <LibGfx/Palette.h>
|
2022-08-21 16:02:56 +01:00
|
|
|
|
2023-01-12 14:45:11 -05:00
|
|
|
namespace GamesSettings {
|
|
|
|
|
2023-10-11 13:07:29 +01:00
|
|
|
static constexpr StringView default_card_back_image_path = "/res/graphics/cards/backs/Red.png"sv;
|
2023-10-03 17:06:54 +01:00
|
|
|
static constexpr StringView default_card_front_image_set = "Classic"sv;
|
2022-08-20 14:14:48 +01:00
|
|
|
|
2023-09-28 17:06:49 +02:00
|
|
|
ErrorOr<NonnullRefPtr<CardGamePreview>> CardGamePreview::try_create()
|
|
|
|
{
|
|
|
|
auto preview = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) CardGamePreview()));
|
2023-01-12 15:07:47 -05:00
|
|
|
|
2023-09-28 17:06:49 +02:00
|
|
|
Gfx::IntPoint point { 25, 24 };
|
|
|
|
TRY(preview->add_stack(point, Cards::CardStack::Type::Stock));
|
2023-01-12 15:07:47 -05:00
|
|
|
|
2023-09-28 17:06:49 +02:00
|
|
|
point.translate_by(Cards::Card::width + 30, 0);
|
|
|
|
TRY(preview->add_stack(point, Cards::CardStack::Type::Normal));
|
2023-01-12 15:07:47 -05:00
|
|
|
|
2023-09-28 17:06:49 +02:00
|
|
|
point.translate_by(Cards::Card::width + 30, 0);
|
|
|
|
TRY(preview->add_stack(point, Cards::CardStack::Type::Normal));
|
2023-01-12 15:07:47 -05:00
|
|
|
|
2023-09-28 17:06:49 +02:00
|
|
|
point.translate_by(20, 10);
|
|
|
|
TRY(preview->add_stack(point, Cards::CardStack::Type::Normal));
|
2023-01-12 15:15:45 -05:00
|
|
|
|
2023-09-28 17:06:49 +02:00
|
|
|
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))));
|
2023-01-12 15:07:47 -05:00
|
|
|
|
2023-09-28 17:06:49 +02:00
|
|
|
preview->stack_at_location(0).peek().set_upside_down(true);
|
|
|
|
preview->stack_at_location(2).set_highlighted(true);
|
2023-01-12 15:15:45 -05:00
|
|
|
|
2023-09-28 17:06:49 +02:00
|
|
|
return preview;
|
|
|
|
}
|
2023-01-12 15:07:47 -05:00
|
|
|
|
2023-09-28 17:06:49 +02:00
|
|
|
void CardGamePreview::paint_event(GUI::PaintEvent& event)
|
|
|
|
{
|
|
|
|
Cards::CardGame::paint_event(event);
|
2023-01-12 15:07:47 -05:00
|
|
|
|
2023-09-28 17:06:49 +02:00
|
|
|
GUI::Painter painter(*this);
|
|
|
|
painter.add_clip_rect(frame_inner_rect());
|
|
|
|
painter.add_clip_rect(event.rect());
|
2023-01-12 15:07:47 -05:00
|
|
|
|
2023-09-28 17:06:49 +02:00
|
|
|
auto background_color = this->background_color();
|
|
|
|
for (auto& stack : stacks())
|
|
|
|
stack->paint(painter, background_color);
|
|
|
|
}
|
2023-01-12 15:07:47 -05:00
|
|
|
|
2023-09-28 17:06:49 +02:00
|
|
|
ErrorOr<NonnullRefPtr<CardSettingsWidget>> CardSettingsWidget::create()
|
2022-08-20 14:14:48 +01:00
|
|
|
{
|
2023-09-28 17:06:49 +02:00
|
|
|
auto card_settings_widget = TRY(try_create());
|
2023-02-01 13:50:10 +00:00
|
|
|
TRY(card_settings_widget->initialize());
|
|
|
|
return card_settings_widget;
|
|
|
|
}
|
|
|
|
|
|
|
|
ErrorOr<void> CardSettingsWidget::initialize()
|
|
|
|
{
|
2022-08-20 14:14:48 +01:00
|
|
|
auto background_color = Gfx::Color::from_string(Config::read_string("Games"sv, "Cards"sv, "BackgroundColor"sv)).value_or(Gfx::Color::from_rgb(0x008000));
|
2022-08-21 16:07:46 +01:00
|
|
|
|
2023-02-01 13:29:07 +00:00
|
|
|
m_preview_frame = find_descendant_of_type_named<CardGamePreview>("cards_preview");
|
2023-01-12 15:07:47 -05:00
|
|
|
m_preview_frame->set_background_color(background_color);
|
2022-08-21 16:07:46 +01:00
|
|
|
|
|
|
|
m_background_color_input = find_descendant_of_type_named<GUI::ColorInput>("cards_background_color");
|
2022-08-20 14:14:48 +01:00
|
|
|
m_background_color_input->set_color(background_color, GUI::AllowCallback::No);
|
2022-08-21 16:07:46 +01:00
|
|
|
m_background_color_input->on_change = [&]() {
|
|
|
|
set_modified(true);
|
2023-01-12 15:07:47 -05:00
|
|
|
m_preview_frame->set_background_color(m_background_color_input->color());
|
2022-08-21 16:07:46 +01:00
|
|
|
};
|
2022-08-21 16:02:56 +01:00
|
|
|
|
2023-10-03 17:06:54 +01:00
|
|
|
m_card_front_images_combo_box = find_descendant_of_type_named<GUI::ComboBox>("cards_front_image_set");
|
|
|
|
m_card_front_sets.append("None");
|
|
|
|
TRY(Core::Directory::for_each_entry("/res/graphics/cards/fronts/"sv, Core::DirIterator::SkipParentAndBaseDir, [&](auto const& entry, auto&) -> ErrorOr<IterationDecision> {
|
|
|
|
TRY(m_card_front_sets.try_append(entry.name));
|
|
|
|
return IterationDecision::Continue;
|
|
|
|
}));
|
|
|
|
auto piece_set_model = GUI::ItemListModel<DeprecatedString>::create(m_card_front_sets);
|
|
|
|
m_card_front_images_combo_box->set_model(piece_set_model);
|
|
|
|
auto card_front_set = Config::read_string("Games"sv, "Cards"sv, "CardFrontImages"sv, default_card_front_image_set);
|
|
|
|
if (card_front_set.is_empty())
|
|
|
|
card_front_set = "None";
|
|
|
|
m_card_front_images_combo_box->set_text(card_front_set, GUI::AllowCallback::No);
|
|
|
|
m_card_front_images_combo_box->on_change = [&](auto&, auto&) {
|
|
|
|
set_modified(true);
|
|
|
|
Cards::CardPainter::the().set_front_images_set_name(card_front_images_set_name());
|
|
|
|
m_preview_frame->update();
|
|
|
|
};
|
|
|
|
|
2022-08-21 16:02:56 +01:00
|
|
|
m_card_back_image_view = find_descendant_of_type_named<GUI::IconView>("cards_back_image");
|
2023-05-05 01:04:46 +01:00
|
|
|
m_card_back_image_view->set_model(GUI::FileSystemModel::create("/res/graphics/cards/backs"));
|
2022-08-21 16:02:56 +01:00
|
|
|
m_card_back_image_view->set_model_column(GUI::FileSystemModel::Column::Name);
|
2023-06-26 20:49:32 +02:00
|
|
|
if (!set_card_back_image_path(TRY(String::from_deprecated_string(Config::read_string("Games"sv, "Cards"sv, "CardBackImage"sv)))))
|
2022-08-21 16:02:56 +01:00
|
|
|
set_card_back_image_path(default_card_back_image_path);
|
|
|
|
m_card_back_image_view->on_selection_change = [&]() {
|
2022-09-18 17:32:59 -04:00
|
|
|
auto& card_back_selection = m_card_back_image_view->selection();
|
|
|
|
if (card_back_selection.is_empty())
|
2022-08-21 16:02:56 +01:00
|
|
|
return;
|
2022-09-18 17:32:59 -04:00
|
|
|
m_last_selected_card_back = card_back_selection.first();
|
2022-08-21 16:02:56 +01:00
|
|
|
set_modified(true);
|
2023-10-03 17:14:43 +01:00
|
|
|
Cards::CardPainter::the().set_back_image_path(card_back_image_path());
|
2023-01-12 15:07:47 -05:00
|
|
|
m_preview_frame->update();
|
2022-08-21 16:02:56 +01:00
|
|
|
};
|
2022-09-18 17:32:59 -04:00
|
|
|
|
|
|
|
m_last_selected_card_back = m_card_back_image_view->selection().first();
|
2023-02-01 13:50:10 +00:00
|
|
|
|
|
|
|
return {};
|
2022-08-20 14:14:48 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void CardSettingsWidget::apply_settings()
|
|
|
|
{
|
|
|
|
Config::write_string("Games"sv, "Cards"sv, "BackgroundColor"sv, m_background_color_input->text());
|
2023-10-03 17:06:54 +01:00
|
|
|
Config::write_string("Games"sv, "Cards"sv, "CardFrontImages"sv, card_front_images_set_name());
|
2022-08-21 16:02:56 +01:00
|
|
|
Config::write_string("Games"sv, "Cards"sv, "CardBackImage"sv, card_back_image_path());
|
2022-08-20 14:14:48 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void CardSettingsWidget::reset_default_values()
|
|
|
|
{
|
|
|
|
m_background_color_input->set_color(Gfx::Color::from_rgb(0x008000));
|
2022-08-21 16:02:56 +01:00
|
|
|
set_card_back_image_path(default_card_back_image_path);
|
2023-10-03 17:06:54 +01:00
|
|
|
// FIXME: `set_text()` on a combobox doesn't trigger the `on_change` callback, but it probably should!
|
|
|
|
// Until then, we have to manually tell the preview to update.
|
|
|
|
m_card_front_images_combo_box->set_text(default_card_front_image_set);
|
|
|
|
Cards::CardPainter::the().set_front_images_set_name(card_front_images_set_name());
|
|
|
|
m_preview_frame->update();
|
2022-08-21 16:02:56 +01:00
|
|
|
}
|
|
|
|
|
2023-06-26 20:49:32 +02:00
|
|
|
bool CardSettingsWidget::set_card_back_image_path(StringView path)
|
2022-08-21 16:02:56 +01:00
|
|
|
{
|
2023-06-26 20:49:32 +02:00
|
|
|
auto index = static_cast<GUI::FileSystemModel*>(m_card_back_image_view->model())->index(path.to_deprecated_string(), m_card_back_image_view->model_column());
|
2022-08-21 16:02:56 +01:00
|
|
|
if (index.is_valid()) {
|
|
|
|
m_card_back_image_view->set_cursor(index, GUI::AbstractView::SelectionUpdate::Set);
|
2023-10-03 17:14:43 +01:00
|
|
|
Cards::CardPainter::the().set_back_image_path(path);
|
2023-01-12 15:07:47 -05:00
|
|
|
m_preview_frame->update();
|
2022-08-21 16:02:56 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2023-06-26 20:49:32 +02:00
|
|
|
String CardSettingsWidget::card_back_image_path() const
|
2022-08-21 16:02:56 +01:00
|
|
|
{
|
2022-09-18 17:32:59 -04:00
|
|
|
auto& card_back_selection = m_card_back_image_view->selection();
|
|
|
|
GUI::ModelIndex card_back_image_index = m_last_selected_card_back;
|
|
|
|
if (!card_back_selection.is_empty())
|
|
|
|
card_back_image_index = card_back_selection.first();
|
2023-06-26 20:49:32 +02:00
|
|
|
return String::from_deprecated_string(static_cast<GUI::FileSystemModel const*>(m_card_back_image_view->model())->full_path(card_back_image_index)).release_value_but_fixme_should_propagate_errors();
|
2022-08-20 14:14:48 +01:00
|
|
|
}
|
2023-01-12 14:45:11 -05:00
|
|
|
|
2023-10-03 17:06:54 +01:00
|
|
|
String CardSettingsWidget::card_front_images_set_name() const
|
|
|
|
{
|
|
|
|
auto selected_set_name = m_card_front_images_combo_box->text();
|
|
|
|
if (selected_set_name == "None")
|
|
|
|
return {};
|
|
|
|
return MUST(String::from_deprecated_string(selected_set_name));
|
|
|
|
}
|
|
|
|
|
2023-01-12 14:45:11 -05:00
|
|
|
}
|