diff options
Diffstat (limited to 'src/iintbox.cpp')
-rw-r--r-- | src/iintbox.cpp | 308 |
1 files changed, 308 insertions, 0 deletions
diff --git a/src/iintbox.cpp b/src/iintbox.cpp new file mode 100644 index 0000000..4a4638c --- /dev/null +++ b/src/iintbox.cpp @@ -0,0 +1,308 @@ +/**************************************************************************\ + ibtk (Insomnia's Basic ToolKit) + + By Insomnia (Steaphan Greene) + (insomnia@core.binghamton.edu) + + Copyright (C) 1999 Steaphan Greene + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + +\**************************************************************************/ + +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/keysym.h> +#include "iintbox.h" + +IIntBox::~IIntBox() { + Win->RemoveClaim(this); + delete upb; + delete dnb; + } + +void IIntBox::Increment() { + Increment(NULL, 0); + } + +void IIntBox::Decrement() { + Decrement(NULL, 0); + } + +void IIntBox::Increment(IDoDad *wb, int mb) { + if(disabled) return; + int nval=val; + do { + ++nval; + if(nval==val || ((nval > vmax) && (!(flags & IBTK_WRAP)))) return; + else if(nval > vmax) nval=vmin; + } while(ElementFlag(nval, ELEMENT_SKIP)); + SetVal(nval); + Rebuild(); + } + +void IIntBox::Decrement(IDoDad *wb, int mb) { + if(disabled) return; + int nval=val; + do { + --nval; + if(nval==val || ((nval < vmin) && (!(flags & IBTK_WRAP)))) return; + else if(nval < vmin) nval=vmax; + } while(ElementFlag(nval, ELEMENT_SKIP)); + SetVal(nval); + Rebuild(); + } + +void __Callback__IIntBox__Increment(IDoDad *p, IDoDad *d, int v) { + ((IIntBox*)p)->Increment(d,v); + } + +void __Callback__IIntBox__Decrement(IDoDad *p, IDoDad *d, int v) { + ((IIntBox*)p)->Decrement(d,v); + } + +IIntBox::IIntBox(int v, IWindow *w, int xp, int yp, int xs, int ys){ + val = v; + vmin = -1000000; + vmax = 1000000; + elfl = NULL; + changecallback = NULL; + upb = NULL; dnb = NULL; + char txt[256]; + sprintf(txt, "%d%c", v, 0); + Init(txt, w, xp, yp, xs+2-((ys+1)/2), ys); + upb = new IButton("", w, xp+xs-((ys+1)/2), yp, (ys+1)/2, (ys+1)/2); + dnb = new IButton("", w, xp+xs-((ys+1)/2), yp+((ys+1)/2), (ys+1)/2, ys/2); + upb->SetParent(this); +// upb->SetClickCallback((void (*)(IDoDad *, IDoDad *, int))&Increment); + upb->SetClickCallback(__Callback__IIntBox__Increment); + dnb->SetParent(this); +// dnb->SetClickCallback((void (*)(IDoDad *, IDoDad *, int))&Decrement); + dnb->SetClickCallback(__Callback__IIntBox__Decrement); + } + +void IIntBox::SetVal(int v) { + int oval = val; + val = v; + if(flags & IBTK_WRAP) { + if(val > vmax) val = vmin; + if(val < vmin) val = vmax; + } + else { + if(val > vmax) val = vmax; + if(val < vmin) val = vmin; + } + char txt[256]; + sprintf(txt, "%d%c", val, 0); + SetText(txt); + if(oval != val && changecallback != NULL) + (*changecallback)(parent, this); + } + +void IIntBox::SetText(char *txt) { + int v = strtol(txt, NULL, 10); + if(v>vmax) { + if(v > 9999) { v=v%10000; if(v>vmax) v=v%1000; } + else if(v > 999) { v=v%1000; if(v>vmax) v=v%100; } + else if(v > 99) { v=v%100; if(v>vmax) v=v%10; } + else if(v > 9) v=v%10; + else v=vmax; + if(v<vmin) v=vmax; + val=vmin-1; + } + if(v != val && v >= vmin) { SetVal(v); return; } +// printf("Val = %d\n", val); + Window wind = Win->GetWindowBuffer(); + Display *disp = Win->GetDisplay(); + GC gc = Win->GetGC(); + + unsigned int p, b, g, gl, gd; + p = Win->GetPaperColor(); + b = Win->GetFGColor(); + g = Win->GetBGColor(); + gl = Win->GetLBGColor(); + gd = Win->GetDBGColor(); + + sprintf(text, "%s%c", txt, 0); + if(tcp > (long)strlen(text)) { tcp = strlen(text); tcp2=tcp; } + else if(tcp2 > (long)strlen(text)) { tcp2 = strlen(text); } + gcp = 0; gcp2=0; + + XFontStruct *fs; + XCharStruct cs; + int dir, as, des; + fs = Win->GetFontStruct(); +// Wlen = XTextWidth(fs, text, strlen(text)); + XTextExtents(fs, text, strlen(text), &dir, &as, &des, &cs); +// printf("dir = %d, as = %d, des = %d\n", dir, as, des); + Wlen = cs.width+4; +// int hgt = cs. + if(Wrk[0] != None) XFreePixmap(disp, Wrk[0]); + if(Wrk[1] != None) XFreePixmap(disp, Wrk[1]); + Wrk[0] = XCreatePixmap(disp, wind, Wlen, ysize-4, DefaultDepth(disp, 0)); + Wrk[1] = XCreatePixmap(disp, wind, Wlen, ysize-4, DefaultDepth(disp, 0)); + XSetForeground(disp, gc, p); + XFillRectangle(disp, Wrk[0], gc, 0, 0, Wlen, ysize-4); + XSetForeground(disp, gc, g); + XFillRectangle(disp, Wrk[1], gc, 0, 0, Wlen, ysize-4); + XSetBackground(disp, gc, p); + XSetForeground(disp, gc, b); + XDrawImageString(disp, Wrk[0], gc, 2, ((ysize+ysize-(as+des-2))>>1)-2, + text, strlen(text)); + XSetBackground(disp, gc, g); + XSetForeground(disp, gc, gl); + XDrawImageString(disp, Wrk[1], gc, 3, ((ysize+ysize-(as+des-2))>>1)-1, + text, strlen(text)); + XSetForeground(disp, gc, gd); + XDrawString(disp, Wrk[1], gc, 2, ((ysize+ysize-(as+des-2))>>1)-2, + text, strlen(text)); + if(tcp > 0) gcp = XTextWidth(fs, text, tcp); + if(tcp2 > 0) gcp2 = XTextWidth(fs, text, tcp2); + if(Win->GetFocus() == this && (!disabled)) { + XDrawLine(disp, Wrk[0], gc, gcp+2, 1, gcp+2, ysize-6); + XDrawLine(disp, Wrk[0], gc, gcp+1, 1, gcp+3, 1); + XDrawLine(disp, Wrk[0], gc, gcp+1, ysize-6, gcp+3, ysize-6); + } + Rebuild(); + } + +void IIntBox::Rebuild() { + IBox::Rebuild(); + if(upb != NULL) { + if(hidden && (!upb->Hidden())) upb->Hide(); + else if((!hidden) && upb->Hidden()) upb->Show(); + else upb->Rebuild(); + } + if(dnb != NULL) { + if(hidden && (!dnb->Hidden())) dnb->Hide(); + else if((!hidden) && dnb->Hidden()) dnb->Show(); + else dnb->Rebuild(); + } + } + +void IIntBox::Redraw() { +// printf("Redraw\n"); + IBox::Redraw(); + if(upb != NULL) { + if(hidden && (!upb->Hidden())) upb->Hide(); + else if((!hidden) && upb->Hidden()) upb->Show(); + else upb->Redraw(); + } + if(dnb != NULL) { + if(hidden && (!dnb->Hidden())) dnb->Hide(); + else if((!hidden) && dnb->Hidden()) dnb->Show(); + else dnb->Redraw(); + } + } + +void IIntBox::Enable() { + disabled = 0; + Rebuild(); + } + +void IIntBox::Disable() { + disabled = 1; + Rebuild(); + } + +int IIntBox::KeyDown(XKeyEvent ev) { + if(disabled) return 0; + KeySym key = XKeycodeToKeysym(Win->GetDisplay(), ev.keycode, 0); + switch(key) { + case(XK_Down): { Decrement(this, 1); }break; + case(XK_Up): { Increment(this, 1); }break; + case(XK_Delete): case(XK_BackSpace): case(XK_Left): case(XK_Right): + { if(flags & IBTK_SUPPLEMENTARY) return 0; } + case(XK_KP_0): case(XK_KP_Insert): + case(XK_KP_1): case(XK_KP_End): + case(XK_KP_2): case(XK_KP_Down): + case(XK_KP_3): case(XK_KP_Page_Down): + case(XK_KP_4): case(XK_KP_Left): + case(XK_KP_5): case(XK_KP_Begin): + case(XK_KP_6): case(XK_KP_Right): + case(XK_KP_7): case(XK_KP_Home): + case(XK_KP_8): case(XK_KP_Up): + case(XK_KP_9): case(XK_KP_Page_Up): + case(XK_0): case(XK_1): case(XK_2): case(XK_3): case(XK_4): + case(XK_5): case(XK_6): case(XK_7): case(XK_8): case(XK_9): { + return IBox::KeyDown(ev); + }break; + default: { + char buf[256]; KeySym key; int len; + len = XLookupString(&ev, buf, sizeof(buf), &key, NULL); + buf[len] = 0; + if(buf[0] != 0 && buf[1] == 0) { + switch(buf[0]) { + case('0'): case('1'): case('2'): case('3'): case('4'): + case('5'): case('6'): case('7'): case('8'): case('9'): { + return IBox::KeyDown(ev); break; + } + default: return 0; break; + } + } + else { + return 0; break; + } + } + } + return 1; + } + +int IIntBox::KeyUp(XKeyEvent ev) { +// char *key = XKeysymToString(XKeycodeToKeysym(Win->GetDisplay(), k, 0)); +// printf("Got \"%s\"\n", key); + return 1; + } + +void IIntBox::SetMax(int mx) { + if(elfl != NULL) { delete elfl; elfl = NULL; } + vmax = mx; + if(vmin>vmax) vmin = vmax; + SetVal(val); + } + +void IIntBox::SetMin(int mn) { + if(elfl != NULL) { delete elfl; elfl = NULL; } + vmin = mn; + if(vmin>vmax) vmax = vmin; + SetVal(val); + } + +int IIntBox::ElementFlag(int el, int fl) { + if(elfl == NULL) { + elfl = new unsigned long int[(vmax-vmin)+1]; + for(int ctr=0; ctr<(vmax-vmin)+1; ++ctr) elfl[ctr]=0; + return 0; + } + else { + return (elfl[el-vmin])&fl; + } + } + +void IIntBox::SetElementFlag(int el, int fl) { + if(elfl == NULL) { + elfl = new unsigned long int[(vmax-vmin)+1]; + for(int ctr=0; ctr<(vmax-vmin)+1; ++ctr) elfl[ctr]=0; + } + elfl[el-vmin] |= fl; + } + +void IIntBox::ClearElementFlag(int el, int fl) { + if(elfl == NULL) { + elfl = new unsigned long int[(vmax-vmin)+1]; + for(int ctr=0; ctr<(vmax-vmin)+1; ++ctr) elfl[ctr]=0; + } + else { + elfl[el-vmin] &= (~(unsigned long int)fl); + } + } |