/* $Id: guppi-scatter-tools.c,v 1.15 2001/08/26 03:04:37 trow Exp $ */

/*
 * guppi-scatter-tools.c
 *
 * Copyright (C) 2000 EMC Capital Management, Inc.
 *
 * Developed by Jon Trowbridge <trow@gnu.org>.

 *
 * 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 <config.h>

#include <libgnome/gnome-defs.h>
#include <libgnome/gnome-config.h>
#include <libgnome/gnome-i18n.h>

#include <guppi-useful.h>
#include <guppi-basic-tools.h>
#include "guppi-scatter-tools.h"
#include "guppi-scatter-state.h"
#include "guppi-scatter-item.h"

static void
radius_brush_cb (GuppiPlotTool * tool, GuppiCanvasItem * gci)
{
  GuppiScatterState *state;
  double x0, y0, x1, y1, scale_x, scale_y;

  state = GUPPI_SCATTER_STATE (guppi_canvas_item_state (gci));

  guppi_canvas_item_c2vp (gci, 0, 0, &x0, &y0);
  guppi_canvas_item_c2vp (gci, 1, 1, &x1, &y1);
  scale_x = guppi_x_pt2px (1) * fabs (x1 - x0);
  scale_y = guppi_y_pt2px (1) * fabs (y1 - y0);

  guppi_scatter_state_brush_circle (state,
				    (gint) tool->arg1,
				    tool->x, tool->y, tool->arg2,
				    scale_x, scale_y);
}

/* Radius is in unscaled screen pt */

GuppiPlotTool *
guppi_scatter_tool_radius_brush (gint brush, double radius)
{
  GuppiPlotTool *tool;

  g_return_val_if_fail (brush >= 0, NULL);
  g_return_val_if_fail (radius > 0, NULL);

  tool = guppi_plot_tool_new ();
  tool->name = guppi_strdup (_("Brush Scatter Points (Radius)"));
  tool->supported_type = GUPPI_TYPE_SCATTER_ITEM;
  tool->cursor = gdk_cursor_new (GDK_SPRAYCAN);
  tool->cue_type = GPTPC_CIRCLE;
  tool->cue_fill_color = 0xff000030;
  tool->cue_arg = radius;

  tool->arg1 = brush;
  tool->arg2 = radius;
  tool->first = tool->middle = tool->last = radius_brush_cb;

  return tool;
}

static void
frame_brush_cb (GuppiPlotTool * tool, GuppiCanvasItem * gci)
{
  GuppiScatterState *state;

  state = GUPPI_SCATTER_STATE (guppi_canvas_item_state (gci));

  guppi_scatter_state_brush_rectangle (state,
				       (gint) tool->arg1,
				       tool->start_x, tool->start_y,
				       tool->x, tool->y);
}

GuppiPlotTool *
guppi_scatter_tool_frame_brush (gint brush)
{
  GuppiPlotTool *tool;

  g_return_val_if_fail (brush >= 0, NULL);

  tool = guppi_plot_tool_new ();
  tool->name = guppi_strdup (_("Brush Scatter Points (Rectangle)"));
  tool->supported_type = GUPPI_TYPE_SCATTER_ITEM;
  tool->cursor = gdk_cursor_new (GDK_SPRAYCAN);
  tool->cue_type = GPTPC_FRAME;
  tool->cue_fill_color = 0xff000030;

  tool->arg1 = brush;
  tool->last = frame_brush_cb;

  return tool;
}

/***************************************************************************/

