Пример #1
0
/*! \brief Change visibility status of attribute object.
 *  \par Function Description
 *  This function toggles the visibility status of the attribute \a
 *  object and updates it. The object is erased or redrawn if
 *  necessary.
 *
 *  \param [in] w_current  The GschemToplevel object.
 *  \param [in] object     The attribute object.
 */
void o_attrib_toggle_visibility(GschemToplevel *w_current, OBJECT *object)
{
  TOPLEVEL *toplevel = gschem_toplevel_get_toplevel (w_current);

  g_return_if_fail (object != NULL && object->type == OBJ_TEXT);

  if (o_is_visible (object)) {
    /* only erase if we are not showing hidden text */
    if (!toplevel->show_hidden_text) {
      o_invalidate (w_current, object);
    }

    o_set_visibility (toplevel, object, INVISIBLE);

    if (toplevel->show_hidden_text) {
      /* draw text so that little I is drawn */
      o_invalidate (w_current, object);
    }

  } else {
    /* if we are in the special show hidden mode, then erase text first */
    /* to get rid of the little I */
    if (toplevel->show_hidden_text) {
      o_invalidate (w_current, object);
    }

    o_set_visibility (toplevel, object, VISIBLE);
    o_text_recreate(toplevel, object);
  }

  gschem_toplevel_page_content_changed (w_current, toplevel->page_current);
}
Пример #2
0
/*! \brief Replace all selected pictures with a new picture
 * \par Function Description
 * Replaces all pictures in the current selection with a new image.
 *
 * \param [in] w_current  The GschemToplevel object
 * \param [in] filename   The filename of the new picture
 * \param [out] error     The location to return error information.
 * \return TRUE on success, FALSE on failure.
 */
gboolean
o_picture_exchange (GschemToplevel *w_current,
                    const gchar *filename, GError **error)
{
  TOPLEVEL *toplevel = gschem_toplevel_get_toplevel (w_current);
  GList *iter;

  for (iter = geda_list_get_glist (toplevel->page_current->selection_list);
       iter != NULL;
       iter = g_list_next (iter)) {

    OBJECT *object = (OBJECT *) iter->data;
    g_assert (object != NULL);

    if (object->type == OBJ_PICTURE) {
      gboolean status;

      /* Erase previous picture */
      o_invalidate (w_current, object);

      status = o_picture_set_from_file (toplevel, object, filename, error);
      if (!status) return FALSE;

      /* Draw new picture */
      o_invalidate (w_current, object);
    }
  }
  return TRUE;
}
Пример #3
0
/*! \brief Set what part of an attribute is shown.
 *  \par Function Description
 *  This function changes what part (name, value or both) of an
 *  attribute is shown by its attribute object. The attribute object
 *  is erased, updated and finally redrawn.
 *
 *  \param [in] w_current  The GschemToplevel object.
 *  \param [in] object     The attribute object.
 *  \param [in] show_name_value  The new display flag for attribute.
 */
void o_attrib_toggle_show_name_value(GschemToplevel *w_current,
                                     OBJECT *object, int show_name_value)
{
  TOPLEVEL *toplevel = gschem_toplevel_get_toplevel (w_current);

  g_return_if_fail (object != NULL && object->type == OBJ_TEXT);

  o_invalidate (w_current, object);
  object->show_name_value = show_name_value;
  o_text_recreate(toplevel, object);

  gschem_toplevel_page_content_changed (w_current, toplevel->page_current);
}
Пример #4
0
/*! \brief Set what part of an attribute is shown.
 *  \par Function Description
 *  This function changes what part (name, value or both) of an
 *  attribute is shown by its attribute object. The attribute object
 *  is erased, updated and finally redrawn.
 *
 *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
 *  \param [in] object     The attribute object.
 *  \param [in] show_name_value  The new display flag for attribute.
 */
