#include #include #include #include #include #include #include #include #include #include "embedded-view.h" #include "font-info.h" #include "lkb-tree.h" font_info small_tree_font = {"fixed", 12, fsRoman, {0,0,0}, 0}; font_info big_tree_font = {"helvetica", 16, fsRoman, {0,0,0}, 0}; font_info small_tree_orth_font = {"fixed", 12, fsRoman, {0,0,0}, 0}; font_info big_tree_orth_font = {"helvetica", 16, fsRoman, {0,0,0}, 0}; font_info tree_bar_font = {"helvetica", 12, fsRoman, {0,0,0}, 0}, mtree_bar_font = {"helvetica", 12, fsRoman, {0,0,0}, 0}; struct tree_params { int hgap; int std_vspace, std_height; int orth_vspace, orth_height; int headroom, un_vspace; font_info *font, *ofont; } _big_params = {11, 30, 22, 40, 32, 14, 21, &big_tree_font, &big_tree_orth_font}, _small_params = {9, 24, 19, 34, 28, 11, 15, &small_tree_font, &small_tree_orth_font}, big_params, small_params; int click_tree(int id, lkb_tree *tr, int x, int y, int button, struct tree_params *par); void click_tree_node(int id, lkb_tree *tr, int button); void do_tree_popup(int tid, lkb_tree *tr, int x, int y, int is_node); void lkb_browse_tree(int tree_id, int avm_id, char *command); struct lkb_tree *locate_node(lkb_tree *root, int x, int y, struct tree_params *par); void show_bar(embedded_view_t *view, char *path, int force, int from_view, font_info *fnt); void set_bar_for_node(embedded_view_t *view, lkb_tree *node, font_info *fnt); void scale_params(struct tree_params *from, struct tree_params *to, float scale) { *to = *from; to->hgap = from->hgap*scale; to->un_vspace = from->un_vspace*scale; to->std_vspace = from->std_vspace*scale; to->std_height = from->std_height*scale; to->orth_vspace = from->orth_vspace*scale; to->orth_height = from->orth_height*scale; to->headroom = from->headroom*scale; to->orth_vspace = to->std_vspace + to->ofont->size+5;//*8/10; to->orth_height = to->std_height + to->ofont->size+5;//*8/10; } /* single tree view */ struct tree_priv { char *shown_bar; lkb_tree *tree; int id; lkb_tree *old_hilite_node; }; #define TP ((struct tree_priv*)view->private) int init_tree_view(embedded_view_t *view, int id, lkb_tree *tree) { view->private = malloc(sizeof(struct tree_priv)); TP->tree = tree; TP->id = id; TP->old_hilite_node = 0; TP->shown_bar = 0; //yzSelectFont("times-6"); scale_params(&_big_params, &big_params, (float)big_tree_font.size / 14); use_font(&big_tree_font); calculate_tree_placement(TP->tree, &big_params); offset_tree_position(TP->tree, TP->tree->left, 0); view->width = (TP->tree->left+TP->tree->right) + 30; view->height = TP->tree->height + 15; return 0; } void close_tree_view(embedded_view_t *view) { if(*(TP->tree->refcnt)<=1) lkb_forget_tree(TP->id); free_lkb_tree(TP->tree); free(TP); } void update_tree_view(embedded_view_t *view, int x1, int y1, int x2, int y2) { use_font(&big_tree_font); yzPenColor(65535,65535,65535); yzRect(x1, y1, x2, y2); yzPenColor(0,0,0); //calculate_tree_placement(TP->tree); //offset_tree_position(TP->tree, TP->tree->left, 0); //yzSelectFont("times-6"); yzPushOrigin(15, 4 + (int)(big_tree_font.size*16/14)); render_tree(TP->tree, &big_params); yzPopOrigin(); //set_embedded_view_size(view, (TP->tree->left+TP->tree->right)+30, TP->tree->height+15); if(x2-x1+1 == view->vis_width && y2-y1+1 == view->vis_height) show_bar(view, TP->shown_bar, 1, 1, &tree_bar_font); } misc_tree_popup(embedded_view_t *view, int x, int y) { window_t *par; menu_data_t *md; int id; void latex_tree_view(embedded_view_t *view); void postscript_tree_view(embedded_view_t *view); md = yzNewMenuData("Tree Options"); yzAddMenuDataItem(md, "Output Postscript", 1); yzAddMenuDataItem(md, "Output LaTeX", 2); yzAddMenuDataItem(md, "Close Window", 3); par = yzGetSelectedWindow(); yzShowMenu(md, &id, x-8, y+8); switch(id) { case 0: break; // cancelled default: fprintf(stderr, "unknown item %d\n", id); break; case 1: postscript_tree_view(view); break; case 2: latex_tree_view(view); break; case 3: sim_key('q'); return -1; } // XXX should dispose memory here return 0; } void event_tree_view(embedded_view_t *view, event_t ev) { switch(ev.type) { case YZ_KEY_DOWN: switch(ev.key) { case YZ_KEYCODE_RIGHT_ARROW: break; case YZ_KEYCODE_LEFT_ARROW: break; } break; case YZ_MOUSE_DOWN: if(!click_tree(TP->id, TP->tree, ev.x-15, ev.y-4-big_tree_font.size*16/14, ev.button, &big_params)) { if((ev.button !=1 || yzQueryKey(YZ_KEYCODE_CONTROL)) && misc_tree_popup(view, ev.x, ev.y)) return; } break; } } void tree_mouse(embedded_view_t *view, int x, int y) { struct lkb_tree *t; int i; x -= 15, y -= 4 + big_tree_font.size*16/14; use_font(&big_tree_font); t = locate_node(TP->tree, x, y, &big_params); if(t != TP->old_hilite_node) { yzRecomputeScrollAreaClipping(view->scroll_area); yzPushOrigin(15, 4 + big_tree_font.size*16/14); if(TP->old_hilite_node) { yzPenColor(0,0,0); render_node(TP->old_hilite_node, -1, &big_params); } if(t) { yzPenColor(0,0,65535); render_node(t, 1, &big_params); } yzPenColor(0,0,0); yzPopOrigin(); yzPopClipRect(); yzPopOrigin(); TP->old_hilite_node = t; } if(TP->old_hilite_node) set_bar_for_node(view, TP->old_hilite_node, &tree_bar_font); else show_bar(view, 0, 0, 0, &tree_bar_font); } void postscript_tree_view(embedded_view_t *view) { window_t *tree_ps, *old; int dy, dx, fd; float scale; char message[1024], fname[768] = "tree-print.ps"; sprintf(fname, "/tmp/tree.%d.ps", TP->id); unlink(fname); fd = open(fname, O_WRONLY | O_CREAT, 0664); tree_ps = (window_t*)yzPostScriptWindow("Parse Tree", 555, 800, fd); old = yzSelectWindow(tree_ps); scale = 500.0 / (TP->tree->left + TP->tree->right); if((660.0 / (TP->tree->height)) < scale) scale = 660.0 / (TP->tree->height); //printf("Tree width = %d, height = %d, scale = %f\n", //TP->tree->left + TP->tree->right, TP->tree->height, scale); yzSetOrigin(0,4+big_tree_font.size*16/14); extern int yzPostScriptSetScale(float); yzPostScriptSetScale(scale); yzPushOrigin(25, 25); render_tree(TP->tree, &big_params); yzPopOrigin(); yzPostScriptEndPage(); close(fd); sprintf(message, "Printed tree to `%s' at scale %.1f%%\n", fname, 100*scale); console_add(message); yzSelectWindow(old); } static void latex_tree(lkb_tree *t, FILE *f, int dep) { int i; char label[512] = ""; for(i=0;indaughters;i++) { latex_tree(t->daughters+i, f, dep+1); } if(t->root_name)strcat(label, t->root_name); if(t->sublabel_id) { if(label[0])strcat(label, "\\endline"); strcat(label, "\\em{"); strcat(label, t->sublabel_id); strcat(label, "}"); } if(!t->ndaughters)fprintf(f, "\\leaf{%s}\n", label); else fprintf(f, "\\branch{%d}{%s}\n", t->ndaughters, label); } void latex_tree_view(embedded_view_t *view) { char fname[768], message[1024]; FILE *f; sprintf(fname, "/tmp/tree.%d.tex", TP->id); f = fopen(fname, "w"); latex_tree(TP->tree, f, 0); fprintf(f, "\\qobitree\n"); fclose(f); sprintf(message, "Output tree to `%s'\n", fname); console_add(message); } embedded_view_t prototype_tree_view = { init: (int(*)(embedded_view_t*,...))init_tree_view, update: update_tree_view, event: event_tree_view, postscript: postscript_tree_view, latex: latex_tree_view, close: close_tree_view, mouse_moved: tree_mouse}; /* multi-tree view */ struct mtree_priv { char *shown_bar; int ntrees; int *ids; lkb_tree **trees; char **treenames; int old_hilite_idx; lkb_tree *old_hilite_node; char *selection_map; }; #undef TP #define TP ((struct mtree_priv*)view->private) int init_mtree_view(embedded_view_t *view, int ntrees, int *treeids, lkb_tree **trees, char **treenames) { view->private = malloc(sizeof(struct mtree_priv)); TP->ntrees = ntrees; TP->trees = trees; TP->ids = treeids; TP->treenames = treenames; TP->old_hilite_idx = ntrees; TP->old_hilite_node = 0; TP->shown_bar = 0; TP->selection_map = calloc(ntrees, 1); layout_mtree(view, 0); return 0; } layout_mtree(embedded_view_t *view, int svs) { int i, x = 0, y = 0; int maxx = 500, actx = 0; int acty = 0, maxrowy = 0; int pad = 10+small_tree_font.size*10/9; scale_params(&_small_params, &small_params, (float)small_tree_font.size / 9); use_font(&small_tree_font); //yzSelectFont("times-6"); for(i=0;intrees;i++) { calculate_tree_placement(TP->trees[i], &small_params); offset_tree_position(TP->trees[i], TP->trees[i]->left+x, y); x += TP->trees[i]->left + TP->trees[i]->right; if(x>actx)actx = x; if(TP->trees[i]->height>maxrowy)maxrowy = TP->trees[i]->height; if(x+pad>maxx) { x = 0; y += maxrowy + pad-10; maxrowy=0; } else x += pad; } acty = y + maxrowy; if(!svs) { view->width = actx + 30; view->height = acty + 15; } else set_embedded_view_size(view, actx+30, acty+15); return 0; } void close_mtree_view(embedded_view_t *view) { int i; for(i=0;intrees;i++) { if(*(TP->trees[i]->refcnt)<=1) lkb_forget_tree(TP->ids[i]); free_lkb_tree(TP->trees[i]); } free(TP->trees); free(TP->ids); free(TP->treenames); free(TP->selection_map); free(TP); } #define TS_TOP (4 + 16*small_tree_font.size/9) show_clip() { int x1, y1, x2, y2; if(yzPopClipRect4p(&x1, &y1, &x2, &y2) == 0) { show_clip(); printf("clip is %d %d %d %d\n", x1, y1, x2, y2); yzPushClipRect(x1, y1, x2, y2); } } color_t normal_outline = {45000,45000,45000}; color_t mouseover_outline = {0,0,0}; color_t selected_outline = {0,0,45000}; color_t selected_mouseover_outline = {30000,30000,65535}; const int selection_border_weight = 2; outline_tree(struct lkb_tree *t, color_t c, int weight) { int ascend = small_tree_font.size*13/9, descend = small_tree_font.size*10/9; yzPenColor1c(c); int maxweight = selection_border_weight; int i; for(i=0;irx-t->left-3 + i, t->ry-ascend + i, t->rx+t->right+3 - i, t->ry+t->height-descend - i); color_t background = {65535,65535,65535}; yzPenColor1c(background); for(;irx-t->left-3 + i, t->ry-ascend + i, t->rx+t->right+3 - i, t->ry+t->height-descend - i); } void update_mtree_view(embedded_view_t *view, int x1, int y1, int x2, int y2) { int i; int ascend = small_tree_font.size*13/9, descend = small_tree_font.size*10/9; lkb_tree *t; //show_clip(); use_font(&small_tree_font); yzPenColor(65535,65535,65535); yzRect(x1, y1, x2, y2); yzPenColor(0,0,0); yzPushOrigin(15, TS_TOP); x1-=15,y1-=TS_TOP; x2-=15,y2-=TS_TOP; //yzSelectFont("times-6"); for(i=0;intrees;i++) { t = TP->trees[i]; if(t->ry+t->height-descend < y1)continue; if(t->ry-ascend > y2)continue; if(t->rx+t->right+3 < x1)continue; if(t->rx-t->left-3 > x2)continue; //printf("draw %d\n", i); outline_tree(t, TP->selection_map[i]?selected_outline:normal_outline, TP->selection_map[i]?selection_border_weight:1); //yzPenColor(45000, 45000, 45000); //yzOutlineRect(t->rx-t->left-3, t->ry-ascend, t->rx+t->right+3, t->ry+t->height-descend); yzPenColor(0,0,0); render_tree(t, &small_params); } yzPopOrigin(); if(x2-x1+1 == view->vis_width && y2-y1+1 == view->vis_height) show_bar(view, TP->shown_bar, 1, 1, &mtree_bar_font); } issue_mtree_comparison(embedded_view_t *view) { int *ids = calloc(TP->ntrees, sizeof(int)); int i, n=0; for(i=0;intrees;i++) if(TP->selection_map[i])ids[n++] = TP->ids[i]; if(!n)lkb_compare_trees(TP->ntrees, TP->ids); else lkb_compare_trees(n, ids); free(ids); } static char *hack_tree_title = "(uninitialized)"; misc_mtree_popup(embedded_view_t *view, int x, int y) { window_t *par; menu_data_t *md; int id; md = yzNewMenuData("Forest Options"); //yzAddMenuDataItem(md, "Output Postscript", 1); //yzAddMenuDataItem(md, "Output LaTeX", 2); yzAddMenuDataItem(md, "Compare Trees", 4); yzAddMenuDataItem(md, "Close Window", 3); par = yzGetSelectedWindow(); yzShowMenu(md, &id, x-8, y+8); switch(id) { case 0: break; // cancelled default: fprintf(stderr, "unknown item %d\n", id); break; //case 1: postscript_tree_view(view); break; //case 2: latex_tree_view(view); break; case 3: sim_key('q'); return -1; case 4: issue_mtree_comparison(view); break; } // XXX should dispose memory here return 0; } void event_mtree_view(embedded_view_t *view, event_t ev) { int i; window_t *par; int ascend = small_tree_font.size*13/9, descend = small_tree_font.size*10/9; switch(ev.type) { case YZ_KEY_DOWN: switch(ev.key) { case '+': small_tree_font.size+=2; case '-': small_tree_font.size--; if(small_tree_font.font) yzFreeFont(small_tree_font.font); small_tree_font.font = 0; layout_mtree(view, 1); yzDrawScrollArea(view->scroll_area); break; case 'c': issue_mtree_comparison(view); break; } break; case YZ_MOUSE_DOWN: ev.x-=15, ev.y-=TS_TOP; for(i=0;intrees;i++) if(TP->trees[i]->rx-TP->trees[i]->left-3 < ev.x && TP->trees[i]->rx+TP->trees[i]->right+3 > ev.x && TP->trees[i]->ry-ascend < ev.y && TP->trees[i]->ry+TP->trees[i]->height-descend > ev.y) { if(yzQueryKey(YZ_KEYCODE_ALT) || yzQueryKey(YZ_KEYCODE_SHIFT)) toggle_tree_selection(view, i); else if(!click_tree(TP->ids[i], TP->trees[i], ev.x, ev.y, ev.button, &small_params)) { // click in open white space around tree, but not on a node if(ev.button!=1 || yzQueryKey(YZ_KEYCODE_CONTROL)) do_tree_popup(TP->ids[i], TP->trees[i], ev.x, ev.y, 0); else { hack_tree_title = TP->treenames[i]; par = yzGetSelectedWindow(); browse_tree(TP->ids[i], copy_lkb_tree(TP->trees[i]), strdup(hack_tree_title)); yzSelectWindow(par); } } // else already handled by click_tree() return; } if(ev.button!=1 || yzQueryKey(YZ_KEYCODE_CONTROL)) if(misc_mtree_popup(view, ev.x+15, ev.y+24))return; break; } } begin_ev_drawing(embedded_view_t *view) { yzPushOrigin(15, TS_TOP); } end_ev_drawing(embedded_view_t *view) { yzPenColor(0,0,0); yzPopOrigin(); yzUpdateBuffer(YZ_BUFFER_FRONT); } toggle_tree_selection(embedded_view_t *view, int idx) { struct lkb_tree *t = TP->trees[idx]; begin_ev_drawing(view); if(TP->selection_map[idx]) { outline_tree(t, mouseover_outline, 1); TP->selection_map[idx] = 0; } else { outline_tree(t, selected_mouseover_outline, selection_border_weight); TP->selection_map[idx] = 1; } end_ev_drawing(view); } void do_tree_popup(int tid, lkb_tree *tr, int x, int y, int is_node) { window_t *par; menu_data_t *md; int id; char *lkb_commands[] = {0, "-extract-", "avm", "avm local", "edges", "chart", "generate", "rephrase", "mrs simple", "mrs indexed", "mrs scoped", "mrs robust", "dependencies"}; md = yzNewMenuData("Tree Options"); if(!is_node) yzAddMenuDataItem(md, "Extract Tree", 1); yzAddMenuDataItem(md, "Full AVM", 2); yzAddMenuDataItem(md, "Local AVM", 3); yzAddMenuDataItem(md, "Chart Edges", 4); yzAddMenuDataItem(md, "Partial Chart", 5); yzAddMenuDataItem(md, "Generate", 6); if(!is_node) yzAddMenuDataItem(md, "Rephrase", 7); yzAddMenuDataItem(md, "Simple MRS", 8); yzAddMenuDataItem(md, "Indexed MRS", 9); yzAddMenuDataItem(md, "Scoped MRS", 10); //yzAddMenuDataItem(md, "Robust MRS", 11); yzAddMenuDataItem(md, "Dependencies", 12); par = yzGetSelectedWindow(); yzShowMenu(md, &id, x + par->origin_x, y + par->origin_y+15); if(id==0){} // cancelled else if(id >= sizeof(lkb_commands)/sizeof(char*)) fprintf(stderr, "Unknown menu item %d selected\n", id); else if(!strcmp(lkb_commands[id], "-extract-")) { // handled internally browse_tree(tid, copy_lkb_tree(tr), strdup(hack_tree_title)); yzSelectWindow(par); } // possibly if !is_node, pass -1 instead of tr->id else lkb_browse_tree(tid, tr->id, lkb_commands[id]); // XXX should dispose memory here dispose: return; } void mtree_mouse(embedded_view_t *view, int x, int y) { struct lkb_tree *t; int i; int ascend = small_tree_font.size*13/9, descend = small_tree_font.size*10/9; yzRecomputeScrollAreaClipping(view->scroll_area); x -= 15, y -= TS_TOP; for(i=0;intrees;i++) if(TP->trees[i]->rx-TP->trees[i]->left-3 < x && TP->trees[i]->rx+TP->trees[i]->right+3 > x && TP->trees[i]->ry-ascend < y && TP->trees[i]->ry+TP->trees[i]->height-descend > y) break; //printf("mouse %d %d in tree %d\n", x, y, i); use_font(&small_tree_font); if(TP->old_hilite_idx != i) { begin_ev_drawing(view); if(intrees) outline_tree(TP->trees[i], TP->selection_map[i]?selected_mouseover_outline:mouseover_outline, TP->selection_map[i]?selection_border_weight:1); if(TP->old_hilite_idxntrees) outline_tree(TP->trees[TP->old_hilite_idx], TP->selection_map[TP->old_hilite_idx]?selected_outline:normal_outline, TP->selection_map[TP->old_hilite_idx]?selection_border_weight:1); TP->old_hilite_idx = i; end_ev_drawing(view); } if(i != TP->ntrees) t = locate_node(TP->trees[i], x, y, &small_params); else t = 0; if(t != TP->old_hilite_node) { begin_ev_drawing(view); if(TP->old_hilite_node) { yzPenColor(0,0,0); render_node(TP->old_hilite_node, -1, &small_params); } if(t) { yzPenColor(0,0,65535); render_node(t, 1, &small_params); } TP->old_hilite_node = t; end_ev_drawing(view); } yzPopOrigin(); yzPopClipRect(); if(TP->old_hilite_node) set_bar_for_node(view, TP->old_hilite_node, &mtree_bar_font); else show_bar(view, 0, 0, 0, &mtree_bar_font); } void collect_lexemes(char *str, lkb_tree *node) { int i; //if(!node->ndaughters) if(node->sublabel_id) { //downcase_string(node->rule_id); //strcat(str, node->rule_id); downcase_string(node->sublabel_id); strcat(str, node->sublabel_id); strcat(str, " "); } else for(i=0;indaughters;i++) collect_lexemes(str, node->daughters+i); } void set_bar_for_node(embedded_view_t *view, lkb_tree *node, font_info *fnt) { static char string[10240]; //if(node->ndaughters) snprintf(string, 10239, "%d: %s (", node->edge_id, node->rule_id); //else snprintf(string, 10239, "%d: (", node->edge_id); collect_lexemes(string, node); if(string[strlen(string) - 1] == ' ' && string[strlen(string) - 2] == ' ') { string[strlen(string) - 2] = 0; strcat(string, ")"); } else string[strlen(string) - 2] = 0; show_bar(view, string, 0, 0, fnt); } embedded_view_t prototype_mtree_view = { init: (int(*)(embedded_view_t*,...))init_mtree_view, update: update_mtree_view, event: event_mtree_view, postscript: 0, latex: 0, close: close_mtree_view, mouse_moved: mtree_mouse}; /* tree management */ struct lkb_tree *locate_node(lkb_tree *root, int x, int y, struct tree_params *par) { int i; struct lkb_tree *t; if(y > root->ry-(1+par->font->size) && y < root->ry+3 && x > root->rx-root->label_width/2 && x < root->rx+root->label_width/2) return root; for(i=0;indaughters;i++) { t = locate_node(root->daughters+i, x, y, par); if(t)return t; } return 0; } int click_tree(int id, lkb_tree *tr, int x, int y, int button, struct tree_params *par) { tr = locate_node(tr, x, y, par); if(!tr)return 0; else { click_tree_node(id, tr, button); return 1; } } void click_tree_node(int id, lkb_tree *tr, int button) { if(button!=1 || yzQueryKey(YZ_KEYCODE_CONTROL)) do_tree_popup(id, tr, tr->rx, tr->ry, 1); else lkb_browse_tree(id, tr->id, "avm"); // default: click just opens the node's avm } calculate_tree_placement(lkb_tree *tr, struct tree_params *par) { int i, j, w, subwidth = 0, nbranchers = 0; int dleft, dright, total = 0, tr_width, vspace; tr->rx = 0; tr->ry = 0; tr->label_width = yzStringSize(tr->root_name, strlen(tr->root_name)); if(tr->sublabel_id && tr->sublabel_id[0]) { use_font(par->ofont); tr->sl_width = yzStringSize(tr->sublabel_id, strlen(tr->sublabel_id)); use_font(par->font); vspace = par->orth_vspace; tr->height = par->orth_height; } else { tr->sl_width = 0; vspace = par->std_vspace; if(tr->ndaughters==1)vspace = par->un_vspace; tr->height = par->std_height; } tr->left = tr->right = tr->label_width/2; if(tr->sl_width/2 > tr->left)tr->left = tr->right = tr->sl_width/2; if(tr->ndaughters) { for(i=0;indaughters;i++) { calculate_tree_placement(tr->daughters+i, par); total += tr->daughters[i].left + tr->daughters[i].right; } total+=par->hgap*(tr->ndaughters-1); total-=tr->daughters[0].left + tr->daughters[tr->ndaughters-1].right; if(total/2 + tr->daughters[0].left > tr->left) tr->left = total/2 + tr->daughters[0].left; if(total/2 + tr->daughters[tr->ndaughters-1].right > tr->right) tr->right = (total+1)/2 + tr->daughters[tr->ndaughters-1].right; for(i=0;indaughters;i++) { if(i>0)subwidth+=par->hgap + tr->daughters[i-1].right + tr->daughters[i].left; offset_tree_position(tr->daughters+i, subwidth - total/2, vspace); if(tr->daughters[i].height+vspace > tr->height) tr->height = tr->daughters[i].height+vspace; if(tr->daughters[i].ndaughters)nbranchers++; } // center root above daughters' roots //tr->rx = (tr->daughters[0].rx - dleft + //tr->daughters[tr->ndaughters-1].rx + dright)/2; } //printf("%s [%s]: width %d\n", tr->root_name, tr->sublabel_id, tr->width); /* if(nbranchers==1) for(i=0;indaughters;i++) if(tr->daughters[i].ndaughters) { j = tr->daughters[i].rx; offset_tree_position(tr->daughters[i], tr->rx - j); tr->daughters[i].rx = j; w = j+tr->daughters[i].width/2 - (tr->rx + tr->width/2); if(w < 0 && i==tr->ndaughters-1) tr->width += w, tr->rx += w/2; w = j-tr->daughters[i].width/2 - (tr->rx - tr->width/2); if(w > 0 && i==0) tr->width -= w, tr->rx += w/2; break; } */ //printf("tree `%s' -> width [%d %d]\n", tr->root_name, tr->left, tr->right); } offset_tree_position(lkb_tree *tr, int x, int y) { int i; tr->rx += x; tr->ry += y; for(i=0;indaughters;i++) offset_tree_position(tr->daughters+i, x, y); } render_tree(lkb_tree *tr, struct tree_params *par) { int i; render_node(tr, 0, par); for(i=0;indaughters;i++) { render_tree(tr->daughters+i, par); render_link(tr, tr->daughters+i, par); } } float scale = 1.0; render_node(lkb_tree *tr, int bf, struct tree_params *par) { int i; if(bf==-1) yzPenColor(65535,65535,65535); else if(bf==1)yzPenColor(0,0,65535); /* don't do bold like this! */ /* if(bf) { i = 1; yzText((tr->rx - tr->label_width/2) * scale+i, tr->ry * scale, tr->root_name); if(tr->sublabel_id) { use_font(par->ofont); if(bf==-1)yzPenColor(65535,65535,65535); yzText((tr->rx - tr->sl_width/2) * scale+i, (tr->ry + par->ofont->size) * scale + 5, tr->sublabel_id); use_font(par->font); } }*/ if(bf!=1)yzPenColor1c(par->font->color); i = 0; yzText((tr->rx - tr->label_width/2) * scale+i, tr->ry * scale, tr->root_name); if(tr->sublabel_id) { use_font(par->ofont); if(bf==1)yzPenColor(0,0,65535); yzText((tr->rx - tr->sl_width/2) * scale+i, (tr->ry + par->ofont->size) * scale + 5, tr->sublabel_id); use_font(par->font); } } render_link(lkb_tree *parent, lkb_tree *child, struct tree_params *par) { int dy; if(parent->sublabel_id)dy = 3 + par->ofont->size*11/12; else dy = 3; yzLine(parent->rx * scale, (parent->ry + dy) * scale, child->rx * scale, (child->ry - par->headroom) * scale); } // bar on top of window void show_bar(embedded_view_t *view, char *path, int force, int from_view, font_info *fnt) { int ox, oy, cx1, cy1, cx2, cy2; char *tmp = TP->shown_bar; if(force || nullstrcmp(tmp, path)) { if(path)TP->shown_bar = strdup(path); else TP->shown_bar = 0; if(tmp)free(tmp); if(from_view) { yzPopClipRect4p(&cx1, &cy1, &cx2, &cy2); yzPopOrigin2p(&ox, &oy); } yzBufferMode(YZ_BUFFER_BACK); int height = top_bar_height(fnt); //yzPushClipRect(0, 0, view->use_width, height-1); yzPenColor(50000, 50000, 50000); yzRect(0, 0, view->use_width, height); yzPenColor(0,0,0); yzOutlineRect(0, 0, view->use_width, height); if(TP->shown_bar) { use_font(fnt); yzText(5, height*0.8, TP->shown_bar); } yzUpdateBuffer(YZ_BUFFER_FRONT); //yzPopClipRect(); if(from_view) { yzPushOrigin(ox, oy); yzPushClipRect(cx1, cy1, cx2, cy2); } } //yzQueryKey(YZ_KEYCODE_CONTROL); }