aboutsummaryrefslogblamecommitdiffstats
path: root/src/menu/mouse_manager.cpp
blob: 3b4eb2680f2cf7640ce34b504cfb936fa6b0b4e4 (plain) (tree)























                                                                        

                  
















































































































                                                                                                                     
/*
 * UltraStar Deluxe - Karaoke Game
 *
 * UltraStar Deluxe is the legal property of its developers, whose names
 * are too numerous to list here. Please refer to the COPYRIGHT
 * file distributed with this source distribution.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; see the file COPYING. If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#include <cstddef>

#include "mouse_manager.hpp"
#include "utils/rectangle.hpp"
#include "container.hpp"
#include "application.hpp"

namespace usdx
{
	log4cpp::Category& MouseManager::log =
		log4cpp::Category::getInstance("usdx.menu.mouse_manager");

	MouseManager::MouseManager(EventManager& event_manager)
		: last_active(NULL)
	{
		mouse_move_connection = event_manager.mouse_move.connect(
			boost::bind(&MouseManager::on_mouse_move, this, _1));
		mouse_down_connection = event_manager.mouse_down.connect(
			boost::bind(&MouseManager::on_mouse_down, this, _1, _2));
		mouse_up_connection = event_manager.mouse_up.connect(
			boost::bind(&MouseManager::on_mouse_up, this, _1, _2));
	}

	MouseManager::~MouseManager()
	{
		mouse_move_connection.disconnect();
		mouse_down_connection.disconnect();
		mouse_up_connection.disconnect();
	}

	void MouseManager::find_active_element(const Point<int>& p)
	{
		DrawableControl *c = find_parent(last_active, p);
		c = c->get_component_at(p);

		if (last_active != c) {
			if (last_active) {
				last_active->mouse_leave();
			}

			last_active = c;

			if (last_active) {
				last_active->mouse_enter();
			}
		}
	}

	DrawableControl* MouseManager::find_parent(DrawableControl* current,
											   const Point<int>& p) const
	{
		if (current == NULL) {
			// start search from top level
			return Application::get_instance();
		}

		if (!current->get_absolut_rect().is_in(p)) {
			current = find_parent(current->get_parent(), p);
		}

		return current;
	}

	void MouseManager::on_mouse_move(const Point<int>& p)
	{
		find_active_element(p);

		if (last_active) {
			last_active->mouse_move(p);
		}
	}

	void MouseManager::on_mouse_down(uint8_t button, const Point<int>& p)
	{
		find_active_element(p);

		if (last_active) {
			last_active->mouse_down(button, p);
		}

		event.add_event(last_active, button, MouseEvent::DOWN);
	}

	void MouseManager::on_mouse_up(uint8_t button, const Point<int>& p)
	{
		find_active_element(p);

		if (last_active) {
			last_active->mouse_up(button, p);
		}

		MouseEvent::Event e = event.add_event(last_active, button,
											  MouseEvent::UP);

		switch (e) {
		case MouseEvent::CLICK:
			last_active->mouse_click(button, p);
			break;

		case MouseEvent::DBL_CLICK:
			last_active->mouse_dbl_click(button, p);
			break;

		default:
			;
		}
	}

	void MouseManager::deactivate_control(const DrawableControl* control)
	{
		if (last_active == control) {
			last_active = NULL;
		}
	}
};