void o_attrib_toggle_show_name_value(GSCHEM_TOPLEVEL *w_current,
                                     OBJECT *object, int show_name_value)
{
  TOPLEVEL *toplevel = w_current->toplevel;

  g_return_if_fail (object != NULL && object->type == OBJ_TEXT);

  o_invalidate (w_current, object);
  object->show_name_value = show_name_value;
  o_text_recreate(toplevel, object);

  toplevel->page_current->CHANGED = 1;
}
Пример #5
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);
  }
}
Пример #6
0
/*! \todo Finish function documentation!!!
 *  \brief
 *  \par Function Description
 *
 */
void o_slot_end(GSCHEM_TOPLEVEL *w_current, const char *string, int len)
{
  TOPLEVEL *toplevel = w_current->toplevel;
  OBJECT *new_obj;
  OBJECT *object;
  OBJECT *temp;
  char *slot_value;
  char *numslots_value;
  OBJECT *slot_text_object;
  char *value = NULL;
  int numslots;
  int new_slot_number;
  int status;

  status = o_attrib_get_name_value(string, NULL, &value);
  if (!status) {
    s_log_message(_("Slot attribute malformed\n"));
    return;
  }

  object = o_select_return_first_object(w_current);

  /* get the parent object if the selection is only a text object */
  if (object != NULL && object->type == OBJ_TEXT) {
    if (object->attached_to != NULL) {
      object = object->attached_to;
    }
  }

  /* now find the slot attribute on the outside first */
  if (object != NULL) {
    numslots_value = o_attrib_search_numslots(object, NULL);

    if (!numslots_value) {
      s_log_message(_("numslots attribute missing\n"));
      s_log_message(
                    _("Slotting not allowed for this component\n"));
      g_free(value);
      return;
    }

    numslots = atoi(numslots_value);
    g_free(numslots_value);

    new_slot_number = atoi(value);

#if DEBUG
    printf("numslots = %d\n", numslots);
#endif

    if (new_slot_number > numslots || new_slot_number <=0 ) {
      s_log_message(_("New slot number out of range\n"));
      g_free(value);
      return;
    }

    /* first see if slot attribute already exists outside
     * complex */
    slot_value = o_attrib_search_slot(object, &slot_text_object);

    if (slot_value) {
      o_text_set_string (toplevel, slot_text_object, string);

      temp = slot_text_object;

      if (temp->visibility == VISIBLE ||
          (temp->visibility == INVISIBLE && toplevel->show_hidden_text)) {
        o_invalidate (w_current,temp);
      }

      o_text_recreate(toplevel, temp);

      /* this doesn't deal with the selection list
       * item */
      if (temp->visibility == VISIBLE ||
          (temp->visibility == INVISIBLE && toplevel->show_hidden_text)) {
        o_invalidate (w_current,temp);
      }

      g_free(slot_value);

    } else {
      /* here you need to do the add the slot
         attribute since it doesn't exist */
      new_obj = o_text_new (toplevel, OBJ_TEXT, ATTRIBUTE_COLOR,
                            object->complex->x, object->complex->y,
                            LOWER_LEFT, 0, /* zero is angle */
                            string, 10, INVISIBLE, SHOW_NAME_VALUE);
      s_page_append (toplevel->page_current, new_obj);

      /* manually attach attribute */
      o_attrib_attach (toplevel, new_obj, object, FALSE);

      slot_text_object = new_obj;
    }

    o_invalidate (w_current, object);
    o_attrib_slot_update(toplevel, object);

    o_invalidate (w_current,object);

    toplevel->page_current->CHANGED = 1;
    g_free(value);

  } else {
    fprintf(stderr,
            _("uggg! you tried to slot edit something that doesn't exist!\n"));
    g_free(value);
    exit(-1);
  }
}
Пример #7
0
/*! \todo Finish function documentation!!!
 *  \brief
 *  \par Function Description
 *
 */
int o_net_add_busrippers(GSCHEM_TOPLEVEL *w_current, OBJECT *net_obj,
                         GList *prev_conn_objects)