static void
find_point_to_drag (GuppiPlotTool * tool, GuppiCanvasItem * gci)
{
  gint closest;
  GuppiScatterState *state;
  double scale;
  double x0, y0, x1, y1, scale_x, scale_y;

  state = GUPPI_SCATTER_STATE (guppi_canvas_item_state (gci));
  scale = guppi_canvas_item_scale (gci);

  guppi_canvas_item_c2vp (gci, 0, 0, &x0, &y0);
  guppi_canvas_item_c2vp (gci, 1, 1, &x1, &y1);
  scale_x = guppi_x_pt2px (1) * fabs (x1 - x0);
  scale_y = guppi_y_pt2px (1) * fabs (y1 - y0);

  if (guppi_scatter_state_closest_point (state, tool->x, tool->y, 9,	/* 1/8" radius */
					 scale_x, scale_y, &closest)) {
    tool->arg1 = 1;
    tool->int_arg1 = closest;
  }
}

static void
drag_first_cb (GuppiPlotTool * tool, GuppiCanvasItem * gci)
{
  tool->arg1 = 0;

  find_point_to_drag (tool, gci);
}

static void
drag_middle_cb (GuppiPlotTool * tool, GuppiCanvasItem * gci)
{
  if (tool->arg1 == 0) {

    find_point_to_drag (tool, gci);

  } else if (tool->arg1 > 0) {

    gint closest;
    GuppiScatterState *state;
    GuppiSeqScalar *x_data;
    GuppiSeqScalar *y_data;

    state = GUPPI_SCATTER_STATE (guppi_canvas_item_state (gci));
    x_data = guppi_scatter_state_get_x_data (state);
    y_data = guppi_scatter_state_get_y_data (state);

    closest = tool->int_arg1;

    if (guppi_data_can_change (GUPPI_DATA (x_data)))
      guppi_seq_scalar_set (x_data, closest, tool->x);

    if (guppi_data_can_change (GUPPI_DATA (y_data)))
      guppi_seq_scalar_set (y_data, closest, tool->y);

  } else {

    g_assert_not_reached ();

  }
}

GuppiPlotTool *
guppi_scatter_tool_drag_point (void)
{
  GuppiPlotTool *tool;
  tool = guppi_plot_tool_new ();
  tool->name = guppi_strdup (_("Drag Scatter Point"));
  tool->supported_type = GUPPI_TYPE_SCATTER_ITEM;

  tool->cursor = gdk_cursor_new (GDK_HAND2);

  tool->first = drag_first_cb;
  tool->middle = drag_middle_cb;

  return tool;
}

/*************************************************************************/

GuppiPlotToolkit *
guppi_scatter_toolkit_default (void)
{
  GuppiPlotToolkit *tk = guppi_plot_toolkit_new (_("Default"));

  guppi_plot_toolkit_set_button_tool (tk, 1, 0,
				      guppi_basic_tool_new_rescale (0.9));
  guppi_plot_toolkit_set_button_tool (tk, 2, 0, guppi_basic_tool_new_drag ());
  guppi_plot_toolkit_set_button_tool (tk, 3, 0,
				      guppi_basic_tool_new_rescale (1 / 0.9));

  guppi_add_keyboard_navigation_to_toolkit (tk);

  return tk;
}

GuppiPlotToolkit *
guppi_scatter_toolkit_drag (void)
{
  GuppiPlotToolkit *tk = guppi_plot_toolkit_new (_("Drag"));

  tk->toolbar_button_image = "scatter-drag.png";

  guppi_plot_toolkit_set_button_tool (tk, 1, 0,
				      guppi_scatter_tool_drag_point ());

  guppi_add_keyboard_navigation_to_toolkit (tk);

  return tk;
}

GuppiPlotToolkit *
guppi_scatter_toolkit_brush (void)
{
  GuppiPlotToolkit *tk = guppi_plot_toolkit_new (_("Brush"));

  tk->toolbar_button_image = "scatter-brush.png";

  guppi_plot_toolkit_set_button_tool (tk, 1, 0,
				      guppi_scatter_tool_radius_brush (2,
								       20));

  guppi_add_keyboard_navigation_to_toolkit (tk);

  return tk;
}


/* $Id: guppi-scatter-tools.c,v 1.15 2001/08/26 03:04:37 trow Exp $ */


syntax highlighted by Code2HTML, v. 0.9.1