Exemplo n.º 1
0
/*! \todo Finish function documentation!!!
 *  \brief
 *  \par Function Description
 *
 */
void o_move_start(GschemToplevel *w_current, int w_x, int w_y)
{
  GList *s_iter;

  g_return_if_fail (w_current != NULL);

  GschemPageView *page_view = gschem_toplevel_get_current_page_view (w_current);
  g_return_if_fail (page_view != NULL);

  PAGE *page = gschem_page_view_get_page (page_view);
  g_return_if_fail (page != NULL);

  g_return_if_fail (w_current->stretch_list == NULL);

  if (o_select_selected (w_current)) {
    i_set_state (w_current, MOVEMODE);

    gboolean net_rubber_band_mode;

    net_rubber_band_mode = gschem_options_get_net_rubber_band_mode (w_current->options);

    w_current->last_drawb_mode = LAST_DRAWB_MODE_NONE;

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

    o_invalidate_glist (w_current, geda_list_get_glist (page->selection_list));

    if (net_rubber_band_mode) {
      o_move_prep_rubberband(w_current);

      /* Set the dont_redraw flag on rubberbanded objects and invalidate them.
       * This ensures that they are not drawn (in their un-stretched position)
       * during screen updates. */
      for (s_iter = w_current->stretch_list;
           s_iter != NULL; s_iter = g_list_next (s_iter)) {
        STRETCH *stretch = s_iter->data;
        stretch->object->dont_redraw = TRUE;
        o_invalidate (w_current, stretch->object);
      }
    }

    o_select_move_to_place_list(w_current);
    i_action_start (w_current);

    o_move_invalidate_rubber (w_current, TRUE);
  }
}
Exemplo n.º 2
0
/*! \todo Finish function documentation!!!
 *  \brief
 *  \par Function Description
 *
 */
gint
x_event_button_released (GschemPageView *page_view, GdkEventButton *event, GschemToplevel *w_current)
{
  PAGE *page = gschem_page_view_get_page (page_view);
  int unsnapped_wx, unsnapped_wy;
  int w_x, w_y;

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

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

#if DEBUG
  printf("released! %d \n", w_current->event_state);
#endif

  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;

  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);

  /* Huge switch statement to evaluate state transitions. Jump to
   * end_button_released label to escape the state evaluation rather
   * than returning from the function directly. */
  scm_dynwind_begin ((scm_t_dynwind_flags) 0);
  g_dynwind_window (w_current);

  if (event->button == 1) {

    if (w_current->inside_action) {
      if (page->place_list != NULL) {
        switch(w_current->event_state) {
          case (COPYMODE)  :
          case (MCOPYMODE) : o_copy_end(w_current); break;
          case (MOVEMODE)  : o_move_end(w_current); break;
          default: break;
        }
      } else {
        switch(w_current->event_state) {
          case (GRIPS)     : o_grips_end(w_current); break;
          case (PATHMODE)  : o_path_end (w_current, w_x, w_y); break;
          case (SBOX)      : o_select_box_end(w_current, unsnapped_wx, unsnapped_wy); break;
          case (SELECT)    : o_select_end(w_current, unsnapped_wx, unsnapped_wy); break;
          case (ZOOMBOX)   : a_zoom_box_end(w_current, unsnapped_wx, unsnapped_wy); break;
          default: break;
        }
      }
    }
  } else if (event->button == 2) {

    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 ) {

        if (w_current->event_state == MOVEMODE) {
          o_move_invalidate_rubber (w_current, FALSE);
        } else {
          o_place_invalidate_rubber (w_current, FALSE);
        }
        w_current->rubber_visible = 0;

        o_place_rotate(w_current);

        if (w_current->event_state == COMPMODE) {
          o_complex_place_changed_run_hook (w_current);
        }

        if (w_current->event_state == MOVEMODE) {
          o_move_invalidate_rubber (w_current, TRUE);
        } else {
          o_place_invalidate_rubber (w_current, TRUE);
        }
        w_current->rubber_visible = 1;
        goto end_button_released;
      }
    }

    switch(w_current->middle_button) {
      case(ACTION):
        if (w_current->inside_action && (page->place_list != NULL)) {
          switch(w_current->event_state) {
            case (COPYMODE): o_copy_end(w_current); break;
            case (MOVEMODE): o_move_end(w_current); break;
          }
        }
      break;

#ifdef HAVE_LIBSTROKE
      case(STROKE):
      DOING_STROKE = FALSE;
      x_stroke_translate_and_execute (w_current);
      break;
#endif /* HAVE_LIBSTROKE */

      case(MID_MOUSEPAN_ENABLED):
        if (gschem_page_view_pan_end (page_view) && w_current->undo_panzoom) {
          o_undo_savestate_old(w_current, UNDO_VIEWPORT_ONLY);
        }
      break;
    }

  } else if (event->button == 3) {
      /* just for ending a mouse pan */
      if (gschem_page_view_pan_end (page_view) && w_current->undo_panzoom) {
        o_undo_savestate_old(w_current, UNDO_VIEWPORT_ONLY);
      }
  }
 end_button_released:
  scm_dynwind_end ();

  return(0);
}
Exemplo n.º 3
0
/*! \todo Finish function documentation!!!
 *  \brief
 *  \par Function Description
 *
 */
