1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 16:17:45 +00:00

LibCards: Add support for card dragging

Solitaire and Spider have almost identical code for dragging cards from
one stack to another, so it makes sense to move that here. But using
the term "moving" for them, instead of "focused" which (to me at least)
was not clear what it meant.
This commit is contained in:
Sam Atkins 2022-09-28 17:05:34 +01:00 committed by Sam Atkins
parent 5960c0556f
commit a2f0b67aea
2 changed files with 74 additions and 0 deletions

View file

@ -1,5 +1,7 @@
/*
* Copyright (c) 2020, Till Mayer <till.mayer@web.de>
* Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org>
* Copyright (c) 2022, the SerenityOS developers.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -32,6 +34,65 @@ void CardGame::mark_intersecting_stacks_dirty(Cards::Card const& intersecting_ca
update(intersecting_card.rect());
}
Gfx::IntRect CardGame::moving_cards_bounds() const
{
if (!is_moving_cards())
return {};
// Note: This assumes that the cards are arranged in a line.
return m_moving_cards.first().rect().united(m_moving_cards.last().rect());
}
void CardGame::pick_up_cards_from_stack(Cards::CardStack& stack, Gfx::IntPoint click_location, CardStack::MovementRule movement_rule)
{
if (m_moving_cards_source_stack)
m_moving_cards_source_stack->set_focused(false);
stack.add_all_grabbed_cards(click_location, m_moving_cards, movement_rule);
stack.set_focused(true);
m_moving_cards_source_stack = stack;
}
RefPtr<CardStack> CardGame::find_stack_to_drop_on(CardStack::MovementRule movement_rule) const
{
auto bounds_to_check = moving_cards_bounds();
// FIXME: This currently returns only the first stack we overlap,
// but what we want is the stack we overlap the most.
for (auto const& stack : stacks()) {
if (stack.is_focused())
continue;
if (stack.bounding_box().intersects(bounds_to_check)) {
if (stack.is_allowed_to_push(moving_cards().at(0), moving_cards().size(), movement_rule)) {
return stack;
}
}
}
return nullptr;
}
void CardGame::drop_cards_on_stack(Cards::CardStack& stack, CardStack::MovementRule movement_rule)
{
VERIFY(stack.is_allowed_to_push(m_moving_cards.at(0), m_moving_cards.size(), movement_rule));
for (auto& to_intersect : moving_cards()) {
mark_intersecting_stacks_dirty(to_intersect);
stack.push(to_intersect);
(void)moving_cards_source_stack()->pop();
}
update(moving_cards_source_stack()->bounding_box());
update(stack.bounding_box());
}
void CardGame::clear_moving_cards()
{
if (!m_moving_cards_source_stack.is_null())
m_moving_cards_source_stack->set_focused(false);
m_moving_cards_source_stack.clear();
m_moving_cards.clear();
}
void CardGame::dump_layout() const
{
dbgln("------------------------------");