ref: 08aef1095811c8f436a469208b088002e8f4ed21
dir: /n_label.c/
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <event.h>
#include "nate.h"
#include "nate_construct.h"
#include "n_label.h"
#define N_TYPE NLabel_Type
char* NLabel_Type = "NLabel";
static char*
getlabelstr(NLabel* l)
{
if (l->labelfunc)
return l->labelfunc();
if (l->label)
return l->label;
return "";
}
static Rectangle
label_calcrect(Nelem* nelem, Image*, Rectangle r)
{
NLabel* l = (NLabel*)nelem;
GUARD(l);
l->slot.r = r;
return r;
}
static Point
label_desiredsize(Nelem *nelem, Image*)
{
Point pt;
NLabel *l = (NLabel*)nelem;
GUARD(l);
pt = stringsize(l->font, getlabelstr(l));
pt.x += l->margin.left + l->margin.right;
pt.y += l->margin.top + l->margin.bottom;
return pt;
}
static void
label_draw(Nelem* nelem, Image* img)
{
char* str;
Rectangle r;
Point sz, p;
NLabel* l = (NLabel*)nelem;
GUARD(l);
str = getlabelstr(l);
r = l->slot.r;
sz = stringsize(l->font, str);
// TODO: background color for text?
draw(img, r, display->white, nil, ZP);
switch (l->align) {
case TOPLEFT:
p.x = r.min.x + l->margin.left;
p.y = r.min.y + l->margin.top;
break;
case TOP:
p.y = r.min.y + l->margin.top;
p.x = r.min.x + (Dx(r) - sz.x)/2;
break;
case TOPRIGHT:
p.x = r.max.x - l->margin.right - sz.x;
p.y = r.min.y + l->margin.top;
break;
case LEFT:
p.x = r.min.x + l->margin.left;
p.y = r.min.y + (Dy(r) - sz.y)/2;
break;
case CENTER:
p.x = r.min.x + (Dx(r) - sz.x)/2;
p.y = r.min.y + (Dy(r) - sz.y)/2;
break;
case RIGHT:
p.x = r.max.x - l->margin.right - sz.x;
p.y = r.min.y + (Dy(r) - sz.y)/2;
break;
case BOTLEFT:
p.x = r.min.x + l->margin.left;
p.y = r.max.y - l->margin.bottom - sz.y;
break;
case BOTTOM:
p.x = r.min.x + (Dx(r) - sz.x)/2;
p.y = r.max.y - l->margin.bottom - sz.y;
break;
case BOTRIGHT:
p.x = r.max.x - l->margin.right - sz.x;
p.y = r.max.y - l->margin.bottom - sz.y;
break;
}
string(img, p, l->color, ZP, l->font, str);
}
static char*
label_getname(Nelem *nelem)
{
NLabel *l = (NLabel*)nelem;
GUARD(l);
return getlabelstr(l);
}
static Nelemfunctions Nlabelfunctions = {
.calcrect = label_calcrect,
.desiredsize = label_desiredsize,
.draw = label_draw,
.getname = label_getname,
};
#define NTYPE NLabel
#define NACCS NLabelAccessors
DEF_ACCESSOR_OneParam(label, char*, label);
DEF_ACCESSOR_OneParam(labelfunc, StringGetter, labelfunc);
DEF_ACCESSOR_OneParam(lfont, Font*, font);
DEF_ACCESSOR_OneParam(lcolor, Image*, color);
DEF_ACCESSOR_OneParam(lmargin, Nmargin, margin);
DEF_ACCESSOR_OneParam(lalign, Nalign, align);
static NACCS accs = {
.Label = label,
.LabelFunc = labelfunc,
.Font = lfont,
.Color = lcolor,
.Margin = lmargin,
.Align = lalign,
};
NACCS*
New_Label(char *name)
{
NLabel *e = MakeNelem(NLabel, NLabel_Type, &Nlabelfunctions, &accs, name, 0);
e->label = nil;
e->labelfunc = nil;
e->font = display->defaultfont;
e->color = display->black;
nc_push(e);
return &accs;
}