void o_move_end(GschemToplevel *w_current)
{
  GschemPageView *page_view = gschem_toplevel_get_current_page_view (w_current);
  g_return_if_fail (page_view != NULL);

  PAGE *page = gschem_page_view_get_page (page_view);
  g_return_if_fail (page != NULL);

  GList *s_current = NULL;
  OBJECT *object;
  int diff_x, diff_y;
  GList *s_iter;
  GList *rubbernet_objects = NULL;
  gboolean net_rubber_band_mode;

  g_return_if_fail (w_current != NULL);
  g_return_if_fail (page != NULL);

  g_assert (w_current->inside_action != 0);

  object = o_select_return_first_object(w_current);

  if (!object) {
    /* actually this is an error condition hack */
    i_action_stop (w_current);
    i_set_state(w_current, SELECT);
    return;
  }

  diff_x = w_current->second_wx - w_current->first_wx;
  diff_y = w_current->second_wy - w_current->first_wy;

  o_move_invalidate_rubber (w_current, FALSE);
  w_current->rubber_visible = 0;

  net_rubber_band_mode = gschem_options_get_net_rubber_band_mode (w_current->options);

  if (net_rubber_band_mode) {
    o_move_end_rubberband (w_current, diff_x, diff_y, &rubbernet_objects);
  }

  /* Unset the dont_redraw flag on rubberbanded objects.
   * We set this above, in o_move_start(). */
  for (s_iter = w_current->stretch_list;
       s_iter != NULL; s_iter = g_list_next (s_iter)) {
    STRETCH *stretch = s_iter->data;
    stretch->object->dont_redraw = FALSE;
  }

  s_current = geda_list_get_glist( page->selection_list );

  while (s_current != NULL) {

    object = (OBJECT *) s_current->data;

    if (object == NULL) {
      fprintf(stderr, _("ERROR: NULL object in o_move_end!\n"));
      exit(-1);
    }


    switch (object->type) {
      case (OBJ_COMPLEX):
      case (OBJ_PLACEHOLDER):

        /* TODO: Fix so we can just pass the complex to o_move_end_lowlevel,
         * IE.. by falling through the bottom of this case statement. */

        /* this next section of code is from */
        /* o_complex_world_translate_world */
        object->complex->x = object->complex->x + diff_x;
        object->complex->y = object->complex->y + diff_y;

        o_move_end_lowlevel_glist (w_current, object->complex->prim_objs,
                                   diff_x, diff_y);
        object->w_bounds_valid_for = NULL;
        break;

      default:
        o_move_end_lowlevel (w_current, object, diff_x, diff_y);
        break;
    }

    s_current = g_list_next(s_current);
  }

  /* Draw the objects that were moved */
  o_invalidate_glist (w_current, geda_list_get_glist (page->selection_list));

  /* Draw the connected nets/buses that were also changed */
  o_invalidate_glist (w_current, rubbernet_objects);

  /* Call move-objects-hook for moved objects and changed connected
   * nets/buses */
  GList *moved_list = g_list_concat (page->place_list, rubbernet_objects);
  page->place_list = NULL;
  rubbernet_objects = NULL;
  g_run_hook_object_list (w_current, "%move-objects-hook", moved_list);
  g_list_free (moved_list);

  gschem_toplevel_page_content_changed (w_current, page);
  o_undo_savestate_old(w_current, UNDO_ALL);

  s_stretch_destroy_all (w_current->stretch_list);
  w_current->stretch_list = NULL;

  i_set_state(w_current, SELECT);
  i_action_stop (w_current);
}
Exemplo n.º 4
0
/*! \todo Finish function documentation!!!
 *  \brief
 *  \par Function Description
 *
 */
