2005-11-18 18:54:58 +03:00
|
|
|
/*
|
|
|
|
* (C)opyright MMIV-MMV Anselm R. Garbe <garbeam at gmail dot com>
|
|
|
|
* See LICENSE file for license details.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <math.h>
|
|
|
|
|
|
|
|
#include "wm.h"
|
2005-12-07 17:06:16 +03:00
|
|
|
#include "layoutdef.h"
|
2005-11-18 18:54:58 +03:00
|
|
|
|
|
|
|
typedef struct Acme Acme;
|
|
|
|
typedef struct Column Column;
|
2005-12-16 04:59:27 +03:00
|
|
|
typedef struct ColFrame ColFrame;
|
2005-11-18 18:54:58 +03:00
|
|
|
|
|
|
|
struct Acme {
|
2005-12-16 04:59:27 +03:00
|
|
|
Column *sel;
|
|
|
|
Column *columns;
|
|
|
|
size_t ncolumns;
|
|
|
|
Frame *frames;
|
|
|
|
size_t nframes;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct ColFrame {
|
|
|
|
Frame *frame;
|
|
|
|
ColFrame *next;
|
|
|
|
ColFrame *prev;
|
|
|
|
Column *col;
|
2005-11-18 18:54:58 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
struct Column {
|
2005-12-16 04:59:27 +03:00
|
|
|
ColFrame *sel;
|
|
|
|
ColFrame *frames;
|
|
|
|
size_t nframes;
|
2005-12-05 01:45:59 +03:00
|
|
|
XRectangle rect;
|
2005-12-16 04:59:27 +03:00
|
|
|
Column *prev;
|
|
|
|
Column *next;
|
2005-11-18 18:54:58 +03:00
|
|
|
};
|
|
|
|
|
2005-12-16 04:59:27 +03:00
|
|
|
static void init_col(Area *a, Client *clients);
|
|
|
|
static Client *deinit_col(Area *a);
|
|
|
|
static void arrange_col(Area *a);
|
|
|
|
static Bool attach_col(Area *a, Client *c);
|
|
|
|
static void detach_col(Area *a, Client *c, Bool unmap);
|
|
|
|
static void resize_col(Frame *f, XRectangle *new, XPoint *pt);
|
|
|
|
static void focus_col(Frame *f, Bool raise);
|
|
|
|
static Frame *frames_col(Area *a);
|
|
|
|
static Frame *sel_col(Area *a);
|
|
|
|
static Action *actions_col(Area *a);
|
2005-12-11 01:43:45 +03:00
|
|
|
|
2005-12-11 02:03:17 +03:00
|
|
|
static void select_frame(void *obj, char *arg);
|
2005-12-11 20:00:27 +03:00
|
|
|
static void swap_frame(void *obj, char *arg);
|
|
|
|
static void new_col(void *obj, char *arg);
|
2005-12-11 02:03:17 +03:00
|
|
|
|
2005-12-11 01:43:45 +03:00
|
|
|
static Action lcol_acttbl[] = {
|
2005-12-11 02:03:17 +03:00
|
|
|
{"select", select_frame},
|
2005-12-11 20:00:27 +03:00
|
|
|
{"swap", swap_frame},
|
|
|
|
{"new", new_col},
|
2005-12-11 01:43:45 +03:00
|
|
|
{0, 0}
|
|
|
|
};
|
2005-11-22 14:49:19 +03:00
|
|
|
|
2005-12-05 01:45:59 +03:00
|
|
|
void init_layout_column()
|
2005-11-18 18:54:58 +03:00
|
|
|
{
|
2005-12-16 04:59:27 +03:00
|
|
|
Layout *lp, *l = cext_emallocz(sizeof(Layout));
|
|
|
|
l->name = "column";
|
|
|
|
l->init = init_col;
|
|
|
|
l->deinit = deinit_col;
|
|
|
|
l->arrange = arrange_col;
|
|
|
|
l->attach = attach_col;
|
|
|
|
l->detach = detach_col;
|
|
|
|
l->resize = resize_col;
|
|
|
|
l->focus = focus_col;
|
|
|
|
l->frames = frames_col;
|
|
|
|
l->sel = sel_col;
|
|
|
|
l->actions = actions_col;
|
|
|
|
|
|
|
|
for (lp = layouts; lp && lp->next; lp = lp->next);
|
|
|
|
if (lp)
|
|
|
|
lp->next = l;
|
2005-12-13 03:10:28 +03:00
|
|
|
else
|
2005-12-16 04:59:27 +03:00
|
|
|
layouts = l;
|
2005-11-18 18:54:58 +03:00
|
|
|
}
|
|
|
|
|
2005-12-16 04:59:27 +03:00
|
|
|
static void arrange_column(Column *col)
|
2005-11-18 18:54:58 +03:00
|
|
|
{
|
2005-12-16 04:59:27 +03:00
|
|
|
ColFrame *cf;
|
|
|
|
unsigned int i = 0, h = area_rect.height / col->nframes;
|
|
|
|
for (cf = col->frames; cf; cf = cf->next) {
|
|
|
|
Frame *f = cf->frame;
|
|
|
|
f->rect = col->rect;
|
|
|
|
f->rect.y = area_rect.y + i * h;
|
|
|
|
if (!cf->next)
|
|
|
|
f->rect.height = area_rect.height - f->rect.y + area_rect.y;
|
|
|
|
else
|
|
|
|
f->rect.height = h;
|
|
|
|
resize_frame(f, &f->rect, 0);
|
|
|
|
i++;
|
2005-12-10 18:38:43 +03:00
|
|
|
}
|
2005-12-07 03:37:37 +03:00
|
|
|
}
|
2005-11-18 18:54:58 +03:00
|
|
|
|
2005-12-07 03:37:37 +03:00
|
|
|
static void arrange_col(Area *a)
|
|
|
|
{
|
|
|
|
Acme *acme = a->aux;
|
2005-12-16 04:59:27 +03:00
|
|
|
Column *col;
|
|
|
|
for (col = acme->columns; col; col = col->next)
|
|
|
|
arrange_column(col);
|
2005-12-12 19:04:40 +03:00
|
|
|
XSync(dpy, False);
|
2005-11-18 18:54:58 +03:00
|
|
|
}
|
|
|
|
|
2005-12-16 04:59:27 +03:00
|
|
|
static void init_col(Area *a, Client *clients)
|
2005-11-18 18:54:58 +03:00
|
|
|
{
|
2005-12-16 04:59:27 +03:00
|
|
|
Client *n, *c = clients;
|
|
|
|
|
|
|
|
a->aux = cext_emallocz(sizeof(Acme));
|
|
|
|
while (c) {
|
|
|
|
n = c->next;
|
|
|
|
attach_col(a, c);
|
|
|
|
c = n;
|
|
|
|
}
|
2005-12-07 03:37:37 +03:00
|
|
|
}
|
2005-11-18 18:54:58 +03:00
|
|
|
|
2005-12-16 04:59:27 +03:00
|
|
|
static void attach_frame(Area *a, Column *col, Frame *f)
|
2005-12-07 03:37:37 +03:00
|
|
|
{
|
2005-12-16 04:59:27 +03:00
|
|
|
Acme *acme = a->aux;
|
|
|
|
ColFrame *c, *cf = cext_emallocz(sizeof(ColFrame));
|
|
|
|
Frame *fr;
|
|
|
|
|
|
|
|
cf->frame = f;
|
|
|
|
cf->col = col;
|
|
|
|
f->aux = cf;
|
|
|
|
for (c = col->frames; c && c->next; c = c->next);
|
|
|
|
if (!c)
|
|
|
|
col->frames = cf;
|
|
|
|
else {
|
|
|
|
c->next = cf;
|
|
|
|
cf->prev = c;
|
|
|
|
}
|
|
|
|
col->sel = cf;
|
|
|
|
col->nframes++;
|
|
|
|
|
|
|
|
for (fr = acme->frames; fr && fr->next; fr = fr->next);
|
|
|
|
if (!fr)
|
|
|
|
acme->frames = f;
|
|
|
|
else {
|
|
|
|
fr->next = f;
|
|
|
|
f->prev = fr;
|
|
|
|
}
|
|
|
|
attach_frame_to_area(a, f);
|
|
|
|
acme->nframes++;
|
|
|
|
|
2005-12-07 03:37:37 +03:00
|
|
|
}
|
|
|
|
|
2005-12-16 04:59:27 +03:00
|
|
|
static void detach_frame(Area *a, Frame *f)
|
2005-12-07 03:37:37 +03:00
|
|
|
{
|
2005-12-16 04:59:27 +03:00
|
|
|
Acme *acme = a->aux;
|
|
|
|
ColFrame *cf = f->aux;
|
|
|
|
Column *col = cf->col;
|
|
|
|
|
|
|
|
if (col->sel == cf) {
|
|
|
|
if (cf->prev)
|
|
|
|
col->sel = cf->prev;
|
|
|
|
else
|
|
|
|
col->sel = nil;
|
|
|
|
}
|
|
|
|
if (cf->prev)
|
|
|
|
cf->prev->next = cf->next;
|
|
|
|
else
|
|
|
|
col->frames = cf->next;
|
|
|
|
if (cf->next)
|
|
|
|
cf->next->prev = cf->prev;
|
|
|
|
if (!col->sel)
|
|
|
|
col->sel = col->frames;
|
|
|
|
free(cf);
|
|
|
|
col->nframes--;
|
|
|
|
|
|
|
|
if (f->prev)
|
|
|
|
f->prev->next = f->next;
|
|
|
|
else
|
|
|
|
acme->frames = f->next;
|
|
|
|
if (f->next)
|
|
|
|
f->next->prev = f->prev;
|
|
|
|
f->aux = nil;
|
|
|
|
detach_frame_from_area(f);
|
|
|
|
acme->nframes--;
|
2005-12-07 03:37:37 +03:00
|
|
|
}
|
|
|
|
|
2005-12-16 04:59:27 +03:00
|
|
|
static Client *deinit_col(Area *a)
|
2005-12-07 03:37:37 +03:00
|
|
|
{
|
|
|
|
Acme *acme = a->aux;
|
2005-12-16 04:59:27 +03:00
|
|
|
Frame *f;
|
|
|
|
Client *cl, *res = nil, *c = nil;
|
|
|
|
Column *col = acme->columns;
|
|
|
|
|
|
|
|
while ((f = acme->frames)) {
|
|
|
|
while ((cl = f->clients)) {
|
|
|
|
detach_client_from_frame(cl, False);
|
|
|
|
cl->prev = cl->next = 0;
|
|
|
|
if (!c)
|
|
|
|
res = c = cl;
|
|
|
|
else {
|
|
|
|
c->next = cl;
|
|
|
|
cl->prev = c;
|
|
|
|
c = cl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
detach_frame(a, f);
|
|
|
|
destroy_frame(f);
|
|
|
|
}
|
|
|
|
while ((col = acme->columns)) {
|
|
|
|
acme->columns = col->next;
|
2005-12-10 18:38:43 +03:00
|
|
|
free(col);
|
|
|
|
}
|
2005-11-18 18:54:58 +03:00
|
|
|
free(acme);
|
2005-11-23 14:53:24 +03:00
|
|
|
a->aux = 0;
|
2005-12-16 04:59:27 +03:00
|
|
|
return res;
|
2005-11-18 18:54:58 +03:00
|
|
|
}
|
|
|
|
|
2005-12-07 17:06:16 +03:00
|
|
|
static Bool attach_col(Area *a, Client *c)
|
2005-11-18 18:54:58 +03:00
|
|
|
{
|
2005-12-05 01:45:59 +03:00
|
|
|
Acme *acme = a->aux;
|
2005-12-16 04:59:27 +03:00
|
|
|
Column *col = acme->sel;
|
|
|
|
Frame *f = nil;
|
|
|
|
|
|
|
|
if (col && col->sel)
|
|
|
|
f = col->sel->frame;
|
2005-12-10 18:38:43 +03:00
|
|
|
|
2005-12-13 18:10:22 +03:00
|
|
|
if (!col) {
|
|
|
|
col = cext_emallocz(sizeof(Column));
|
|
|
|
col->rect = area_rect;
|
2005-12-16 04:59:27 +03:00
|
|
|
acme->columns = acme->sel = col;
|
|
|
|
acme->ncolumns++;
|
2005-12-13 18:10:22 +03:00
|
|
|
}
|
|
|
|
|
2005-12-10 18:38:43 +03:00
|
|
|
/* check for tabbing? */
|
|
|
|
if (f && (((char *) f->file[F_LOCKED]->content)[0] == '1'))
|
|
|
|
f = 0;
|
|
|
|
if (!f) {
|
|
|
|
f = alloc_frame(&c->rect);
|
2005-12-16 04:59:27 +03:00
|
|
|
attach_frame(a, col, f);
|
2005-12-10 18:38:43 +03:00
|
|
|
}
|
2005-11-23 14:53:24 +03:00
|
|
|
attach_client_to_frame(f, c);
|
2005-12-16 04:59:27 +03:00
|
|
|
arrange_column(col);
|
|
|
|
if (a->page == selpage)
|
2005-12-10 18:38:43 +03:00
|
|
|
XMapWindow(dpy, f->win);
|
2005-12-16 04:59:27 +03:00
|
|
|
focus_col(f, True);
|
2005-12-07 17:06:16 +03:00
|
|
|
return True;
|
2005-11-18 18:54:58 +03:00
|
|
|
}
|
|
|
|
|
2005-12-13 18:10:22 +03:00
|
|
|
static void update_column_width(Area *a)
|
|
|
|
{
|
|
|
|
Acme *acme = a->aux;
|
2005-12-16 04:59:27 +03:00
|
|
|
unsigned int i = 0, width;
|
|
|
|
Column *col;
|
2005-12-13 18:10:22 +03:00
|
|
|
|
2005-12-16 04:59:27 +03:00
|
|
|
if (!acme->ncolumns)
|
2005-12-13 18:10:22 +03:00
|
|
|
return;
|
|
|
|
|
2005-12-16 04:59:27 +03:00
|
|
|
width = area_rect.width / acme->ncolumns;
|
|
|
|
for (col = acme->columns; col; col = col->next) {
|
2005-12-13 21:45:56 +03:00
|
|
|
col->rect = area_rect;
|
2005-12-13 18:10:22 +03:00
|
|
|
col->rect.x = i * width;
|
|
|
|
col->rect.width = width;
|
2005-12-16 04:59:27 +03:00
|
|
|
i++;
|
2005-12-13 18:10:22 +03:00
|
|
|
}
|
|
|
|
arrange_col(a);
|
|
|
|
}
|
|
|
|
|
2005-12-11 18:24:52 +03:00
|
|
|
static void detach_col(Area *a, Client *c, Bool unmap)
|
2005-11-18 18:54:58 +03:00
|
|
|
{
|
2005-12-10 18:38:43 +03:00
|
|
|
Acme *acme = a->aux;
|
2005-12-05 01:45:59 +03:00
|
|
|
Frame *f = c->frame;
|
|
|
|
Column *col = f->aux;
|
2005-11-18 18:54:58 +03:00
|
|
|
|
2005-12-11 18:24:52 +03:00
|
|
|
detach_client_from_frame(c, unmap);
|
2005-12-16 04:59:27 +03:00
|
|
|
if (!f->clients) {
|
|
|
|
detach_frame(a, f);
|
2005-12-10 18:38:43 +03:00
|
|
|
destroy_frame(f);
|
|
|
|
}
|
2005-12-14 05:49:25 +03:00
|
|
|
else return;
|
2005-12-16 04:59:27 +03:00
|
|
|
if (col->frames)
|
|
|
|
arrange_column(col);
|
2005-12-13 18:10:22 +03:00
|
|
|
else {
|
2005-12-16 04:59:27 +03:00
|
|
|
if (acme->sel == col) {
|
|
|
|
if (col->prev)
|
|
|
|
acme->sel = col->prev;
|
|
|
|
else
|
|
|
|
acme->sel = nil;
|
|
|
|
}
|
|
|
|
if (col->prev)
|
|
|
|
col->prev->next = col->next;
|
|
|
|
else
|
|
|
|
acme->columns = col->next;
|
|
|
|
if (col->next)
|
|
|
|
col->next->prev = col->prev;
|
|
|
|
if (!acme->sel)
|
|
|
|
acme->sel = acme->columns;
|
|
|
|
acme->ncolumns--;
|
2005-12-13 18:10:22 +03:00
|
|
|
free(col);
|
|
|
|
update_column_width(a);
|
|
|
|
}
|
2005-11-18 18:54:58 +03:00
|
|
|
}
|
|
|
|
|
2005-12-16 04:59:27 +03:00
|
|
|
static void match_frame_horiz(Column *col, XRectangle *r)
|
2005-11-18 18:54:58 +03:00
|
|
|
{
|
2005-12-16 04:59:27 +03:00
|
|
|
ColFrame *cf;
|
|
|
|
for (cf = col->frames; cf; cf = cf->next) {
|
|
|
|
Frame *f = cf->frame;
|
|
|
|
f->rect.x = r->x;
|
|
|
|
f->rect.width = r->width;
|
|
|
|
resize_frame(f, &f->rect, nil);
|
|
|
|
}
|
2005-12-10 18:38:43 +03:00
|
|
|
}
|
2005-11-18 18:54:58 +03:00
|
|
|
|
2005-12-10 18:38:43 +03:00
|
|
|
static void drop_resize(Frame *f, XRectangle *new)
|
|
|
|
{
|
|
|
|
Column *west = 0, *east = 0, *col = f->aux;
|
2005-12-16 04:59:27 +03:00
|
|
|
ColFrame *north = 0, *south = 0;
|
|
|
|
ColFrame *cf = f->aux;
|
2005-12-10 18:38:43 +03:00
|
|
|
|
2005-12-16 04:59:27 +03:00
|
|
|
west = col->prev;
|
|
|
|
east = col->next;
|
|
|
|
north = cf->prev;
|
|
|
|
south = cf->next;
|
2005-12-10 18:38:43 +03:00
|
|
|
|
|
|
|
/* horizontal resize */
|
2005-12-13 21:45:56 +03:00
|
|
|
if (west && (new->x != f->rect.x)) {
|
|
|
|
west->rect.width = new->x - west->rect.x;
|
|
|
|
col->rect.width += f->rect.x - new->x;
|
|
|
|
col->rect.x = new->x;
|
2005-12-16 04:59:27 +03:00
|
|
|
match_frame_horiz(west, &west->rect);
|
|
|
|
match_frame_horiz(col, &col->rect);
|
2005-11-18 18:54:58 +03:00
|
|
|
}
|
2005-12-13 21:45:56 +03:00
|
|
|
if (east && (new->x + new->width != f->rect.x + f->rect.width)) {
|
|
|
|
east->rect.width -= new->x + new->width - east->rect.x;
|
|
|
|
east->rect.x = new->x + new->width;
|
|
|
|
col->rect.x = new->x;
|
|
|
|
col->rect.width = new->width;
|
2005-12-16 04:59:27 +03:00
|
|
|
match_frame_horiz(col, &col->rect);
|
|
|
|
match_frame_horiz(east, &east->rect);
|
2005-11-18 18:54:58 +03:00
|
|
|
}
|
|
|
|
|
2005-12-10 18:38:43 +03:00
|
|
|
/* vertical resize */
|
2005-12-13 21:45:56 +03:00
|
|
|
if (north && (new->y != f->rect.y)) {
|
2005-12-16 04:59:27 +03:00
|
|
|
north->frame->rect.height = new->y - north->frame->rect.y;
|
2005-12-13 21:45:56 +03:00
|
|
|
f->rect.height += f->rect.y - new->y;
|
|
|
|
f->rect.y = new->y;
|
2005-12-16 04:59:27 +03:00
|
|
|
resize_frame(north->frame, &north->frame->rect, nil);
|
2005-12-13 21:45:56 +03:00
|
|
|
resize_frame(f, &f->rect, nil);
|
2005-11-18 18:54:58 +03:00
|
|
|
}
|
2005-12-15 02:23:31 +03:00
|
|
|
if (south && (new->y + new->height != f->rect.y + f->rect.height)) {
|
2005-12-16 04:59:27 +03:00
|
|
|
south->frame->rect.height -= new->y + new->height - south->frame->rect.y;
|
|
|
|
south->frame->rect.y = new->y + new->height;
|
2005-12-13 21:45:56 +03:00
|
|
|
f->rect.y = new->y;
|
|
|
|
f->rect.height = new->height;
|
|
|
|
resize_frame(f, &f->rect, nil);
|
2005-12-16 04:59:27 +03:00
|
|
|
resize_frame(south->frame, &south->frame->rect, nil);
|
2005-11-18 18:54:58 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-12-10 18:38:43 +03:00
|
|
|
static void drop_moving(Frame *f, XRectangle *new, XPoint *pt)
|
2005-11-18 18:54:58 +03:00
|
|
|
{
|
2005-12-16 04:59:27 +03:00
|
|
|
Area *a = f->area;
|
|
|
|
ColFrame *fcf = f->aux;
|
|
|
|
Column *src = fcf->col, *tgt = 0;
|
|
|
|
Acme *acme = a->aux;
|
2005-11-18 18:54:58 +03:00
|
|
|
|
2005-12-10 18:38:43 +03:00
|
|
|
if (!pt)
|
|
|
|
return;
|
2005-11-18 18:54:58 +03:00
|
|
|
|
2005-12-16 04:59:27 +03:00
|
|
|
for (tgt = acme->columns; tgt && !blitz_ispointinrect(pt->x, pt->y, &tgt->rect); tgt = tgt->next);
|
|
|
|
if (tgt) {
|
2005-12-13 21:45:56 +03:00
|
|
|
if (tgt != src) {
|
2005-12-16 04:59:27 +03:00
|
|
|
if (src->nframes < 2)
|
2005-12-13 21:45:56 +03:00
|
|
|
return;
|
2005-12-16 04:59:27 +03:00
|
|
|
detach_frame(a, f);
|
|
|
|
attach_frame(a, tgt, f);
|
|
|
|
arrange_column(src);
|
|
|
|
arrange_column(tgt);
|
|
|
|
focus_col(f, True);
|
2005-12-13 21:45:56 +03:00
|
|
|
}
|
|
|
|
else {
|
2005-12-16 04:59:27 +03:00
|
|
|
ColFrame *cf;
|
|
|
|
for (cf = src->frames; cf && !blitz_ispointinrect(pt->x, pt->y, &cf->frame->rect); cf = cf->next);
|
|
|
|
if (cf && cf != fcf) {
|
|
|
|
Frame *tmp = cf->frame;
|
|
|
|
cf->frame = f;
|
|
|
|
fcf->frame = tmp;
|
|
|
|
arrange_column(src);
|
|
|
|
focus_col(f, True);
|
2005-12-13 21:45:56 +03:00
|
|
|
}
|
|
|
|
}
|
2005-11-18 18:54:58 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-12-07 03:37:37 +03:00
|
|
|
static void resize_col(Frame *f, XRectangle *new, XPoint *pt)
|
2005-11-18 18:54:58 +03:00
|
|
|
{
|
|
|
|
if ((f->rect.width == new->width)
|
2005-12-05 01:45:59 +03:00
|
|
|
&& (f->rect.height == new->height))
|
2005-12-10 18:38:43 +03:00
|
|
|
drop_moving(f, new, pt);
|
2005-11-18 18:54:58 +03:00
|
|
|
else
|
|
|
|
drop_resize(f, new);
|
|
|
|
}
|
2005-12-09 04:46:59 +03:00
|
|
|
|
2005-12-16 04:59:27 +03:00
|
|
|
static void focus_col(Frame *f, Bool raise)
|
2005-12-09 04:46:59 +03:00
|
|
|
{
|
2005-12-11 01:43:45 +03:00
|
|
|
Area *a = f->area;
|
|
|
|
Acme *acme = a->aux;
|
2005-12-16 04:59:27 +03:00
|
|
|
ColFrame *old, *fcf = f->aux;
|
|
|
|
Column *col = fcf->col;
|
2005-12-14 03:22:37 +03:00
|
|
|
|
2005-12-16 04:59:27 +03:00
|
|
|
old = col->sel;
|
|
|
|
acme->sel = col;
|
|
|
|
col->sel = fcf;
|
|
|
|
sel_client(f->sel);
|
2005-12-11 01:43:45 +03:00
|
|
|
a->file[A_SEL_FRAME]->content = f->file[F_PREFIX]->content;
|
2005-12-11 17:47:23 +03:00
|
|
|
if (raise)
|
|
|
|
center_pointer(f);
|
2005-12-16 04:59:27 +03:00
|
|
|
if (old && old != fcf)
|
|
|
|
draw_frame(old->frame);
|
2005-12-14 03:22:37 +03:00
|
|
|
draw_frame(f);
|
2005-12-09 04:46:59 +03:00
|
|
|
}
|
2005-12-10 16:50:20 +03:00
|
|
|
|
2005-12-16 04:59:27 +03:00
|
|
|
static Frame *frames_col(Area *a)
|
2005-12-10 16:50:20 +03:00
|
|
|
{
|
|
|
|
Acme *acme = a->aux;
|
2005-12-16 04:59:27 +03:00
|
|
|
return acme->frames;
|
2005-12-10 16:50:20 +03:00
|
|
|
}
|
|
|
|
|
2005-12-16 04:59:27 +03:00
|
|
|
static Frame *sel_col(Area *a) {
|
|
|
|
Acme *acme = a->aux;
|
|
|
|
Column *col = acme->sel;
|
|
|
|
|
|
|
|
if (col && col->sel)
|
|
|
|
return col->sel->frame;
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Action *actions_col(Area *a)
|
2005-12-11 01:43:45 +03:00
|
|
|
{
|
|
|
|
return lcol_acttbl;
|
|
|
|
}
|
2005-12-11 02:03:17 +03:00
|
|
|
|
|
|
|
static void select_frame(void *obj, char *arg)
|
|
|
|
{
|
|
|
|
Area *a = obj;
|
|
|
|
Acme *acme = a->aux;
|
|
|
|
Column *col = get_sel_column(acme);
|
2005-12-14 03:22:37 +03:00
|
|
|
Frame *f;
|
2005-12-11 02:03:17 +03:00
|
|
|
|
2005-12-13 22:06:07 +03:00
|
|
|
if (!col)
|
|
|
|
return;
|
|
|
|
|
2005-12-14 03:22:37 +03:00
|
|
|
f = cext_stack_get_top_item(&col->frames);
|
2005-12-11 02:03:17 +03:00
|
|
|
if (!f || !arg)
|
|
|
|
return;
|
|
|
|
if (!strncmp(arg, "prev", 5))
|
2005-12-15 14:38:22 +03:00
|
|
|
f = cext_list_get_prev_item(&acme->frames, f);
|
2005-12-11 02:03:17 +03:00
|
|
|
else if (!strncmp(arg, "next", 5))
|
2005-12-15 14:38:22 +03:00
|
|
|
f = cext_list_get_next_item(&acme->frames, f);
|
|
|
|
else if (!strncmp(arg, "north", 6))
|
|
|
|
f = cext_list_get_next_item(&col->frames, f);
|
|
|
|
else if (!strncmp(arg, "south", 6))
|
2005-12-11 02:03:17 +03:00
|
|
|
f = cext_list_get_next_item(&col->frames, f);
|
2005-12-11 20:14:06 +03:00
|
|
|
else if (!strncmp(arg, "west", 5)) {
|
|
|
|
col = cext_list_get_prev_item(&acme->columns, col);
|
|
|
|
cext_stack_top_item(&acme->columns, col);
|
|
|
|
f = cext_stack_get_top_item(&col->frames);
|
|
|
|
}
|
|
|
|
else if (!strncmp(arg, "east", 5)) {
|
|
|
|
col = cext_list_get_next_item(&acme->columns, col);
|
|
|
|
cext_stack_top_item(&acme->columns, col);
|
|
|
|
f = cext_stack_get_top_item(&col->frames);
|
|
|
|
}
|
2005-12-11 02:03:17 +03:00
|
|
|
else
|
2005-12-13 18:10:22 +03:00
|
|
|
f = cext_list_get_item(&col->frames, blitz_strtonum(arg, 0, cext_sizeof_container(&col->frames) - 1));
|
2005-12-16 04:59:27 +03:00
|
|
|
focus_col(f, True);
|
2005-12-11 02:03:17 +03:00
|
|
|
}
|
2005-12-11 20:00:27 +03:00
|
|
|
|
|
|
|
static void swap_frame(void *obj, char *arg)
|
|
|
|
{
|
|
|
|
Area *a = obj;
|
|
|
|
Acme *acme = a->aux;
|
2005-12-13 21:45:56 +03:00
|
|
|
Column *west = 0, *east = 0, *col = get_sel_column(acme);
|
2005-12-13 22:06:07 +03:00
|
|
|
Frame *north = 0, *south = 0, *f;
|
2005-12-13 21:58:05 +03:00
|
|
|
XRectangle r;
|
2005-12-13 21:45:56 +03:00
|
|
|
size_t ncol, nfr;
|
|
|
|
int colidx, fidx;
|
|
|
|
|
2005-12-13 22:06:07 +03:00
|
|
|
if (!col)
|
|
|
|
return;
|
|
|
|
|
|
|
|
f = cext_stack_get_top_item(&col->frames);
|
|
|
|
|
2005-12-11 20:00:27 +03:00
|
|
|
if (!f || !arg)
|
|
|
|
return;
|
2005-12-13 21:45:56 +03:00
|
|
|
|
|
|
|
ncol = cext_sizeof_container(&acme->columns);
|
|
|
|
nfr = cext_sizeof_container(&col->frames);
|
|
|
|
colidx = cext_list_get_item_index(&acme->columns, col);
|
|
|
|
fidx = cext_list_get_item_index(&col->frames, f);
|
|
|
|
|
|
|
|
if (colidx > 0)
|
|
|
|
west = cext_list_get_item(&acme->columns, colidx - 1);
|
|
|
|
if (colidx + 1 < ncol)
|
|
|
|
east = cext_list_get_item(&acme->columns, colidx + 1);
|
|
|
|
if (fidx > 0)
|
|
|
|
north = cext_list_get_item(&col->frames, fidx - 1);
|
|
|
|
if (fidx + 1 < nfr)
|
|
|
|
south = cext_list_get_item(&col->frames, fidx + 1);
|
|
|
|
|
|
|
|
if (!strncmp(arg, "north", 6) && north) {
|
2005-12-13 21:58:05 +03:00
|
|
|
r = north->rect;
|
|
|
|
north->rect = f->rect;
|
|
|
|
f->rect = r;
|
2005-12-13 21:45:56 +03:00
|
|
|
cext_swap_items(&col->frames, f, north);
|
2005-12-13 21:58:05 +03:00
|
|
|
resize_frame(f, &f->rect, nil);
|
|
|
|
resize_frame(north, &north->rect, nil);
|
2005-12-16 04:59:27 +03:00
|
|
|
focus_col(f, True);
|
2005-12-13 21:45:56 +03:00
|
|
|
}
|
|
|
|
else if (!strncmp(arg, "south", 6) && south) {
|
2005-12-13 21:58:05 +03:00
|
|
|
r = south->rect;
|
|
|
|
south->rect = f->rect;
|
|
|
|
f->rect = r;
|
2005-12-13 21:45:56 +03:00
|
|
|
cext_swap_items(&col->frames, f, south);
|
2005-12-13 21:58:05 +03:00
|
|
|
resize_frame(f, &f->rect, nil);
|
|
|
|
resize_frame(south, &south->rect, nil);
|
2005-12-16 04:59:27 +03:00
|
|
|
focus_col(f, True);
|
2005-12-13 21:45:56 +03:00
|
|
|
}
|
|
|
|
else if (!strncmp(arg, "west", 5) && west && (ncol > 1)) {
|
|
|
|
Frame *other = cext_stack_get_top_item(&west->frames);
|
2005-12-13 21:58:05 +03:00
|
|
|
r = other->rect;
|
|
|
|
other->rect = f->rect;
|
|
|
|
f->rect = r;
|
2005-12-13 21:45:56 +03:00
|
|
|
cext_detach_item(&col->frames, f);
|
|
|
|
cext_detach_item(&west->frames, other);
|
|
|
|
cext_attach_item(&west->frames, f);
|
|
|
|
cext_attach_item(&col->frames, other);
|
|
|
|
f->aux = west;
|
|
|
|
other->aux = col;
|
2005-12-13 21:58:05 +03:00
|
|
|
resize_frame(f, &f->rect, nil);
|
|
|
|
resize_frame(other, &other->rect, nil);
|
2005-12-16 04:59:27 +03:00
|
|
|
focus_col(f, True);
|
2005-12-13 21:45:56 +03:00
|
|
|
}
|
|
|
|
else if (!strncmp(arg, "east", 5) && east && (ncol > 1)) {
|
|
|
|
Frame *other = cext_stack_get_top_item(&east->frames);
|
2005-12-13 21:58:05 +03:00
|
|
|
r = other->rect;
|
|
|
|
other->rect = f->rect;
|
|
|
|
f->rect = r;
|
2005-12-13 21:45:56 +03:00
|
|
|
cext_detach_item(&col->frames, f);
|
|
|
|
cext_detach_item(&east->frames, other);
|
|
|
|
cext_attach_item(&east->frames, f);
|
|
|
|
cext_attach_item(&col->frames, other);
|
|
|
|
f->aux = east;
|
|
|
|
other->aux = col;
|
2005-12-13 21:58:05 +03:00
|
|
|
resize_frame(f, &f->rect, nil);
|
|
|
|
resize_frame(other, &other->rect, nil);
|
2005-12-16 04:59:27 +03:00
|
|
|
focus_col(f, True);
|
2005-12-13 21:45:56 +03:00
|
|
|
}
|
2005-12-11 20:00:27 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void new_col(void *obj, char *arg)
|
|
|
|
{
|
|
|
|
Area *a = obj;
|
|
|
|
Acme *acme = a->aux;
|
2005-12-13 18:10:22 +03:00
|
|
|
Column *col = get_sel_column(acme);
|
2005-12-13 22:06:07 +03:00
|
|
|
Frame *f;
|
2005-12-13 18:10:22 +03:00
|
|
|
|
2005-12-13 22:06:07 +03:00
|
|
|
if (!col || (cext_sizeof_container(&col->frames) < 2))
|
2005-12-13 18:10:22 +03:00
|
|
|
return;
|
|
|
|
|
2005-12-13 22:06:07 +03:00
|
|
|
f = cext_stack_get_top_item(&col->frames);
|
2005-12-13 18:10:22 +03:00
|
|
|
cext_detach_item(&col->frames, f);
|
|
|
|
f->aux = col = cext_emallocz(sizeof(Column));
|
|
|
|
cext_attach_item(&col->frames, f);
|
2005-12-11 20:00:27 +03:00
|
|
|
cext_attach_item(&acme->columns, col);
|
|
|
|
update_column_width(a);
|
2005-12-16 04:59:27 +03:00
|
|
|
focus_col(f, True);
|
2005-12-11 20:00:27 +03:00
|
|
|
}
|
2005-12-16 04:59:27 +03:00
|
|
|
|