void gli_windows_size_change() { compute_content_box(); if (gli_rootwin) { gli_window_rearrange(gli_rootwin, &content_box); } gli_windows_redraw(); gli_msgline_redraw(); gli_event_store(evtype_Arrange, NULL, 0, 0); }
void gli_windows_metrics_change(data_metrics_t *newmetrics) { metrics = *newmetrics; if (gli_rootwin) { grect_t box; compute_content_box(&box); gli_window_rearrange(gli_rootwin, &box, &metrics); } gli_event_store(evtype_Arrange, NULL, 0, 0); }
void win_pair_rearrange(window_t *win, grect_t *box) { window_pair_t *dwin = win->data; grect_t box1, box2; int min, diff, split, splitwid, max; window_t *key; window_t *ch1, *ch2; win->bbox = *box; /*dwin->flat = FALSE;*/ if (dwin->vertical) { min = win->bbox.left; max = win->bbox.right; } else { min = win->bbox.top; max = win->bbox.bottom; } diff = max-min; /* We now figure split. The window attributes control this, unless the pref_override_window_borders option is set. */ if (pref_override_window_borders) { if (pref_window_borders) splitwid = 1; else splitwid = 0; } else { // if (dwin->hasborder) // splitwid = 1; // else splitwid = 0; } switch (dwin->division) { case winmethod_Proportional: split = (diff * dwin->size) / 100; break; case winmethod_Fixed: /* Keeping track of the key may seem silly, since we don't really use it when all sizes are measured in characters. But it's good to know when it's invalid, so that the split can be set to zero. It would suck if invalid keys seemed to work in GlkTerm but not in GUI Glk libraries. */ key = dwin->key; if (!key) { split = 0; } else { switch (key->type) { case wintype_TextBuffer: case wintype_TextGrid: if (dwin->vertical) split = dwin->size * iosif_fixed_font_width; else split = dwin->size * iosif_fixed_font_height; break; case wintype_Graphics: split = dwin->size; if (!dwin->vertical) { if (win->bbox.right-win->bbox.left == iosif_screenwidth && !gLargeScreenDevice) split /= 2; } break; default: split = 0; break; } } break; default: split = diff / 2; break; } if (!dwin->backward) { split = max-split-splitwid; } else { split = min+split; } if (min >= max) { split = min; } else { if (split < min) split = min; else if (split > max-splitwid) split = max-splitwid; } if (dwin->vertical) { dwin->splitpos = split; dwin->splitwidth = splitwid; box1.left = win->bbox.left; box1.right = dwin->splitpos; box2.left = box1.right + dwin->splitwidth; box2.right = win->bbox.right; box1.top = win->bbox.top; box1.bottom = win->bbox.bottom; box2.top = win->bbox.top; box2.bottom = win->bbox.bottom; if (!dwin->backward) { ch1 = dwin->child1; ch2 = dwin->child2; } else { ch1 = dwin->child2; ch2 = dwin->child1; } } else { dwin->splitpos = split; dwin->splitwidth = splitwid; box1.top = win->bbox.top; box1.bottom = dwin->splitpos; box2.top = box1.bottom + dwin->splitwidth; box2.bottom = win->bbox.bottom; box1.left = win->bbox.left; box1.right = win->bbox.right; box2.left = win->bbox.left; box2.right = win->bbox.right; if (!dwin->backward) { ch1 = dwin->child1; ch2 = dwin->child2; } else { ch1 = dwin->child2; ch2 = dwin->child1; } } gli_window_rearrange(ch1, &box1); gli_window_rearrange(ch2, &box2); }
void glk_window_set_arrangement(window_t *win, glui32 method, glui32 size, winid_t key) { window_pair_t *dwin; glui32 newdir; grect_t box; int newvertical, newbackward; if (!win) { gli_strict_warning("window_set_arrangement: invalid ref"); return; } if (win->type != wintype_Pair) { gli_strict_warning("window_set_arrangement: not a Pair window"); return; } if (key) { window_t *wx; if (key->type == wintype_Pair) { gli_strict_warning("window_set_arrangement: keywin cannot be a Pair"); return; } for (wx=key; wx; wx=wx->parent) { if (wx == win) break; } if (wx == NULL) { gli_strict_warning("window_set_arrangement: keywin must be a descendant"); return; } } dwin = win->data; box = win->bbox; newdir = method & winmethod_DirMask; newvertical = (newdir == winmethod_Left || newdir == winmethod_Right); newbackward = (newdir == winmethod_Left || newdir == winmethod_Above); if (!key) key = dwin->key; if ((newvertical && !dwin->vertical) || (!newvertical && dwin->vertical)) { if (!dwin->vertical) gli_strict_warning("window_set_arrangement: split must stay horizontal"); else gli_strict_warning("window_set_arrangement: split must stay vertical"); return; } if (key && key->type == wintype_Blank && (method & winmethod_DivisionMask) == winmethod_Fixed) { gli_strict_warning("window_set_arrangement: a Blank window cannot have a fixed size"); return; } if ((newbackward && !dwin->backward) || (!newbackward && dwin->backward)) { /* switch the children */ window_t *tmpwin = dwin->child1; dwin->child1 = dwin->child2; dwin->child2 = tmpwin; } /* set up everything else */ dwin->dir = newdir; dwin->division = method & winmethod_DivisionMask; dwin->key = key; dwin->size = size; dwin->hasborder = ((method & winmethod_BorderMask) == winmethod_Border); dwin->vertical = (dwin->dir == winmethod_Left || dwin->dir == winmethod_Right); dwin->backward = (dwin->dir == winmethod_Left || dwin->dir == winmethod_Above); gli_window_rearrange(win, &box, &metrics); }
void glk_window_close(window_t *win, stream_result_t *result) { if (!win) { gli_strict_warning("window_close: invalid ref"); return; } if (win == gli_rootwin || win->parent == NULL) { /* close the root window, which means all windows. */ gli_rootwin = 0; /* begin (simpler) closation */ geometry_changed = TRUE; gli_stream_fill_result(win->str, result); gli_window_close(win, TRUE); } else { /* have to jigger parent */ grect_t box; window_t *pairwin, *sibwin, *grandparwin, *wx; window_pair_t *dpairwin, *dgrandparwin; int keydamage_flag; pairwin = win->parent; dpairwin = pairwin->data; if (win == dpairwin->child1) { sibwin = dpairwin->child2; } else if (win == dpairwin->child2) { sibwin = dpairwin->child1; } else { gli_strict_warning("window_close: window tree is corrupted"); return; } box = pairwin->bbox; grandparwin = pairwin->parent; if (!grandparwin) { gli_rootwin = sibwin; sibwin->parent = NULL; } else { dgrandparwin = grandparwin->data; if (dgrandparwin->child1 == pairwin) dgrandparwin->child1 = sibwin; else dgrandparwin->child2 = sibwin; sibwin->parent = grandparwin; } /* Begin closation */ gli_stream_fill_result(win->str, result); /* Close the child window (and descendants), so that key-deletion can crawl up the tree to the root window. */ gli_window_close(win, TRUE); /* This probably isn't necessary, but the child *is* gone, so just in case. */ if (win == dpairwin->child1) { dpairwin->child1 = NULL; } else if (win == dpairwin->child2) { dpairwin->child2 = NULL; } /* Now we can delete the parent pair. */ gli_window_close(pairwin, FALSE); keydamage_flag = FALSE; for (wx=sibwin; wx; wx=wx->parent) { if (wx->type == wintype_Pair) { window_pair_t *dwx = wx->data; if (dwx->keydamage) { keydamage_flag = TRUE; dwx->keydamage = FALSE; } } } if (keydamage_flag) { compute_content_box(&box); gli_window_rearrange(gli_rootwin, &box, &metrics); } else { gli_window_rearrange(sibwin, &box, &metrics); } } }
winid_t glk_window_open(winid_t splitwin, glui32 method, glui32 size, glui32 wintype, glui32 rock) { window_t *newwin, *pairwin, *oldparent; window_pair_t *dpairwin; grect_t box; glui32 val; if (!gli_rootwin) { if (splitwin) { gli_strict_warning("window_open: ref must be NULL"); return 0; } /* ignore method and size now */ oldparent = NULL; compute_content_box(&box); } else { if (!splitwin) { gli_strict_warning("window_open: ref must not be NULL"); return 0; } val = (method & winmethod_DivisionMask); if (val != winmethod_Fixed && val != winmethod_Proportional) { gli_strict_warning("window_open: invalid method (not fixed or proportional)"); return 0; } val = (method & winmethod_DirMask); if (val != winmethod_Above && val != winmethod_Below && val != winmethod_Left && val != winmethod_Right) { gli_strict_warning("window_open: invalid method (bad direction)"); return 0; } box = splitwin->bbox; oldparent = splitwin->parent; if (oldparent && oldparent->type != wintype_Pair) { gli_strict_warning("window_open: parent window is not Pair"); return 0; } } newwin = gli_new_window(wintype, rock); if (!newwin) { gli_strict_warning("window_open: unable to create window"); return 0; } switch (wintype) { case wintype_Blank: newwin->data = win_blank_create(newwin); break; case wintype_TextGrid: newwin->data = win_textgrid_create(newwin); break; case wintype_TextBuffer: newwin->data = win_textbuffer_create(newwin); break; case wintype_Pair: gli_strict_warning("window_open: cannot open pair window directly"); gli_delete_window(newwin); return 0; default: /* Unknown window type -- do not print a warning, just return 0 to indicate that it's not possible. */ gli_delete_window(newwin); return 0; } if (!newwin->data) { gli_strict_warning("window_open: unable to create window"); return 0; } if (!splitwin) { gli_rootwin = newwin; gli_window_rearrange(newwin, &box, &metrics); } else { /* create pairwin, with newwin as the key */ pairwin = gli_new_window(wintype_Pair, 0); dpairwin = win_pair_create(pairwin, method, newwin, size); pairwin->data = dpairwin; dpairwin->child1 = splitwin; dpairwin->child2 = newwin; splitwin->parent = pairwin; newwin->parent = pairwin; pairwin->parent = oldparent; if (oldparent) { window_pair_t *dparentwin = oldparent->data; if (dparentwin->child1 == splitwin) dparentwin->child1 = pairwin; else dparentwin->child2 = pairwin; } else { gli_rootwin = pairwin; } gli_window_rearrange(pairwin, &box, &metrics); } return newwin; }