{
  TOPLEVEL *toplevel = w_current->toplevel;
  OBJECT *new_obj;
  int color;
  GList *cl_current = NULL;
  OBJECT *bus_object = NULL;
  CONN *found_conn = NULL;
  int done;
  int otherone;
  BUS_RIPPER rippers[2];
  int ripper_count = 0;
  int i;
  double length;
  int sign;
  double distance1, distance2;
  int first, second;
  int made_changes = FALSE;
  const int ripper_size = w_current->bus_ripper_size;
  int complex_angle = 0;
  const CLibSymbol *rippersym = NULL;
  
  length = o_line_length(net_obj);

  if (!prev_conn_objects) {
    return(FALSE);
  }
  
  if (length <= ripper_size) {
    return(FALSE);
  }

  if (toplevel->override_net_color == -1) {
    color = NET_COLOR;
  } else {
    color = toplevel->override_net_color;
  }

  
  /* check for a bus connection and draw rippers if so */
  cl_current = prev_conn_objects;
  while (cl_current != NULL) {
    
    bus_object = (OBJECT *) cl_current->data;
    if (bus_object && bus_object->type == OBJ_BUS) {
      /* yes, using the net routine is okay */
      int bus_orientation = o_net_orientation(bus_object);
      int net_orientation = o_net_orientation(net_obj);

      /* find the CONN structure which is associated with this object */
      GList *cl_current2 = net_obj->conn_list;
      done = FALSE;
      while (cl_current2 != NULL && !done) {
	CONN *tmp_conn = (CONN *) cl_current2->data;

	if (tmp_conn && tmp_conn->other_object &&
	    tmp_conn->other_object == bus_object) {

	  found_conn = tmp_conn;
	  done = TRUE;
	}

	cl_current2 = g_list_next(cl_current2);
      }

      if (!found_conn) {
        return(FALSE);
      }
      
      otherone = !found_conn->whichone;
      
      /* now deal with the found connection */
      if (bus_orientation == HORIZONTAL && net_orientation == VERTICAL) {
	/* printf("found horiz bus %s %d!\n", bus_object->name, 
           found_conn->whichone);*/

        sign = bus_object->bus_ripper_direction;
        if (!sign) {
          if (bus_object->line->x[0] < bus_object->line->x[1]) {
            first = 0;
            second = 1;
          } else {
            first = 1;
            second = 0;
          }
              
          distance1 = abs(bus_object->line->x[first] -
                          net_obj->line->x[found_conn->whichone]);
          distance2 = abs(bus_object->line->x[second] -
                          net_obj->line->x[found_conn->whichone]);
          
          if (distance1 <= distance2) {
            sign = 1;
          } else {
            sign = -1;
          }
          bus_object->bus_ripper_direction = sign;
        }
        /* printf("hor sign: %d\n", sign); */

        if (net_obj->line->y[otherone] < bus_object->line->y[0]) {
          /* new net is below bus */
          /*printf("below\n");*/

          if (ripper_count >= 2) {
            /* try to exit gracefully */
            fprintf(stderr, _("Tried to add more than two bus rippers. Internal gschem error.\n"));
            made_changes = FALSE;
            break;
          }

          if (w_current->bus_ripper_rotation == NON_SYMMETRIC) {
            /* non-symmetric */
            if (sign == 1) {
              complex_angle = 0;
            } else {
              complex_angle = 90;
            }
          } else {
            /* symmetric */
            complex_angle = 0;
          }

          net_obj->line->y[found_conn->whichone] -= ripper_size;
          o_recalc_single_object(toplevel, net_obj);
          rippers[ripper_count].x[0] = 
            net_obj->line->x[found_conn->whichone];
          rippers[ripper_count].y[0] =
            net_obj->line->y[found_conn->whichone];
          rippers[ripper_count].x[1] =
            net_obj->line->x[found_conn->whichone] + sign*ripper_size;       
          rippers[ripper_count].y[1] =
            net_obj->line->y[found_conn->whichone] + ripper_size;
          ripper_count++;
          /* printf("done\n"); */
          made_changes++;
          
        } else {
          /* new net is above bus */
          /* printf("above\n"); */

          if (ripper_count >= 2) {
            /* try to exit gracefully */
            fprintf(stderr, _("Tried to add more than two bus rippers. Internal gschem error.\n"));
            made_changes = FALSE;
            break;
          }

          if (w_current->bus_ripper_rotation == NON_SYMMETRIC) {
            /* non-symmetric */
            if (sign == 1) {
              complex_angle = 270;
            } else {
              complex_angle = 180;
            }
          } else {
            /* symmetric */
            complex_angle = 180;
          }
          
          net_obj->line->y[found_conn->whichone] += ripper_size;
          o_recalc_single_object(toplevel, net_obj);
          rippers[ripper_count].x[0] = 
            net_obj->line->x[found_conn->whichone];
          rippers[ripper_count].y[0] =
            net_obj->line->y[found_conn->whichone];
          rippers[ripper_count].x[1] =
            net_obj->line->x[found_conn->whichone] + sign*ripper_size;      
          rippers[ripper_count].y[1] =
            net_obj->line->y[found_conn->whichone] - ripper_size;
            ripper_count++;
            
            /* printf("done\n"); */
          made_changes++;
        }
        
        
      } else if (bus_orientation == VERTICAL &&
		 net_orientation == HORIZONTAL) {

	/* printf("found vert bus %s %d!\n", bus_object->name,
           found_conn->whichone); */

        sign = bus_object->bus_ripper_direction;
        if (!sign) {
          if (bus_object->line->y[0] < bus_object->line->y[1]) {
            first = 0;
            second = 1;
          } else {
            first = 1;
            second = 0;
          }

          distance1 = abs(bus_object->line->y[first] -
                          net_obj->line->y[found_conn->whichone]);
          distance2 = abs(bus_object->line->y[second] -
                          net_obj->line->y[found_conn->whichone]);
          
          if (distance1 <= distance2) {
            sign = 1;
          } else {
            sign = -1;
          }
          bus_object->bus_ripper_direction = sign;
        } 
        /* printf("ver sign: %d\n", sign); */

        
        if (net_obj->line->x[otherone] < bus_object->line->x[0]) {
          /* new net is to the left of the bus */
          /* printf("left\n"); */
          
          if (ripper_count >= 2) {
            /* try to exit gracefully */
            fprintf(stderr, _("Tried to add more than two bus rippers. Internal gschem error.\n"));
            made_changes = FALSE;
            break;
          }

          if (w_current->bus_ripper_rotation == NON_SYMMETRIC) {
            /* non-symmetric */
            if (sign == 1) {
              complex_angle = 0;
            } else {
              complex_angle = 270;
            }
          } else {
            /* symmetric */
            complex_angle = 270;
          }

          net_obj->line->x[found_conn->whichone] -= ripper_size;
          o_recalc_single_object(toplevel, net_obj);
          rippers[ripper_count].x[0] = 
            net_obj->line->x[found_conn->whichone];
          rippers[ripper_count].y[0] =
            net_obj->line->y[found_conn->whichone];
          rippers[ripper_count].x[1] =
            net_obj->line->x[found_conn->whichone] + ripper_size;
          rippers[ripper_count].y[1] =
            net_obj->line->y[found_conn->whichone] + sign*ripper_size;
          ripper_count++;
                    
          made_changes++;
        } else {
          /* new net is to the right of the bus */
          /* printf("right\n"); */

          if (ripper_count >= 2) {
            /* try to exit gracefully */
            fprintf(stderr, _("Tried to add more than two bus rippers. Internal gschem error.\n"));
            made_changes = FALSE;
            break;
          }

          if (w_current->bus_ripper_rotation == NON_SYMMETRIC) {
            /* non-symmetric */
            if (sign == 1) {
              complex_angle = 90;
            } else {
              complex_angle = 180;
            }
          } else {
            /* symmetric */
            complex_angle = 90;
          }

          net_obj->line->x[found_conn->whichone] += ripper_size;
          o_recalc_single_object(toplevel, net_obj);
          rippers[ripper_count].x[0] = 
            net_obj->line->x[found_conn->whichone];
          rippers[ripper_count].y[0] =
            net_obj->line->y[found_conn->whichone];
          rippers[ripper_count].x[1] =
            net_obj->line->x[found_conn->whichone] - ripper_size;
          rippers[ripper_count].y[1] =
            net_obj->line->y[found_conn->whichone] + sign*ripper_size;
          ripper_count++;

          made_changes++;
        }
      }
    }


    cl_current = g_list_next(cl_current);
  }
 
  if (made_changes) {
    s_conn_remove_object (toplevel, net_obj);

    if (w_current->bus_ripper_type == COMP_BUS_RIPPER) {
      GList *symlist = 
	s_clib_search (toplevel->bus_ripper_symname, CLIB_EXACT);
      if (symlist != NULL) {
        rippersym = (CLibSymbol *) symlist->data;
      }
      g_list_free (symlist);
    }
    
    for (i = 0; i < ripper_count; i++) {
      if (w_current->bus_ripper_type == NET_BUS_RIPPER) {
        new_obj = o_net_new(toplevel, OBJ_NET, color,
                  rippers[i].x[0], rippers[i].y[0],
                  rippers[i].x[1], rippers[i].y[1]);
        s_page_append (toplevel->page_current, new_obj);
      } else {

        if (rippersym != NULL) {
          new_obj = o_complex_new (toplevel, OBJ_COMPLEX, DEFAULT_COLOR,
                                   rippers[i].x[0], rippers[i].y[0],
                                   complex_angle, 0,
                                   rippersym,
                                   toplevel->bus_ripper_symname, 1);
          s_page_append_list (toplevel->page_current,
                              o_complex_promote_attribs (toplevel, new_obj));
          s_page_append (toplevel->page_current, new_obj);

          o_invalidate (w_current, new_obj);
        } else {
          s_log_message(_("Bus ripper symbol [%s] was not found in any component library\n"),
                        toplevel->bus_ripper_symname);
        }
      }
    }
    
    s_conn_update_object (toplevel, net_obj);
    return(TRUE);
  }

  return(FALSE);
}
Пример #8
0
/*! \brief finish a net drawing action 
 * \par Function Description 
 * This function finishes the drawing of a net. If we have a visible
 * magnetic marker, we use that instead of the current cursor
 * position.
 *
 * The rubber nets are removed, the nets and cues are drawn and the
 * net is added to the TOPLEVEL structure.  
 *
 * The function returns TRUE if it has drawn a net, FALSE otherwise.
 */
