#include "vikmapslayer.h"
#include "geonamessearch.h"
#include "vikutils.h"
+#include "dir.h"
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
/* End Drawing Functions */
+static void toggle_draw_scale ( GtkAction *a, VikWindow *vw );
+static void toggle_draw_centermark ( GtkAction *a, VikWindow *vw );
+static void toggle_draw_highlight ( GtkAction *a, VikWindow *vw );
+
static void menu_addlayer_cb ( GtkAction *a, VikWindow *vw );
static void menu_properties_cb ( GtkAction *a, VikWindow *vw );
static void menu_delete_layer_cb ( GtkAction *a, VikWindow *vw );
gboolean show_toolbar;
gboolean show_main_menu;
+ gboolean select_move;
gboolean pan_move;
gint pan_x, pan_y;
gint delayed_pan_x, delayed_pan_y; // Temporary storage
*/
void vik_window_statusbar_update ( VikWindow *vw, const gchar* message, vik_statusbar_type_t vs_type )
{
+ GThread *thread = vik_window_get_thread ( vw );
+ if ( !thread )
+ // Do nothing
+ return;
+
statusbar_idle_data *sid = g_malloc ( sizeof (statusbar_idle_data) );
sid->vs = vw->viking_vs;
sid->vs_type = vs_type;
sid->message = g_strdup ( message );
- if ( g_thread_self() == vik_window_get_thread ( vw ) ) {
+ if ( g_thread_self() == thread ) {
g_idle_add ( (GSourceFunc) statusbar_idle_update, sid );
}
else {
vik_statusbar_set_message ( vw->viking_vs, VIK_STATUSBAR_INFO, _("Trying to determine location...") );
- a_background_thread ( GTK_WINDOW(vw),
+ a_background_thread ( BACKGROUND_POOL_REMOTE,
+ GTK_WINDOW(vw),
_("Determining location"),
(vik_thr_func) determine_location_thread,
vw,
GtkWidget *aw = gtk_menu_get_active ( GTK_MENU (menushell) );
gint active = GPOINTER_TO_INT(g_object_get_data ( G_OBJECT (aw), "position" ));
- gdouble zoom_request = pow (2, active-2 );
+ gdouble zoom_request = pow (2, active-5 );
// But has it really changed?
gdouble current_zoom = vik_viewport_get_zoom ( vw->viking_vvp );
static GtkWidget *create_zoom_menu_all_levels ( gdouble mpp )
{
GtkWidget *menu = gtk_menu_new ();
- char *itemLabels[] = { "0.25", "0.5", "1", "2", "4", "8", "16", "32", "64", "128", "256", "512", "1024", "2048", "4096", "8192", "16384", "32768" };
+ char *itemLabels[] = { "0.031", "0.063", "0.125", "0.25", "0.5", "1", "2", "4", "8", "16", "32", "64", "128", "256", "512", "1024", "2048", "4096", "8192", "16384", "32768" };
int i;
for (i = 0 ; i < G_N_ELEMENTS(itemLabels) ; i++)
g_object_set_data (G_OBJECT (item), "position", GINT_TO_POINTER(i));
}
- gint active = 2 + round ( log (mpp) / log (2) );
+ gint active = 5 + round ( log (mpp) / log (2) );
// Ensure value derived from mpp is in bounds of the menu
if ( active >= G_N_ELEMENTS(itemLabels) )
active = G_N_ELEMENTS(itemLabels) - 1;
#define VIK_SETTINGS_WIN_SAVE_IMAGE_PNG "window_save_image_as_png"
#define VIK_SETTINGS_WIN_COPY_CENTRE_FULL_FORMAT "window_copy_centre_full_format"
+#define VIKING_ACCELERATOR_KEY_FILE "keys.rc"
+
static void vik_window_init ( VikWindow *vw )
{
vw->action_group = NULL;
vw->loaded_type = LOAD_TYPE_READ_FAILURE; //AKA none
vw->modified = FALSE;
vw->only_updating_coord_mode_ui = FALSE;
-
+
+ vw->select_move = FALSE;
vw->pan_move = FALSE;
vw->pan_x = vw->pan_y = -1;
vw->single_click_pending = FALSE;
center_changed_cb ( vw );
vw->hpaned = gtk_hpaned_new ();
- gtk_paned_pack1 ( GTK_PANED(vw->hpaned), GTK_WIDGET (vw->viking_vlp), FALSE, FALSE );
+ gtk_paned_pack1 ( GTK_PANED(vw->hpaned), GTK_WIDGET (vw->viking_vlp), FALSE, TRUE );
gtk_paned_pack2 ( GTK_PANED(vw->hpaned), GTK_WIDGET (vw->viking_vvp), TRUE, TRUE );
/* This packs the button into the window (a gtk container). */
// Set the default tool + mode
gtk_action_activate ( gtk_action_group_get_action ( vw->action_group, "Pan" ) );
gtk_action_activate ( gtk_action_group_get_action ( vw->action_group, "ModeMercator" ) );
+
+ gchar *accel_file_name = g_build_filename ( a_get_viking_dir(), VIKING_ACCELERATOR_KEY_FILE, NULL );
+ gtk_accel_map_load ( accel_file_name );
+ g_free ( accel_file_name );
}
static VikWindow *window_new ()
a_settings_set_integer ( VIK_SETTINGS_WIN_SAVE_IMAGE_WIDTH, vw->draw_image_width );
a_settings_set_integer ( VIK_SETTINGS_WIN_SAVE_IMAGE_HEIGHT, vw->draw_image_height );
a_settings_set_boolean ( VIK_SETTINGS_WIN_SAVE_IMAGE_PNG, vw->draw_image_save_as_png );
+
+ gchar *accel_file_name = g_build_filename ( a_get_viking_dir(), VIKING_ACCELERATOR_KEY_FILE, NULL );
+ gtk_accel_map_save ( accel_file_name );
+ g_free ( accel_file_name );
}
return FALSE;
ck->cont = !vik_layer_get_interface(vl->type)->select_click ( vl, ck->event, ck->vvp, ck->tool_edit );
}
+#ifdef WINDOWS
+// Hopefully Alt keys by default
+#define VIK_MOVE_MODIFIER GDK_MOD1_MASK
+#else
+// Alt+mouse on Linux desktops tend to be used by the desktop manager
+// Thus use an alternate modifier - you may need to set something into this group
+#define VIK_MOVE_MODIFIER GDK_MOD5_MASK
+#endif
+
static VikLayerToolFuncStatus selecttool_click (VikLayer *vl, GdkEventButton *event, tool_ed_t *t)
{
+ t->vw->select_move = FALSE;
/* Only allow selection on primary button */
if ( event->button == 1 ) {
- /* Enable click to apply callback to potentially all track/waypoint layers */
- /* Useful as we can find things that aren't necessarily in the currently selected layer */
- GList* gl = vik_layers_panel_get_all_layers_of_type ( t->vw->viking_vlp, VIK_LAYER_TRW, FALSE ); // Don't get invisible layers
- clicker ck;
- ck.cont = TRUE;
- ck.vvp = t->vw->viking_vvp;
- ck.event = event;
- ck.tool_edit = t;
- g_list_foreach ( gl, (GFunc) click_layer_selected, &ck );
- g_list_free ( gl );
-
- // If nothing found then deselect & redraw screen if necessary to remove the highlight
- if ( ck.cont ) {
- GtkTreeIter iter;
- VikTreeview *vtv = vik_layers_panel_get_treeview ( t->vw->viking_vlp );
-
- if ( vik_treeview_get_selected_iter ( vtv, &iter ) ) {
- // Only clear if selected thing is a TrackWaypoint layer or a sublayer
- gint type = vik_treeview_item_get_type ( vtv, &iter );
- if ( type == VIK_TREEVIEW_TYPE_SUBLAYER ||
- VIK_LAYER(vik_treeview_item_get_pointer ( vtv, &iter ))->type == VIK_LAYER_TRW ) {
+
+ if ( event->state & VIK_MOVE_MODIFIER )
+ vik_window_pan_click ( t->vw, event );
+ else {
+ /* Enable click to apply callback to potentially all track/waypoint layers */
+ /* Useful as we can find things that aren't necessarily in the currently selected layer */
+ GList* gl = vik_layers_panel_get_all_layers_of_type ( t->vw->viking_vlp, VIK_LAYER_TRW, FALSE ); // Don't get invisible layers
+ clicker ck;
+ ck.cont = TRUE;
+ ck.vvp = t->vw->viking_vvp;
+ ck.event = event;
+ ck.tool_edit = t;
+ g_list_foreach ( gl, (GFunc) click_layer_selected, &ck );
+ g_list_free ( gl );
+
+ // If nothing found then deselect & redraw screen if necessary to remove the highlight
+ if ( ck.cont ) {
+ GtkTreeIter iter;
+ VikTreeview *vtv = vik_layers_panel_get_treeview ( t->vw->viking_vlp );
+
+ if ( vik_treeview_get_selected_iter ( vtv, &iter ) ) {
+ // Only clear if selected thing is a TrackWaypoint layer or a sublayer
+ gint type = vik_treeview_item_get_type ( vtv, &iter );
+ if ( type == VIK_TREEVIEW_TYPE_SUBLAYER ||
+ VIK_LAYER(vik_treeview_item_get_pointer ( vtv, &iter ))->type == VIK_LAYER_TRW ) {
- vik_treeview_item_unselect ( vtv, &iter );
- if ( vik_window_clear_highlight ( t->vw ) )
- draw_update ( t->vw );
- }
+ vik_treeview_item_unselect ( vtv, &iter );
+ if ( vik_window_clear_highlight ( t->vw ) )
+ draw_update ( t->vw );
+ }
+ }
+ }
+ else {
+ // Something found - so enable movement
+ t->vw->select_move = TRUE;
}
}
}
return VIK_LAYER_TOOL_ACK;
}
-static VikLayerToolFuncStatus selecttool_move (VikLayer *vl, GdkEventButton *event, tool_ed_t *t)
+static VikLayerToolFuncStatus selecttool_move (VikLayer *vl, GdkEventMotion *event, tool_ed_t *t)
{
- /* Only allow selection on primary button */
- if ( event->button == 1 ) {
+ if ( t->vw->select_move ) {
// Don't care about vl here
if ( t->vtl )
if ( vik_layer_get_interface(VIK_LAYER_TRW)->select_move )
- vik_layer_get_interface(VIK_LAYER_TRW)->select_move ( vl, event, t->vvp, t );
+ vik_layer_get_interface(VIK_LAYER_TRW)->select_move ( vl, event, t->vvp, t );
}
+ else
+ // Optional Panning
+ if ( event->state & VIK_MOVE_MODIFIER )
+ vik_window_pan_move ( t->vw, event );
+
return VIK_LAYER_TOOL_ACK;
}
static VikLayerToolFuncStatus selecttool_release (VikLayer *vl, GdkEventButton *event, tool_ed_t *t)
{
- /* Only allow selection on primary button */
- if ( event->button == 1 ) {
+ if ( t->vw->select_move ) {
// Don't care about vl here
if ( t->vtl )
if ( vik_layer_get_interface(VIK_LAYER_TRW)->select_release )
- vik_layer_get_interface(VIK_LAYER_TRW)->select_release ( (VikLayer*)t->vtl, event, t->vvp, t );
+ vik_layer_get_interface(VIK_LAYER_TRW)->select_release ( (VikLayer*)t->vtl, event, t->vvp, t );
}
+
+ if ( event->button == 1 && (event->state & VIK_MOVE_MODIFIER) )
+ vik_window_pan_release ( t->vw, event );
+
+ // Force pan off incase it was on
+ t->vw->pan_move = FALSE;
+ t->vw->pan_x = t->vw->pan_y = -1;
+
+ // End of this select movement
+ t->vw->select_move = FALSE;
+
return VIK_LAYER_TOOL_ACK;
}
g_free ( msg );
}
+static void back_forward_info_cb ( GtkAction *a, VikWindow *vw )
+{
+ vik_viewport_show_centers ( vw->viking_vvp, GTK_WINDOW(vw) );
+}
+
static void menu_delete_layer_cb ( GtkAction *a, VikWindow *vw )
{
if ( vik_layers_panel_get_selected ( vw->viking_vlp ) )
vw->only_updating_coord_mode_ui = FALSE;
vik_layers_panel_change_coord_mode ( vw->viking_vlp, vik_viewport_get_coord_mode ( vw->viking_vvp ) );
-
- mode_button = gtk_ui_manager_get_widget ( vw->uim, "/ui/MainMenu/View/SetShow/ShowScale" );
- g_assert ( mode_button );
- gtk_check_menu_item_set_active ( GTK_CHECK_MENU_ITEM(mode_button),vik_viewport_get_draw_scale(vw->viking_vvp) );
- mode_button = gtk_ui_manager_get_widget ( vw->uim, "/ui/MainMenu/View/SetShow/ShowCenterMark" );
- g_assert ( mode_button );
- gtk_check_menu_item_set_active ( GTK_CHECK_MENU_ITEM(mode_button),vik_viewport_get_draw_centermark(vw->viking_vvp) );
-
- mode_button = gtk_ui_manager_get_widget ( vw->uim, "/ui/MainMenu/View/SetShow/ShowHighlight" );
- g_assert ( mode_button );
- gtk_check_menu_item_set_active ( GTK_CHECK_MENU_ITEM(mode_button),vik_viewport_get_draw_highlight (vw->viking_vvp) );
+ // Slightly long winded methods to align loaded viewport settings with the UI
+ // Since the rewrite for toolbar + menu actions
+ // there no longer exists a simple way to directly change the UI to a value for toggle settings
+ // it only supports toggling the existing setting (otherwise get infinite loops in trying to align tb+menu elements)
+ // Thus get state, compare them, if different then invert viewport setting and (re)sync the setting (via toggling)
+ gboolean vp_state_scale = vik_viewport_get_draw_scale ( vw->viking_vvp );
+ gboolean ui_state_scale = gtk_check_menu_item_get_active ( GTK_CHECK_MENU_ITEM(get_show_widget_by_name(vw, "ShowScale")) );
+ if ( vp_state_scale != ui_state_scale ) {
+ vik_viewport_set_draw_scale ( vw->viking_vvp, !vp_state_scale );
+ toggle_draw_scale ( NULL, vw );
+ }
+ gboolean vp_state_centermark = vik_viewport_get_draw_centermark ( vw->viking_vvp );
+ gboolean ui_state_centermark = gtk_check_menu_item_get_active ( GTK_CHECK_MENU_ITEM(get_show_widget_by_name(vw, "ShowCenterMark")) );
+ if ( vp_state_centermark != ui_state_centermark ) {
+ vik_viewport_set_draw_centermark ( vw->viking_vvp, !vp_state_centermark );
+ toggle_draw_centermark ( NULL, vw );
+ }
+ gboolean vp_state_highlight = vik_viewport_get_draw_highlight ( vw->viking_vvp );
+ gboolean ui_state_highlight = gtk_check_menu_item_get_active ( GTK_CHECK_MENU_ITEM(get_show_widget_by_name(vw, "ShowHighlight")) );
+ if ( vp_state_highlight != ui_state_highlight ) {
+ vik_viewport_set_draw_highlight ( vw->viking_vvp, !vp_state_highlight );
+ toggle_draw_highlight ( NULL, vw );
+ }
}
// NB No break, carry on to redraw
//case LOAD_TYPE_OTHER_SUCCESS:
}
}
-static void set_draw_scale ( GtkAction *a, VikWindow *vw )
+static void toggle_draw_scale ( GtkAction *a, VikWindow *vw )
{
gboolean state = !vik_viewport_get_draw_scale ( vw->viking_vvp );
GtkWidget *check_box = gtk_ui_manager_get_widget ( vw->uim, "/ui/MainMenu/View/SetShow/ShowScale" );
draw_update ( vw );
}
-static void set_draw_centermark ( GtkAction *a, VikWindow *vw )
+static void toggle_draw_centermark ( GtkAction *a, VikWindow *vw )
{
gboolean state = !vik_viewport_get_draw_centermark ( vw->viking_vvp );
GtkWidget *check_box = gtk_ui_manager_get_widget ( vw->uim, "/ui/MainMenu/View/SetShow/ShowCenterMark" );
draw_update ( vw );
}
-static void set_draw_highlight ( GtkAction *a, VikWindow *vw )
+static void toggle_draw_highlight ( GtkAction *a, VikWindow *vw )
{
- gboolean next_state = !vik_viewport_get_draw_highlight ( vw->viking_vvp );
- GtkWidget *check_box = get_show_widget_by_name ( vw, gtk_action_get_name(a) );
- if ( !check_box )
- return;
- gboolean menu_state = gtk_check_menu_item_get_active ( GTK_CHECK_MENU_ITEM(check_box) );
- if ( next_state != menu_state )
- gtk_check_menu_item_set_active ( GTK_CHECK_MENU_ITEM(check_box), next_state );
- else {
- vik_viewport_set_draw_highlight ( vw->viking_vvp, next_state );
- draw_update ( vw );
- }
-/*
gboolean state = !vik_viewport_get_draw_highlight ( vw->viking_vvp );
GtkWidget *check_box = gtk_ui_manager_get_widget ( vw->uim, "/ui/MainMenu/View/SetShow/ShowHighlight" );
if ( !check_box )
return;
gtk_check_menu_item_set_active ( GTK_CHECK_MENU_ITEM(check_box), state );
- */
+ vik_viewport_set_draw_highlight ( vw->viking_vvp, state );
+ draw_update ( vw );
}
static void set_bg_color ( GtkAction *a, VikWindow *vw )
static GtkActionEntry debug_entries[] = {
{ "MapCacheInfo", NULL, "_Map Cache Info", NULL, NULL, (GCallback)help_cache_info_cb },
+ { "BackForwardInfo", NULL, "_Back/Forward Info", NULL, NULL, (GCallback)back_forward_info_cb },
};
static GtkActionEntry entries_gpsbabel[] = {
};
static GtkToggleActionEntry toggle_entries[] = {
- { "ShowScale", NULL, N_("Show _Scale"), "<shift>F5", N_("Show Scale"), (GCallback)set_draw_scale, TRUE },
- { "ShowCenterMark", NULL, N_("Show _Center Mark"), "F6", N_("Show Center Mark"), (GCallback)set_draw_centermark, TRUE },
- { "ShowHighlight", GTK_STOCK_UNDERLINE, N_("Show _Highlight"), "F7", N_("Show Highlight"), (GCallback)set_draw_highlight, TRUE },
+ { "ShowScale", NULL, N_("Show _Scale"), "<shift>F5", N_("Show Scale"), (GCallback)toggle_draw_scale, TRUE },
+ { "ShowCenterMark", NULL, N_("Show _Center Mark"), "F6", N_("Show Center Mark"), (GCallback)toggle_draw_centermark, TRUE },
+ { "ShowHighlight", GTK_STOCK_UNDERLINE, N_("Show _Highlight"), "F7", N_("Show Highlight"), (GCallback)toggle_draw_highlight, TRUE },
{ "FullScreen", GTK_STOCK_FULLSCREEN, N_("_Full Screen"), "F11", N_("Activate full screen mode"), (GCallback)full_screen_cb, FALSE },
{ "ViewSidePanel", GTK_STOCK_INDEX, N_("Show Side _Panel"), "F9", N_("Show Side Panel"), (GCallback)view_side_panel_cb, TRUE },
{ "ViewStatusBar", NULL, N_("Show Status_bar"), "F12", N_("Show Statusbar"), (GCallback)view_statusbar_cb, TRUE },
gtk_action_group_add_radio_actions (action_group, mode_entries, G_N_ELEMENTS (mode_entries), 4, (GCallback)window_change_coord_mode_cb, window);
if ( vik_debug ) {
if ( gtk_ui_manager_add_ui_from_string ( uim,
- "<ui><menubar name='MainMenu'><menu action='Help'><menuitem action='MapCacheInfo'/></menu></menubar></ui>",
+ "<ui><menubar name='MainMenu'><menu action='Help'>"
+ "<menuitem action='MapCacheInfo'/>"
+ "<menuitem action='BackForwardInfo'/>"
+ "</menu></menubar></ui>",
-1, NULL ) ) {
gtk_action_group_add_actions (action_group, debug_entries, G_N_ELEMENTS (debug_entries), window);
}
return need_redraw;
}
+/**
+ * May return NULL if the window no longer exists
+ */
GThread *vik_window_get_thread ( VikWindow *vw )
{
- return vw->thread;
+ if ( vw )
+ return vw->thread;
+ return NULL;
}