Fl_Panzoomer: Always draw box.
[ntk.git] / src / fl_show_colormap.cxx
blobb3d705a05dee798e00db909542f140fcf9c0928f
1 //
2 // "$Id: fl_show_colormap.cxx 7903 2010-11-28 21:06:39Z matt $"
3 //
4 // Colormap color selection dialog for the Fast Light Tool Kit (FLTK).
5 //
6 // Copyright 1998-2010 by Bill Spitzak and others.
7 //
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Library General Public
10 // License as published by the Free Software Foundation; either
11 // version 2 of the License, or (at your option) any later version.
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Library General Public License for more details.
18 // You should have received a copy of the GNU Library General Public
19 // License along with this library; if not, write to the Free Software
20 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21 // USA.
23 // Please report all bugs and problems on the following page:
25 // http://www.fltk.org/str.php
28 #include <FL/Fl.H>
29 #include <FL/Fl_Single_Window.H>
30 #include <FL/fl_draw.H>
31 #include <FL/fl_show_colormap.H>
32 #include <config.h>
34 #define BOXSIZE 14
35 #define BORDER 4
37 /**
38 This widget creates a modal window for selecting a color from the colormap.
39 Pretty much unchanged from Forms.
41 class ColorMenu : public Fl_Window {
42 Fl_Color initial;
43 Fl_Color which, previous;
44 int done;
45 void drawbox(Fl_Color);
46 void draw();
47 int handle(int);
48 public:
49 ColorMenu(Fl_Color oldcol);
50 Fl_Color run();
53 ColorMenu::ColorMenu(Fl_Color oldcol) :
54 Fl_Window(BOXSIZE*8+1+2*BORDER, BOXSIZE*32+1+2*BORDER) {
55 clear_border();
56 set_modal();
57 initial = which = oldcol;
60 void ColorMenu::drawbox(Fl_Color c) {
61 if (c < 0 || c > 255) return;
62 int X = (c%8)*BOXSIZE+BORDER;
63 int Y = (c/8)*BOXSIZE+BORDER;
64 #if BORDER_WIDTH < 3
65 if (c == which) fl_draw_box(FL_DOWN_BOX, X+1, Y+1, BOXSIZE-1, BOXSIZE-1, c);
66 else fl_draw_box(FL_BORDER_BOX, X, Y, BOXSIZE+1, BOXSIZE+1, c);
67 #else
68 fl_draw_box(c == which ? FL_DOWN_BOX : FL_BORDER_BOX,
69 X, Y, BOXSIZE+1, BOXSIZE+1, c);
70 #endif
73 void ColorMenu::draw() {
74 if (damage() != FL_DAMAGE_CHILD) {
75 fl_draw_box(FL_UP_BOX,0,0,w(),h(),color());
76 for (int c = 0; c < 256; c++) drawbox((Fl_Color)c);
77 } else {
78 drawbox(previous);
79 drawbox(which);
81 previous = which;
84 int ColorMenu::handle(int e) {
85 Fl_Color c = which;
86 switch (e) {
87 case FL_PUSH:
88 case FL_DRAG: {
89 int X = (Fl::event_x_root() - x() - BORDER);
90 if (X >= 0) X = X/BOXSIZE;
91 int Y = (Fl::event_y_root() - y() - BORDER);
92 if (Y >= 0) Y = Y/BOXSIZE;
93 if (X >= 0 && X < 8 && Y >= 0 && Y < 32)
94 c = 8*Y + X;
95 else
96 c = initial;
97 } break;
98 case FL_RELEASE:
99 done = 1;
100 return 1;
101 case FL_KEYBOARD:
102 switch (Fl::event_key()) {
103 case FL_Up: if (c > 7) c -= 8; break;
104 case FL_Down: if (c < 256-8) c += 8; break;
105 case FL_Left: if (c > 0) c--; break;
106 case FL_Right: if (c < 255) c++; break;
107 case FL_Escape: which = initial; done = 1; return 1;
108 case FL_KP_Enter:
109 case FL_Enter: done = 1; return 1;
110 default: return 0;
112 break;
113 default:
114 return 0;
116 if (c != which) {
117 which = (Fl_Color)c; damage(FL_DAMAGE_CHILD);
118 int bx = (c%8)*BOXSIZE+BORDER;
119 int by = (c/8)*BOXSIZE+BORDER;
120 int px = x();
121 int py = y();
122 int scr_x, scr_y, scr_w, scr_h;
123 Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h);
124 if (px < scr_x) px = scr_x;
125 if (px+bx+BOXSIZE+BORDER >= scr_x+scr_w) px = scr_x+scr_w-bx-BOXSIZE-BORDER;
126 if (py < scr_y) py = scr_y;
127 if (py+by+BOXSIZE+BORDER >= scr_y+scr_h) py = scr_y+scr_h-by-BOXSIZE-BORDER;
128 if (px+bx < BORDER) px = BORDER-bx;
129 if (py+by < BORDER) py = BORDER-by;
130 position(px,py);
132 return 1;
135 extern char fl_override_redirect; // hack for menus
137 #ifdef _MSC_VER
138 #pragma optimize("a",off) // needed to get the done check to work
139 #endif
140 Fl_Color ColorMenu::run() {
141 if (which < 0 || which > 255) {
142 position(Fl::event_x_root()-w()/2, Fl::event_y_root()-y()/2);
143 } else {
144 position(Fl::event_x_root()-(initial%8)*BOXSIZE-BOXSIZE/2-BORDER,
145 Fl::event_y_root()-(initial/8)*BOXSIZE-BOXSIZE/2-BORDER);
147 show();
148 Fl::grab(*this);
149 done = 0;
150 while (!done) Fl::wait();
151 Fl::grab(0);
152 return which;
155 Fl_Color fl_show_colormap(Fl_Color oldcol) {
156 ColorMenu m(oldcol);
157 return m.run();
161 // End of "$Id: fl_show_colormap.cxx 7903 2010-11-28 21:06:39Z matt $".