mirror of https://github.com/0intro/wmii
251 lines
5.5 KiB
C
251 lines
5.5 KiB
C
/*
|
|
* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
|
|
* See LICENSE file for license details.
|
|
*/
|
|
|
|
#include <math.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <cext.h>
|
|
|
|
#include "blitz.h"
|
|
|
|
BlitzAlign
|
|
blitz_align_of_rect(XRectangle *rect, int x, int y)
|
|
{
|
|
int w = x <= rect->x + rect->width / 2;
|
|
int n = y <= rect->y + rect->height / 2;
|
|
int e = x > rect->x + rect->width / 2;
|
|
int s = y > rect->y + rect->height / 2;
|
|
int nw = w && n;
|
|
int ne = e && n;
|
|
int sw = w && s;
|
|
int se = e && s;
|
|
|
|
if(nw)
|
|
return NWEST;
|
|
else if(ne)
|
|
return NEAST;
|
|
else if(se)
|
|
return SEAST;
|
|
else if(sw)
|
|
return SWEST;
|
|
|
|
return CENTER;
|
|
}
|
|
|
|
int blitz_strtoalign(BlitzAlign *result, char *val)
|
|
{
|
|
/*
|
|
* note, resize allows syntax like "east-20", this we cannot do
|
|
* include zero termination in strncmp checking!
|
|
*/
|
|
|
|
*result = CENTER;
|
|
if (!strncmp(val, "west", 4))
|
|
*result = WEST;
|
|
else if (!strncmp(val, "nwest", 5))
|
|
*result = NWEST;
|
|
else if (!strncmp(val, "north", 5))
|
|
*result = NORTH;
|
|
else if (!strncmp(val, "neast", 5))
|
|
*result = NEAST;
|
|
else if (!strncmp(val, "east", 4))
|
|
*result = EAST;
|
|
else if (!strncmp(val, "seast", 5))
|
|
*result = SEAST;
|
|
else if (!strncmp(val, "south", 5))
|
|
*result = SOUTH;
|
|
else if (!strncmp(val, "swest", 5))
|
|
*result = SWEST;
|
|
else if (!strncmp(val, "center", 6))
|
|
*result = CENTER;
|
|
else
|
|
return -1;
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Basic Syntax: <x> <y> <width> <height>
|
|
* Each component can be of following format:
|
|
* <...> = [+|-]0..n|<alignment>[[+|-]0..n]
|
|
*/
|
|
int blitz_strtorect(XRectangle *root, XRectangle *r, char *val)
|
|
{
|
|
const char *err;
|
|
char buf[64];
|
|
char *x, *y, *w, *h;
|
|
char *p;
|
|
int rx, ry, rw, rh, sx, sy, sw, sh;
|
|
|
|
if (!val)
|
|
return -1;
|
|
rx = r->x;
|
|
ry = r->y;
|
|
rw = r->width;
|
|
rh = r->height;
|
|
sx = sy = sw = sh = 0;
|
|
x = y = w = h = 0;
|
|
cext_strlcpy(buf, val, sizeof(buf));
|
|
|
|
x = strtok_r(buf, " ", &p);
|
|
if (x) {
|
|
y = strtok_r(0, " ", &p);
|
|
if (y) {
|
|
w = strtok_r(0, " ", &p);
|
|
if (w) {
|
|
h = strtok_r(0, "", &p);
|
|
}
|
|
}
|
|
}
|
|
if (x && (sx = (x[0] >= '0') && (x[0] <= '9')))
|
|
rx = cext_strtonum(x, 0, 65535, &err);
|
|
if (y && (sy = (y[0] >= '0') && (y[0] <= '9')))
|
|
ry = cext_strtonum(y, 0, 65535, &err);
|
|
if (w && (sw = (w[0] >= '0') && (w[0] <= '9')))
|
|
rw = cext_strtonum(w, 0, 65535, &err);
|
|
if (h && (sh = (h[0] >= '0') && (h[0] <= '9')))
|
|
rh = cext_strtonum(h, 0, 65535, &err);
|
|
|
|
if (!sx && !sw && x && w
|
|
&& x[0] != '-' && x[0] != '+' && w[0] != '-' && w[0] != '+') {
|
|
BlitzAlign ax, aw;
|
|
blitz_strtoalign(&ax, x);
|
|
blitz_strtoalign(&aw, w);
|
|
if ((ax == CENTER) && (aw == EAST)) {
|
|
rx = root->x + root->width / 2;
|
|
rw = root->width / 2;
|
|
} else {
|
|
rx = root->x;
|
|
if (aw == CENTER) {
|
|
rw = root->width / 2;
|
|
} else {
|
|
rw = root->width;
|
|
}
|
|
}
|
|
} else if (!sx && x && x[0] != '-' && x[0] != '+') {
|
|
BlitzAlign ax;
|
|
blitz_strtoalign(&ax, x);
|
|
if (ax == CENTER) {
|
|
rx = root->x + (root->width / 2) - (rw / 2);
|
|
} else if (ax == EAST) {
|
|
rx = root->x + root->width - rw;
|
|
} else {
|
|
rx = root->x;
|
|
}
|
|
} else if (!sw && w && w[0] != '-' && w[0] != '+') {
|
|
BlitzAlign aw;
|
|
blitz_strtoalign(&aw, w);
|
|
if (aw == CENTER) {
|
|
rw = (root->width / 2) - rx;
|
|
} else {
|
|
rw = root->width - rx;
|
|
}
|
|
}
|
|
if (!sy && !sh && y && h
|
|
&& y[0] != '-' && y[0] != '+' && h[0] != '-' && h[0] != '+') {
|
|
BlitzAlign ay, ah;
|
|
blitz_strtoalign(&ay, y);
|
|
blitz_strtoalign(&ah, h);
|
|
if ((ay == CENTER) && (ah == SOUTH)) {
|
|
ry = root->y + root->height / 2;
|
|
rh = root->height / 2;
|
|
} else {
|
|
ry = root->y;
|
|
if (ah == CENTER) {
|
|
rh = root->height / 2;
|
|
} else {
|
|
rh = root->height;
|
|
}
|
|
}
|
|
} else if (!sy && y && y[0] != '-' && y[0] != '+') {
|
|
BlitzAlign ay;
|
|
blitz_strtoalign(&ay, y);
|
|
if (ay == CENTER) {
|
|
ry = root->y + (root->height / 2) - (rh / 2);
|
|
} else if (ay == SOUTH) {
|
|
ry = root->y + root->height - rh;
|
|
} else {
|
|
ry = root->y;
|
|
}
|
|
} else if (!sh && h && h[0] != '-' && h[0] != '+') {
|
|
BlitzAlign ah;
|
|
blitz_strtoalign(&ah, h);
|
|
if (ah == CENTER) {
|
|
rh = (root->height / 2) - ry;
|
|
} else {
|
|
rh = root->height - ry;
|
|
}
|
|
}
|
|
/* now do final calculations */
|
|
if (x) {
|
|
p = strchr(x, '-');
|
|
if (p)
|
|
rx -= cext_strtonum(++p, 0, 65535, &err);
|
|
p = strchr(x, '+');
|
|
if (p)
|
|
rx += cext_strtonum(++p, 0, 65535, &err);
|
|
}
|
|
if (y) {
|
|
p = strchr(y, '-');
|
|
if (p)
|
|
ry -= cext_strtonum(++p, 0, 65535, &err);
|
|
p = strchr(y, '+');
|
|
if (p)
|
|
ry += cext_strtonum(++p, 0, 65535, &err);
|
|
}
|
|
if (w) {
|
|
p = strchr(w, '-');
|
|
if (p)
|
|
rw -= cext_strtonum(++p, 0, 65535, &err);
|
|
p = strchr(w, '+');
|
|
if (p)
|
|
rw += cext_strtonum(++p, 0, 65535, &err);
|
|
}
|
|
if (h) {
|
|
p = strchr(h, '-');
|
|
if (p)
|
|
rh -= cext_strtonum(++p, 0, 65535, &err);
|
|
p = strchr(h, '+');
|
|
if (p)
|
|
rh += cext_strtonum(++p, 0, 65535, &err);
|
|
}
|
|
|
|
if (rw < 1)
|
|
rw = 10;
|
|
if (rh < 1)
|
|
rh = 10;
|
|
r->x = rx;
|
|
r->y = ry;
|
|
r->width = rw;
|
|
r->height = rh;
|
|
return 0;
|
|
}
|
|
|
|
Bool blitz_ispointinrect(int x, int y, XRectangle * r)
|
|
{
|
|
return (x >= r->x) && (x <= r->x + r->width) && (y >= r->y) && (y <= r->y + r->height);
|
|
}
|
|
|
|
int blitz_distance(XRectangle * origin, XRectangle * target)
|
|
{
|
|
int ox = origin->x + origin->width / 2;
|
|
int oy = origin->y + origin->height / 2;
|
|
int tx = target->x + target->width / 2;
|
|
int ty = target->y + target->height / 2;
|
|
|
|
return (int) sqrt((double) (((ox - tx) * (ox - tx)) + ((oy - ty) * (oy - ty))));
|
|
}
|
|
|
|
void blitz_getbasegeometry(unsigned int size, unsigned int *cols, unsigned int *rows)
|
|
{
|
|
float sq, dummy;
|
|
|
|
sq = sqrt(size);
|
|
if (modff(sq, &dummy) < 0.5)
|
|
*rows = floor(sq);
|
|
else
|
|
*rows = ceil(sq);
|
|
*cols = ((*rows) * (*rows)) < (size) ? *rows + 1 : *rows;
|
|
}
|