mirror of
https://github.com/wesnoth/wesnoth
synced 2025-05-03 17:23:52 +00:00
Added a minimal implementation for the tooltips.
Since the tooltips are currently only used for the multiplayer menu the have been impemented so they work there. Post 1.8 it will be implemented better but it might be that the tooltips then become separate floating windows. Since that's not sure added the minimal version for 1.8 and look further after that version has been shipped.
This commit is contained in:
parent
6fb52460ec
commit
72cf13ed3c
@ -16,23 +16,26 @@
|
||||
|
||||
#include "gui/auxiliary/event/distributor.hpp"
|
||||
|
||||
#include "events.hpp"
|
||||
#include "gui/auxiliary/log.hpp"
|
||||
#include "gui/widgets/settings.hpp"
|
||||
#include "gui/widgets/widget.hpp"
|
||||
#include "gui/widgets/window.hpp"
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
namespace gui2{
|
||||
|
||||
namespace event {
|
||||
#if 0
|
||||
|
||||
/**
|
||||
* SDL_AddTimer() callback for the hover event.
|
||||
*
|
||||
* When this callback is called it pushes a new hover event in the event queue.
|
||||
*
|
||||
* @param interval The time parameter of SDL_AddTimer.
|
||||
* @param param Pointer to parameter structure.
|
||||
* @param param Pointer to a widget that's able to show the
|
||||
* tooltip (will be used as a dispatcher).
|
||||
*
|
||||
* @returns The new timer interval, 0 to stop.
|
||||
*/
|
||||
@ -46,7 +49,7 @@ static Uint32 hover_callback(Uint32 /*interval*/, void *param)
|
||||
data.type = HOVER_EVENT;
|
||||
data.code = 0;
|
||||
data.data1 = param;
|
||||
data.data2 = 0;
|
||||
data.data2 = NULL;
|
||||
|
||||
event.type = HOVER_EVENT;
|
||||
event.user = data;
|
||||
@ -54,7 +57,7 @@ static Uint32 hover_callback(Uint32 /*interval*/, void *param)
|
||||
SDL_PushEvent(&event);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* SDL_AddTimer() callback for the popup event.
|
||||
*
|
||||
@ -125,12 +128,26 @@ tmouse_motion::tmouse_motion(twidget& owner
|
||||
: mouse_focus_(NULL)
|
||||
, mouse_captured_(false)
|
||||
, owner_(owner)
|
||||
, hover_timer_(NULL)
|
||||
, hover_widget_(NULL)
|
||||
, hover_position_(0, 0)
|
||||
, hover_shown_(true)
|
||||
, signal_handler_sdl_mouse_motion_entered_(false)
|
||||
{
|
||||
owner.connect_signal<event::SDL_MOUSE_MOTION>(
|
||||
boost::bind(&tmouse_motion::signal_handler_sdl_mouse_motion
|
||||
, this, _2, _3, _5)
|
||||
, queue_position);
|
||||
|
||||
owner.connect_signal<event::SHOW_HOVER_TOOLTIP>(
|
||||
boost::bind(&tmouse_motion::signal_handler_show_hover_tooltip
|
||||
, this, _2)
|
||||
, queue_position);
|
||||
}
|
||||
|
||||
tmouse_motion::~tmouse_motion()
|
||||
{
|
||||
stop_hover_timer();
|
||||
}
|
||||
|
||||
void tmouse_motion::capture_mouse(//twidget* widget)
|
||||
@ -191,6 +208,9 @@ void tmouse_motion::mouse_enter(twidget* mouse_over)
|
||||
|
||||
mouse_focus_ = mouse_over;
|
||||
owner_.fire(event::MOUSE_ENTER, *mouse_over);
|
||||
|
||||
hover_shown_ = false;
|
||||
start_hover_timer(mouse_over, get_mouse_position());
|
||||
}
|
||||
|
||||
void tmouse_motion::mouse_motion(twidget* mouse_over, const tpoint& coordinate)
|
||||
@ -200,6 +220,15 @@ void tmouse_motion::mouse_motion(twidget* mouse_over, const tpoint& coordinate)
|
||||
assert(mouse_over);
|
||||
|
||||
owner_.fire(event::MOUSE_MOTION, *mouse_over, coordinate);
|
||||
|
||||
if(hover_timer_) {
|
||||
if((abs(hover_position_.x - coordinate.x) > 5)
|
||||
|| (abs(hover_position_.y - coordinate.y) > 5)) {
|
||||
|
||||
stop_hover_timer();
|
||||
start_hover_timer(mouse_over, coordinate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tmouse_motion::mouse_leave()
|
||||
@ -209,6 +238,73 @@ void tmouse_motion::mouse_leave()
|
||||
owner_.fire(event::MOUSE_LEAVE, *mouse_focus_);
|
||||
|
||||
mouse_focus_ = NULL;
|
||||
|
||||
/** @todo also a bit ugly. */
|
||||
owner_.get_window()->do_remove_tooltip();
|
||||
stop_hover_timer();
|
||||
}
|
||||
|
||||
void tmouse_motion::start_hover_timer(twidget* widget, const tpoint& coordinate)
|
||||
{
|
||||
assert(widget);
|
||||
stop_hover_timer();
|
||||
|
||||
if(hover_shown_ || !widget->wants_mouse_hover()) {
|
||||
return;
|
||||
}
|
||||
|
||||
DBG_GUI_E << LOG_HEADER << "Start hover timer for widget '"
|
||||
<< widget->id() << "' at address " << widget << ".\n";
|
||||
|
||||
|
||||
hover_timer_ = SDL_AddTimer(50, hover_callback, &owner_);
|
||||
if(hover_timer_) {
|
||||
hover_widget_ = widget;
|
||||
hover_position_ = coordinate;
|
||||
} else {
|
||||
ERR_GUI_E << LOG_HEADER << "Failed to add hover timer.\n";
|
||||
}
|
||||
}
|
||||
|
||||
void tmouse_motion::stop_hover_timer()
|
||||
{
|
||||
if(hover_timer_) {
|
||||
assert(hover_widget_);
|
||||
DBG_GUI_E << LOG_HEADER << "Stop hover timer for widget '"
|
||||
<< hover_widget_->id() << "' at address "
|
||||
<< hover_widget_ << ".\n";
|
||||
|
||||
if(SDL_RemoveTimer(hover_timer_) == SDL_FALSE) {
|
||||
ERR_GUI_E << LOG_HEADER << "Failed to remove hover timer.\n";
|
||||
}
|
||||
|
||||
hover_timer_ = NULL;
|
||||
hover_widget_ = NULL;
|
||||
hover_position_ = tpoint(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void tmouse_motion::signal_handler_show_hover_tooltip(const event::tevent event)
|
||||
{
|
||||
DBG_GUI_E << LOG_HEADER << event << ".\n";
|
||||
|
||||
if(!hover_widget_) {
|
||||
ERR_GUI_E << LOG_HEADER << event << " bailing out, no hover widget.\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo See whether this code can be cleanup a bit.
|
||||
*
|
||||
* It now feels a bit hacky with all the casts. It should work but just is
|
||||
* a bit ugly.
|
||||
*/
|
||||
owner_.get_window()->do_show_tooltip(hover_position_
|
||||
, dynamic_cast<tcontrol&>(*hover_widget_).tooltip());
|
||||
hover_shown_ = true;
|
||||
|
||||
hover_timer_ = NULL;
|
||||
hover_widget_ = NULL;
|
||||
hover_position_ = tpoint(0, 0);
|
||||
}
|
||||
|
||||
/***** ***** ***** ***** tmouse_button ***** ***** ***** ***** *****/
|
||||
@ -759,6 +855,10 @@ void tdistributor::signal_handler_notify_removal(
|
||||
* functions...
|
||||
*/
|
||||
|
||||
if(hover_widget_ == &widget) {
|
||||
stop_hover_timer();
|
||||
}
|
||||
|
||||
if(tmouse_button_left::last_clicked_widget_ == &widget) {
|
||||
tmouse_button_left::last_clicked_widget_ = NULL;
|
||||
}
|
||||
|
@ -45,12 +45,12 @@
|
||||
|
||||
#include "gui/auxiliary/event/dispatcher.hpp"
|
||||
#include "gui/widgets/event_executor.hpp"
|
||||
#include "gui/widgets/helper.hpp"
|
||||
|
||||
class t_string;
|
||||
|
||||
namespace gui2{
|
||||
|
||||
struct tpoint;
|
||||
class twidget;
|
||||
|
||||
namespace event {
|
||||
@ -63,6 +63,8 @@ public:
|
||||
|
||||
tmouse_motion(twidget& owner, const tdispatcher::tposition queue_position);
|
||||
|
||||
~tmouse_motion();
|
||||
|
||||
/**
|
||||
* Captures the mouse input.
|
||||
*
|
||||
@ -83,6 +85,35 @@ protected:
|
||||
/** The widget that owns us. */
|
||||
twidget& owner_;
|
||||
|
||||
/** The timer for the hover event. */
|
||||
SDL_TimerID hover_timer_;
|
||||
|
||||
/** The widget which should get the hover event. */
|
||||
twidget* hover_widget_;
|
||||
|
||||
/** The anchor point of the hover event. */
|
||||
tpoint hover_position_;
|
||||
|
||||
/**
|
||||
* Has the hover been shown for the widget?
|
||||
*
|
||||
* A widget won't get a second hover event after the tooltip has been
|
||||
* triggered. Only after (shortly) entering another widget it will be shown
|
||||
* again for this widget.
|
||||
*/
|
||||
bool hover_shown_;
|
||||
|
||||
/**
|
||||
* Starts the hover timer.
|
||||
*
|
||||
* @param widget The widget that wants the tooltip.
|
||||
* @param coordinate The anchor coordinate.
|
||||
*/
|
||||
void start_hover_timer(twidget* widget, const tpoint& coordinate);
|
||||
|
||||
/** Stops the current hover timer. */
|
||||
void stop_hover_timer();
|
||||
|
||||
/**
|
||||
* Called when the mouse enters a widget.
|
||||
*
|
||||
@ -94,6 +125,7 @@ protected:
|
||||
void mouse_leave();
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Called when the mouse moves over a widget.
|
||||
*
|
||||
@ -108,6 +140,8 @@ private:
|
||||
, bool& handled
|
||||
, const tpoint& coordinate);
|
||||
|
||||
void signal_handler_show_hover_tooltip(const event::tevent event);
|
||||
|
||||
};
|
||||
|
||||
/***** ***** ***** ***** tmouse_button ***** ***** ***** ***** *****/
|
||||
|
@ -27,6 +27,18 @@
|
||||
|
||||
#include <cassert>
|
||||
|
||||
/**
|
||||
* @todo The items below are not implemented yet.
|
||||
*
|
||||
* - Tooltips have a fixed short time until showing up.
|
||||
* - Tooltips are shown until the widget is exited.
|
||||
* - Help messages aren't shown yet.
|
||||
*
|
||||
* @note it might be that tooltips will be shown independent of a window and in
|
||||
* their own window, therefore the code will be cleaned up after that has been
|
||||
* determined.
|
||||
*/
|
||||
|
||||
/*
|
||||
* At some point in the future this event handler should become the main event
|
||||
* handler. This switch controls the experimental switch for that change.
|
||||
@ -134,6 +146,14 @@ private:
|
||||
|
||||
/***** Handlers *****/
|
||||
|
||||
/**
|
||||
* Fires a hover event.
|
||||
*
|
||||
* @param caller The distributor for which to fire the
|
||||
* event.
|
||||
*/
|
||||
void hover(void* caller);
|
||||
|
||||
/** Fires a draw event. */
|
||||
void draw();
|
||||
|
||||
@ -257,7 +277,7 @@ void thandler::handle_event(const SDL_Event& event)
|
||||
break;
|
||||
|
||||
case HOVER_EVENT:
|
||||
// hover();
|
||||
hover(event.user.data1);
|
||||
break;
|
||||
|
||||
case HOVER_REMOVE_POPUP_EVENT:
|
||||
@ -356,6 +376,31 @@ void thandler::disconnect(tdispatcher* dispatcher)
|
||||
#endif
|
||||
}
|
||||
|
||||
void thandler::hover(void* caller)
|
||||
{
|
||||
DBG_GUI_E << "Firing: " << SHOW_HOVER_TOOLTIP << ".\n";
|
||||
|
||||
/*
|
||||
* Although the caller should be a valid widget, we won't blindly trust
|
||||
* this to be true. Instead test whether it's a valid widget before firing.
|
||||
* Since the parameter is a twidget* we need to cast the dispatcher to a
|
||||
* widget.
|
||||
*/
|
||||
|
||||
foreach(tdispatcher* dispatcher, dispatchers_) {
|
||||
twidget* widget = dynamic_cast<twidget*>(dispatcher);
|
||||
if(widget == caller) {
|
||||
assert(widget);
|
||||
dispatcher->fire(SHOW_HOVER_TOOLTIP, *widget, NULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ERR_GUI_E << "While firing " << SHOW_HOVER_TOOLTIP
|
||||
<< " encountered an invalid dispatcher address "
|
||||
<< caller << ".\n";
|
||||
}
|
||||
|
||||
void thandler::draw()
|
||||
{
|
||||
// Don't display this event since it floods the screen
|
||||
@ -624,6 +669,8 @@ std::ostream& operator<<(std::ostream& stream, const tevent event)
|
||||
case NOTIFY_REMOVAL : stream << "notify removal"; break;
|
||||
case RECEIVE_KEYBOARD_FOCUS : stream << "receive keyboard focus"; break;
|
||||
case LOSE_KEYBOARD_FOCUS : stream << "lose keyboard focus"; break;
|
||||
case SHOW_HOVER_TOOLTIP : stream << "show hover tooltip"; break;
|
||||
case REMOVE_TOOLTIP : stream << "remove tooltip"; break;
|
||||
}
|
||||
|
||||
return stream;
|
||||
|
@ -99,6 +99,8 @@ enum tevent {
|
||||
*/
|
||||
, RECEIVE_KEYBOARD_FOCUS /**< Widget gets keyboard focus. */
|
||||
, LOSE_KEYBOARD_FOCUS /**< Widget loses keyboard focus. */
|
||||
, SHOW_HOVER_TOOLTIP /**< Request to show the hover tooltip. */
|
||||
, REMOVE_TOOLTIP /**< Request to remove a tooltip. */
|
||||
};
|
||||
|
||||
/**
|
||||
@ -180,6 +182,8 @@ typedef
|
||||
boost::mpl::int_<NOTIFY_REMOVAL>
|
||||
, boost::mpl::int_<RECEIVE_KEYBOARD_FOCUS>
|
||||
, boost::mpl::int_<LOSE_KEYBOARD_FOCUS>
|
||||
, boost::mpl::int_<SHOW_HOVER_TOOLTIP>
|
||||
, boost::mpl::int_<REMOVE_TOOLTIP>
|
||||
>
|
||||
tset_event_notification;
|
||||
|
||||
|
@ -528,11 +528,13 @@ private:
|
||||
*/
|
||||
void layout_linked_widgets();
|
||||
|
||||
public:
|
||||
/** Inherited from tevent_handler. */
|
||||
void do_show_tooltip(const tpoint& location, const t_string& tooltip);
|
||||
|
||||
/** Inherited from tevent_handler. */
|
||||
void do_remove_tooltip();
|
||||
private:
|
||||
|
||||
/** Inherited from tevent_handler. */
|
||||
void do_show_help_popup(const tpoint& location, const t_string& help_popup);
|
||||
|
Loading…
x
Reference in New Issue
Block a user