You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

350 lines
7.2KB

  1. //
  2. // "$Id: colbrowser.cxx 8166 2011-01-01 21:06:56Z matt $"
  3. //
  4. // X Color Browser demo program 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.
  12. //
  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.
  17. //
  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.
  22. //
  23. // Please report all bugs and problems on the following page:
  24. //
  25. // http://www.fltk.org/str.php
  26. //
  27. #include <FL/Fl.H>
  28. #include <FL/Fl_Double_Window.H>
  29. #include <FL/Fl_Button.H>
  30. #include <FL/Fl_Value_Slider.H>
  31. #include <FL/Fl_Hold_Browser.H>
  32. #include <FL/Fl_Box.H>
  33. #include <FL/fl_ask.H>
  34. #include <FL/filename.H>
  35. #include <stdlib.h>
  36. #include <stdio.h>
  37. #include <string.h>
  38. // some constants
  39. #define MAX_RGB 3000
  40. #define FL_FREE_COL4 ((Fl_Color)(FL_FREE_COLOR+3))
  41. #define FL_INDIANRED ((Fl_Color)(164))
  42. static Fl_Double_Window *cl;
  43. static Fl_Box *rescol;
  44. static Fl_Button *dbobj;
  45. static Fl_Hold_Browser *colbr;
  46. static Fl_Value_Slider *rs, *gs, *bs;
  47. static char dbname[FL_PATH_MAX];
  48. static void create_form_cl(void);
  49. static int load_browser(char *);
  50. typedef struct { int r, g, b; } RGBdb;
  51. static RGBdb rgbdb[MAX_RGB];
  52. int main(int argc, char *argv[])
  53. {
  54. Fl::args(argc, argv);
  55. create_form_cl();
  56. #ifdef USING_XCODE
  57. // Xcode apps do not set the current directory
  58. strcpy(dbname, argv[0]);
  59. char *slash = strrchr(dbname, '/');
  60. if (slash)
  61. strcpy(slash, "/../Resources/rgb.txt");
  62. #else
  63. strcpy(dbname, "rgb.txt");
  64. #endif
  65. if (load_browser(dbname))
  66. dbobj->label(dbname);
  67. else
  68. dbobj->label("None");
  69. dbobj->redraw();
  70. cl->size_range(cl->w(),cl->h(),2*cl->w(),2*cl->h());
  71. cl->label("RGB Browser");
  72. cl->free_position();
  73. cl->show(argc,argv);
  74. return Fl::run();
  75. }
  76. static void set_entry(int i)
  77. {
  78. RGBdb *db = rgbdb + i;
  79. Fl::set_color(FL_FREE_COL4, db->r, db->g, db->b);
  80. rs->value(db->r);
  81. gs->value(db->g);
  82. bs->value(db->b);
  83. rescol->redraw();
  84. }
  85. static void br_cb(Fl_Widget *ob, long)
  86. {
  87. int r = ((Fl_Browser *)ob)->value();
  88. if (r <= 0)
  89. return;
  90. set_entry(r - 1);
  91. }
  92. static int read_entry(FILE * fp, int *r, int *g, int *b, char *name)
  93. {
  94. int n;
  95. char buf[512], *p;
  96. if (!fgets(buf, sizeof(buf) - 1, fp))
  97. return 0;
  98. if(buf[0] == '!') {
  99. if (fgets(buf,sizeof(buf)-1,fp)==0) {
  100. /* ignore */
  101. }
  102. }
  103. if(sscanf(buf, " %d %d %d %n", r, g, b, &n) < 3)
  104. return 0;
  105. p = buf + n;
  106. /* squeeze out all spaces */
  107. while (*p)
  108. {
  109. if (*p != ' ' && *p != '\n')
  110. *name++ = *p;
  111. p++;
  112. }
  113. *name = 0;
  114. return (feof(fp) || ferror(fp)) ? 0 : 1;
  115. }
  116. static int load_browser(char *fname)
  117. {
  118. FILE *fp;
  119. RGBdb *db = rgbdb, *dbs = db + MAX_RGB;
  120. int r, g, b, lr = -1 , lg = -1, lb = -1;
  121. char name[256], buf[256];
  122. #ifdef __EMX__
  123. if (!(fp = fl_fopen(__XOS2RedirRoot(fname), "r")))
  124. #else
  125. if (!(fp = fl_fopen(fname, "r")))
  126. #endif
  127. {
  128. fl_alert("%s\n%s\n%s","Load", fname, "Can't open");
  129. return 0;
  130. }
  131. /* read the items */
  132. for (; db < dbs && read_entry(fp, &r, &g, &b, name);)
  133. {
  134. db->r = r;
  135. db->g = g;
  136. db->b = b;
  137. /* unique the entries on the fly */
  138. if (lr != r || lg != g || lb != b)
  139. {
  140. db++;
  141. lr = r;
  142. lg = g;
  143. lb = b;
  144. sprintf(buf, "(%3d %3d %3d) %s", r, g, b, name);
  145. colbr->add(buf);
  146. }
  147. }
  148. fclose(fp);
  149. if (db < dbs)
  150. db->r = 1000; /* sentinel */
  151. else
  152. {
  153. db--;
  154. db->r = 1000;
  155. }
  156. colbr->topline(1);
  157. colbr->select(1,1);
  158. set_entry(0);
  159. return 1;
  160. }
  161. static int search_entry(int r, int g, int b)
  162. {
  163. register RGBdb *db = rgbdb;
  164. int i, j, diffr, diffg, diffb;
  165. unsigned int diff, mindiff;
  166. mindiff = (unsigned int)~0;
  167. for (i = j = 0; db->r < 256; db++, i++)
  168. {
  169. diffr = r - db->r;
  170. diffg = g - db->g;
  171. diffb = b - db->b;
  172. #ifdef FL_LINEAR
  173. diff = unsigned(3.0 * (FL_abs(r - db->r)) +
  174. (5.9 * FL_abs(g - db->g)) +
  175. (1.1 * (FL_abs(b - db->b))));
  176. #else
  177. diff = unsigned(3.0 * (diffr *diffr) +
  178. 5.9 * (diffg *diffg) +
  179. 1.1 * (diffb *diffb));
  180. #endif
  181. if (mindiff > diff)
  182. {
  183. mindiff = diff;
  184. j = i;
  185. }
  186. }
  187. return j;
  188. }
  189. static void search_rgb(Fl_Widget *, long)
  190. {
  191. int r, g, b, i;
  192. int top = colbr->topline();
  193. r = int(rs->value());
  194. g = int(gs->value());
  195. b = int(bs->value());
  196. // fl_freeze_form(cl);
  197. Fl::set_color(FL_FREE_COL4, r, g, b);
  198. rescol->redraw();
  199. i = search_entry(r, g, b);
  200. /* change topline only if necessary */
  201. if(i < top || i > (top+15))
  202. colbr->topline(i-8);
  203. colbr->select(i+1, 1);
  204. // fl_unfreeze_form(cl);
  205. }
  206. /* change database */
  207. static void db_cb(Fl_Widget * ob, long)
  208. {
  209. const char *p = fl_input("Enter New Database Name", dbname);
  210. char buf[512];
  211. if (!p || strcmp(p, dbname) == 0)
  212. return;
  213. strcpy(buf, p);
  214. if (load_browser(buf))
  215. strcpy(dbname, buf);
  216. else
  217. ob->label(dbname);
  218. }
  219. static void done_cb(Fl_Widget *, long)
  220. {
  221. exit(0);
  222. }
  223. static void create_form_cl(void)
  224. {
  225. if (cl)
  226. return;
  227. cl = new Fl_Double_Window(400,385);
  228. cl->box(FL_UP_BOX);
  229. cl->color(FL_INDIANRED, FL_GRAY);
  230. Fl_Box *title = new Fl_Box(40, 10, 300, 30, "Color Browser");
  231. title->box(FL_NO_BOX);
  232. title->labelcolor(FL_RED);
  233. title->labelsize(32);
  234. title->labelfont(FL_HELVETICA_BOLD);
  235. title->labeltype(FL_SHADOW_LABEL);
  236. dbobj = new Fl_Button(40, 50, 300, 25, "");
  237. dbobj->type(FL_NORMAL_BUTTON);
  238. dbobj->box(FL_BORDER_BOX);
  239. dbobj->color(FL_INDIANRED,FL_INDIANRED);
  240. dbobj->callback(db_cb, 0);
  241. colbr = new Fl_Hold_Browser(10, 90, 280, 240, "");
  242. colbr->textfont(FL_COURIER);
  243. colbr->callback(br_cb, 0);
  244. colbr->box(FL_DOWN_BOX);
  245. rescol = new Fl_Box(300, 90, 90, 35, "");
  246. rescol->color(FL_FREE_COL4, FL_FREE_COL4);
  247. rescol->box(FL_BORDER_BOX);
  248. rs = new Fl_Value_Slider(300, 130, 30, 200, "");
  249. rs->type(FL_VERT_FILL_SLIDER);
  250. rs->color(FL_INDIANRED, FL_RED);
  251. rs->bounds(0, 255);
  252. rs->precision(0);
  253. rs->callback(search_rgb, 0);
  254. rs->when(FL_WHEN_RELEASE);
  255. gs = new Fl_Value_Slider(330, 130, 30, 200, "");
  256. gs->type(FL_VERT_FILL_SLIDER);
  257. gs->color(FL_INDIANRED, FL_GREEN);
  258. gs->bounds(0, 255);
  259. gs->precision(0);
  260. gs->callback(search_rgb, 1);
  261. gs->when(FL_WHEN_RELEASE);
  262. bs = new Fl_Value_Slider(360, 130, 30, 200, "");
  263. bs->type(FL_VERT_FILL_SLIDER);
  264. bs->color(FL_INDIANRED, FL_BLUE);
  265. bs->bounds(0, 255);
  266. bs->precision(0);
  267. bs->callback(search_rgb, 2);
  268. bs->when(FL_WHEN_RELEASE);
  269. Fl_Button *done = new Fl_Button(160, 345, 80, 30, "Done");
  270. done->type(FL_NORMAL_BUTTON);
  271. done->callback(done_cb, 0);
  272. cl->end();
  273. cl->resizable(cl);
  274. }
  275. //
  276. // End of "$Id: colbrowser.cxx 8166 2011-01-01 21:06:56Z matt $".
  277. //