int o_net_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
{
  TOPLEVEL *toplevel = w_current->toplevel;
  int color;
  int primary_zero_length, secondary_zero_length;
  int found_primary_connection = FALSE;
  int save_wx, save_wy;

  GList *prev_conn_objects = NULL;
  OBJECT *new_net = NULL;

  g_assert( w_current->inside_action != 0 );

  o_net_invalidate_rubber (w_current);

  if (w_current->magnetic_wx != -1 && w_current->magnetic_wy != -1)
    o_net_finishmagnetic(w_current);

  w_current->rubber_visible = 0;

  /* See if either of the nets are zero length.  We'll only add */
  /* the non-zero ones */
  primary_zero_length = (w_current->first_wx == w_current->second_wx) &&
    (w_current->first_wy == w_current->second_wy);
 
  secondary_zero_length = (w_current->second_wx == w_current->third_wx) &&
      (w_current->second_wy == w_current->third_wy);

  /* If both nets are zero length... */
  /* this ends the net drawing behavior */
  if ( primary_zero_length && secondary_zero_length ) {
    return FALSE;
  }

  save_wx = w_current->third_wx;
  save_wy = w_current->third_wy;

  if (toplevel->override_net_color == -1) {
    color = NET_COLOR;
  } else {
    color = toplevel->override_net_color;
  }

  if (w_current->third_wx != snap_grid (w_current, w_current->third_wx)
      || w_current->third_wy != snap_grid (w_current, w_current->third_wy))
      s_log_message(_("Warning: Ending net at off grid coordinate\n"));

  if (!primary_zero_length ) {
  /* create primary net */
      new_net = o_net_new(toplevel, OBJ_NET, color,
                          w_current->first_wx, w_current->first_wy,
                          w_current->second_wx, w_current->second_wy);
      s_page_append (toplevel->page_current, new_net);

      /* conn stuff */
      /* LEAK CHECK 1 */
      prev_conn_objects = s_conn_return_others (prev_conn_objects, new_net);

      if (o_net_add_busrippers (w_current, new_net, prev_conn_objects)) {
        g_list_free (prev_conn_objects);
        prev_conn_objects = NULL;
        prev_conn_objects = s_conn_return_others (prev_conn_objects, new_net);
      }

#if DEBUG 
      printf("primary:\n"); 
      s_conn_print(new_net->conn_list);
#endif

      o_invalidate (w_current, new_net);

      o_invalidate_glist (w_current, prev_conn_objects);

      g_list_free (prev_conn_objects);
      prev_conn_objects = NULL;

      /* Go off and search for valid connection on this newly created net */
      found_primary_connection = s_conn_net_search(new_net, 1, 
                                                   new_net->conn_list);
      if (found_primary_connection)
      {
      	/* if a net connection is found, reset start point of next net */
	save_wx = w_current->second_wx;
	save_wy = w_current->second_wy;
      }

      /* you don't want to consolidate nets which are drawn non-ortho */
      if (toplevel->net_consolidate == TRUE && !w_current->CONTROLKEY) {
        /* CAUTION: Object list will change when nets are consolidated, don't
         *          keep pointers to other objects than new_net after this. */
        o_net_consolidate_segments(toplevel, new_net);
      }
  }


  /* If the second net is not zero length, add it as well */
  /* Also, a valid net connection from the primary net was not found */
  if (!secondary_zero_length && !found_primary_connection) {
      
      /* Add secondary net */
      new_net = o_net_new(toplevel, OBJ_NET, color,
                          w_current->second_wx, w_current->second_wy,
                          w_current->third_wx, w_current->third_wy);
      s_page_append (toplevel->page_current, new_net);

      /* conn stuff */
      /* LEAK CHECK 2 */
      prev_conn_objects = s_conn_return_others (prev_conn_objects, new_net);

      if (o_net_add_busrippers (w_current, new_net, prev_conn_objects)) {
        g_list_free (prev_conn_objects);
        prev_conn_objects = NULL;
        prev_conn_objects = s_conn_return_others (prev_conn_objects, new_net);
      }
#if DEBUG
      s_conn_print(new_net->conn_list);
#endif

      o_invalidate (w_current, new_net);

      o_invalidate_glist (w_current, prev_conn_objects);

      g_list_free (prev_conn_objects);
      prev_conn_objects = NULL;

      /* you don't want to consolidate nets which are drawn non-ortho */
      if (toplevel->net_consolidate == TRUE && !w_current->CONTROLKEY) {
        /* CAUTION: Object list will change when nets are consolidated, don't
         *          keep pointers to other objects than new_net after this. */
        o_net_consolidate_segments(toplevel, new_net);
      }
  }

  toplevel->page_current->CHANGED = 1;
  w_current->first_wx = save_wx;
  w_current->first_wy = save_wy;
  o_undo_savestate(w_current, UNDO_ALL);

  return (TRUE);
}
Пример #9
0
/*! \brief Add a component to the page.
 *  \par Function Description
 *  Adds a component <B>scm_comp_name</B> to the schematic, at
 *  position (<B>scm_x</B>, <B>scm_y</B>), with some properties set by
 *  the parameters:
 *  \param [in] scm_x Coordinate X of the symbol.
 *  \param [in] scm_y Coordinate Y of the symbol.
 *  \param [in] angle Angle of rotation of the symbol.
 *  \param [in] selectable True if the symbol is selectable, false otherwise.
 *  \param [in] mirror True if the symbol is mirrored, false otherwise.
 *  If scm_comp_name is a scheme empty list, SCM_BOOL_F, or an empty
 *  string (""), then g_add_component returns SCM_BOOL_F without writing
 *  to the log.
 *  \return TRUE if the component was added, FALSE otherwise.
 *
 */
