Example #1
0
/* \brief Begin inputting a new path node.
 * \par Function Description
 * Re-enters path creation mode, saving the current pointer location
 * as the location of the next path control point.
 */
void
o_path_continue (GschemToplevel *w_current, int w_x, int w_y)
{
  g_assert (w_current);

  o_path_invalidate_rubber (w_current);

  w_current->first_wx = w_x;
  w_current->first_wy = w_y;
  w_current->second_wx = w_x;
  w_current->second_wy = w_y;

  o_path_invalidate_rubber (w_current);
}
Example #2
0
/* \brief Give feedback on path creation during mouse movement.
 * \par Function Description
 * If the user is currently in the process of creating a path node
 * (i.e. has mouse button pressed), moves the next node's control
 * point.  If the user has not yet pressed the mouse button to start
 * defining a path node, moves the next node's location and control
 * point together.
 */
void
o_path_motion (GschemToplevel *w_current, int w_x, int w_y)
{
  g_assert (w_current);

  o_path_invalidate_rubber (w_current);

  switch (w_current->event_state) {
  case PATHCONT:
    w_current->first_wx = w_x;
    w_current->first_wy = w_y;
  case ENDPATH:
    w_current->second_wx = w_x;
    w_current->second_wy = w_y;
    break;
  default:
    g_warn_if_reached ();
  }

  o_path_invalidate_rubber (w_current);
}
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);
}
Example #4
0
/*! \brief End the input of a path.
 *  \par Function Description
 *  This function ends the process of interactively adding a path to the
 *  current sheet.
 *
 *  It first erases the last temporary path displayed, calculates the
 *  corresponding world coordinates of the two ends of the path and finally
 *  adds a new initialized path object to the list of object of the current
 *  sheet.
 *
 *  \param [in] w_current  The GschemToplevel object.
 *  \param [in] w_x        (unused)
 *  \param [in] w_y        (unused)
 */
gboolean
o_path_end(GschemToplevel *w_current, int w_x, int w_y)
{
  GschemPageView *page_view = gschem_toplevel_get_current_page_view (w_current);
  TOPLEVEL *toplevel = gschem_page_view_get_toplevel (page_view);
  PAGE *page = gschem_page_view_get_page (page_view);
  gboolean close_path, end_path, start_path;
  PATH *p;
  PATH_SECTION *section, *prev_section;
  int x1, y1, x2, y2;

  g_assert (w_current);
  g_assert (w_current->toplevel);
  g_assert (w_current->temp_path != NULL);
  g_assert (w_current->temp_path->sections != NULL);
  g_assert (toplevel != NULL);
  g_assert (page != NULL);

  o_path_invalidate_rubber (w_current);

  x1 = w_current->first_wx;
  y1 = w_current->first_wy;
  x2 = w_current->second_wx;
  y2 = w_current->second_wy;
  p = w_current->temp_path;

  /* Check whether the section that's being added is the initial
   * MOVETO.  This is detected if the path is currently empty. */
  start_path = (p->num_sections == 0);

  prev_section = start_path ? NULL : &p->sections[p->num_sections - 1];

  /* Check whether the section that's being added closes the path.
   * This is detected if the location of the node is the same as the
   * location of the starting node, and there is at least one section
   * in the path in addition to the initial MOVETO section. */
  section = &p->sections[0];
  close_path = (!start_path
                && x1 == section->x3
                && y1 == section->y3);

  /* Check whether the section that's being added ends the path. This
   * is detected if the location of the node is the same as the
   * location of the previous node. */
  end_path = (!start_path
              && x1 == prev_section->x3
              && y1 == prev_section->y3);

  /* Add predicted next sections */
  path_next_sections (w_current);

  if (end_path || close_path) {
    /* Add object to page and clean up path drawing state */
    OBJECT *obj = o_path_new_take_path (toplevel, OBJ_PATH,
                                        GRAPHIC_COLOR, p);
    w_current->temp_path = NULL;
    w_current->first_wx = -1;
    w_current->first_wy = -1;
    w_current->second_wx = -1;
    w_current->second_wy = -1;
    w_current->third_wx = -1;
    w_current->third_wy = -1;

    s_page_append (toplevel, page, obj);
    g_run_hook_object (w_current, "%add-objects-hook", obj);
    gschem_toplevel_page_content_changed (w_current, page);
    o_undo_savestate (w_current, page, UNDO_ALL);

    w_current->rubber_visible = FALSE;

    return FALSE;
  } else {
    /* Leave state as it is and continue path drawing... */

    /* Save the control point coordinates for the next section */
    w_current->third_wx = x2;
    w_current->third_wy = y2;

    return TRUE;
  }
}