code added for tabbed window interface
This commit is contained in:
parent
34bd7873e3
commit
e238f571b0
|
|
@ -75,7 +75,7 @@ unsigned int hash_file(const char *f, int skip_path_lines)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* mod=-1 used to force set title */
|
||||
void set_modify(int mod)
|
||||
{
|
||||
char *top_path;
|
||||
|
|
@ -83,7 +83,8 @@ void set_modify(int mod)
|
|||
top_path = xctx->top_path[0] ? xctx->top_path : ".";
|
||||
xctx->modified = mod;
|
||||
dbg(1, "set_modify(): %d\n", mod);
|
||||
if(mod != xctx->prev_set_modify) {
|
||||
if(mod == -1 || mod != xctx->prev_set_modify) { /* mod=-1 used to force set title */
|
||||
mod = 0;
|
||||
xctx->prev_set_modify = mod;
|
||||
if(has_x && strcmp(get_cell(xctx->sch[xctx->currsch],1), "systemlib/font")) {
|
||||
if(mod == 1) {
|
||||
|
|
@ -95,6 +96,7 @@ void set_modify(int mod)
|
|||
}
|
||||
}
|
||||
}
|
||||
tcleval("set_tab_names");
|
||||
}
|
||||
|
||||
void print_version()
|
||||
|
|
|
|||
|
|
@ -809,17 +809,20 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key,
|
|||
dbg(1, "callback(): semaphore >=2 (or Expose) switching window context: %s --> %s\n", old_winpath, winpath);
|
||||
redraw_only = 1;
|
||||
} else {
|
||||
dbg(1, "callback(): switching window context: %s --> %s\n", old_winpath, winpath);
|
||||
dbg(1, "callback(): switching window context: %s --> %s, semaphore=%d\n", old_winpath, winpath, xctx->semaphore);
|
||||
if(old_winpath[0]) tclvareval("save_ctx ", old_winpath, NULL);
|
||||
tclvareval("restore_ctx ", winpath, NULL);
|
||||
tclvareval("housekeeping_ctx", NULL);
|
||||
}
|
||||
new_schematic("switch", xctx->top_path, winpath, "");
|
||||
new_schematic("switch", winpath, "");
|
||||
}
|
||||
/* artificially set semaphore to allow only redraw operations in switched schematic,
|
||||
* so we don't need to switch tcl context which is costly performance-wise
|
||||
*/
|
||||
if(redraw_only) xctx->semaphore++;
|
||||
if(redraw_only) {
|
||||
dbg(1, "callback(): incrementing semaphore for redraw_only\n");
|
||||
xctx->semaphore++;
|
||||
}
|
||||
|
||||
xctx->semaphore++; /* to recognize recursive callback() calls */
|
||||
|
||||
|
|
@ -1364,12 +1367,13 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key,
|
|||
}
|
||||
if(key=='q' && state == ControlMask) /* exit */
|
||||
{
|
||||
char * top_path;
|
||||
top_path = xctx->top_path[0] ? xctx->top_path : ".";
|
||||
if(xctx->semaphore >= 2) break;
|
||||
if(!strcmp(winpath, ".drw")) {
|
||||
tcleval("new_window destroy_all"); /* close child schematics */
|
||||
if(tclresult()[0] == '1') {
|
||||
int remaining;
|
||||
/* tcleval("new_window destroy_all"); */ /* close child schematics */
|
||||
remaining = new_schematic("destroy_all", NULL, NULL);
|
||||
/* if(tclresult()[0] == '1') { */
|
||||
if(!remaining) {
|
||||
if(xctx->modified) {
|
||||
tcleval("tk_messageBox -type okcancel -parent [xschem get topwindow] -message \""
|
||||
"[get_cell [xschem get schname] 0]"
|
||||
|
|
@ -1379,11 +1383,7 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key,
|
|||
}
|
||||
} else {
|
||||
/* xschem new_schematic destroy asks user confirmation if schematic changed */
|
||||
tclvareval("xschem new_schematic destroy ", top_path, " ", winpath," {}" , NULL);
|
||||
/* ================================================================ */
|
||||
/* We must return here, since current schematic is no more existing */
|
||||
/* ================================================================ */
|
||||
return 0;
|
||||
new_schematic("destroy", winpath, NULL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -2565,7 +2565,7 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key,
|
|||
if(redraw_only) {
|
||||
xctx->semaphore--; /* decrement articially incremented semaphore (see above) */
|
||||
dbg(1, "callback(): semaphore >=2 restoring window context: %s <-- %s\n", old_winpath, winpath);
|
||||
if(old_winpath[0]) new_schematic("switch", xctx->top_path, old_winpath, "");
|
||||
if(old_winpath[0]) new_schematic("switch", old_winpath, "");
|
||||
}
|
||||
else
|
||||
if(strcmp(old_winpath, winpath)) {
|
||||
|
|
|
|||
15
src/draw.c
15
src/draw.c
|
|
@ -2268,24 +2268,19 @@ static void show_node_measures(int measure_p, double measure_x, double measure_p
|
|||
int n_bits, int n_nodes, const char *ntok, int wcnt, Graph_ctx *gr)
|
||||
{
|
||||
char tmpstr[1024];
|
||||
double yy1;
|
||||
double diffy;
|
||||
double diffx;
|
||||
double yy;
|
||||
char *fmt1, *fmt2;
|
||||
|
||||
|
||||
|
||||
/* show values of signals if cursor1 active */
|
||||
if(measure_p >= 0) {
|
||||
int hex_digits = ((n_bits - 1) >> 2) + 1;
|
||||
double vthl, vthh;
|
||||
|
||||
/* draw node values in graph */
|
||||
bbox(START, 0.0, 0.0, 0.0, 0.0);
|
||||
bbox(ADD, gr->rx1, gr->ry1, gr->rx2, gr->ry2);
|
||||
bbox(SET_INSIDE, 0.0, 0.0, 0.0, 0.0);
|
||||
if(!bus_msb) {
|
||||
double diffy;
|
||||
double diffx;
|
||||
char *fmt1, *fmt2;
|
||||
double yy1;
|
||||
yy1 = xctx->graph_values[idx][measure_p-1];
|
||||
diffy = xctx->graph_values[idx][measure_p] - yy1;
|
||||
diffx = measure_x - measure_prev_x;
|
||||
|
|
@ -2301,6 +2296,8 @@ static void show_node_measures(int measure_p, double measure_x, double measure_p
|
|||
if(gr->unity != 1.0) my_snprintf(tmpstr, S(tmpstr), fmt2, yy * gr->unity, gr->unity_suffix);
|
||||
else my_snprintf(tmpstr, S(tmpstr), fmt1, yy);
|
||||
} else {
|
||||
double vthl, vthh;
|
||||
int hex_digits = ((n_bits - 1) >> 2) + 1;
|
||||
vthh = gr->gy1 * 0.2 + gr->gy2 * 0.8;
|
||||
vthl = gr->gy1 * 0.8 + gr->gy2 * 0.2;
|
||||
get_bus_value(n_bits, hex_digits, idx_arr, measure_p - 1, tmpstr, vthl, vthh);
|
||||
|
|
|
|||
10
src/save.c
10
src/save.c
|
|
@ -976,22 +976,15 @@ int save_schematic(const char *schname) /* 20171020 added return value */
|
|||
{
|
||||
FILE *fd;
|
||||
char name[PATH_MAX]; /* overflow safe 20161122 */
|
||||
char *top_path;
|
||||
struct stat buf;
|
||||
|
||||
top_path = xctx->top_path[0] ? xctx->top_path : ".";
|
||||
|
||||
if( strcmp(schname,"") ) my_strncpy(xctx->sch[xctx->currsch], schname, S(xctx->sch[xctx->currsch]));
|
||||
else return 0;
|
||||
dbg(1, "save_schematic(): currsch=%d name=%s\n",xctx->currsch, schname);
|
||||
dbg(1, "save_schematic(): sch[currsch]=%s\n", xctx->sch[xctx->currsch]);
|
||||
dbg(1, "save_schematic(): abs_sym_path=%s\n", abs_sym_path(xctx->sch[xctx->currsch], ""));
|
||||
my_strncpy(name, xctx->sch[xctx->currsch], S(name));
|
||||
if(has_x) {
|
||||
tclvareval("wm title ", top_path, " \"xschem - [file tail [xschem get schname]]\"", NULL);
|
||||
tclvareval("wm iconname ", top_path, " \"xschem - [file tail [xschem get schname]]\"", NULL);
|
||||
}
|
||||
|
||||
set_modify(-1);
|
||||
if(!stat(name, &buf)) {
|
||||
if(xctx->time_last_modify && xctx->time_last_modify != buf.st_mtime) {
|
||||
tclvareval("ask_save \"Schematic file: ", name,
|
||||
|
|
@ -999,7 +992,6 @@ int save_schematic(const char *schname) /* 20171020 added return value */
|
|||
if(strcmp(tclresult(), "yes") ) return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(!(fd=fopen(name,"w")))
|
||||
{
|
||||
fprintf(errfp, "save_schematic(): problems opening file %s \n",name);
|
||||
|
|
|
|||
|
|
@ -482,10 +482,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
xctx->prep_net_structs=0;
|
||||
xctx->prep_hi_structs=0;
|
||||
if(has_x) {
|
||||
char *top_path;
|
||||
top_path = xctx->top_path[0] ? xctx->top_path : ".";
|
||||
tclvareval("wm title ", top_path, " \"xschem - [file tail [xschem get schname]]\"", NULL);
|
||||
tclvareval("wm iconname ", top_path, " \"xschem - [file tail [xschem get schname]]\"", NULL);
|
||||
set_modify(-1);
|
||||
}
|
||||
}
|
||||
Tcl_ResetResult(interp);
|
||||
|
|
@ -648,13 +645,12 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
|
||||
else if(!strcmp(argv[1],"exit"))
|
||||
{
|
||||
char * top_path;
|
||||
cmd_found = 1;
|
||||
top_path = xctx->top_path[0] ? xctx->top_path : ".";
|
||||
if(!strcmp(top_path, ".")) {
|
||||
if(!strcmp(xctx->top_path, "")) {
|
||||
if(has_x) {
|
||||
tcleval("new_window destroy_all"); /* close child schematics */
|
||||
if(tclresult()[0] == '1') {
|
||||
int remaining;
|
||||
remaining = new_schematic("destroy_all", NULL, NULL);
|
||||
if(!remaining) {
|
||||
if(xctx->modified) {
|
||||
tcleval("tk_messageBox -type okcancel -parent [xschem get topwindow] -message \""
|
||||
"[get_cell [xschem get schname] 0]"
|
||||
|
|
@ -665,7 +661,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
}
|
||||
else tcleval("exit"); /* if has_x == 0 there are no additional windows to close */
|
||||
} else {
|
||||
tclvareval("xschem new_schematic destroy ", top_path, " ", xctx->top_path, ".drw {}" , NULL);
|
||||
new_schematic("destroy", xctx->current_win_path, NULL);
|
||||
}
|
||||
Tcl_ResetResult(interp);
|
||||
}
|
||||
|
|
@ -778,6 +774,9 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
else if(!strcmp(argv[2],"current_name")) {
|
||||
Tcl_SetResult(interp, xctx->current_name, TCL_VOLATILE);
|
||||
}
|
||||
else if(!strcmp(argv[2],"current_win_path")) {
|
||||
Tcl_SetResult(interp, xctx->current_win_path, TCL_VOLATILE);
|
||||
}
|
||||
else if(!strcmp(argv[2],"currsch")) {
|
||||
char s[30]; /* overflow safe 20161122 */
|
||||
my_snprintf(s, S(s), "%d",xctx->currsch);
|
||||
|
|
@ -856,8 +855,13 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
else
|
||||
Tcl_SetResult(interp, "0",TCL_STATIC);
|
||||
}
|
||||
else if(!strcmp(argv[2],"ntabs")) {
|
||||
char s[30];
|
||||
my_snprintf(s, S(s), "%d",new_schematic("ntabs", NULL, NULL));
|
||||
Tcl_SetResult(interp, s,TCL_VOLATILE);
|
||||
}
|
||||
else if(!strcmp(argv[2],"pinlayer")) {
|
||||
char s[30]; /* overflow safe 20161122 */
|
||||
char s[30];
|
||||
my_snprintf(s, S(s), "%d",PINLAYER);
|
||||
Tcl_SetResult(interp, s,TCL_VOLATILE);
|
||||
}
|
||||
|
|
@ -919,6 +923,9 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
my_snprintf(s, S(s), "%d",TEXTLAYER);
|
||||
Tcl_SetResult(interp, s,TCL_VOLATILE);
|
||||
}
|
||||
else if(!strcmp(argv[2],"top_path")) {
|
||||
Tcl_SetResult(interp, xctx->top_path, TCL_VOLATILE);
|
||||
}
|
||||
else if(!strcmp(argv[2],"topwindow")) {
|
||||
char *top_path;
|
||||
top_path = xctx->top_path[0] ? xctx->top_path : ".";
|
||||
|
|
@ -1570,7 +1577,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
my_snprintf(fullname, S(fullname),"%s", tclresult());
|
||||
}
|
||||
if( fullname[0] ) {
|
||||
tclvareval("new_window create {", fullname, "}", NULL);
|
||||
new_schematic("create", NULL, fullname);
|
||||
tclvareval("update_recent_file {", fullname, "}", NULL);
|
||||
}
|
||||
}
|
||||
|
|
@ -1714,9 +1721,9 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
else if(!strcmp(argv[1],"new_schematic"))
|
||||
{
|
||||
cmd_found = 1;
|
||||
if(argc == 4) new_schematic(argv[2], argv[3], "{}","{}");
|
||||
else if(argc == 5) new_schematic(argv[2], argv[3], argv[4], "{}");
|
||||
else if(argc == 6) new_schematic(argv[2], argv[3], argv[4], argv[5]);
|
||||
if(argc == 3) new_schematic(argv[2], NULL, NULL);
|
||||
else if(argc == 4) new_schematic(argv[2], argv[3], NULL);
|
||||
else if(argc == 5) new_schematic(argv[2], argv[3], argv[4]);
|
||||
Tcl_ResetResult(interp);
|
||||
}
|
||||
|
||||
|
|
@ -2482,6 +2489,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
text_svg=atoi(argv[3]);
|
||||
}
|
||||
else if(!strcmp(argv[2],"semaphore")) {
|
||||
dbg(1, "scheduler(): set semaphore to %s\n", argv[3]);
|
||||
xctx->semaphore=atoi(argv[3]);
|
||||
}
|
||||
else if(!strcmp(argv[2],"sym_txt")) {
|
||||
|
|
|
|||
436
src/xinit.c
436
src/xinit.c
|
|
@ -318,7 +318,7 @@ void init_pixdata()/* populate xctx->fill_type array that is used in create_gc()
|
|||
}
|
||||
}
|
||||
|
||||
void free_xschem_data()
|
||||
static void free_xschem_data()
|
||||
{
|
||||
int i;
|
||||
xctx->delete_undo();
|
||||
|
|
@ -373,6 +373,7 @@ void free_xschem_data()
|
|||
my_free(1123, &xctx->enable_layer);
|
||||
my_free(1121, &xctx->active_layer);
|
||||
my_free(1295, &xctx->top_path);
|
||||
my_free(1295, &xctx->current_win_path);
|
||||
my_free(1120, &xctx->fill_type);
|
||||
if(xctx->inst_redraw_table) my_free(604, &xctx->inst_redraw_table);
|
||||
my_free(269, &xctx);
|
||||
|
|
@ -401,7 +402,7 @@ void free_gc()
|
|||
}
|
||||
}
|
||||
|
||||
void alloc_xschem_data(const char *top_path)
|
||||
static void alloc_xschem_data(const char *top_path, const char *win_path)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
|
|
@ -598,7 +599,9 @@ void alloc_xschem_data(const char *top_path)
|
|||
xctx->hide_symbols = 0;
|
||||
xctx->netlist_type = CAD_SPICE_NETLIST;
|
||||
xctx->top_path = NULL;
|
||||
xctx->current_win_path = NULL;
|
||||
my_strdup2(1296, &xctx->top_path, top_path);
|
||||
my_strdup2(1462, &xctx->current_win_path, win_path);
|
||||
xctx->fill_type=my_calloc(640, cadlayers, sizeof(int));
|
||||
xctx->fill_pattern = 1;
|
||||
xctx->draw_window = 0;
|
||||
|
|
@ -894,7 +897,7 @@ int source_tcl_file(char *s)
|
|||
return TCL_OK;
|
||||
}
|
||||
|
||||
void preview_window(const char *what, const char *tk_win_path, const char *filename)
|
||||
void preview_window(const char *what, const char *win_path, const char *filename)
|
||||
{
|
||||
static char *current_file = NULL;
|
||||
static Xschem_ctx *save_xctx = NULL; /* save pointer to current schematic context structure */
|
||||
|
|
@ -904,8 +907,8 @@ void preview_window(const char *what, const char *tk_win_path, const char *filen
|
|||
|
||||
dbg(1, "------\n");
|
||||
if(!strcmp(what, "create")) {
|
||||
dbg(1, "preview_window() create, save ctx, tk_win_path=%s\n", tk_win_path);
|
||||
tkpre_window = Tk_NameToWindow(interp, tk_win_path, mainwindow);
|
||||
dbg(1, "preview_window() create, save ctx, win_path=%s\n", win_path);
|
||||
tkpre_window = Tk_NameToWindow(interp, win_path, mainwindow);
|
||||
Tk_MakeWindowExist(tkpre_window);
|
||||
pre_window = Tk_WindowId(tkpre_window);
|
||||
save_xctx = xctx; /* save current schematic */
|
||||
|
|
@ -919,7 +922,7 @@ void preview_window(const char *what, const char *tk_win_path, const char *filen
|
|||
}
|
||||
my_strdup(117, ¤t_file, filename);
|
||||
xctx = NULL; /* reset for preview */
|
||||
alloc_xschem_data(".dialog"); /* alloc data into xctx */
|
||||
alloc_xschem_data(".dialog", ".dialog.drw"); /* alloc data into xctx */
|
||||
init_pixdata(); /* populate xctx->fill_type array that is used in create_gc() to set fill styles */
|
||||
preview_xctx = xctx;
|
||||
preview_xctx->window = pre_window;
|
||||
|
|
@ -950,137 +953,338 @@ void preview_window(const char *what, const char *tk_win_path, const char *filen
|
|||
}
|
||||
|
||||
|
||||
/* top_path is the path prefix of tk_win_path:
|
||||
/* top_path is the path prefix of win_path:
|
||||
*
|
||||
* tk_win_path top_path
|
||||
* win_path top_path
|
||||
* ".drw" ""
|
||||
* ".xx.drw" ".xx"
|
||||
* ".x1.drw" ".x1"
|
||||
*/
|
||||
void new_schematic(const char *what, const char *top_path, const char *tk_win_path, const char *filename)
|
||||
int new_schematic(const char *what, const char *win_path, const char *filename)
|
||||
{
|
||||
static int cnt = 0;
|
||||
static Xschem_ctx *save_xctx[MAX_NEW_WINDOWS]; /* save pointer to current schematic context structure */
|
||||
static Tk_Window tknew_window[MAX_NEW_WINDOWS];
|
||||
/* static Tk_Window new_window[MAX_NEW_WINDOWS]; */
|
||||
static char new_window[MAX_NEW_WINDOWS][80];
|
||||
int i, n;
|
||||
Window new_window;
|
||||
Tk_Window tkwin;
|
||||
char toppath[80];
|
||||
int tabbed_interface;
|
||||
const char *tmp;
|
||||
|
||||
if(!strcmp(what, "create")) {
|
||||
dbg(1, "new_schematic() create, save ctx tk_win_path=%s\n", tk_win_path);
|
||||
if(cnt == 0) {
|
||||
for(i = 0; i < MAX_NEW_WINDOWS; i++) {
|
||||
save_xctx[i] = NULL;
|
||||
tknew_window[i] = NULL;
|
||||
}
|
||||
save_xctx[0] = xctx; /* save current schematic */
|
||||
tknew_window[0] = Tk_NameToWindow(interp, ".drw", mainwindow);
|
||||
}
|
||||
if(cnt + 1 >= MAX_NEW_WINDOWS) {
|
||||
dbg(0, "new_schematic(\"create\"...): no more free slots\n");
|
||||
return; /* no more free slots */
|
||||
}
|
||||
cnt++;
|
||||
n = -1;
|
||||
for(i = 1; i < MAX_NEW_WINDOWS; i++) { /* search 1st free slot */
|
||||
if(save_xctx[i] == NULL) {
|
||||
n = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(n == -1) {
|
||||
dbg(0, "new_schematic(\"create\"...): no more free slots\n");
|
||||
return;
|
||||
}
|
||||
tknew_window[n] = Tk_NameToWindow(interp, tk_win_path, mainwindow);
|
||||
Tk_MakeWindowExist(tknew_window[n]);
|
||||
new_window = Tk_WindowId(tknew_window[n]);
|
||||
Tk_ChangeWindowAttributes(tknew_window[n], CWBackingStore, &winattr);
|
||||
dbg(1, "new_schematic() draw\n");
|
||||
xctx = NULL; /* reset for preview */
|
||||
alloc_xschem_data(top_path); /* alloc data into xctx */
|
||||
xctx->netlist_type = CAD_SPICE_NETLIST; /* for new windows start with spice netlist mode */
|
||||
tclsetvar("netlist_type","spice");
|
||||
init_pixdata();/* populate xctx->fill_type array that is used in create_gc() to set fill styles */
|
||||
save_xctx[n] = xctx;
|
||||
dbg(1, "new_schematic() draw, load schematic\n");
|
||||
xctx->window = new_window;
|
||||
set_snap(0); /* set default value specified in xschemrc as 'snap' else CADSNAP */
|
||||
set_grid(0); /* set default value specified in xschemrc as 'grid' else CADGRID */
|
||||
create_gc();
|
||||
enable_layers();
|
||||
build_colors(0.0, 0.0);
|
||||
resetwin(1, 0, 1, 0, 0); /* create preview pixmap. resetwin(create_pixmap, clear_pixmap, force, w, h) */
|
||||
/* draw empty window so if following load fails due to missing file window appears correctly drawn */
|
||||
zoom_full(1, 0, 1, 0.97);
|
||||
load_schematic(1,filename, 1);
|
||||
zoom_full(1, 0, 1, 0.97); /* draw */
|
||||
} else if(!strcmp(what, "destroy")) {
|
||||
if(cnt) {
|
||||
int close = 0;
|
||||
dbg(1, "new_schematic() destroy\n");
|
||||
/* reset old focused window so callback() will force repaint on expose events */
|
||||
if(xctx->modified && has_x) {
|
||||
tcleval("tk_messageBox -type okcancel -parent [xschem get topwindow] -message \""
|
||||
"[get_cell [xschem get schname] 0]"
|
||||
": UNSAVED data: want to exit?\"");
|
||||
if(strcmp(tclresult(),"ok")==0) close = 1;
|
||||
}
|
||||
else close = 1;
|
||||
Tcl_ResetResult(interp);
|
||||
if(close) {
|
||||
tkwin = Tk_NameToWindow(interp, tk_win_path, mainwindow); /* NULL if tk_win_path not existing */
|
||||
if(!tkwin) dbg(0, "new_schematic(\"destroy\", ...): Warning: %s has been destroyed\n", tk_win_path);
|
||||
n = -1;
|
||||
if(tkwin) for(i = 1; i < MAX_NEW_WINDOWS; i++) {
|
||||
if(tkwin == tknew_window[i]) {
|
||||
n = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(n == -1) {
|
||||
dbg(0, "new_schematic(\"destroy\"...): no window to destroy found: %s\n", tk_win_path);
|
||||
return;
|
||||
}
|
||||
if(tkwin && n >= 1 && n < MAX_NEW_WINDOWS) {
|
||||
xctx = save_xctx[n];
|
||||
delete_schematic_data();
|
||||
save_xctx[n] = NULL;
|
||||
tclvareval("winfo toplevel ", tk_win_path, NULL);
|
||||
Tk_DestroyWindow(tknew_window[n]);
|
||||
tclvareval("destroy ", tclresult(), NULL);
|
||||
tknew_window[n] = NULL;
|
||||
/* delete Tcl context of deleted schematic window */
|
||||
tclvareval("delete_ctx ", tk_win_path, "; incr tctx::cnt -1", NULL);
|
||||
cnt--;
|
||||
tabbed_interface = 0;
|
||||
if((tmp = tclgetvar("tabbed_interface"))) {
|
||||
if(tmp[0] == '1') tabbed_interface = 1;
|
||||
}
|
||||
dbg(1, "new_schematic(): current_win_path=%s, what=%s, win_path=%s\n", xctx->current_win_path, what, win_path);
|
||||
/********************** NTABS **********************/
|
||||
if(!strcmp(what, "ntabs")) {
|
||||
return cnt;
|
||||
} else if(!strcmp(what, "create")) {
|
||||
/********************** CREATE **********************/
|
||||
if(!tabbed_interface) {
|
||||
Window win_id;
|
||||
dbg(1, "new_schematic() create\n");
|
||||
if(cnt == 0) {
|
||||
for(i = 0; i < MAX_NEW_WINDOWS; i++) {
|
||||
save_xctx[i] = NULL;
|
||||
my_strncpy(new_window[i], "", S(new_window[i]));
|
||||
}
|
||||
tcleval("save_ctx .drw");
|
||||
save_xctx[0] = xctx; /* save current schematic */
|
||||
/* new_window[0] = Tk_NameToWindow(interp, ".drw", mainwindow); */
|
||||
my_strncpy(new_window[0], ".drw", S(new_window[0]));
|
||||
}
|
||||
xctx = save_xctx[0]; /* restore main (.drw) schematic */
|
||||
tcleval("restore_ctx .drw; housekeeping_ctx");
|
||||
set_modify(xctx->modified); /* sets window title */
|
||||
}
|
||||
} else if(!strcmp(what, "switch")) {
|
||||
if(cnt) {
|
||||
dbg(1, "new_schematic() switch: %s\n", tk_win_path);
|
||||
tkwin = Tk_NameToWindow(interp, tk_win_path, mainwindow); /* NULL if tk_win_path not existing */
|
||||
if(!tkwin) dbg(0, "new_schematic(\"switch\",...): Warning: %s has been destroyed\n", tk_win_path);
|
||||
if(cnt + 1 >= MAX_NEW_WINDOWS) {
|
||||
dbg(0, "new_schematic(\"create\"...): no more free slots\n");
|
||||
return cnt; /* no more free slots */
|
||||
}
|
||||
cnt++;
|
||||
n = -1;
|
||||
if(tkwin) for(i = 0; i < MAX_NEW_WINDOWS; i++) {
|
||||
if(tkwin == tknew_window[i]) {
|
||||
for(i = 1; i < MAX_NEW_WINDOWS; i++) { /* search 1st free slot */
|
||||
if(save_xctx[i] == NULL) {
|
||||
n = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(n == -1) {
|
||||
dbg(0, "new_schematic(\"switch\"...): no window to switch to found: %s\n", tk_win_path);
|
||||
return;
|
||||
dbg(0, "new_schematic(\"create\"...): no more free slots\n");
|
||||
return cnt;
|
||||
}
|
||||
/* if window was closed then tkwin == 0 --> do nothing */
|
||||
if(tkwin && n >= 0 && n < MAX_NEW_WINDOWS) {
|
||||
xctx = save_xctx[n];
|
||||
my_snprintf(new_window[n], S(new_window[n]), ".x%d.drw", n);
|
||||
my_snprintf(toppath, S(toppath), ".x%d", n);
|
||||
tclvareval("toplevel ", toppath, " -bg {} -width 400 -height 400", NULL);
|
||||
tclvareval("build_widgets ", toppath, NULL);
|
||||
tclvareval("pack_widgets ", toppath, " ; update", NULL);
|
||||
Tk_MakeWindowExist(Tk_NameToWindow(interp, new_window[n], mainwindow));
|
||||
win_id = Tk_WindowId(Tk_NameToWindow(interp, new_window[n], mainwindow));
|
||||
Tk_ChangeWindowAttributes(Tk_NameToWindow(interp, new_window[n], mainwindow), CWBackingStore, &winattr);
|
||||
dbg(1, "new_schematic() draw\n");
|
||||
xctx = NULL; /* reset for preview */
|
||||
alloc_xschem_data(toppath, new_window[n]); /* alloc data into xctx */
|
||||
xctx->netlist_type = CAD_SPICE_NETLIST; /* for new windows start with spice netlist mode */
|
||||
tclsetvar("netlist_type","spice");
|
||||
init_pixdata();/* populate xctx->fill_type array that is used in create_gc() to set fill styles */
|
||||
save_xctx[n] = xctx;
|
||||
dbg(1, "new_schematic() draw, load schematic\n");
|
||||
xctx->window = win_id;
|
||||
set_snap(0); /* set default value specified in xschemrc as 'snap' else CADSNAP */
|
||||
set_grid(0); /* set default value specified in xschemrc as 'grid' else CADGRID */
|
||||
create_gc();
|
||||
enable_layers();
|
||||
build_colors(0.0, 0.0);
|
||||
resetwin(1, 0, 1, 0, 0); /* create preview pixmap. resetwin(create_pixmap, clear_pixmap, force, w, h) */
|
||||
/* draw empty window so if following load fails due to missing file window appears correctly drawn */
|
||||
zoom_full(1, 0, 1, 0.97);
|
||||
load_schematic(1,filename, 1);
|
||||
zoom_full(1, 0, 1, 0.97); /* draw */
|
||||
tclvareval("set_bindings ", new_window[n], NULL);
|
||||
tclvareval("save_ctx ", new_window[n], NULL);
|
||||
windowid(toppath);
|
||||
/********************** NEW_TAB **********************/
|
||||
} else {
|
||||
dbg(1, "new_schematic() new_tab, creating...\n");
|
||||
if(cnt == 0) {
|
||||
for(i = 0; i < MAX_NEW_WINDOWS; i++) {
|
||||
save_xctx[i] = NULL;
|
||||
my_strncpy(new_window[i], "", S(new_window[i]));
|
||||
}
|
||||
tcleval("save_ctx .drw");
|
||||
save_xctx[0] = xctx; /* save current schematic */
|
||||
my_strncpy(new_window[0], ".drw", S(new_window[0]));
|
||||
}
|
||||
if(cnt + 1 >= MAX_NEW_WINDOWS) {
|
||||
dbg(0, "new_schematic(\"new_tab\"...): no more free slots\n");
|
||||
return cnt; /* no more free slots */
|
||||
}
|
||||
cnt++;
|
||||
n = -1;
|
||||
for(i = 1; i < MAX_NEW_WINDOWS; i++) { /* search 1st free slot */
|
||||
if(save_xctx[i] == NULL) {
|
||||
n = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(n == -1) {
|
||||
dbg(0, "new_schematic(\"newtab\"...): no more free slots\n");
|
||||
return cnt;
|
||||
}
|
||||
my_strncpy(new_window[n], win_path, S(new_window[n]));
|
||||
xctx = NULL; /* reset for preview */
|
||||
alloc_xschem_data("", win_path); /* alloc data into xctx */
|
||||
xctx->netlist_type = CAD_SPICE_NETLIST; /* for new windows start with spice netlist mode */
|
||||
tclsetvar("netlist_type","spice");
|
||||
init_pixdata();/* populate xctx->fill_type array that is used in create_gc() to set fill styles */
|
||||
save_xctx[n] = xctx;
|
||||
dbg(1, "new_schematic() draw, load schematic\n");
|
||||
xctx->window = save_xctx[0]->window;
|
||||
set_snap(0); /* set default value specified in xschemrc as 'snap' else CADSNAP */
|
||||
set_grid(0); /* set default value specified in xschemrc as 'grid' else CADGRID */
|
||||
create_gc();
|
||||
enable_layers();
|
||||
build_colors(0.0, 0.0);
|
||||
resetwin(1, 0, 1, 0, 0); /* create pixmap. resetwin(create_pixmap, clear_pixmap, force, w, h) */
|
||||
/* draw empty window so if following load fails due to missing file window appears correctly drawn */
|
||||
zoom_full(1, 0, 1, 0.97);
|
||||
load_schematic(1,filename, 1);
|
||||
zoom_full(1, 0, 1, 0.97); /* draw */
|
||||
}
|
||||
} else if(!strcmp(what, "destroy")) {
|
||||
/********************** DESTROY **********************/
|
||||
if(!tabbed_interface) {
|
||||
Xschem_ctx *savectx;
|
||||
savectx = xctx;
|
||||
if(cnt) {
|
||||
int close = 0;
|
||||
dbg(1, "new_schematic() destroy {%s}\n", win_path);
|
||||
if(xctx->modified && has_x) {
|
||||
tcleval("tk_messageBox -type okcancel -parent [xschem get topwindow] -message \""
|
||||
"[get_cell [xschem get schname] 0]"
|
||||
": UNSAVED data: want to exit?\"");
|
||||
if(strcmp(tclresult(),"ok")==0) close = 1;
|
||||
}
|
||||
else close = 1;
|
||||
Tcl_ResetResult(interp);
|
||||
if(close) {
|
||||
tkwin = Tk_NameToWindow(interp, win_path, mainwindow); /* NULL if win_path not existing */
|
||||
if(!tkwin) dbg(0, "new_schematic(\"destroy\", ...): Warning: %s has been destroyed\n", win_path);
|
||||
n = -1;
|
||||
if(tkwin) for(i = 1; i < MAX_NEW_WINDOWS; i++) {
|
||||
if(!strcmp(win_path, new_window[i])) {
|
||||
n = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(n == -1) {
|
||||
dbg(0, "new_schematic(\"destroy\"...): no window to destroy found: %s\n", win_path);
|
||||
return cnt;
|
||||
}
|
||||
if(tkwin && n >= 1 && n < MAX_NEW_WINDOWS) {
|
||||
xctx = save_xctx[n];
|
||||
/* set saved ctx to main window if current is to be destroyed */
|
||||
if(savectx == xctx) savectx = save_xctx[0];
|
||||
tclvareval("winfo toplevel ", win_path, NULL);
|
||||
delete_schematic_data();
|
||||
save_xctx[n] = NULL;
|
||||
Tk_DestroyWindow(Tk_NameToWindow(interp, new_window[n], mainwindow));
|
||||
tclvareval("destroy ", tclresult(), NULL);
|
||||
my_strncpy(new_window[n], "", S(new_window[n]));
|
||||
/* delete Tcl context of deleted schematic window */
|
||||
tclvareval("delete_ctx ", win_path, NULL);
|
||||
cnt--;
|
||||
}
|
||||
}
|
||||
/* following 3 lines must be done also if window not closed */
|
||||
xctx = savectx; /* restore previous schematic or main window if previous destroyed */
|
||||
tcleval("restore_ctx .drw; housekeeping_ctx");
|
||||
set_modify(xctx->modified); /* sets window title */
|
||||
}
|
||||
/********************** DESTROY_TAB **********************/
|
||||
} else {
|
||||
if(cnt) {
|
||||
int close = 0;
|
||||
dbg(1, "new_schematic() destroy_tab\n");
|
||||
|
||||
if(strcmp(win_path, xctx->current_win_path)) {
|
||||
dbg(0, "new_schematic(\"destroy_tab\", %s): must be in this tab to destroy\n", win_path);
|
||||
return cnt;
|
||||
}
|
||||
if(xctx->modified && has_x) {
|
||||
tcleval("tk_messageBox -type okcancel -parent [xschem get topwindow] -message \""
|
||||
"[get_cell [xschem get schname] 0]"
|
||||
": UNSAVED data: want to exit?\"");
|
||||
if(strcmp(tclresult(),"ok")==0) close = 1;
|
||||
}
|
||||
else close = 1;
|
||||
Tcl_ResetResult(interp);
|
||||
if(close) {
|
||||
n = -1;
|
||||
for(i = 1; i < MAX_NEW_WINDOWS; i++) {
|
||||
if(!strcmp(win_path, new_window[i])) {
|
||||
n = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(n == -1) {
|
||||
dbg(0, "new_schematic(\"destroy_tab\"...): no tab to destroy found: %s\n", win_path);
|
||||
return cnt;
|
||||
}
|
||||
if(n >= 1 && n < MAX_NEW_WINDOWS) {
|
||||
xctx = save_xctx[n];
|
||||
delete_schematic_data();
|
||||
save_xctx[n] = NULL;
|
||||
my_strncpy(new_window[n], "", S(new_window[n]));
|
||||
/* delete Tcl context of deleted schematic window */
|
||||
tclvareval("delete_ctx ", win_path, NULL);
|
||||
cnt--;
|
||||
}
|
||||
xctx = save_xctx[0]; /* restore main (.drw) schematic */
|
||||
tcleval("restore_ctx .drw; housekeeping_ctx");
|
||||
set_modify(xctx->modified); /* sets window title */
|
||||
draw();
|
||||
}
|
||||
} else {
|
||||
dbg(0, "new_schematic() destroy_tab: there are no additional tabs\n");
|
||||
}
|
||||
}
|
||||
/********************** DESTROY_ALL **********************/
|
||||
} else if(!strcmp(what, "destroy_all")) {
|
||||
Xschem_ctx *savectx;
|
||||
savectx = xctx;
|
||||
if(cnt) {
|
||||
int close;
|
||||
dbg(1, "new_schematic() destroy_all\n");
|
||||
for(i = 1; i < MAX_NEW_WINDOWS; i++) {
|
||||
if(new_window[i][0]) {
|
||||
tkwin = Tk_NameToWindow(interp, new_window[i], mainwindow); /* NULL if win_path not existing */
|
||||
if(!tkwin) dbg(0, "new_schematic(\"switch\",...): Warning: %s has been destroyed\n", new_window[i]);
|
||||
else {
|
||||
xctx = save_xctx[i];
|
||||
close = 0;
|
||||
/* reset old focused window so callback() will force repaint on expose events */
|
||||
if(xctx->modified && has_x) {
|
||||
tcleval("tk_messageBox -type okcancel -parent [xschem get topwindow] -message \""
|
||||
"[get_cell [xschem get schname] 0]"
|
||||
": UNSAVED data: want to exit?\"");
|
||||
if(strcmp(tclresult(),"ok")==0) close = 1;
|
||||
}
|
||||
else close = 1;
|
||||
Tcl_ResetResult(interp);
|
||||
if(close) {
|
||||
tclvareval("winfo toplevel ", new_window[i], NULL);
|
||||
delete_schematic_data();
|
||||
/* set saved ctx to main window if previous is about to be destroyed */
|
||||
if(savectx == save_xctx[i]) savectx = save_xctx[0];
|
||||
save_xctx[i] = NULL;
|
||||
Tk_DestroyWindow(Tk_NameToWindow(interp, new_window[i], mainwindow));
|
||||
tclvareval("destroy ", tclresult(), NULL);
|
||||
/* delete Tcl context of deleted schematic window */
|
||||
tclvareval("delete_ctx ", new_window[i], NULL);
|
||||
my_strncpy(new_window[i], "", S(new_window[i]));
|
||||
cnt--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* following 3 lines must be done also if windows not closed */
|
||||
xctx = savectx; /* restore previous schematic or main if old is destroyed */
|
||||
tcleval("restore_ctx .drw; housekeeping_ctx");
|
||||
set_modify(xctx->modified); /* sets window title */
|
||||
} else if(!strcmp(what, "switch")) {
|
||||
/********************** SWITCH **********************/
|
||||
if(!tabbed_interface) {
|
||||
if(cnt) {
|
||||
dbg(1, "new_schematic() switch: %s\n", win_path);
|
||||
tkwin = Tk_NameToWindow(interp, win_path, mainwindow); /* NULL if win_path not existing */
|
||||
if(!tkwin) dbg(0, "new_schematic(\"switch\",...): Warning: %s has been destroyed\n", win_path);
|
||||
n = -1;
|
||||
if(tkwin) for(i = 0; i < MAX_NEW_WINDOWS; i++) {
|
||||
if(!strcmp(win_path, new_window[i])) {
|
||||
n = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(n == -1) {
|
||||
dbg(0, "new_schematic(\"switch\"...): no window to switch to found: %s\n", win_path);
|
||||
return cnt;
|
||||
}
|
||||
/* if window was closed then tkwin == 0 --> do nothing */
|
||||
if(tkwin && n >= 0 && n < MAX_NEW_WINDOWS) {
|
||||
xctx = save_xctx[n];
|
||||
set_modify(xctx->modified); /* sets window title */
|
||||
}
|
||||
}
|
||||
/********************** SWITCH_TAB **********************/
|
||||
} else {
|
||||
if(cnt) {
|
||||
dbg(1, "new_schematic() switch_tab: %s\n", win_path);
|
||||
n = -1;
|
||||
for(i = 0; i < MAX_NEW_WINDOWS; i++) {
|
||||
if(!strcmp(win_path, new_window[i])) {
|
||||
n = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(n == -1) {
|
||||
dbg(0, "new_schematic(\"switch_tab\"...): no tab to switch to found: %s\n", win_path);
|
||||
return cnt;
|
||||
}
|
||||
/* if window was closed then tkwin == 0 --> do nothing */
|
||||
if(n >= 0 && n < MAX_NEW_WINDOWS) {
|
||||
tclvareval("save_ctx ", xctx->current_win_path, NULL);
|
||||
xctx = save_xctx[n];
|
||||
tclvareval("restore_ctx ", win_path, NULL);
|
||||
tclvareval("housekeeping_ctx", NULL);
|
||||
tclvareval("reconfigure_layers_button {}", NULL);
|
||||
xctx->window = save_xctx[0]->window;
|
||||
resetwin(1, 1, 1, 0, 0);
|
||||
set_modify(xctx->modified); /* sets window title */
|
||||
draw();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
void change_linewidth(double w)
|
||||
|
|
@ -1601,7 +1805,7 @@ int Tcl_AppInit(Tcl_Interp *inter)
|
|||
/* */
|
||||
/* [m]allocate dynamic memory */
|
||||
/* */
|
||||
alloc_xschem_data("");
|
||||
alloc_xschem_data("", ".drw");
|
||||
|
||||
/* global context / graphic preferences/settings */
|
||||
pixdata=my_calloc(641, cadlayers, sizeof(char*));
|
||||
|
|
|
|||
16
src/xschem.h
16
src/xschem.h
|
|
@ -668,7 +668,7 @@ typedef struct
|
|||
} Iterator_ctx;
|
||||
|
||||
|
||||
/* will be used some day? <<<< */
|
||||
/* context struct for waveform graphs */
|
||||
typedef struct {
|
||||
double digital;
|
||||
double rx1, ry1, rx2, ry2, rw, rh; /* container rectangle */
|
||||
|
|
@ -905,13 +905,15 @@ typedef struct {
|
|||
int hide_symbols;
|
||||
int netlist_type;
|
||||
char * top_path;
|
||||
/* top_path is the path prefix of drawing canvas:
|
||||
/* top_path is the path prefix of drawing canvas (current_win_path):
|
||||
*
|
||||
* canvas top_path
|
||||
* ----------------------
|
||||
* ".drw" ""
|
||||
* ".xx.drw" ".xx"
|
||||
* current_win_path
|
||||
* canvas top_path
|
||||
* ----------------------------
|
||||
* ".drw" ""
|
||||
* ".xx.drw" ".xx"
|
||||
*/
|
||||
char *current_win_path;
|
||||
int *fill_type; /* for every layer: 0: no fill, 1, solid fill, 2: stipple fill */
|
||||
int fill_pattern;
|
||||
int draw_window;
|
||||
|
|
@ -1368,7 +1370,7 @@ extern void change_layer();
|
|||
extern void launcher();
|
||||
extern void windowid(const char *winpath);
|
||||
extern void preview_window(const char *what, const char *tk_win_path, const char *filename);
|
||||
extern void new_schematic(const char *what, const char *top_path, const char *tk_win_path, const char *filename);
|
||||
extern int new_schematic(const char *what, const char *win_path, const char *filename);
|
||||
extern int window_state (Display *disp, Window win, char *arg);
|
||||
extern void toggle_fullscreen(const char *topwin);
|
||||
extern void toggle_only_probes();
|
||||
|
|
|
|||
140
src/xschem.tcl
140
src/xschem.tcl
|
|
@ -3586,6 +3586,7 @@ proc context_menu { } {
|
|||
|
||||
#
|
||||
# toolbar: Public variables that we allow to be overridden
|
||||
# Code contributed by Neil Johnson (github: nejohnson)
|
||||
#
|
||||
proc setup_toolbar {} {
|
||||
global toolbar_visible toolbar_horiz toolbar_list XSCHEM_SHAREDIR
|
||||
|
|
@ -3656,10 +3657,14 @@ proc toolbar_create {name cmd { help "" } {topwin {} } } {
|
|||
# adding any separators as needed.
|
||||
#
|
||||
proc toolbar_show { { topwin {} } } {
|
||||
global toolbar_horiz toolbar_list toolbar_visible
|
||||
global toolbar_horiz toolbar_list toolbar_visible tabbed_interface
|
||||
if { ! $toolbar_visible } { return }
|
||||
if { $toolbar_horiz } {
|
||||
pack $topwin.toolbar -fill x -before $topwin.drw
|
||||
if {$tabbed_interface} {
|
||||
pack $topwin.toolbar -fill x -before $topwin.tabs
|
||||
} else {
|
||||
pack $topwin.toolbar -fill x -before $topwin.drw
|
||||
}
|
||||
} else {
|
||||
pack $topwin.toolbar -side left -anchor w -fill y -before $topwin.drw
|
||||
}
|
||||
|
|
@ -3709,6 +3714,22 @@ proc toolbar_hide { { topwin {} } } {
|
|||
set $toolbar_visible 0
|
||||
}
|
||||
|
||||
|
||||
proc set_tab_names {} {
|
||||
global tabbed_interface has_x
|
||||
|
||||
if {[info exists has_x] && $tabbed_interface } {
|
||||
set currwin [xschem get current_win_path]
|
||||
# puts "set_tab_names : currwin=$currwin"
|
||||
if { $currwin eq {.drw}} {
|
||||
.tabs.x0 configure -text [file rootname [file tail [xschem get schname]]]
|
||||
} else {
|
||||
regsub {\.drw} $currwin {} top_path
|
||||
.tabs$top_path configure -text [file rootname [file tail [xschem get schname]]]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
proc raise_dialog {parent window_path } {
|
||||
if {[winfo exists .dialog] && [winfo ismapped .dialog] && [winfo ismapped $parent] &&
|
||||
[wm stackorder .dialog isbelow $parent ]} {
|
||||
|
|
@ -3735,91 +3756,10 @@ proc every {interval script} {
|
|||
after $interval [list every $interval $script]
|
||||
}
|
||||
|
||||
proc new_window {what {filename {}} {path {-}}} {
|
||||
global max_new_windows
|
||||
if { $what eq {create}} {
|
||||
if {$tctx::cnt == 0} {
|
||||
save_ctx .drw
|
||||
}
|
||||
if {$tctx::cnt + 1 >= $max_new_windows} {
|
||||
puts "proc new_window: no more free slots"
|
||||
return
|
||||
}
|
||||
incr tctx::cnt
|
||||
|
||||
if {$path eq {-}} {
|
||||
for {set i 1} {$i <= $tctx::cnt} {incr i} {
|
||||
if {![winfo exists .x$i]} {
|
||||
set path .x$i
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
toplevel $path -bg {} -width 400 -height 400
|
||||
build_widgets $path
|
||||
pack_widgets $path
|
||||
update
|
||||
xschem new_schematic create $path $path.drw [abs_sym_path $filename]
|
||||
set_bindings $path.drw
|
||||
# set bindings after creating new schematic otherwise
|
||||
# a Configure or Expose event is sent before window setup completed.
|
||||
save_ctx $path.drw
|
||||
xschem windowid $path ;# set icon for window
|
||||
return $path
|
||||
} elseif { $what eq {destroy}} {
|
||||
set path $filename
|
||||
xschem new_schematic switch $path $path.drw {}
|
||||
#### no need to switch tcl context to something that is about to be deleted
|
||||
# restore_ctx $path.drw
|
||||
# housekeeping_ctx
|
||||
####
|
||||
# xschem new_schematic destroy also decrements tctx::cnt
|
||||
xschem new_schematic destroy $path $path.drw {}
|
||||
#### following 3 lines already done in new_schematic("destroy",...)
|
||||
# restore_ctx .drw
|
||||
# housekeeping_ctx
|
||||
# xschem new_schematic switch . .drw {}
|
||||
####
|
||||
} elseif { $what eq {destroy_all}} {
|
||||
set all_closed 1
|
||||
foreach i [info globals .*.drw] {
|
||||
regsub {\.drw$} $i {} j
|
||||
xschem new_schematic switch $j $i {}
|
||||
#### no need to switch tcl context to something that is about to be deleted
|
||||
# restore_ctx $i
|
||||
# housekeeping_ctx
|
||||
####
|
||||
xschem new_schematic destroy $j $i {}
|
||||
#### following 3 lines already done in new_schematic("destroy",...)
|
||||
# restore_ctx .drw
|
||||
# housekeeping_ctx
|
||||
# xschem new_schematic switch . .drw {}
|
||||
####
|
||||
if { [winfo exists $i] } { set all_closed 0}
|
||||
}
|
||||
return $all_closed
|
||||
}
|
||||
return {}
|
||||
}
|
||||
|
||||
#### TEST MODE #####
|
||||
proc test1 {} {
|
||||
xschem load [abs_sym_path rom8k.sch]
|
||||
new_window create [abs_sym_path mos_power_ampli.sch] .xx
|
||||
new_window create [abs_sym_path solar_panel.sch] .yy
|
||||
}
|
||||
|
||||
#### TEST MODE #####
|
||||
proc test1_end {} {
|
||||
new_window destroy .xx
|
||||
new_window destroy .yy
|
||||
}
|
||||
|
||||
## tcl context switching global namespace
|
||||
namespace eval tctx {
|
||||
variable tctx
|
||||
variable i
|
||||
variable cnt 0
|
||||
variable global_list
|
||||
variable global_array_list
|
||||
variable dialog_list
|
||||
|
|
@ -3845,6 +3785,7 @@ proc no_open_dialogs {} {
|
|||
## "textwindow_wcounter" should be kept unique as it is the number of open textwindows
|
||||
## "viewdata_wcounter" should be kept unique as it is the number of open viewdatas
|
||||
## "measure_id" should be kept unique since we allow only one measure tooltip in graphs
|
||||
## tabbed_interface is unique
|
||||
|
||||
set tctx::global_list {
|
||||
auto_hilight autotrim_wires bespice_listen_port big_grid_points bus_replacement_char
|
||||
|
|
@ -3892,6 +3833,7 @@ proc delete_ctx {context} {
|
|||
}
|
||||
|
||||
proc restore_ctx {context} {
|
||||
# puts "restoring tcl context $context : semaphore=[xschem get semaphore]"
|
||||
set tctx::tctx $context
|
||||
array unset ::sim
|
||||
uplevel #0 {
|
||||
|
|
@ -3914,6 +3856,7 @@ proc restore_ctx {context} {
|
|||
}
|
||||
|
||||
proc save_ctx {context} {
|
||||
# puts "saving tcl context $context : semaphore=[xschem get semaphore]"
|
||||
set tctx::tctx $context
|
||||
uplevel #0 {
|
||||
# puts "save_ctx $tctx::tctx"
|
||||
|
|
@ -4007,7 +3950,7 @@ global env has_x OS
|
|||
## this could lead to crashes on some (may be slow) systems due to Configure/Expose events being delivered
|
||||
## before xschem being ready to handle them.
|
||||
proc pack_widgets { { topwin {} } } {
|
||||
global env has_x OS
|
||||
global env has_x OS tabbed_interface
|
||||
if {($OS== "Windows" || [string length [lindex [array get env DISPLAY] 1] ] > 0 ) && [info exists has_x]} {
|
||||
pack $topwin.statusbar.2 -side left
|
||||
pack $topwin.statusbar.3 -side left
|
||||
|
|
@ -4017,8 +3960,11 @@ proc pack_widgets { { topwin {} } } {
|
|||
pack $topwin.statusbar.7 -side left
|
||||
pack $topwin.statusbar.8 -side left
|
||||
pack $topwin.statusbar.1 -side left -fill x
|
||||
pack $topwin.menubar -anchor n -side top -fill x
|
||||
if {$tabbed_interface} {
|
||||
pack $topwin.tabs -fill x -side top -expand false -side top
|
||||
}
|
||||
pack $topwin.drw -anchor n -side top -fill both -expand true
|
||||
pack $topwin.menubar -anchor n -side top -fill x -before $topwin.drw
|
||||
toolbar_show $topwin
|
||||
pack $topwin.statusbar -after $topwin.drw -anchor sw -fill x
|
||||
bind $topwin.statusbar.5 <Leave> "set cadgrid \[$topwin.statusbar.5 get\]; xschem set cadgrid \$cadgrid"
|
||||
|
|
@ -4054,7 +4000,7 @@ proc switch_undo {} {
|
|||
}
|
||||
|
||||
proc build_widgets { {topwin {} } } {
|
||||
global XSCHEM_SHAREDIR
|
||||
global XSCHEM_SHAREDIR tabbed_interface
|
||||
global colors recentfile color_ps transparent_svg menu_debug_var enable_stretch
|
||||
global netlist_show flat_netlist split_files hspice_netlist tmp_bus_char
|
||||
global draw_grid big_grid_points sym_txt change_lw incr_hilight symbol_width
|
||||
|
|
@ -4067,6 +4013,15 @@ proc build_widgets { {topwin {} } } {
|
|||
set mbg {-bg gray50}
|
||||
set bbg {-bg gray50 -highlightthickness 0}
|
||||
}
|
||||
|
||||
if { $tabbed_interface } {
|
||||
frame $topwin.tabs
|
||||
button $topwin.tabs.x0 -padx 2 -pady 0 -text Main -command {xschem new_schematic switch .drw}
|
||||
button $topwin.tabs.x1 -padx 2 -pady 0 -text Tab1 -command {xschem new_schematic switch .x1.drw}
|
||||
button $topwin.tabs.x2 -padx 2 -pady 0 -text Tab2 -command {xschem new_schematic switch .x2.drw}
|
||||
button $topwin.tabs.add -padx 0 -pady 0 -text { + }
|
||||
pack $topwin.tabs.x0 $topwin.tabs.x1 $topwin.tabs.x2 $topwin.tabs.add -side left
|
||||
}
|
||||
eval frame $topwin.menubar -relief raised -bd 2 $mbg
|
||||
toolbar_toolbar $topwin
|
||||
eval menubutton $topwin.menubar.file -text "File" -menu $topwin.menubar.file.menu \
|
||||
|
|
@ -4134,6 +4089,10 @@ proc build_widgets { {topwin {} } } {
|
|||
setup_recent_menu 0 $topwin
|
||||
setup_recent_menu 1 $topwin
|
||||
$topwin.menubar.file.menu add command -label {Open new window [exp]} -command "xschem load_new_window"
|
||||
if {$tabbed_interface} {
|
||||
$topwin.menubar.file.menu entryconfigure 6 -state disabled
|
||||
$topwin.menubar.file.menu entryconfigure 7 -state disabled
|
||||
}
|
||||
toolbar_create FileOpen "xschem load" "Open File" $topwin
|
||||
$topwin.menubar.file.menu add command -label "Delete files" -command "xschem delete_files" -accelerator {Shift-D}
|
||||
|
||||
|
|
@ -4166,10 +4125,10 @@ proc build_widgets { {topwin {} } } {
|
|||
$topwin.menubar.file.menu add command -label "SVG Export" -command "xschem print svg" -accelerator {Alt+*}
|
||||
$topwin.menubar.file.menu add separator
|
||||
$topwin.menubar.file.menu add command -label "Exit" -accelerator {Ctrl+Q} -command "
|
||||
if { {$topwin} eq {} } {
|
||||
if { \[xschem get current_win_path\] eq {.drw} } {
|
||||
xschem exit
|
||||
} else {
|
||||
xschem new_schematic destroy $topwin $topwin.drw {}
|
||||
xschem new_schematic destroy \[xschem get current_win_path\] {}
|
||||
}"
|
||||
$topwin.menubar.option.menu add checkbutton -label "Color Postscript/SVG" -variable color_ps \
|
||||
-command {
|
||||
|
|
@ -4537,7 +4496,7 @@ proc build_widgets { {topwin {} } } {
|
|||
if { $rootwin == {.}} {
|
||||
wm protocol $rootwin WM_DELETE_WINDOW {xschem exit}
|
||||
} else {
|
||||
wm protocol $topwin WM_DELETE_WINDOW "xschem new_schematic destroy $topwin $topwin.drw {}"
|
||||
wm protocol $topwin WM_DELETE_WINDOW "xschem new_schematic destroy $topwin.drw {}"
|
||||
}
|
||||
|
||||
frame $topwin.statusbar
|
||||
|
|
@ -4799,6 +4758,9 @@ set_ne to_pdf {ps2pdf}
|
|||
## undo_type: disk or memory
|
||||
set_ne undo_type disk
|
||||
|
||||
## show tab bar (tabbed interface)
|
||||
set_ne tabbed_interface 0
|
||||
|
||||
## max number of windows (including main) a single xschem process can handle
|
||||
set_ne max_new_windows -1 ;# this is set by xinit.c
|
||||
## remember edit_prop widget size
|
||||
|
|
|
|||
Loading…
Reference in New Issue