/* $Id: guppi-pie-tool.c,v 1.13 2001/08/26 03:04:35 trow Exp $ */ /* * guppi-pie-tool.c * * Copyright (C) 2000 EMC Capital Management, Inc. * * Developed by Jon Trowbridge . * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA */ #include #include #include #include #include #include #include #include #include "guppi-pie-tool.h" #include "guppi-pie-state.h" #include "guppi-pie-view.h" #include "guppi-pie-item.h" static void explode_all_first_cb (GuppiPlotTool *tool, GuppiCanvasItem *gci) { guppi_element_state_get (guppi_canvas_item_state (gci), "base_offset", &tool->arg1, NULL); } static void explode_all_cb (GuppiPlotTool *tool, GuppiCanvasItem *gci) { gint cx0, cy0, cx1, cy1; double cx, cy, dx, dy; double ux, uy; double r, t; guppi_canvas_item_get_bbox_c (gci, &cx0, &cy0, &cx1, &cy1); cx = (cx0 + cx1) / 2.0; cy = (cy0 + cy1) / 2.0; ux = tool->raw_start_x - cx; uy = tool->raw_start_y - cy; r = sqrt (ux * ux + uy * uy); ux /= r; uy /= r; dx = tool->raw_x - tool->raw_start_x; dy = tool->raw_y - tool->raw_start_y; t = (dx * ux + dy * uy); t = (guppi_x_px2pt (t) + guppi_y_px2pt (t)) / 2; guppi_element_state_set (guppi_canvas_item_state (gci), "base_offset", tool->arg1 + t, NULL); } GuppiPlotTool * guppi_pie_tool_new_explode_all (void) { GuppiPlotTool *tool; tool = guppi_plot_tool_new (); tool->name = guppi_strdup (_("Explode All")); tool->supported_type = GUPPI_TYPE_PIE_ITEM; tool->cursor = gdk_cursor_new (GDK_FLEUR); tool->tracks_motion = TRUE; tool->repeating = FALSE; tool->first = explode_all_first_cb; tool->middle = explode_all_cb; return tool; } /***************************************************************************/ static void pick_slice (GuppiPlotTool *tool, GuppiCanvasItem *gci) { gint slice; if (tool->int_arg1) return; if (guppi_pie_item_in_slice (GUPPI_PIE_ITEM (gci), tool->raw_x, tool->raw_y, &slice)) { GuppiPieState *state = GUPPI_PIE_STATE (guppi_canvas_item_state (gci)); tool->int_arg1 = 1; tool->int_arg2 = slice; tool->arg1 = guppi_pie_state_slice_offset (state, slice); } } static void explode_slice_first_cb (GuppiPlotTool * tool, GuppiCanvasItem * gci) { tool->int_arg1 = 0; pick_slice (tool, gci); } static void explode_slice_cb (GuppiPlotTool * tool, GuppiCanvasItem * gci) { GuppiPieState *state = GUPPI_PIE_STATE (guppi_canvas_item_state (gci)); gint cx0, cy0, cx1, cy1; double cx, cy, dx, dy; double ux, uy; double r, t; if (tool->int_arg1 == 0) { pick_slice (tool, gci); return; } guppi_canvas_item_get_bbox_c (gci, &cx0, &cy0, &cx1, &cy1); cx = (cx0 + cx1) / 2.0; cy = (cy0 + cy1) / 2.0; ux = tool->raw_start_x - cx; uy = tool->raw_start_y - cy; r = sqrt (ux * ux + uy * uy); ux /= r; uy /= r; dx = tool->raw_x - tool->raw_start_x; dy = tool->raw_y - tool->raw_start_y; t = (dx * ux + dy * uy); t = (guppi_x_px2pt (t) + guppi_y_px2pt (t)) / 2; guppi_pie_state_set_slice_offset (state, tool->int_arg2, tool->arg1 + t); guppi_element_state_changed (GUPPI_ELEMENT_STATE (state)); } GuppiPlotTool * guppi_pie_tool_new_explode_slice (void) { GuppiPlotTool *tool; tool = guppi_plot_tool_new (); tool->name = guppi_strdup (_("Explode Slice")); tool->supported_type = GUPPI_TYPE_PIE_ITEM; tool->cursor = gdk_cursor_new (GDK_FLEUR); tool->tracks_motion = TRUE; tool->repeating = FALSE; tool->first = explode_slice_first_cb; tool->middle = explode_slice_cb; return tool; } /***************************************************************************/ static void change_radius_first_cb (GuppiPlotTool * tool, GuppiCanvasItem * gci) { GuppiPieView *view = GUPPI_PIE_VIEW (guppi_canvas_item_view (gci)); guppi_element_state_get (guppi_canvas_item_state (gci), "radius", &tool->arg1, NULL); tool->arg2 = guppi_pie_view_max_radius (view); } static void change_radius_cb (GuppiPlotTool * tool, GuppiCanvasItem * gci) { gint cx0, cy0, cx1, cy1; double cx, cy, dx, dy; double ux, uy; double r, t; guppi_canvas_item_get_bbox_c (gci, &cx0, &cy0, &cx1, &cy1); cx = (cx0 + cx1) / 2.0; cy = (cy0 + cy1) / 2.0; ux = tool->raw_start_x - cx; uy = tool->raw_start_y - cy; r = sqrt (ux * ux + uy * uy); ux /= r; uy /= r; dx = tool->raw_x - tool->raw_start_x; dy = tool->raw_y - tool->raw_start_y; t = (dx * ux + dy * uy); t = (guppi_x_px2pt (t) + guppi_y_px2pt (t)) / 2; guppi_element_state_set (guppi_canvas_item_state (gci), "radius", CLAMP (tool->arg1 + t, 72 / 8.0, tool->arg2), NULL); } GuppiPlotTool * guppi_pie_tool_new_change_radius (void) { GuppiPlotTool *tool; tool = guppi_plot_tool_new (); tool->name = guppi_strdup (_("Change Radius")); tool->supported_type = GUPPI_TYPE_PIE_ITEM; tool->cursor = gdk_cursor_new (GDK_SIZING); tool->tracks_motion = TRUE; tool->repeating = FALSE; tool->first = change_radius_first_cb; tool->middle = change_radius_cb; return tool; } /***************************************************************************/ static void spin_first_cb (GuppiPlotTool *tool, GuppiCanvasItem *gci) { gint cx0, cy0, cx1, cy1, cx, cy; guppi_canvas_item_get_bbox_c (gci, &cx0, &cy0, &cx1, &cy1); cx = (cx0 + cx1) / 2.0; cy = (cy0 + cy1) / 2.0; guppi_element_state_get (guppi_canvas_item_state (gci), "base_angle", &tool->arg1, NULL); tool->arg2 = atan2 (tool->raw_start_y - cy, tool->raw_start_x - cx); } static void spin_cb (GuppiPlotTool *tool, GuppiCanvasItem *gci) { gint cx0, cy0, cx1, cy1, cx, cy; double theta; guppi_canvas_item_get_bbox_c (gci, &cx0, &cy0, &cx1, &cy1); cx = (cx0 + cx1) / 2.0; cy = (cy0 + cy1) / 2.0; theta = atan2 (tool->raw_y - cy, tool->raw_x - cx); guppi_element_state_set (guppi_canvas_item_state (gci), "base_angle", tool->arg1 + theta - tool->arg2, NULL); } GuppiPlotTool * guppi_pie_tool_new_spin (void) { GuppiPlotTool *tool; tool = guppi_plot_tool_new (); tool->name = guppi_strdup (_("Rotate Pie Chart")); tool->supported_type = GUPPI_TYPE_PIE_ITEM; tool->cursor = gdk_cursor_new (GDK_EXCHANGE); tool->tracks_motion = TRUE; tool->repeating = FALSE; tool->first = spin_first_cb; tool->middle = spin_cb; return tool; } /***************************************************************************/ static void fixed_spin_cb (GuppiPlotTool * tool, GuppiCanvasItem * item) { GuppiElementState *state = guppi_canvas_item_state (item); double th; guppi_element_state_get (state, "base_angle", &th, NULL); th += tool->arg1; guppi_element_state_set (state, "base_angle", th, NULL); } GuppiPlotTool * guppi_pie_tool_new_fixed_spin (double theta_degrees) { GuppiPlotTool *tool; tool = guppi_plot_tool_new (); tool->name = guppi_strdup_printf (_("Rotate Pie Chart %g degrees"), theta_degrees); tool->supported_type = GUPPI_TYPE_PIE_ITEM; tool->arg1 = theta_degrees * (M_PI / 180); /* convert to radians */ tool->cursor = gdk_cursor_new (GDK_EXCHANGE); tool->tracks_motion = FALSE; tool->repeating = TRUE; tool->repeat_interval = 100; tool->first = fixed_spin_cb; tool->repeat = fixed_spin_cb; return tool; } /***************************************************************************/ static void slice_callback_cb (GuppiPlotTool * tool, GuppiCanvasItem * gci) { gint slice; /* If the pointer is inside of a slice, execute the callback with the slice # as an argument. */ if (guppi_pie_item_in_slice (GUPPI_PIE_ITEM (gci), tool->raw_x, tool->raw_y, &slice)) { GuppiPieSliceFunc func = tool->ptr_arg1; func (slice, tool->ptr_arg2 /* == user data */ ); } } GuppiPlotTool * guppi_pie_tool_new_slice_callback (GuppiPieSliceFunc func, const gchar * name, gpointer user_data) { GuppiPlotTool *tool; g_return_val_if_fail (func != NULL, NULL); tool = guppi_plot_tool_new (); tool->name = guppi_strdup (name); tool->tracks_motion = FALSE; tool->repeating = FALSE; tool->first = slice_callback_cb; tool->ptr_arg1 = (gpointer) func; tool->ptr_arg2 = user_data; return tool; } /**************************************************************************/ GuppiPlotToolkit * guppi_pie_toolkit_default (void) { GuppiPlotToolkit *tk = guppi_plot_toolkit_new (_("Default")); guppi_plot_toolkit_set_button_tool (tk, 1, 0, guppi_pie_tool_new_explode_slice ()); guppi_plot_toolkit_set_button_tool (tk, 1, GDK_SHIFT_MASK, guppi_pie_tool_new_explode_slice ()); guppi_plot_toolkit_set_button_tool (tk, 3, 0, guppi_pie_tool_new_spin ()); guppi_plot_toolkit_set_button_tool (tk, 4, 0, guppi_pie_tool_new_fixed_spin (15)); guppi_plot_toolkit_set_button_tool (tk, 5, 0, guppi_pie_tool_new_fixed_spin (-15)); guppi_plot_toolkit_set_key_tool (tk, GDK_Right, 0, guppi_pie_tool_new_fixed_spin (12)); guppi_plot_toolkit_set_key_tool (tk, GDK_Left, 0, guppi_pie_tool_new_fixed_spin (-12)); return tk; } GuppiPlotToolkit * guppi_pie_toolkit_explode (void) { GuppiPlotToolkit *tk = guppi_plot_toolkit_new (_("Explode")); tk->toolbar_button_image = "pie-explode.png"; guppi_plot_toolkit_set_button_tool (tk, 1, 0, guppi_pie_tool_new_explode_slice ()); guppi_plot_toolkit_set_button_tool (tk, 3, 0, guppi_pie_tool_new_explode_all ()); return tk; } GuppiPlotToolkit * guppi_pie_toolkit_spin (void) { GuppiPlotToolkit *tk = guppi_plot_toolkit_new (_("Spin")); tk->toolbar_button_image = "pie-spin.png"; guppi_plot_toolkit_set_button_tool (tk, 1, 0, guppi_pie_tool_new_spin ()); return tk; } /* $Id: guppi-pie-tool.c,v 1.13 2001/08/26 03:04:35 trow Exp $ */