void TEST_window_w() { char *routine = "TEST_window_w"; printf(testing, routine); //First a valid window Window win = active_window(); int w = window_w(win); assert(w > INT_MIN); //Then an invalid window assert(window_w(20) == INT_MIN); printf(done, routine); }
size_t window_w(struct window *window) { if (!window->parent) { return window->w; } if (window->parent->split_type == WINDOW_SPLIT_HORIZONTAL) { return window_w(window->parent); } if (window == window->parent->split.first) { return window->parent->split.point; } return window_w(window->parent) - window->parent->split.point; }
struct window *window_split(struct window *window, enum window_split_direction direction) { assert(window->split_type == WINDOW_LEAF); struct window *copy = xmalloc(sizeof(*window)); memcpy(copy, window, sizeof(*window)); struct window *sibling = window_create( window->buffer, window->w, window->h); copy->parent = window; sibling->parent = window; copy->opt = window->opt; sibling->opt = window->opt; switch (direction) { case WINDOW_SPLIT_LEFT: window->split_type = WINDOW_SPLIT_VERTICAL; window->split.point = window_w(window) / 2; window->split.first = sibling; window->split.second = copy; break; case WINDOW_SPLIT_RIGHT: window->split_type = WINDOW_SPLIT_VERTICAL; window->split.point = window_w(window) / 2; window->split.first = copy; window->split.second = sibling; break; case WINDOW_SPLIT_ABOVE: window->split_type = WINDOW_SPLIT_HORIZONTAL; window->split.point = window_h(window) / 2; window->split.first = sibling; window->split.second = copy; break; case WINDOW_SPLIT_BELOW: window->split_type = WINDOW_SPLIT_HORIZONTAL; window->split.point = window_h(window) / 2; window->split.first = copy; window->split.second = sibling; } return sibling; }
size_t window_x(struct window *window) { if (!window->parent) { return 0; } switch (window->parent->split_type) { case WINDOW_SPLIT_HORIZONTAL: return window_x(window->parent); case WINDOW_SPLIT_VERTICAL: if (window == window->parent->split.first) { return window_x(window->parent); } return window_x(window->parent) + window_w(window_sibling(window)); case WINDOW_LEAF: assert(0); } return 0; }
struct window *window_close(struct window *window) { assert(window->split_type == WINDOW_LEAF); struct window *parent = window->parent; struct window *sibling = window_sibling(window); bool was_left_child = window == window->parent->split.first; enum window_split_type old_parent_type = parent->split_type; struct window *grandparent = parent->parent; size_t w = parent->w; size_t h = parent->h; memcpy(parent, sibling, sizeof(*sibling)); parent->parent = grandparent; parent->w = w; parent->h = h; if (parent->split_type != WINDOW_LEAF) { parent->split.first->parent = parent; parent->split.second->parent = parent; } if (was_left_child && old_parent_type == parent->split_type) { if (parent->split_type == WINDOW_SPLIT_HORIZONTAL) { parent->split.point = window_h(parent) - parent->split.point; } else if (parent->split_type == WINDOW_SPLIT_VERTICAL) { parent->split.point = window_w(parent) - parent->split.point; } } window_free(window); // free, not window_free, because that would free parent's fields. free(sibling); return window_first_leaf(parent); }