SCM g_add_component(SCM page_smob, SCM scm_comp_name, SCM scm_x, SCM scm_y,
                    SCM scm_angle, SCM scm_selectable, SCM scm_mirror)
{
    TOPLEVEL *toplevel;
    PAGE *page;
    gboolean selectable, mirror;
    gchar *comp_name;
    int x, y, angle;
    OBJECT *new_obj;
    const CLibSymbol *clib;

    /* Return if scm_comp_name is NULL (an empty list) or scheme's FALSE */
    if (SCM_NULLP(scm_comp_name) ||
            (SCM_BOOLP(scm_comp_name) && !(SCM_NFALSEP(scm_comp_name))) ) {
        return SCM_BOOL_F;
    }

    /* Get toplevel and the page */
    SCM_ASSERT (g_get_data_from_page_smob (page_smob, &toplevel, &page),
                page_smob, SCM_ARG1, "add-component-at-xy");
    /* Check the arguments */
    SCM_ASSERT (scm_is_string(scm_comp_name), scm_comp_name,
                SCM_ARG2, "add-component-at-xy");
    SCM_ASSERT ( scm_is_integer(scm_x), scm_x,
                 SCM_ARG3, "add-component-at-xy");
    SCM_ASSERT ( scm_is_integer(scm_y), scm_y,
                 SCM_ARG4, "add-component-at-xy");
    SCM_ASSERT ( scm_is_integer(scm_angle), scm_angle,
                 SCM_ARG5, "add-component-at-xy");
    SCM_ASSERT ( scm_boolean_p(scm_selectable), scm_selectable,
                 SCM_ARG6, "add-component-at-xy");
    SCM_ASSERT ( scm_boolean_p(scm_mirror), scm_mirror,
                 SCM_ARG7, "add-component-at-xy");

    /* Get the parameters */
    comp_name = SCM_STRING_CHARS(scm_comp_name);
    x = scm_to_int(scm_y);
    y = scm_to_int(scm_y);
    angle = scm_to_int(scm_angle);
    selectable = SCM_NFALSEP(scm_selectable);
    mirror = SCM_NFALSEP(scm_mirror);

    SCM_ASSERT (comp_name, scm_comp_name,
                SCM_ARG2, "add-component-at-xy");

    if (strcmp(comp_name, "") == 0) {
        return SCM_BOOL_F;
    }

    clib = s_clib_get_symbol_by_name (comp_name);

    new_obj = o_complex_new (toplevel, 'C', DEFAULT_COLOR, x, y, angle, mirror,
                             clib, comp_name, selectable);
    s_page_append_list (page, o_complex_promote_attribs (toplevel, new_obj));
    s_page_append (page, new_obj);

    /*
     * For now, do not redraw the newly added complex, since this might cause
     * flicker if you are zoom/panning right after this function executes
     */
#if 0
    /* Now the new component should be added to the object's list and
       drawn in the screen */
    o_invalidate (toplevel, new_object);
#endif

    return SCM_BOOL_T;
}
Пример #10
0
/*
 * Sets several text properties of the given <B>attribute smob</B>:
  - <B>coloridx</B>: The index of the text color, or -1 to keep previous color.
  - <B>size</B>: Size (numeric) of the text, or -1 to keep the previous size.
  - <B>alignment</B>: String with the alignment of the text. Possible values are:
    * ""           : Keep the previous alignment.
    * "Lower Left"
    * "Middle Left"
    * "Upper Left"
    * "Lower Middle"
    * "Middle Middle"
    * "Upper Middle"
    * "Lower Right"
    * "Middle Right"
    * "Upper Right"
  - <B>rotation</B>: Angle of the text, or -1 to keep previous angle.
  - <B>x</B>, <B>y</B>: Coords of the text.
 */
