diff --git a/doc/xschem_man/developer_info.html b/doc/xschem_man/developer_info.html index 663421e0..e5b0cc1e 100644 --- a/doc/xschem_man/developer_info.html +++ b/doc/xschem_man/developer_info.html @@ -504,6 +504,8 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns" + + @@ -538,6 +540,8 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns" Invoke the callback event dispatcher with a software event
  • case_insensitive 1|0
  •     Set case insensitive symbol lookup. Use only on case insensitive filesystems 
    +
  • change_elem_order n
  • +   set selected object (instance, wire, line, rect, ...) to position 'n' in its respective array 
  • check_symbols
  •     List all used symbols in current schematic and warn if some symbol is newer 
  • check_unique_names [1|0]
  • @@ -631,8 +635,9 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
        
  • find_nth string sep n
  •     Find n-th field string separated by characters in sep. 1st field is in position 1
        xschem find_nth {aaa,bbb,ccc,ddd} {,} 2  --> bbb 
    -
  • flip
  • -   Flip selection horizontally 
    +
  • flip [x0 y0]
  • +   Flip selection horizontally around point x0 y0. 
    +   if x0, y0 not given use mouse coordinates 
  • flip_in_place
  •     Flip selection horizontally, each object around its center 
  • fullscreen
  • @@ -880,6 +885,10 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
        to deduce symbol interface pins. 
  • merge [f]
  •     Merge another file. if 'f' not given prompt user. 
    +
  • move_instance inst x y rot flip [nodraw] [noundo]
  • +   resets instance coordinates, and rotaton/flip. A dash will keep existing value
    +   if 'nodraw' is given do not draw the moved instance
    +   if 'noundo' is given operation is not undoable 
  • move_objects [dx dy]
  •     Start a move operation on selection and let user terminate the operation in the GUI
        if dx and dy are given move by that amount. 
    @@ -1041,8 +1050,9 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns" if 'net' is given return its topmost full hierarchy name else returns the topmost full hierarchy name of selected net/pin/label. Nets connected to I/O ports are mapped to upper level recursively
    -
  • rotate
  • -   Rotate selected objects around their centers 
    +
  • rotate [x0 y0]
  • +   Rotate selection around point x0 y0. 
    +   if x0, y0 not given use mouse coordinates 
  • save
  •     Save schematic if modified. Does not ask confirmation! 
  • saveas [file] [type]
  • @@ -1293,6 +1303,9 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
     
     
     
    +
    +
    +
     
     
     
    diff --git a/src/callback.c b/src/callback.c
    index 34c378f9..9ce11f0f 100644
    --- a/src/callback.c
    +++ b/src/callback.c
    @@ -1913,7 +1913,7 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key,
        if(key=='S' && state == ShiftMask)   /* change element order */
        {
         if(xctx->semaphore >= 2) break;
    -    change_elem_order();
    +    change_elem_order(-1);
         break;
        }
        if(key=='k' && state==Mod1Mask)        /* select whole net (all attached wires/labels/pins) */
    @@ -2106,8 +2106,7 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key,
           xctx->mx_double_save=xctx->mousex_snap;
           xctx->my_double_save=xctx->mousey_snap;
           move_objects(START,0,0,0);
    -      if(xctx->lastsel>1) move_objects(FLIP,0,0,0);
    -      else               move_objects(FLIP|ROTATELOCAL,0,0,0);
    +      move_objects(FLIP,0,0,0);
           move_objects(END,0,0,0);
         }
         break;
    @@ -2142,8 +2141,7 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key,
           xctx->mx_double_save=xctx->mousex_snap;
           xctx->my_double_save=xctx->mousey_snap;
           move_objects(START,0,0,0);
    -      if(xctx->lastsel>1) move_objects(ROTATE,0,0,0);
    -      else               move_objects(ROTATE|ROTATELOCAL,0,0,0);
    +      move_objects(ROTATE,0,0,0);
           move_objects(END,0,0,0);
         }
     
    diff --git a/src/editprop.c b/src/editprop.c
    index e311a476..33d62024 100644
    --- a/src/editprop.c
    +++ b/src/editprop.c
    @@ -1520,7 +1520,7 @@ static int edit_symbol_property(int x, int first_sel)
        return modified;
     }
     
    -void change_elem_order(void)
    +void change_elem_order(int n)
     {
       xInstance tmpinst;
       xRect tmpbox;
    @@ -1531,20 +1531,30 @@ void change_elem_order(void)
       rebuild_selected_array();
       if(xctx->lastsel==1)
       {
    -    my_snprintf(tmp_txt, S(tmp_txt), "%d",xctx->sel_array[0].n);
    -    tclsetvar("retval",tmp_txt);
    -    xctx->semaphore++;
    -    tcleval("text_line {Object Sequence number} 0");
    -    xctx->semaphore--;
    -    if(strcmp(tclgetvar("rcode"),"") )
    -    {
    +    if(n < 0) {
    +      my_snprintf(tmp_txt, S(tmp_txt), "%d",xctx->sel_array[0].n);
    +      tclsetvar("retval",tmp_txt);
    +      xctx->semaphore++;
    +      tcleval("text_line {Object Sequence number} 0");
    +      xctx->semaphore--;
    +      if(strcmp(tclgetvar("rcode"),"") )
    +      {
    +        xctx->push_undo();
    +        modified = 1;
    +        xctx->prep_hash_inst=0;
    +        xctx->prep_net_structs=0;
    +        xctx->prep_hi_structs=0;
    +      }
    +      sscanf(tclgetvar("retval"), "%d",&new_n);
    +      if(new_n < 0) new_n = 0;
    +    } else {
    +      new_n = n;
           xctx->push_undo();
           modified = 1;
           xctx->prep_hash_inst=0;
           xctx->prep_net_structs=0;
           xctx->prep_hi_structs=0;
         }
    -    sscanf(tclgetvar("retval"), "%d",&new_n);
     
         if(xctx->sel_array[0].type==ELEMENT)
         {
    diff --git a/src/scheduler.c b/src/scheduler.c
    index c08e8c3f..f9aec12c 100644
    --- a/src/scheduler.c
    +++ b/src/scheduler.c
    @@ -366,6 +366,16 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
           }
         }
     
    +    /* change_elem_order n
    +     *   set selected object (instance, wire, line, rect, ...) to position 'n' in its respective array */
    +    else if(!strcmp(argv[1], "change_elem_order"))
    +    {
    +      if(argc > 2) {
    +        int n = atoi(argv[2]);
    +        if(n >= 0) change_elem_order(n);
    +      }
    +    }
    +
         /* check_symbols
          *   List all used symbols in current schematic and warn if some symbol is newer */
         else if(!strcmp(argv[1], "check_symbols"))
    @@ -822,19 +832,23 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
           }
         }
     
    -    /* flip
    -     *   Flip selection horizontally */
    +    /* flip [x0 y0]
    +     *   Flip selection horizontally around point x0 y0. 
    +     *   if x0, y0 not given use mouse coordinates */
         else if(!strcmp(argv[1], "flip"))
         {
    +      double x0 = xctx->mousex_snap;
    +      double y0 = xctx->mousey_snap;
    +      if(argc > 3) {
    +        x0 = atof(argv[2]);
    +        y0 = atof(argv[3]);
    +      }
           if(! (xctx->ui_state & (STARTMOVE | STARTCOPY) ) ) { 
             rebuild_selected_array();
    -        xctx->mx_double_save=xctx->mousex_snap;
    -        xctx->my_double_save=xctx->mousey_snap;
    +        xctx->mx_double_save = xctx->mousex_snap = x0;
    +        xctx->my_double_save = xctx->mousey_snap = y0;
             move_objects(START,0,0,0);
    -        if(xctx->lastsel>1) move_objects(FLIP,0, 0, 0);
    -        else                move_objects(FLIP|ROTATELOCAL,0,0,0);
    -        xctx->deltax = -xctx->mx_double_save;
    -        xctx->deltay = 0;
    +        move_objects(FLIP,0, 0, 0);
             move_objects(END,0,0,0);
           }
           Tcl_ResetResult(interp);
    @@ -2249,6 +2263,48 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
           Tcl_ResetResult(interp);
         }
     
    +    /* move_instance inst x y rot flip [nodraw] [noundo]
    +     *   resets instance coordinates, and rotaton/flip. A dash will keep existing value
    +     *   if 'nodraw' is given do not draw the moved instance
    +     *   if 'noundo' is given operation is not undoable */
    +    else if(!strcmp(argv[1], "move_instance"))
    +    {
    +      int undo = 1, dr = 1;
    +      if(argc > 7) {
    +        int i;
    +        for(i = 7; i < argc; i++) {
    +          if(!strcmp(argv[i], "nodraw")) dr = 0;
    +          if(!strcmp(argv[i], "noundo")) undo = 0;
    +        }
    +      }
    +      if(argc > 6) {
    +        int i;
    +        if((i = get_instance(argv[2])) < 0 ) {
    +          Tcl_SetResult(interp, "xschem pinlist: instance not found", TCL_STATIC);
    +          return TCL_ERROR;
    +        }
    +        if(undo) xctx->push_undo();
    +        if(dr) {
    +          bbox(START,0.0,0.0,0.0,0.0);
    +          bbox(ADD, xctx->inst[i].x1, xctx->inst[i].y1, xctx->inst[i].x2, xctx->inst[i].y2);
    +        }
    +        if(strcmp(argv[3], "-")) xctx->inst[i].x0 = atof(argv[3]);
    +        if(strcmp(argv[4], "-")) xctx->inst[i].y0 = atof(argv[4]);
    +        if(strcmp(argv[5], "-")) xctx->inst[i].rot = (unsigned short)atoi(argv[5]);
    +        if(strcmp(argv[6], "-")) xctx->inst[i].flip = (unsigned short)atoi(argv[6]);
    +        symbol_bbox(i, &xctx->inst[i].x1, &xctx->inst[i].y1, &xctx->inst[i].x2, &xctx->inst[i].y2);
    +        if(dr) {
    +          bbox(ADD, xctx->inst[i].x1, xctx->inst[i].y1, xctx->inst[i].x2, xctx->inst[i].y2);
    +          bbox(SET,0.0,0.0,0.0,0.0);
    +          draw();
    +          bbox(END,0.0,0.0,0.0,0.0);
    +        }
    +        set_modify(1);
    +        xctx->prep_hash_inst=0;
    +        xctx->prep_net_structs=0;
    +        xctx->prep_hi_structs=0;
    +      }
    +    }
         /* move_objects [dx dy]
          *   Start a move operation on selection and let user terminate the operation in the GUI
          *   if dx and dy are given move by that amount. */
    @@ -3118,14 +3174,23 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
           my_free(_ALLOC_ID_, &rn);
         }
     
    -    /* rotate
    -     *   Rotate selected objects around their centers */
    +    /* rotate [x0 y0]
    +     *   Rotate selection around point x0 y0. 
    +     *   if x0, y0 not given use mouse coordinates */
         else if(!strcmp(argv[1], "rotate"))
         {
    +      double x0 = xctx->mousex_snap;
    +      double y0 = xctx->mousey_snap;
    +      if(argc > 3) {
    +        x0 = atof(argv[2]);
    +        y0 = atof(argv[3]);
    +      }
           if(! (xctx->ui_state & (STARTMOVE | STARTCOPY) ) ) { 
             rebuild_selected_array();
    +        xctx->mx_double_save = xctx->mousex_snap = x0;
    +        xctx->my_double_save = xctx->mousey_snap = y0;
             move_objects(START,0,0,0);
    -        move_objects(ROTATE|ROTATELOCAL,0,0,0);
    +        move_objects(ROTATE,0,0,0);
             move_objects(END,0,0,0);
           }
           Tcl_ResetResult(interp);
    diff --git a/src/xschem.h b/src/xschem.h
    index 7ab26412..001e6ecc 100644
    --- a/src/xschem.h
    +++ b/src/xschem.h
    @@ -1556,7 +1556,7 @@ extern void hilight_child_pins(void);
     extern void hilight_parent_pins(void);
     extern void hilight_net_pin_mismatches(void);
     extern Node_hashentry **get_node_table_ptr(void);
    -extern void change_elem_order(void);
    +extern void change_elem_order(int n);
     extern int is_generator(const char *name);
     extern char *str_chars_replace(const char *str, const char *replace_set, const char with);
     extern char *str_replace(const char *str, const char *rep, const char *with, int escape);