/* horizon, a sketch, note and scribbling application. Copyright (C) 2005 Øyvind Kolås 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; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include "config.h" #include "actions.h" #include "canvas/canvas.h" #include "toolkit/box.h" #include "tools/tool_library.h" #include "vectors/font.h" #include "teleport.h" static gboolean action_refresh (Horizon *horizon) { tool_flush (get_current_tool ()); canvas_update_zoom (horizon->canvas); box_render (horizon->root); views_flush (); canvas_flush_dirty (horizon->canvas); return TRUE; } static gboolean action_toggle_fullscreen (Horizon *horizon) { gint ratio; ratio = box_get_ratio (horizon->root); if (ratio == 65536) { box_set_ratio (horizon->root, 0.85 * 65536); } else { box_set_ratio (horizon->root, 65536); } return TRUE; } static gboolean action_zoom_in (Horizon *horizon) { gint scale = view_get_scale ((View*)horizon->easel); if (scale * (65536.0 * ZOOM_IN) / 65536.0 < ZOOM_MAX) scale = scale * (65536.0 * ZOOM_IN) / 65536.0; if (scale > 65536 - 100&& scale < 65536 + 100) scale = 65536; view_set_center_scale ((View*)horizon->easel, scale); return TRUE; } static gboolean action_zoom_out (Horizon *horizon) { gint scale = view_get_scale ((View*)horizon->easel); if (scale * (65536.0 * ZOOM_OUT) / 65536.0 > ZOOM_MIN) { scale = scale * (65536.0 * ZOOM_OUT) / 65536.0; } if (scale > 65536 - 100&& scale < 65536 + 100) scale = 65536; view_set_center_scale ((View*)horizon->easel, scale); return TRUE; } static gboolean action_pan_left (Horizon *horizon) { gint scale = view_get_scale ((View*)horizon->easel); view_set_x ((View*)horizon->easel, view_get_x ((View*)horizon->easel) - box_get_width ((Box*)horizon->easel) / 4 * 65536 / scale); return TRUE; } static gboolean action_pan_right (Horizon *horizon) { gint scale = view_get_scale ((View*)horizon->easel); view_set_x ((View*)horizon->easel, view_get_x ((View*)horizon->easel) + box_get_width ((Box*)horizon->easel) / 4 * 65536 / scale); return TRUE; } static gboolean action_pan_up (Horizon *horizon) { gint scale = view_get_scale ((View*)horizon->easel); view_set_y ((View*)horizon->easel, view_get_y ((View*)horizon->easel) - box_get_height ((Box*)horizon->easel) / 4 * 65536 / scale); return TRUE; } static gboolean action_pan_down (Horizon *horizon) { gint scale = view_get_scale ((View*)horizon->easel); view_set_y ((View*)horizon->easel, view_get_y ((View*)horizon->easel) + box_get_height ((Box*)horizon->easel) / 4 * 65536 / scale); return TRUE; } static gboolean action_undo (Horizon *horizon) { undo_stack_undo (horizon->undo_stack); return TRUE; } static gboolean action_redo (Horizon *horizon) { undo_stack_redo (horizon->undo_stack); return TRUE; } static gboolean action_select_tool_nav (Horizon *horizon) { tool_library_set_tool (lookup_tool("Nav")); return TRUE; } static gboolean action_save_position (Horizon *horizon) { FILE *file; char path[512]; sprintf (path, "%s/position", horizon->storage_path); file = fopen (path, "w"); fprintf (file, "%li %li %i\n", view_get_x ((View*)horizon->easel), view_get_y ((View*)horizon->easel), view_get_scale ((View*)horizon->easel)); fclose (file); return FALSE; } static gboolean action_restore_position (Horizon *horizon) { FILE *file; char path[512]; sprintf (path, "%s/position", horizon->storage_path); file = fopen (path, "r"); if (file) { glong x, y; gint scale; if (fscanf (file, "%li %li %i\n", &x, &y, &scale)) { view_set_x ((View*)horizon->easel, x); view_set_y ((View*)horizon->easel, y); view_set_scale ((View*)horizon->easel, scale); } fclose (file); } return TRUE; } static gboolean action_initial_teleport (Horizon *horizon) { gint x, y, scale; x = view_get_center_x ((View*)horizon->easel); y = view_get_center_y ((View*)horizon->easel); scale = view_get_scale ((View*)horizon->easel); view_set_center_scale ((View*)horizon->easel, 65535/8); view_set_center_x ((View*)horizon->easel, 65535); view_set_center_y ((View*)horizon->easel, 65535); horizon_teleport (horizon, x, y, 65536/8, 2000); horizon_teleport (horizon, x, y, scale, 2000); return TRUE; } static gboolean action_quit (Horizon *horizon) { horizon->quit = TRUE; return TRUE; } static gboolean action_change_mode (Horizon *horizon) { Tool *tool = get_current_tool (); if (tool->change_mode) tool->change_mode (tool); tool = NULL; return TRUE; } static char about_text[]= "Welcome to horizon"; static gboolean action_splash (Horizon *horizon) { HorizonFont *font = font_new (); Canvas *canvas = horizon->canvas; Path *path = NULL; font_set_size (font, 30); path = font_path (font, NULL, (65536 + 50) * SPP, (65536 + 100) * SPP, 0, about_text); path_set_rgba (path, 0,0,0, 65536 * 0.1); path_set_hardness (path, 65536 * 0.08); path_set_line_width (path, 65536 * 0.8); path_stroke (path, canvas); path_set_rgba (path, 65536, 65536, 65536, 65536 * 0.6); path_set_line_width (path, 65536 * 0.2); path_stroke (path, canvas); path_set_rgba (path, 65536 * 0.6, 65536 * 0.8, 65536 * 1.0, 65536 * 0.6); path_set_line_width (path, 65536 * 0.08); path_stroke (path, canvas); path=path_destroy (path); font_destroy (font); return TRUE; } static gint w_x = (65536 + 50) * SPP; static gint w_y = (65536 + 180) * SPP; static gint w_width = 500 * SPP; static void w_move_to (gint x, gint y, gint width) { w_x = x * SPP; w_y = y * SPP; w_width = width * SPP; } #define w(ascii)\ {\ HorizonFont *font = font_new ();\ Path *path = NULL;\ \ font_set_size (font, 14); \ path = font_path (font, path, w_x, w_y, w_width, ascii);\ path_set_rgba (path, 0,0,0, 65536 * 0.4);\ path_set_line_width (path, 65536 * 0.04);\ path_set_hardness (path, 65536 * 0.1);\ path_stroke (path, canvas);\ w_y = path_last_y (path);\ path_destroy (path);\ font_destroy (font);\ action (horizon, "refresh");\ } static gboolean action_welcome (Horizon *horizon) { Canvas *canvas = horizon->canvas; undo_stack_freeze (horizon->undo_stack); action (horizon, "splash"); action (horizon, "refresh"); w_move_to (65536 + 50, 65536 + 120, 400); w ("\n\nThe user interface\n\n"); w ("This is written on your canvas, to the upper right of your screen are tools you can select and use to manipulate the the canvas. Below the tools is a tool specific region providing further options. This is the initial contents of the canvas, horizon will restart in the location of the canvas you left.\n"); w ("\n\nThe tools:\n\n"); w ("Paint: writing scribbling and painting on the canvas, allows adjusting virtual brush, and has a palette for picking colors. The select button toggles between painting and color picking mode, this is indicated by the symbol next to the pallette.\n"); w ("Erase: a predefined paint tool that only paints with white, has it's own seperate brush settings as well\n"); w ("Nav: allows dragging around the canvas as well as seeing the context of the current region in a scaled down view.\n"); w ("Clone: Paint with the source data coming from a different region of the canvas. Use select/return to change between set source and clone.\n"); w ("Link: create hyperlinked thumbnails that can be followed in with the nav tool\n"); w ("File: import and export of rectangular regions. Exported files are called horizon-???.png and are stored on your memory card. PNG and and Jpeg files on the memory card can be imported, combining import and export you can do copy/paste. Both import and export can be triggered by using the select key.\n"); w ("\n\nZoom:\n\n"); w ("Zooming is done either with shortcut keys or by using the Nav tool\n"); w ("The brush size is zoom sensitive.\n"); w ("\n\nKeybindings:\n\n"); { gint i; for (i=0; actions[i].keysym; i++) { char buf[512]; sprintf (buf, "%s", actions[i].keysym); w (buf); sprintf (buf, " %s\n", actions[i].name); w (buf); } } w ("\n\nAbout this text\n\n"); w ("This text might be rewritten by horizon in later versions, keep important data away from this text ;)\n"); w ("\n\nCopyright\n\n"); w ("Horizon in the current release is released under the GNU GPL 2.0 or any later version of that license, the source is available from GNOME CVS in the module horizon.\n"); w ("\n\nAuthors\n\n"); w ("O '"); w ("/yvind Kolas"); w (" \n"); w ("Eero Tanskanen"); w (" \n"); w ("Cody Russell"); w (" \n"); undo_stack_thaw (horizon->undo_stack); return TRUE; } Action actions[] = { {"F4", "select_tool_nav", action_select_tool_nav}, {"Left", "pan_left", action_pan_left}, {"Right", "pan_right", action_pan_right}, {"Up", "pan_up", action_pan_up}, {"Down", "pan_down", action_pan_down}, {"F7", "zoom_in", action_zoom_in}, {"F8", "zoom_out", action_zoom_out}, {"F5", "quit", action_quit}, {"F6", "toggle_fullscreen",action_toggle_fullscreen}, {"Escape", "undo", action_undo}, {"q", "quit", action_quit}, {"Return", "change_mode", action_change_mode}, {"space", "change_mode", action_change_mode}, {"r", "redo", action_redo}, {"h", "restore_position", action_restore_position}, {"s", "splash", action_splash}, {"o", "refresh", action_refresh}, {"w", "welcome", action_welcome}, /* unbound actions */ {NULL, "initial_teleport", action_initial_teleport}, {NULL, "save_position", action_save_position}, {NULL, NULL, NULL} }; gboolean action (Horizon *horizon, gchar *action) { gint i; for (i=0; actions[i].name != NULL; i++) { if (!strcmp (actions[i].name, action)) return actions[i].action(horizon); } g_warning ("unknown action '%s'", action); return FALSE; }