summaryrefslogtreecommitdiff
path: root/src/iintbox.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/iintbox.cpp')
-rw-r--r--src/iintbox.cpp308
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);
+ }
+ }