Example #1
0
/*! \brief Draw an arc using one angle modification.
 *  \par Function Description
 *  This function draws an arc according to its internal representation
 *  and allows the modification of one of its angle. The start or end
 *  angle of the arc is updated according to <B>whichone</B> with the angle
 *  that the current pointer and the arc center are making with the horizontal.
 *
 *  The previous temporary arc is erased, the angle is then computed
 *  and updated and finally a new temporary arc with the new angle is drawn.
 *
 *  The arc is internally described by :
 *  <DL>
 *    <DT>*</DT><DD>(<B>w_current->first_wx</B>,<B>w_current->first_wy</B>) as
 *                   its center.
 *    <DT>*</DT><DD><B>w_current->distance</B> as its radius.
 *    <DT>*</DT><DD><B>w_current->second_wx</B> and <B>w_current->second_wx</B> as its
 *                  start and end angle respectively.
 *  </DL>
 *
 *  \param [in] w_current  The GschemToplevel object.
 *  \param [in] w_x        Current x coordinate of pointer in world units.
 *  \param [in] w_y        Current y coordinate of pointer in world units.
 *  \param [in] whichone   Which angle to change.
 *
 *  <B>whichone</B> can have one of the following values:
 *  <DL>
 *    <DT>ARC_RADIUS</DT>
 *    <DD>at the center of the arc. This grip is used to modify
 *        the radius of the arc.
 *    <DT>ARC_START_ANGLE</DT>
 *    <DD>at one end of the arc. It corresponds to the starting
 *        angle of the arc.
 *    <DT>ARC_SWEEP_ANGLE</DT>
 *    <DD>at the other end of the arc. It corresponds to the
 *        ending angle of the arc.
 *  </DL>
 */
void o_arc_motion (GschemToplevel *w_current, int w_x, int w_y, int whichone)
{
  int diff_x, diff_y, angle_deg;

  g_assert (w_current->inside_action != 0);

  /* erase the previous temporary arc */
  if (w_current->rubber_visible)
    o_arc_invalidate_rubber (w_current);

  if(whichone == ARC_RADIUS) {
    /*
     * The radius is taken as the biggest distance on the x and y
     * axis between the center of the arc and the mouse position.
     */
    diff_x = abs(w_current->first_wx - snap_grid (w_current, w_x));
    diff_y = abs(w_current->first_wy - snap_grid (w_current, w_y));
    w_current->distance = MAX(diff_x, diff_y);
  }
  else if((whichone == ARC_START_ANGLE) || (whichone == ARC_SWEEP_ANGLE)) {
    /* compute the angle */
    diff_x = w_x - w_current->first_wx;
    diff_y = w_y - w_current->first_wy;
    angle_deg = atan2 (diff_y, diff_x) * 180 / M_PI;

    /* set the start or end angle with this angle */
    switch(whichone) {
    case ARC_START_ANGLE:
      w_current->second_wx = (angle_deg + 360) % 360;
      break;

    case ARC_SWEEP_ANGLE:
      w_current->second_wy = (((angle_deg + 360) % 360) -
                              w_current->second_wx + 360) % 360;
      if (w_current->which_object->arc->sweep_angle < 0)
        w_current->second_wy = w_current->second_wy - 360;
      if (w_current->second_wy == 0)
        w_current->second_wy = 360;
      break;

      /*
       * No default required - one of above two branches
       * *must* be taken - Coverity ID 201571
       */
    }

  }

  /* draw the new temporary arc */
  o_arc_invalidate_rubber (w_current);
  w_current->rubber_visible = 1;
}
Example #2
0
/*! \brief Start process to input a new arc.
 *  \par Function Description
 *  This function starts the process to input a new arc. Parameters for
 *  this arc are put into/extracted from the <B>w_current</B> toplevel structure.
 *  <B>w_x</B> and <B>w_y</B> are current coordinates of the pointer in screen unit.
 *
 *  First step of the arc input is to set the radius of the arc. The center
 *  of the arc is kept in (<B>w_current->first_wx</B>,<B>w_current->first_wy</B>).
 *  The radius of the arc is in <B>w_current->distance</B>.
 *
 *  \param [in] w_current  The GschemToplevel object.
 *  \param [in] w_x        Current x coordinate of pointer in world units.
 *  \param [in] w_y        Current y coordinate of pointer in world units.
 */
void o_arc_start(GschemToplevel *w_current, int w_x, int w_y)
{
  i_action_start (w_current);

  /* set the center of the arc */
  w_current->first_wx = w_x;
  w_current->first_wy = w_y;

  /* set the radius */
  w_current->distance = 0;

  /* set the start and end angles */
  w_current->second_wx = w_current->second_wy = 0;

  /* start the rubberbanding process of the radius */
  o_arc_invalidate_rubber (w_current);
  w_current->rubber_visible = 1;
}
Example #3
0
/*! \todo Finish function documentation!!!
 *  \brief
 *  \par Function Description
 *
 */