void o_move_motion (GschemToplevel *w_current, int w_x, int w_y)
{
  GList *selection, *s_current;
  OBJECT *object;
  gint object_x, object_y;
  gboolean resnap = FALSE;
  SNAP_STATE snap_mode;

  g_assert (w_current->inside_action != 0);

  GschemPageView *page_view = gschem_toplevel_get_current_page_view (w_current);
  g_return_if_fail (page_view != NULL);

  PAGE *page = gschem_page_view_get_page (page_view);
  g_return_if_fail (page != NULL);
  g_return_if_fail (page->place_list != NULL);

  snap_mode = gschem_options_get_snap_mode (w_current->options);

  selection = geda_list_get_glist (page->selection_list);

  /* realign the object if we are in resnap mode */
  if ((selection != NULL) && (snap_mode == SNAP_RESNAP)) {
    if (g_list_length(selection) > 1) {
      /* find an object that is not attached to any other object */
      for (s_current = selection;
           s_current != NULL;
           s_current = g_list_next(s_current)) {
        if (((OBJECT *) s_current->data)->attached_to == NULL) {
          object = (OBJECT *) s_current->data;
          resnap = TRUE;
          break;
        }
      }

      /* Only resnap single elements. This is also the case if
         the selection contains one object and all other object
         elements are attributes of the object element.*/
      for (s_current = selection;
           s_current != NULL && resnap == TRUE;
           s_current = g_list_next(s_current)) {
        if (!(object == (OBJECT *) s_current->data)
            && !o_attrib_is_attached(page->toplevel,
                                     (OBJECT *) s_current->data, object)) {
          resnap = FALSE;
        }
      }
    } else { /* single object */
      resnap = TRUE;
      object = (OBJECT *) selection->data;
    }

    /* manipulate w_x and w_y in a way that will lead to a position
       of the object that is aligned with the grid */
    if (resnap) {
      if (o_get_position(page->toplevel, &object_x, &object_y, object)) {
        w_x += snap_grid (w_current, object_x) - object_x;
        w_y += snap_grid (w_current, object_y) - object_y;
      }
    }
  }

  o_move_invalidate_rubber (w_current, FALSE);
  w_current->second_wx = w_x;
  w_current->second_wy = w_y;
  o_move_invalidate_rubber (w_current, TRUE);
}
Exemplo n.º 5
0
/*! \brief Handle motion during a move operation, resnapping if necessary
 * \par Function Description
 * Handle movement during a move operation, by updating the global
 * candidate transformation parameters.  The \a w_x and \b w_y
 * parameters are the incremental translation to be handled.
 *
 * This function mostly exists to implement the "resnapping" logic,
 * which destructively puts objects back onto the grid during a move
 * operation, as long as specific criteria are met.
 *
 * \param w_current  Global gschem state structure.
 * \param w_x        X-axis translation
 * \param w_y        Y-axis translation
 */
void o_move_motion (GschemToplevel *w_current, int w_x, int w_y)
{
  GList *selection, *s_current;
  OBJECT *object = NULL;
  gint object_x, object_y;
  SNAP_STATE snap_mode;

  g_assert (w_current->inside_action != 0);

  GschemPageView *page_view = gschem_toplevel_get_current_page_view (w_current);
  g_return_if_fail (page_view != NULL);

  PAGE *page = gschem_page_view_get_page (page_view);
  g_return_if_fail (page != NULL);
  g_return_if_fail (page->place_list != NULL);

  snap_mode = gschem_options_get_snap_mode (w_current->options);

  selection = geda_list_get_glist (page->selection_list);

  /* There are three posssibilities:
   *
   * 1. There is exactly one object selected, in which case it is
   *    snapped.
   *
   * 2. There are multiple objects selected, but there is some object
   *    O[i] such that all other selected objects O[j!=i] are attached
   *    as attributes of O[i].  In that case, the O[i] is snapped.
   *
   * 3. Other cases, in which case no snapping occurs.
   */

  if (NULL == selection || SNAP_RESNAP != snap_mode) {
    object = NULL;

  } else if (1 == g_list_length (selection)) {
    object = (OBJECT *) selection->data;

  } else {

    /* The object that things are supposed to be attached to */
    OBJECT *attached = NULL;

    /* Scan the selection, searching for an object that's not attached
     * to any other object.  As we go, also check whether everything
     * in the list that *is* attached as an attribute is attached to
     * the same object. */
    for (s_current = selection;
         NULL != s_current;
         s_current = g_list_next (s_current)) {

      OBJECT *candidate = (OBJECT *) s_current->data;

      if (NULL == candidate->attached_to) {

        /* If the object is *not* attached as an attribute, then check
         * whether we previously found an independent object.  If we
         * did, we can't do snapping, so give up. */
        if (NULL == object) {
          object = candidate;
        } else if (candidate != object) {
          break; /* Give up */
        }

      } else {

        /* If the object is attached as an attribute, then check if
         * it's attached as an attribute of the same object as
         * everything else is.  If not, we can't do snapping, so give
         * up. */
        if (NULL == attached) {
          attached = candidate->attached_to;
        } else if (attached != candidate->attached_to) {
          break; /* Give up */
        }
      }
    }

    if (NULL == object ||
        (NULL != attached && object != attached)) {
      object = NULL;
    } else {
      g_assert (NULL != object);
    }
  }

  /* manipulate w_x and w_y in a way that will lead to a position
     of the object that is aligned with the grid */
  if (NULL != object) {
    if (geda_object_get_position (object, &object_x, &object_y)) {
      w_x += snap_grid (w_current, object_x) - object_x;
      w_y += snap_grid (w_current, object_y) - object_y;
    }
  }

  o_move_invalidate_rubber (w_current, FALSE);
  w_current->second_wx = w_x;
  w_current->second_wy = w_y;
  o_move_invalidate_rubber (w_current, TRUE);
}