CardGame.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /*
  2. * Copyright (c) 2020, Till Mayer <till.mayer@web.de>
  3. * Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org>
  4. * Copyright (c) 2022, the SerenityOS developers.
  5. *
  6. * SPDX-License-Identifier: BSD-2-Clause
  7. */
  8. #include "CardGame.h"
  9. #include <LibCards/CardPainter.h>
  10. #include <LibConfig/Client.h>
  11. #include <LibGfx/Palette.h>
  12. namespace Cards {
  13. CardGame::CardGame()
  14. {
  15. auto background_color = Gfx::Color::from_string(Config::read_string("Games"sv, "Cards"sv, "BackgroundColor"sv));
  16. set_background_color(background_color.value_or(Color::from_rgb(0x008000)));
  17. }
  18. void CardGame::add_stack(NonnullRefPtr<CardStack> stack)
  19. {
  20. m_stacks.append(move(stack));
  21. }
  22. void CardGame::mark_intersecting_stacks_dirty(Cards::Card const& intersecting_card)
  23. {
  24. for (auto& stack : stacks()) {
  25. if (intersecting_card.rect().intersects(stack.bounding_box()))
  26. update(stack.bounding_box());
  27. }
  28. update(intersecting_card.rect());
  29. }
  30. Gfx::IntRect CardGame::moving_cards_bounds() const
  31. {
  32. if (!is_moving_cards())
  33. return {};
  34. // Note: This assumes that the cards are arranged in a line.
  35. return m_moving_cards.first().rect().united(m_moving_cards.last().rect());
  36. }
  37. void CardGame::pick_up_cards_from_stack(Cards::CardStack& stack, Gfx::IntPoint click_location, CardStack::MovementRule movement_rule)
  38. {
  39. if (m_moving_cards_source_stack)
  40. m_moving_cards_source_stack->set_focused(false);
  41. stack.add_all_grabbed_cards(click_location, m_moving_cards, movement_rule);
  42. stack.set_focused(true);
  43. m_moving_cards_source_stack = stack;
  44. }
  45. RefPtr<CardStack> CardGame::find_stack_to_drop_on(CardStack::MovementRule movement_rule) const
  46. {
  47. auto bounds_to_check = moving_cards_bounds();
  48. RefPtr<CardStack> closest_stack;
  49. float closest_distance = FLT_MAX;
  50. for (auto const& stack : stacks()) {
  51. if (stack.is_focused())
  52. continue;
  53. if (stack.bounding_box().intersects(bounds_to_check)
  54. && stack.is_allowed_to_push(moving_cards().at(0), moving_cards().size(), movement_rule)) {
  55. auto distance = bounds_to_check.center().distance_from(stack.bounding_box().center());
  56. if (distance < closest_distance) {
  57. closest_stack = stack;
  58. closest_distance = distance;
  59. }
  60. }
  61. }
  62. return closest_stack;
  63. }
  64. void CardGame::drop_cards_on_stack(Cards::CardStack& stack, CardStack::MovementRule movement_rule)
  65. {
  66. VERIFY(stack.is_allowed_to_push(m_moving_cards.at(0), m_moving_cards.size(), movement_rule));
  67. for (auto& to_intersect : moving_cards()) {
  68. mark_intersecting_stacks_dirty(to_intersect);
  69. stack.push(to_intersect);
  70. (void)moving_cards_source_stack()->pop();
  71. }
  72. update(moving_cards_source_stack()->bounding_box());
  73. update(stack.bounding_box());
  74. }
  75. void CardGame::clear_moving_cards()
  76. {
  77. if (!m_moving_cards_source_stack.is_null())
  78. m_moving_cards_source_stack->set_focused(false);
  79. m_moving_cards_source_stack.clear();
  80. m_moving_cards.clear();
  81. }
  82. void CardGame::dump_layout() const
  83. {
  84. dbgln("------------------------------");
  85. for (auto const& stack : stacks())
  86. dbgln("{}", stack);
  87. }
  88. void CardGame::config_string_did_change(String const& domain, String const& group, String const& key, String const& value)
  89. {
  90. if (domain == "Games" && group == "Cards") {
  91. if (key == "BackgroundColor") {
  92. if (auto maybe_color = Gfx::Color::from_string(value); maybe_color.has_value())
  93. set_background_color(maybe_color.value());
  94. return;
  95. }
  96. if (key == "CardBackImage") {
  97. CardPainter::the().set_background_image_path(value);
  98. update();
  99. return;
  100. }
  101. }
  102. }
  103. Gfx::Color CardGame::background_color() const
  104. {
  105. return palette().color(background_role());
  106. }
  107. void CardGame::set_background_color(Gfx::Color const& color)
  108. {
  109. auto new_palette = palette();
  110. new_palette.set_color(Gfx::ColorRole::Background, color);
  111. set_palette(new_palette);
  112. }
  113. }