gint
x_event_button_pressed(GschemPageView *page_view, GdkEventButton *event, GschemToplevel *w_current)
{
  PAGE *page = gschem_page_view_get_page (page_view);
  int w_x, w_y;
  int unsnapped_wx, unsnapped_wy;

  g_return_val_if_fail ((w_current != NULL), 0);

  if (page == NULL) {
    return TRUE; /* terminate event */
  }

  if (!gtk_widget_has_focus (GTK_WIDGET (page_view))) {
    gtk_widget_grab_focus (GTK_WIDGET (page_view));
  }

  scm_dynwind_begin ((scm_t_dynwind_flags) 0);
  g_dynwind_window (w_current);

#if DEBUG
  printf("pressed button %d! \n", event->button);
  printf("event state: %d \n", event->state);
  printf("w_current state: %d \n", w_current->event_state);
  printf("Selection is:\n");
  o_selection_print_all(&(page->selection_list));
  printf("\n");
#endif

  gschem_page_view_SCREENtoWORLD (page_view, (int) event->x, (int) event->y,
                                  &unsnapped_wx, &unsnapped_wy);
  w_x = snap_grid (w_current, unsnapped_wx);
  w_y = snap_grid (w_current, unsnapped_wy);

  if (event->type == GDK_2BUTTON_PRESS &&
      w_current->event_state == SELECT) {
    /* Don't re-select an object (lp-912978) */
    /* o_find_object(w_current, w_x, w_y, TRUE); */

    /* GDK_BUTTON_EVENT is emitted before GDK_2BUTTON_EVENT, which
     * leads to setting of the inside_action flag.  If o_edit()
     * brings up a modal window (e.g., the edit attribute dialog),
     * it intercepts the release button event and thus doesn't
     * allow resetting of the inside_action flag so we do it
     * manually here before processing the double-click event. */
    i_action_stop (w_current);
    o_edit(w_current, geda_list_get_glist( page->selection_list ));
    scm_dynwind_end ();
    return(0);
  }

  w_current->SHIFTKEY   = (event->state & GDK_SHIFT_MASK  ) ? 1 : 0;
  w_current->CONTROLKEY = (event->state & GDK_CONTROL_MASK) ? 1 : 0;
  w_current->ALTKEY     = (event->state & GDK_MOD1_MASK) ? 1 : 0;

  /* Huge switch statement to evaluate state transitions. Jump to
   * end_button_pressed label to escape the state evaluation rather than
   * returning from the function directly. */

  if (event->button == 1) {
    if (w_current->inside_action) {
      /* End action */
      if (page->place_list != NULL) {
        switch(w_current->event_state) {
          case (COMPMODE)   : o_place_end(w_current, w_x, w_y, w_current->continue_component_place,
                                "%add-objects-hook"); break;
          case (TEXTMODE)   : o_place_end(w_current, w_x, w_y, FALSE,
                                "%add-objects-hook"); break;
          case (PASTEMODE)  : o_place_end(w_current, w_x, w_y, FALSE,
                                "%paste-objects-hook"); break;
          default: break;
        }
      } else {
        switch(w_current->event_state) {
          case (ARCMODE)    : o_arc_end1(w_current, w_x, w_y); break;
          case (BOXMODE)    : o_box_end(w_current, w_x, w_y); break;
          case (BUSMODE)    : o_bus_end(w_current, w_x, w_y); break;
          case (CIRCLEMODE) : o_circle_end(w_current, w_x, w_y); break;
          case (LINEMODE)   : o_line_end(w_current, w_x, w_y); break;
          case (NETMODE)    : o_net_end(w_current, w_x, w_y); break;
          case (PATHMODE)   : o_path_continue (w_current, w_x, w_y); break;
          case (PICTUREMODE): o_picture_end(w_current, w_x, w_y); break;
          case (PINMODE)    : o_pin_end (w_current, w_x, w_y); break;
          default: break;
        }
      }
    } else {
      /* Start action */
      switch(w_current->event_state) {
        case (ARCMODE)    : o_arc_start(w_current, w_x, w_y); break;
        case (BOXMODE)    : o_box_start(w_current, w_x, w_y); break;
        case (BUSMODE)    : o_bus_start(w_current, w_x, w_y); break;
        case (CIRCLEMODE) : o_circle_start(w_current, w_x, w_y); break;
        case (LINEMODE)   : o_line_start(w_current, w_x, w_y); break;
        case (NETMODE)    : o_net_start(w_current, w_x, w_y); break;
        case (PATHMODE)   : o_path_start (w_current, w_x, w_y); break;
        case (PICTUREMODE): o_picture_start(w_current, w_x, w_y); break;
        case (PINMODE)    : o_pin_start (w_current, w_x, w_y); break;
        case (ZOOMBOX)    : a_zoom_box_start(w_current, unsnapped_wx, unsnapped_wy); break;
        case (SELECT)     : o_select_start(w_current, w_x, w_y); break;

        case (COPYMODE)   :
        case (MCOPYMODE)  : o_copy_start(w_current, w_x, w_y); break;
        case (MOVEMODE)   : o_move_start(w_current, w_x, w_y); break;
        default: break;
      }
    }

    switch(w_current->event_state) {
      case(ROTATEMODE):   o_rotate_world_update(w_current, w_x, w_y, 90,
                            geda_list_get_glist(page->selection_list)); break;
      case(MIRRORMODE):   o_mirror_world_update(w_current, w_x, w_y,
                            geda_list_get_glist(page->selection_list)); break;

      case(PAN):
        gschem_page_view_pan (page_view, w_x, w_y);
        i_set_state(w_current, SELECT);
        break;
    }
  } else if (event->button == 2) {

    /* try this out and see how it behaves */
    if (w_current->inside_action) {
      if (!(w_current->event_state == COMPMODE||
            w_current->event_state == TEXTMODE||
            w_current->event_state == MOVEMODE||
            w_current->event_state == COPYMODE  ||
            w_current->event_state == MCOPYMODE ||
            w_current->event_state == PASTEMODE )) {
        i_callback_cancel(w_current, 0, NULL);
      }
      goto end_button_pressed;
    }

    switch(w_current->middle_button) {

      case(ACTION):

      /* don't want to search if shift */
      /* key is pressed */
      if (!w_current->SHIFTKEY) {
        o_find_object(w_current, unsnapped_wx, unsnapped_wy, TRUE);
      }

      /* make sure the list is not empty */
      if (!o_select_selected(w_current)) {
        /* this means the above find did not
         * find anything */
        i_action_stop (w_current);
        i_set_state(w_current, SELECT);
        goto end_button_pressed;
      }

      /* determine here if copy or move */
      if (w_current->ALTKEY) {
        i_set_state(w_current, COPYMODE);
        o_copy_start(w_current, w_x, w_y);
      } else {
        o_move_start(w_current, w_x, w_y);
      }
      break;

      case(REPEAT):
      if (w_current->last_callback != NULL) {
        (*w_current->last_callback)(w_current, 0, NULL);
      }
      break;
#ifdef HAVE_LIBSTROKE
      case(STROKE):
      DOING_STROKE=TRUE;
      break;
#endif /* HAVE_LIBSTROKE */

      case(MID_MOUSEPAN_ENABLED):
      gschem_page_view_pan_start (page_view, (int) event->x, (int) event->y);
      break;
    }

  } else if (event->button == 3) {
    if (!w_current->inside_action) {
      if (w_current->third_button == POPUP_ENABLED) {
        /* (third-button "popup") */
        i_update_menus(w_current);  /* update menus before popup  */
        do_popup(w_current, event);
      } else {
        /* (third-button "mousepan") */
        gschem_page_view_pan_start (page_view, (int) event->x, (int) event->y);
      }
    } else {
      if ((w_current->third_button == MOUSEPAN_ENABLED) &&
          (!w_current->third_button_cancel)) {
        gschem_page_view_pan_start (page_view, (int) event->x, (int) event->y);
      } else { /* this is the default cancel */

        /* reset all draw and place actions */

        switch (w_current->event_state) {

          case (ARCMODE)    : o_arc_invalidate_rubber     (w_current); break;
          case (BOXMODE)    : o_box_invalidate_rubber     (w_current); break;
          case (BUSMODE)    : o_bus_invalidate_rubber     (w_current); break;
          case (CIRCLEMODE) : o_circle_invalidate_rubber  (w_current); break;
          case (LINEMODE)   : o_line_invalidate_rubber    (w_current); break;
          case (NETMODE)    : o_net_reset                 (w_current); break;
          case (PATHMODE)   : o_path_invalidate_rubber    (w_current); break;
          case (PICTUREMODE): o_picture_invalidate_rubber (w_current); break;
          case (PINMODE)    : o_pin_invalidate_rubber     (w_current); break;

          default:
            i_callback_cancel(w_current, 0, NULL);
            break;
        }
      }
    }
  }

 end_button_pressed:
  scm_dynwind_end ();

  return(0);
}