2 * Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>
4 * This file is part of CasparCG (www.casparcg.com).
6 * CasparCG is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * CasparCG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with CasparCG. If not, see <http://www.gnu.org/licenses/>.
19 * Author: Helge Norberg, helge.norberg@svt.se
27 #include <boost/optional.hpp>
29 #include "interaction_event.h"
30 #include "interaction_sink.h"
31 #include "../frame/frame_transform.h"
34 namespace caspar { namespace core {
36 typedef std::pair<frame_transform, interaction_sink*> interaction_target;
37 typedef std::function<boost::optional<interaction_target> (double x, double y)>
40 class interaction_aggregator
42 std::queue<interaction_event::ptr> events_;
43 collission_detector collission_detector_;
46 boost::optional<interaction_target> clicked_and_held_;
47 int num_buttons_clicked_and_held_ = 0;
49 interaction_aggregator(const collission_detector& collission_detector)
50 : collission_detector_(collission_detector)
54 void offer(const interaction_event::ptr& event)
57 && is<mouse_move_event>(event)
58 && is<mouse_move_event>(events_.back()))
60 events_.back() = event;
68 void translate_and_send()
70 while (!events_.empty())
72 translate_and_send(events_.front());
77 void translate_and_send(const interaction_event::ptr& event)
79 if (is<position_event>(event))
81 auto pos_event = as<position_event>(event);
82 boost::optional<interaction_target> target;
84 if (clicked_and_held_)
85 target = clicked_and_held_;
87 target = collission_detector_(pos_event->x, pos_event->y);
89 if (is<mouse_button_event>(event))
91 auto button_event = as<mouse_button_event>(event);
93 if (button_event->pressed)
95 if (num_buttons_clicked_and_held_ == 0)
96 clicked_and_held_ = target;
98 ++num_buttons_clicked_and_held_;
101 --num_buttons_clicked_and_held_;
103 if (num_buttons_clicked_and_held_ == 0)
104 clicked_and_held_.reset();
108 target->second->on_interaction(
109 pos_event->translate(target->first));