From 37da2899f40661e3e9631e497da8dc59b971cbd0 Mon Sep 17 00:00:00 2001 From: "Charles.Forsyth" Date: Fri, 22 Dec 2006 17:07:39 +0000 Subject: 20060303a --- libtk/scale.c | 958 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 958 insertions(+) create mode 100644 libtk/scale.c (limited to 'libtk/scale.c') diff --git a/libtk/scale.c b/libtk/scale.c new file mode 100644 index 00000000..e32f7e69 --- /dev/null +++ b/libtk/scale.c @@ -0,0 +1,958 @@ +#include +#include +#include "draw.h" +#include "tk.h" +#include "keyboard.h" + +#define O(t, e) ((long)(&((t*)0)->e)) + +typedef struct TkScale TkScale; +struct TkScale +{ + int value; + int bigi; + int digits; + int digwidth; + int from; /* Base of range */ + int to; /* Limit of range */ + int len; /* Length of groove */ + int res; /* Resolution */ + int sv; /* Show value */ + int sl; /* Slider length */ + int sw; /* Slider width div 2 */ + int relief; + int tick; + int orient; + char* command; + char* label; + int pixmin; + int pixmax; + int pixpos; + int center; + int pix; + int base; + int flag; + int jump; +}; + +enum { + Dragging = (1<<0), + Autorepeat = (1<<1), +}; + +static +TkOption opts[] = +{ + "bigincrement", OPTnnfrac, O(TkScale, bigi), nil, + "digits", OPTdist, O(TkScale, digits), nil, + "from", OPTfrac, O(TkScale, from), nil, + "to", OPTfrac, O(TkScale, to), nil, + "length", OPTdist, O(TkScale, len), nil, + "resolution", OPTnnfrac, O(TkScale, res), nil, + "showrange", OPTignore, 0, nil, + "showvalue", OPTstab, O(TkScale, sv), tkbool, + "jump", OPTstab, O(TkScale, jump), tkbool, + "sliderlength", OPTdist, O(TkScale, sl), nil, + "sliderrelief", OPTstab, O(TkScale, relief), tkrelief, + "tickinterval", OPTfrac, O(TkScale, tick), nil, + "tick", OPTfrac, O(TkScale, tick), nil, + "label", OPTtext, O(TkScale, label), nil, + "command", OPTtext, O(TkScale, command), nil, + "orient", OPTstab, O(TkScale, orient), tkorient, + nil +}; + +static char trough1[] = "trough1"; +static char trough2[] = "trough2"; +static char slider[] = "slider"; + +static +TkEbind b[] = +{ + {TkMotion, "%W tkScaleMotion %x %y"}, + {TkButton1P|TkMotion, "%W tkScaleDrag %x %y"}, + {TkButton1P, "%W tkScaleMotion %x %y; %W tkScaleBut1P %x %y"}, + {TkButton1P|TkDouble, "%W tkScaleMotion %x %y; %W tkScaleBut1P %x %y"}, + {TkButton1R, "%W tkScaleDrag %x %y; %W tkScaleBut1R; %W tkScaleMotion %x %y"}, + {TkKey, "%W tkScaleKey 0x%K"}, +}; + +enum +{ + Scalewidth = 18, + ScalePad = 2, + ScaleBW = 2, + ScaleSlider = 16, + ScaleLen = 80, + +}; + +static int +maximum(int a, int b) +{ + if (a > b) + return a; + return b; +} + +void +tksizescale(Tk *tk) +{ + Point p; + char buf[32]; + TkScale *tks; + int fh, w, h, digits, digits2; + + tks = TKobj(TkScale, tk); + + digits = tks->digits; + if(digits <= 0) { + digits = tkfprint(buf, tks->from) - buf; + digits2 = tkfprint(buf, tks->to) - buf; + digits = maximum(digits, digits2); + if (tks->res > 0) { + digits2 = tkfprint(buf, tks->from + tks->res) - buf; + digits = maximum(digits, digits2); + digits2 = tkfprint(buf, tks->to - tks->res) - buf; + digits = maximum(digits, digits2); + } + } + + digits *= tk->env->wzero; + if(tks->sv != BoolT) + digits = 0; + + tks->digwidth = digits; + + p = tkstringsize(tk, tks->label); + if(tks->orient == Tkvertical) { + h = tks->len + 2*ScaleBW + 2*ScalePad; + w = Scalewidth + 2*ScalePad + 2*ScaleBW; + if (p.x) + w += p.x + ScalePad; + if (tks->sv == BoolT) + w += digits + ScalePad; + } + else { + w = maximum(p.x, tks->len + ScaleBW + 2*ScalePad); + h = Scalewidth + 2*ScalePad + 2*ScaleBW; + fh = tk->env->font->height; + if(tks->label != nil) + h += fh + ScalePad; + if(tks->sv == BoolT) + h += fh + ScalePad; + } + w += 2*tk->highlightwidth; + h += 2*tk->highlightwidth; + if(!(tk->flag & Tksetwidth)) + tk->req.width = w; + if(!(tk->flag & Tksetheight)) + tk->req.height = h; +} + +static int +tkscalecheckvalue(Tk *tk) +{ + int v; + TkScale *tks = TKobj(TkScale, tk); + int limit = 1; + + v = tks->value; + if (tks->res > 0) + v = (v / tks->res) * tks->res; + if (tks->to >= tks->from) { + if (v < tks->from) + v = tks->from; + else if (v > tks->to) + v = tks->to; + else + limit = 0; + } else { + if (v < tks->to) + v = tks->to; + else if (v > tks->from) + v = tks->from; + else + limit = 0; + } + /* + * it's possible for the value to end up as a non-whole + * multiple of resolution here, if the end points aren't + * themselves such a multiple. if so, tough - that's + * what you asked for! (it does mean that the endpoints + * are always accessible however, which could be a good thing). + */ + tks->value = v; + return limit; +} + +char* +tkscale(TkTop *t, char *arg, char **ret) +{ + Tk *tk; + char *e; + TkName *names; + TkScale *tks; + TkOptab tko[3]; + + tk = tknewobj(t, TKscale, sizeof(Tk)+sizeof(TkScale)); + if(tk == nil) + return TkNomem; + + tk->flag |= Tktakefocus; + tks = TKobj(TkScale, tk); + tks->res = TKI2F(1); + tks->to = TKI2F(100); + tks->len = ScaleLen; + tks->orient = Tkvertical; + tks->relief = TKraised; + tks->sl = ScaleSlider; + tks->sv = BoolT; + tks->bigi = 0; + + tko[0].ptr = tk; + tko[0].optab = tkgeneric; + tko[1].ptr = tks; + tko[1].optab = opts; + tko[2].ptr = nil; + + names = nil; + e = tkparse(t, arg, tko, &names); + if(e != nil) { + tkfreeobj(tk); + return e; + } + tksettransparent(tk, tkhasalpha(tk->env, TkCbackgnd)); + tkscalecheckvalue(tk); + tksizescale(tk); + if (tks->bigi == 0) + tks->bigi = TKI2F(TKF2I(tks->to - tks->from) / 10); + e = tkbindings(t, tk, b, nelem(b)); + + if(e != nil) { + tkfreeobj(tk); + return e; + } + + e = tkaddchild(t, tk, &names); + tkfreename(names); + if(e != nil) { + tkfreeobj(tk); + return e; + } + tk->name->link = nil; + + return tkvalue(ret, "%s", tk->name->name); +} + +static char* +tkscalecget(Tk *tk, char *arg, char **val) +{ + TkOptab tko[3]; + TkScale *tks = TKobj(TkScale, tk); + + tko[0].ptr = tk; + tko[0].optab = tkgeneric; + tko[1].ptr = tks; + tko[1].optab = opts; + tko[2].ptr = nil; + + return tkgencget(tko, arg, val, tk->env->top); +} + +void +tkfreescale(Tk *tk) +{ + TkScale *tks = TKobj(TkScale, tk); + + if(tks->command != nil) + free(tks->command); + if(tks->label != nil) + free(tks->label); +} + +static void +tkscalehoriz(Tk *tk, Image *i) +{ + TkEnv *e; + char sv[32]; + TkScale *tks; + Image *d, *l; + Rectangle r, r2, sr; + Point p, q; + int fh, sh, sl, v, w, h, len; + int fgnd; + + e = tk->env; + tks = TKobj(TkScale, tk); + + + fh = e->font->height; + fgnd = TkCforegnd; + if (tk->flag & Tkdisabled) + fgnd = TkCdisablefgnd; + + r = Rect(0, 0, tk->act.width, tk->act.height); + r = rectaddpt(r, Pt(tk->borderwidth, tk->borderwidth)); + r = insetrect(r, tk->highlightwidth); + r = insetrect(r, ScalePad); + + if(tks->label != nil) { + string(i, r.min, tkgc(e, fgnd), ZP, e->font, tks->label); + r.min.y += fh + ScalePad; + } + if(tks->sv == BoolT) + r.min.y += fh + ScalePad; + + sr = insetrect(r, ScaleBW); + w = Dx(sr); + h = Dy(sr); + sl = tks->sl + 2*ScaleBW; + + l = tkgc(e, TkCbackgndlght); + d = tkgc(e, TkCbackgnddark); + tkbevel(i, r.min, w, h, ScaleBW, d, l); + + tks->pixmin = sr.min.x; + tks->pixmax = sr.max.x; + + sh = h - 2*ScaleBW; + tks->sw = sh/2; + + w -= sl; + if (w <= 0) + w = 1; + p.x = sr.min.x; + p.y = sr.max.y; + if(tks->tick > 0){ + int j, t, l; + t = tks->tick; + l = tks->to-tks->from; + if (l < 0) + l = -l; + if (l == 0) + l = 1; + r2.min.y = p.y; + r2.max.y = p.y + ScaleBW + ScalePad; + for(j = 0; j <= l; j += t){ + r2.min.x = p.x+((vlong)j*w)/l+sl/2; + r2.max.x = r2.min.x+1; + draw(i, r2, tkgc(e, fgnd), nil, ZP); + } + } + v = tks->value-tks->from; + len = tks->to-tks->from; + if (len != 0) + p.x += ((vlong)v*w)/len; + p.y = sr.min.y; + q = p; + q.x += tks->sl/2 + 1; + q.y++; + if(tk->flag & Tkactivated) { + r2.min = p; + r2.max.x = p.x+sl; + r2.max.y = sr.max.y; + draw(i, r2, tkgc(e, TkCactivebgnd), nil, ZP); + } + switch(tks->relief) { + case TKsunken: + tkbevel(i, p, tks->sl, sh, ScaleBW, d, l); + tkbevel(i, q, 0, sh, 1, l, d); + break; + case TKraised: + tkbevel(i, p, tks->sl, sh, ScaleBW, l, d); + tkbevel(i, q, 0, sh, 1, d, l); + break; + } + tks->pixpos = p.x; + tks->center = p.y + sh/2 + ScaleBW; + + if(tks->sv != BoolT) + return; + + tkfprint(sv, tks->value); + if(tks->digits > 0 && tks->digits < strlen(sv)) + sv[tks->digits] = '\0'; + + w = stringwidth(e->font, sv); + p.x = q.x; + p.x -= w/2; + p.y = r.min.y - fh - ScalePad; + if(p.x < tks->pixmin) + p.x = tks->pixmin; + if(p.x+w > tks->pixmax) + p.x = tks->pixmax - w; + + string(i, p, tkgc(e, fgnd), ZP, e->font, sv); +} + +static void +tkscalevert(Tk *tk, Image *i) +{ + TkEnv *e; + TkScale *tks; + char sv[32]; + Image *d, *l; + Rectangle r, r2, sr; + Point p, q; + int fh, v, sw, w, h, len, sl; + int fgnd; + + e = tk->env; + tks = TKobj(TkScale, tk); + + fh = e->font->height; + fgnd = TkCforegnd; + if (tk->flag & Tkdisabled) + fgnd = TkCdisablefgnd; + + r = Rect(0, 0, tk->act.width, tk->act.height); + r = rectaddpt(r, Pt(tk->borderwidth, tk->borderwidth)); + r = insetrect(r, tk->highlightwidth); + r = insetrect(r, ScalePad); + + if (tks->sv) + r.min.x += tks->digwidth + ScalePad; + + if(tks->label != nil) { + p = stringsize(e->font, tks->label); + r.max.x -= p.x; + string(i, Pt(r.max.x, r.min.y), tkgc(e, fgnd), ZP, e->font, tks->label); + r.max.x -= ScalePad; + } + + sr = insetrect(r, ScaleBW); + h = Dy(sr); + w = Dx(sr); + sl = tks->sl + 2*ScaleBW; + + l = tkgc(e, TkCbackgndlght); + d = tkgc(e, TkCbackgnddark); + tkbevel(i, r.min, w, h, ScaleBW, d, l); + + tks->pixmin = sr.min.y; + tks->pixmax = sr.max.y; + + sw = w - 2*ScaleBW; + tks->sw = sw/2; + + h -= sl; + if (h <= 0) + h = 1; + p.x = sr.max.x; + p.y = sr.min.y; + if(tks->tick > 0){ + int j, t, l; + t = tks->tick; + l = tks->to-tks->from; + if (l < 0) + l = -l; + if (l == 0) + l = 1; + r2.min = p; + r2.max.x = p.x + ScaleBW + ScalePad; + for(j = 0; j <= l; j += t){ + r2.min.y = p.y+((vlong)j*h)/l+sl/2; + r2.max.y = r2.min.y+1; + draw(i, r2, tkgc(e, fgnd), nil, ZP); + } + } + + v = tks->value-tks->from; + len = tks->to-tks->from; + if (len != 0) + p.y += ((vlong)v*h)/len; + p.x = sr.min.x; + q = p; + q.x++; + q.y += tks->sl/2 + 1; + if(tk->flag & Tkactivated) { + r2.min = p; + r2.max.x = sr.max.x; + r2.max.y = p.y+sl; + draw(i, r2, tkgc(e, TkCactivebgnd), nil, ZP); + } + switch(tks->relief) { + case TKsunken: + tkbevel(i, p, sw, tks->sl, ScaleBW, d, l); + tkbevel(i, q, sw, 0, 1, l, d); + break; + case TKraised: + tkbevel(i, p, sw, tks->sl, ScaleBW, l, d); + tkbevel(i, q, sw, 0, 1, d, l); + break; + } + tks->pixpos = p.y; + tks->center = p.x + sw/2 + ScaleBW; + + if(tks->sv != BoolT) + return; + + tkfprint(sv, tks->value); + if(tks->digits > 0 && tks->digits < strlen(sv)) + sv[tks->digits] = '\0'; + + p.x = r.min.x - ScalePad - stringwidth(e->font, sv); + p.y = q.y; + p.y -= fh/2; + if (p.y < tks->pixmin) + p.y = tks->pixmin; + if (p.y + fh > tks->pixmax) + p.y = tks->pixmax - fh; + string(i, p, tkgc(e, fgnd), ZP, e->font, sv); +} + +char* +tkdrawscale(Tk *tk, Point orig) +{ + Point p; + TkEnv *env; + TkScale *tks; + Rectangle r, fr; + Image *i; + + tks = TKobj(TkScale, tk); + env = tk->env; + + r.min = ZP; + r.max.x = tk->act.width + 2*tk->borderwidth; + r.max.y = tk->act.height + 2*tk->borderwidth; + i = tkitmp(env, r.max, TkCbackgnd); + if(i == nil) + return nil; + + if(tks->orient == Tkvertical) + tkscalevert(tk, i); + else + tkscalehoriz(tk, i); + + tkdrawrelief(i, tk, ZP, TkCbackgnd, tk->relief); + if (tkhaskeyfocus(tk)) { + fr = insetrect(r, tk->borderwidth); + tkbox(i, fr, tk->highlightwidth, tkgc(env, TkChighlightfgnd)); + } + + p.x = tk->act.x + orig.x; + p.y = tk->act.y + orig.y; + r = rectaddpt(r, p); + draw(tkimageof(tk), r, i, nil, ZP); + + return nil; +} + +/* Widget Commands (+ means implemented) + +cget + +configure + +coords + +get + +identify + +set +*/ + +static char* +tkscaleconf(Tk *tk, char *arg, char **val) +{ + char *e; + TkGeom g; + int bd; + TkOptab tko[3]; + TkScale *tks = TKobj(TkScale, tk); + + tko[0].ptr = tk; + tko[0].optab = tkgeneric; + tko[1].ptr = tks; + tko[1].optab = opts; + tko[2].ptr = nil; + + if(*arg == '\0') + return tkconflist(tko, val); + + g = tk->req; + bd = tk->borderwidth; + e = tkparse(tk->env->top, arg, tko, nil); + tksettransparent(tk, tkhasalpha(tk->env, TkCbackgnd)); + tkscalecheckvalue(tk); + tksizescale(tk); + tkgeomchg(tk, &g, bd); + + tk->dirty = tkrect(tk, 1); + return e; +} + +char* +tkscaleposn(TkEnv *env, Tk *tk, char *arg, int *z) +{ + int x, y; + TkScale *tks = TKobj(TkScale, tk); + char *e; + + e = tkfracword(env->top, &arg, &x, env); + if(e != nil) + return e; + e = tkfracword(env->top, &arg, &y, env); + if(e != nil) + return e; + + x = TKF2I(x) + tk->borderwidth; + y = TKF2I(y) + tk->borderwidth; + + if(tks->orient == Tkvertical) { + if(z != nil) { + z[0] = x; + z[1] = y; + } + x = y; + } + else { + if(z != nil) { + z[0] = y; + z[1] = x; + } + } + if(x > tks->pixmin && x < tks->pixpos) + return trough1; + else + if(x >= tks->pixpos && x < tks->pixpos+tks->sl+2*ScaleBW) + return slider; + else + if(x >= tks->pixpos+tks->sl+2*ScaleBW && x < tks->pixmax) + return trough2; + + return ""; +} + +static char* +tkscaleident(Tk *tk, char *arg, char **val) +{ + char *v; + + v = tkscaleposn(tk->env, tk, arg, nil); + if(v == nil) + return TkBadvl; + return tkvalue(val, "%s", v); +} + +static char* +tkscalecoords(Tk *tk, char *arg, char **val) +{ + int p, x, y, l, value; + TkScale *tks = TKobj(TkScale, tk); + char *e; + + value = tks->value; + if(arg != nil && arg[0] != '\0') { + e = tkfracword(tk->env->top, &arg, &value, tk->env); + if (e != nil) + return e; + } + + value -= tks->from; + p = tks->pixmax - tks->pixmin; + l = TKF2I(tks->to-tks->from); + if (l==0) + p /= 2; + else + p = TKF2I(value*p/l); + p += tks->pixmin; + if(tks->orient == Tkvertical) { + x = tks->center; + y = p; + } + else { + x = p; + y = tks->center; + } + return tkvalue(val, "%d %d", x, y); +} + +static char* +tkscaleget(Tk *tk, char *arg, char **val) +{ + int x, y, value, v, l; + char buf[Tkminitem], *e; + TkScale *tks = TKobj(TkScale, tk); + + value = tks->value; + if(arg[0] != '\0') { + e = tkfracword(tk->env->top, &arg, &x, tk->env); + if (e != nil) + return e; + e = tkfracword(tk->env->top, &arg, &y, tk->env); + if (e != nil) + return e; + if(tks->orient == Tkvertical) + v = TKF2I(y) + tk->borderwidth; + else + v = TKF2I(x) + tk->borderwidth; + + if(v < tks->pixmin) + value = tks->from; + else + if(v > tks->pixmax) + value = tks->to; + else { + l = tks->pixmax-tks->pixmin; + value = 0; + if (l!=0) + value = v * ((tks->to-tks->from)/l); + value += tks->from; + } + if(tks->res > 0) + value = (value/tks->res)*tks->res; + } + tkfprint(buf, value); + return tkvalue(val, "%s", buf); +} + +static char* +tkscaleset(Tk *tk, char *arg, char **val) +{ + TkScale *tks = TKobj(TkScale, tk); + char *e; + + USED(val); + + e = tkfracword(tk->env->top, &arg, &tks->value, tk->env); + if (e != nil) + return e; + tkscalecheckvalue(tk); + tk->dirty = tkrect(tk, 1); + return nil; +} + +/* tkScaleMotion %x %y */ +static char* +tkscalemotion(Tk *tk, char *arg, char **val) +{ + int o, z[2]; + char *v; + TkScale *tks = TKobj(TkScale, tk); + extern int tkstylus; + + USED(val); + v = tkscaleposn(tk->env, tk, arg, z); + if(v == nil) + return TkBadvl; + + o = tk->flag; + if(v != slider || z[0] < tks->center-tks->sw || z[0] > tks->center+tks->sw) + tk->flag &= ~Tkactivated; + else if(tkstylus == 0 || tk->env->top->ctxt->mstate.b != 0) + tk->flag |= Tkactivated; + + if((o & Tkactivated) != (tk->flag & Tkactivated)) + tk->dirty = tkrect(tk, 1); + + return nil; +} + +static char* +tkscaledrag(Tk *tk, char *arg, char **val) +{ + int x, y, v; + char *e, buf[Tkmaxitem], f[32]; + TkScale *tks = TKobj(TkScale, tk); + + USED(val); + if((tks->flag & Dragging) == 0) + return nil; + if(tks->flag & Autorepeat) + return nil; + + e = tkfracword(tk->env->top, &arg, &x, tk->env); + if(e != nil) + return e; + e = tkfracword(tk->env->top, &arg, &y, tk->env); + if(e != nil) + return e; + + if(tks->orient == Tkvertical) + v = TKF2I(y) + tk->borderwidth; + else + v = TKF2I(x) + tk->borderwidth; + + v -= tks->pix; + x = tks->pixmax-tks->pixmin; + if (x!=tks->sl) + v = tks->base + (vlong)v * (tks->to-tks->from)/(x-tks->sl); + else + v = tks->base; + if(tks->res > 0) { + int a = tks->res / 2; + if (v < 0) + a = -a; + v = ((v+a)/tks->res)*tks->res; + } + + tks->value = v; + tkscalecheckvalue(tk); + + if(tks->command != nil && tks->jump != BoolT) { + tkfprint(f, tks->value); + snprint(buf, sizeof(buf), "%s %s", tks->command, f); + e = tkexec(tk->env->top, buf, nil); + } + tk->dirty = tkrect(tk, 1); + return e; +} + +static int +sgn(int v) +{ + return v >= 0 ? 1 : -1; +} + +static char* +stepscale(Tk *tk, char *pos, int *end) +{ + TkScale *tks = TKobj(TkScale, tk); + char *e, buf[Tkmaxitem], f[32]; + int s; + + s = sgn(tks->to - tks->from); + if(pos == trough1) { + tks->value -= s * tks->bigi; + } else { + /* trough2 */ + tks->value += s * tks->bigi; + } + s = !tkscalecheckvalue(tk); + if (end != nil) + *end = s; + e = nil; + if(tks->command != nil) { + /* XXX perhaps should only send command if value has actually changed */ + tkfprint(f, tks->value); + snprint(buf, sizeof(buf), "%s %s", tks->command, f); + e = tkexec(tk->env->top, buf, nil); + } + return e; +} + +static void +screpeat(Tk *tk, void *v, int cancelled) +{ + char *e, *pos; + int repeat; + TkScale *tks = TKobj(TkScale, tk); + + pos = v; + if (cancelled) { + tks->flag &= ~Autorepeat; + return; + } + e = stepscale(tk, pos, &repeat); + if(e != nil || !repeat) { + tks->flag &= ~Autorepeat; + tkcancelrepeat(tk); + } + tk->dirty = tkrect(tk, 1); + tkupdate(tk->env->top); +} + +static char* +tkscalebut1p(Tk *tk, char *arg, char **val) +{ + int z[2]; + char *v, *e; + TkScale *tks = TKobj(TkScale, tk); + int repeat; + + USED(val); + v = tkscaleposn(tk->env, tk, arg, z); + if(v == nil) + return TkBadvl; + + e = nil; + if(v[0] == '\0' || z[0] < tks->center-tks->sw || z[0] > tks->center+tks->sw) + return nil; + if(v == slider) { + tks->flag |= Dragging; + tks->relief = TKsunken; + tks->pix = z[1]; + tks->base = tks->value; + tkscalecheckvalue(tk); + } else { + e = stepscale(tk, v, &repeat); + if (e == nil && repeat) { + tks->flag |= Autorepeat; + tkrepeat(tk, screpeat, v, TkRptpause, TkRptinterval); + } + } + + tk->dirty = tkrect(tk, 1); + return e; +} + +static char* +tkscalebut1r(Tk *tk, char *arg, char **val) +{ + TkScale *tks = TKobj(TkScale, tk); + char *e, buf[Tkmaxitem], f[32]; + USED(val); + USED(arg); + if(tks->flag & Autorepeat) { + tkcancelrepeat(tk); + tks->flag &= ~Autorepeat; + } + e = nil; + if (tks->flag & Dragging) { + if (tks->command != nil && tks->jump == BoolT && (tks->flag & Dragging)) { + tkfprint(f, tks->value); + snprint(buf, sizeof(buf), "%s %s", tks->command, f); + e = tkexec(tk->env->top, buf, nil); + } + tks->relief = TKraised; + tks->flag &= ~Dragging; + tk->dirty = tkrect(tk, 1); + } + return e; +} + +static char* +tkscalekey(Tk *tk, char *arg, char **val) +{ + char *e; + int key; + char *pos = nil; + USED(arg); + USED(val); + + if(tk->flag & Tkdisabled) + return nil; + + key = atoi(arg); + if (key == Up || key == Left) + pos = trough1; + else if (key == Down || key == Right) + pos = trough2; + if (pos != nil) { + e = stepscale(tk, pos, nil); + tk->dirty = tkrect(tk, 1); + return e; + } + return nil; +} + +TkCmdtab tkscalecmd[] = +{ + "cget", tkscalecget, + "configure", tkscaleconf, + "set", tkscaleset, + "identify", tkscaleident, + "get", tkscaleget, + "coords", tkscalecoords, + "tkScaleMotion", tkscalemotion, + "tkScaleDrag", tkscaledrag, + "tkScaleBut1P", tkscalebut1p, + "tkScaleBut1R", tkscalebut1r, + "tkScaleKey", tkscalekey, + nil +}; + +TkMethod scalemethod = { + "scale", + tkscalecmd, + tkfreescale, + tkdrawscale +}; -- cgit v1.2.3