SCM g_set_attrib_text_properties(SCM attrib_smob, SCM scm_coloridx,
                                 SCM scm_size, SCM scm_alignment,
                                 SCM scm_rotation, SCM scm_x, SCM scm_y)
{
    struct st_attrib_smob *attribute =
        (struct st_attrib_smob *)SCM_CDR(attrib_smob);
    OBJECT *object;
    GSCHEM_TOPLEVEL *w_current = global_window_current;
    TOPLEVEL *toplevel = w_current->toplevel;

    int color = -1;
    int size = -1;
    char *alignment_string;
    int alignment = -2;
    int rotation = 0;
    int x = -1, y = -1;

    SCM_ASSERT (scm_is_integer(scm_coloridx), scm_coloridx,
                SCM_ARG2, "set-attribute-text-properties!");
    SCM_ASSERT ( scm_is_integer(scm_size),
                 scm_size, SCM_ARG3, "set-attribute-text-properties!");
    SCM_ASSERT (scm_is_string(scm_alignment), scm_alignment,
                SCM_ARG4, "set-attribute-text-properties!");
    SCM_ASSERT ( scm_is_integer(scm_rotation),
                 scm_rotation, SCM_ARG5, "set-attribute-text-properties!");
    SCM_ASSERT ( scm_is_integer(scm_x),
                 scm_x, SCM_ARG6, "set-attribute-text-properties!");
    SCM_ASSERT ( scm_is_integer(scm_y),
                 scm_y, SCM_ARG7, "set-attribute-text-properties!");

    color = scm_to_int(scm_coloridx);

    SCM_ASSERT (!(color < -1 || color >= MAX_COLORS),
                scm_coloridx, SCM_ARG2, "set-attribute-text-properties!");

    size = scm_to_int(scm_size);
    rotation = scm_to_int(scm_rotation);
    x = scm_to_int(scm_x);
    y = scm_to_int(scm_y);

    alignment_string = SCM_STRING_CHARS(scm_alignment);

    if (strlen(alignment_string) == 0) {
        alignment = -1;
    }
    if (strcmp(alignment_string, "Lower Left") == 0) {
        alignment = 0;
    }
    if (strcmp(alignment_string, "Middle Left") == 0) {
        alignment = 1;
    }
    if (strcmp(alignment_string, "Upper Left") == 0) {
        alignment = 2;
    }
    if (strcmp(alignment_string, "Lower Middle") == 0) {
        alignment = 3;
    }
    if (strcmp(alignment_string, "Middle Middle") == 0) {
        alignment = 4;
    }
    if (strcmp(alignment_string, "Upper Middle") == 0) {
        alignment = 5;
    }
    if (strcmp(alignment_string, "Lower Right") == 0) {
        alignment = 6;
    }
    if (strcmp(alignment_string, "Middle Right") == 0) {
        alignment = 7;
    }
    if (strcmp(alignment_string, "Upper Right") == 0) {
        alignment = 8;
    }
    if (alignment == -2) {
        /* Bad specified */
        SCM_ASSERT (scm_is_string(scm_alignment), scm_alignment,
                    SCM_ARG4, "set-attribute-text-properties!");
    }

    if (attribute &&
            attribute->attribute) {
        object = attribute->attribute;
        if (object &&
                object->text) {
            o_invalidate (w_current, object);
            if (x != -1) {
                object->text->x = x;
            }
            if (y != -1) {
                object->text->y = y;
            }
            if (size != -1) {
                object->text->size = size;
            }
            if (alignment != -1) {
                object->text->alignment = alignment;
            }
            if (rotation != -1) {
                object->text->angle = rotation;
            }
            o_text_recreate(toplevel, object);
            if (!toplevel->DONT_REDRAW) {
                o_invalidate (w_current, object);
            }
        }
    }
    return SCM_BOOL_T;
}