/**************************************************************************\ 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 #include #include #include #include #include #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) { 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); } }