[Freeciv-Dev] (PR#7171) Patch: sdl client - mouse behavior
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://bugs.freeciv.org/Ticket/Display.html?id=7171 >
> [jpliberato@xxxxxxxxx - Mo 29. Dez 2003, 15:31:28]:
>
> This patch changes the mouse behavior in the sdl
> client.
> left button -> keep pressed for a goto order. You can
> drag the mouse to change the goto location, like in
> civ3 or alpha centauri. Just click for actions like
> selecting a unit or a city.
> right button -> Open a popup menu.
> center button -> recenter screen.
>
> Joao Paulo Liberato
> jpliberato at yahoo dot com
>
> __________________________________
> Do you Yahoo!?
> New Yahoo! Photos - easier uploading and sharing.
> http://photos.yahoo.com/
>
Inspired by Joao Paulo's patch, here's another one. It implements the
"click-and-hold" feature with three hold states:
short hold: simple click (delay < 750ms)
medium hold: delay between 750ms and 2000ms
long hold: delay above 2000ms
The "long hold" state is meant for the Pocket PC interface where you
have only one 'mouse button' (tap on screen with stylus). On a desktop
PC currently the same action as in "medium hold" state is performed.
The mouse behavior with this patch is the following:
- left mouse button (short hold): usual left click action (no change)
- left mouse button (medium hold): enter goto mode, like described above
by Joao Paulo
- left mouse button (long hold): nothing/no effect on medium hold action
on desktop PC / cancel goto mode and popup the context menu on Pocket PC
unless the mouse has already been moved over another tile in goto mode
- middle mouse button (any hold state): popup context menu (no change)
- right mouse button (short hold): recenter screen (no change)
- right mouse button (medium hold): popup context menu (meant for
2-button mice)
- right mouse button (long hold): nothing/no effect on medium hold action
Index: client/gui-sdl/mapview.c
===================================================================
--- client/gui-sdl/mapview.c (Revision 11410)
+++ client/gui-sdl/mapview.c (Arbeitskopie)
@@ -55,9 +55,6 @@
#include "mapview.h"
extern SDL_Event *pFlush_User_Event;
-extern enum cursor_type mouse_cursor_type;
-extern bool mouse_cursor_changed;
-extern bool do_cursor_animation;
int OVERVIEW_START_X;
int OVERVIEW_START_Y;
Index: client/gui-sdl/gui_main.c
===================================================================
--- client/gui-sdl/gui_main.c (Revision 11411)
+++ client/gui-sdl/gui_main.c (Arbeitskopie)
@@ -58,6 +58,7 @@
#include "cityrep.h"
#include "graphics.h"
#include "gui_id.h"
+#include "gui_mem.h"
#include "gui_stuff.h" /* gui */
#include "gui_tilespec.h"
#include "inteldlg.h"
@@ -102,6 +103,9 @@
static bool autoconnect = FALSE;
static bool is_map_scrolling = FALSE;
static enum direction8 scroll_dir;
+
+static struct mouse_button_behavior button_behavior;
+
static SDL_Event *pNet_User_Event = NULL;
static SDL_Event *pAnim_User_Event = NULL;
static SDL_Event *pInfo_User_Event = NULL;
@@ -280,9 +284,19 @@
return widget_pressed_action(pWidget);
} else {
#ifdef UNDER_CE
- check_scroll_area(pButtonEvent->x, pButtonEvent->y);
+ if (!check_scroll_area(pButtonEvent->x, pButtonEvent->y)) {
#endif
- }
+ if (!button_behavior.button_down_ticks) {
+ /* start counting */
+ button_behavior.button_down_ticks = SDL_GetTicks();
+ *button_behavior.event = *pButtonEvent;
+ button_behavior.hold_state = MB_HOLD_SHORT;
+ button_behavior.ptile = canvas_pos_to_tile(pButtonEvent->x,
pButtonEvent->y);
+ }
+#ifdef UNDER_CE
+ }
+#endif
+ }
return ID_ERROR;
}
@@ -290,9 +304,12 @@
static Uint16 main_mouse_button_up_handler(SDL_MouseButtonEvent *pButtonEvent,
void *pData)
{
if (!MainWidgetListScaner(pButtonEvent->x, pButtonEvent->y)) {
- button_down_on_map(pButtonEvent);
+ *button_behavior.event = *pButtonEvent;
+ button_up_on_map(&button_behavior);
}
+ button_behavior.button_down_ticks = 0;
+
#ifdef UNDER_CE
is_map_scrolling = FALSE;
#endif
@@ -308,7 +325,18 @@
static Uint16 main_mouse_motion_handler(SDL_MouseMotionEvent *pMotionEvent,
void *pData)
{
static struct GUI *pWidget;
-
+ struct tile *ptile;
+
+ /* stop evaluating button hold time when moving to another tile in medium
+ * hold state or above */
+ if (button_behavior.hold_state >= MB_HOLD_MEDIUM) {
+ ptile = canvas_pos_to_tile(pMotionEvent->x, pMotionEvent->y);
+ if ((ptile->x != button_behavior.ptile->x)
+ || (ptile->y != button_behavior.ptile->y)) {
+ button_behavior.button_down_ticks = 0;
+ }
+ }
+
if(draw_goto_patrol_lines) {
update_line(pMotionEvent->x, pMotionEvent->y);
}
@@ -376,7 +404,28 @@
flip = !flip;
}
-
+
+ /* button pressed */
+ if (button_behavior.button_down_ticks) {
+ if (((SDL_GetTicks() - button_behavior.button_down_ticks) >=
MB_MEDIUM_HOLD_DELAY)
+ && ((SDL_GetTicks() - button_behavior.button_down_ticks) <
MB_LONG_HOLD_DELAY)) {
+
+ if (button_behavior.hold_state != MB_HOLD_MEDIUM) {
+ button_behavior.hold_state = MB_HOLD_MEDIUM;
+ button_down_on_map(&button_behavior);
+ }
+
+ } else if (((SDL_GetTicks() - button_behavior.button_down_ticks)
+ >= MB_LONG_HOLD_DELAY)) {
+
+ if (button_behavior.hold_state != MB_HOLD_LONG) {
+ button_behavior.hold_state = MB_HOLD_LONG;
+ button_down_on_map(&button_behavior);
+ }
+
+ }
+ }
+
return;
}
@@ -699,6 +748,10 @@
SDL_Surface *pBgd;
Uint32 iSDL_Flags;
+ button_behavior.button_down_ticks = 0;
+ button_behavior.hold_state = MB_HOLD_SHORT;
+ button_behavior.event = MALLOC(sizeof(SDL_MouseButtonEvent));
+
SDL_Client_Flags = 0;
iSDL_Flags = SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE;
@@ -914,6 +967,8 @@
unload_cursors();
+ FREE(button_behavior.event);
+
/* FIXME: the font system cannot be freed yet, because it is still
* needed in civclient.c for message window output */
#if 0
Index: client/gui-sdl/gui_main.h
===================================================================
--- client/gui-sdl/gui_main.h (Revision 11410)
+++ client/gui-sdl/gui_main.h (Arbeitskopie)
@@ -56,6 +56,24 @@
#define CF_DRAW_PLAYERS_ALLIANCE_STATUS (1<<22)
#define CF_DRAW_PLAYERS_NEUTRAL_STATUS (1<<23)
+/* mouse button behavior */
+#define MB_MEDIUM_HOLD_DELAY 750 /* medium hold: 750ms */
+#define MB_LONG_HOLD_DELAY 2000 /* long hold: 2000ms */
+
+enum mouse_button_hold_state {
+ MB_HOLD_SHORT,
+ MB_HOLD_MEDIUM,
+ MB_HOLD_LONG
+};
+
+struct mouse_button_behavior {
+ Uint32 button_down_ticks;
+ enum mouse_button_hold_state hold_state;
+ SDL_MouseButtonEvent *event;
+ struct tile *ptile;
+};
+
+
extern struct GUI *pSellected_Widget;
extern Uint32 SDL_Client_Flags;
extern bool LSHIFT;
@@ -66,6 +84,8 @@
extern bool do_focus_animation;
extern int city_names_font_size;
extern int city_productions_font_size;
+extern enum cursor_type mouse_cursor_type;
+extern bool mouse_cursor_changed;
void force_exit_from_event_loop(void);
void add_autoconnect_to_timer(void);
Index: client/gui-sdl/mapctrl.c
===================================================================
--- client/gui-sdl/mapctrl.c (Revision 11410)
+++ client/gui-sdl/mapctrl.c (Arbeitskopie)
@@ -26,6 +26,7 @@
/* utility */
#include "fcintl.h"
+#include "log.h"
/* common */
#include "unit.h"
@@ -1959,9 +1960,76 @@
/**************************************************************************
mouse click handler
**************************************************************************/
-void button_down_on_map(SDL_MouseButtonEvent * pButtonEvent)
+void button_down_on_map(struct mouse_button_behavior *button_behavior)
{
struct tile *ptile;
+
+ if (get_client_state() != CLIENT_GAME_RUNNING_STATE) {
+ return;
+ }
+
+ if (button_behavior->event->button == SDL_BUTTON_LEFT) {
+ switch(button_behavior->hold_state) {
+ case MB_HOLD_SHORT:
+ break;
+ case MB_HOLD_MEDIUM:
+ /* switch to goto mode */
+ key_unit_goto();
+ mouse_cursor_type = CURSOR_GOTO;
+ mouse_cursor_changed = TRUE;
+ break;
+ case MB_HOLD_LONG:
+#ifdef UNDER_CE
+ /* cancel goto mode and open context menu on Pocket PC since we have
+ * only one 'mouse button' */
+ key_cancel_action();
+ draw_goto_patrol_lines = FALSE;
+ mouse_cursor_type = CURSOR_DEFAULT;
+ mouse_cursor_changed = TRUE;
+ /* popup context menu */
+ if ((ptile = canvas_pos_to_tile((int) button_behavior->event->x,
+ (int) button_behavior->event->y))) {
+ popup_advanced_terrain_dialog(ptile);
+ }
+#endif
+ break;
+ default:
+ break;
+ }
+ } else if (button_behavior->event->button == SDL_BUTTON_MIDDLE) {
+ switch(button_behavior->hold_state) {
+ case MB_HOLD_SHORT:
+ break;
+ case MB_HOLD_MEDIUM:
+ break;
+ case MB_HOLD_LONG:
+ break;
+ default:
+ break;
+ }
+ } else if (button_behavior->event->button == SDL_BUTTON_RIGHT) {
+ switch (button_behavior->hold_state) {
+ case MB_HOLD_SHORT:
+ break;
+ case MB_HOLD_MEDIUM:
+ /* popup context menu */
+ if ((ptile = canvas_pos_to_tile((int) button_behavior->event->x,
+ (int) button_behavior->event->y))) {
+ popup_advanced_terrain_dialog(ptile);
+ }
+ break;
+ case MB_HOLD_LONG:
+ break;
+ default:
+ break;
+ }
+ }
+
+}
+
+void button_up_on_map(struct mouse_button_behavior *button_behavior)
+{
+ struct tile *ptile;
struct city *pCity;
if (get_client_state() != CLIENT_GAME_RUNNING_STATE) {
@@ -1970,40 +2038,86 @@
draw_goto_patrol_lines = FALSE;
- if (pButtonEvent->button == SDL_BUTTON_LEFT) {
- if(LSHIFT || LALT || LCTRL) {
- if ((ptile = canvas_pos_to_tile((int) pButtonEvent->x,
- (int) pButtonEvent->y))) {
- if(LSHIFT) {
- popup_advanced_terrain_dialog(ptile);
- } else {
- if(((pCity = ptile->city) != NULL) &&
- (pCity->owner == game.player_ptr)) {
- if(LCTRL) {
- popup_worklist_editor(pCity, &(pCity->worklist));
- } else {
- /* LALT - this work only with fullscreen mode */
- popup_hurry_production_dialog(pCity, NULL);
- }
- }
- }
- }
- } else {
- action_button_pressed(pButtonEvent->x, pButtonEvent->y, SELECT_POPUP);
+ if (button_behavior->event->button == SDL_BUTTON_LEFT) {
+ switch(button_behavior->hold_state) {
+ case MB_HOLD_SHORT:
+ if(LSHIFT || LALT || LCTRL) {
+ if ((ptile = canvas_pos_to_tile((int) button_behavior->event->x,
+ (int) button_behavior->event->y))) {
+ if(LSHIFT) {
+ popup_advanced_terrain_dialog(ptile);
+ } else {
+ if(((pCity = ptile->city) != NULL) &&
+ (pCity->owner == game.player_ptr)) {
+ if(LCTRL) {
+ popup_worklist_editor(pCity, &(pCity->worklist));
+ } else {
+ /* LALT - this work only with fullscreen mode */
+ popup_hurry_production_dialog(pCity, NULL);
+ }
+ }
+ }
+ }
+ } else {
+ mouse_cursor_type = CURSOR_DEFAULT;
+ mouse_cursor_changed = TRUE;
+ action_button_pressed(button_behavior->event->x,
+ button_behavior->event->y, SELECT_POPUP);
+ }
+ break;
+ case MB_HOLD_MEDIUM:
+ /* finish goto */
+ mouse_cursor_type = CURSOR_DEFAULT;
+ mouse_cursor_changed = TRUE;
+ action_button_pressed(button_behavior->event->x,
+ button_behavior->event->y, SELECT_POPUP);
+ break;
+ case MB_HOLD_LONG:
+#ifndef UNDER_CE
+ /* finish goto */
+ mouse_cursor_type = CURSOR_DEFAULT;
+ mouse_cursor_changed = TRUE;
+ action_button_pressed(button_behavior->event->x,
+ button_behavior->event->y, SELECT_POPUP);
+#endif
+ break;
+ default:
+ break;
}
- } else {
- if (pButtonEvent->button == SDL_BUTTON_MIDDLE) {
- if ((ptile = canvas_pos_to_tile((int) pButtonEvent->x,
- (int) pButtonEvent->y))) {
- popup_advanced_terrain_dialog(ptile);
- }
- } else {
- recenter_button_pressed(pButtonEvent->x, pButtonEvent->y);
- flush_dirty();
+ } else if (button_behavior->event->button == SDL_BUTTON_MIDDLE) {
+ switch(button_behavior->hold_state) {
+ case MB_HOLD_SHORT:
+/* break;*/
+ case MB_HOLD_MEDIUM:
+/* break;*/
+ case MB_HOLD_LONG:
+/* break;*/
+ default:
+ /* popup context menu */
+ if ((ptile = canvas_pos_to_tile((int) button_behavior->event->x,
+ (int) button_behavior->event->y))) {
+ popup_advanced_terrain_dialog(ptile);
+ }
+ break;
}
+ } else if (button_behavior->event->button == SDL_BUTTON_RIGHT) {
+ switch (button_behavior->hold_state) {
+ case MB_HOLD_SHORT:
+ /* recenter map */
+ recenter_button_pressed(button_behavior->event->x,
button_behavior->event->y);
+ flush_dirty();
+ break;
+ case MB_HOLD_MEDIUM:
+ break;
+ case MB_HOLD_LONG:
+ break;
+ default:
+ break;
+ }
}
+
}
-
+
/**************************************************************************
Toggle map drawing stuff.
**************************************************************************/
@@ -2015,6 +2129,8 @@
case SDLK_ESCAPE:
key_cancel_action();
draw_goto_patrol_lines = FALSE;
+ mouse_cursor_type = CURSOR_DEFAULT;
+ mouse_cursor_changed = TRUE;
return FALSE;
case SDLK_UP:
@@ -2400,7 +2516,10 @@
**************************************************************************/
void create_line_at_mouse_pos(void)
{
- update_line(Main.event.motion.x, Main.event.motion.y);
+ int pos_x, pos_y;
+
+ SDL_GetMouseState(&pos_x, &pos_y);
+ update_line(pos_x, pos_y);
draw_goto_patrol_lines = TRUE;
}
Index: client/gui-sdl/mapctrl.h
===================================================================
--- client/gui-sdl/mapctrl.h (Revision 11410)
+++ client/gui-sdl/mapctrl.h (Arbeitskopie)
@@ -73,6 +73,8 @@
void enable_main_widgets(void);
void disable_main_widgets(void);
bool map_event_handler(SDL_keysym Key);
-void button_down_on_map(SDL_MouseButtonEvent * pButtonEvent);
+void button_down_on_map(struct mouse_button_behavior *button_behavior);
+void button_up_on_map(struct mouse_button_behavior *button_behavior);
+
#endif /* FC__MAPCTRL_H */
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Freeciv-Dev] (PR#7171) Patch: sdl client - mouse behavior,
Christian Prochaska <=
|
|