File: palette.c

package info (click to toggle)
grafix 1.6-5
  • links: PTS
  • area: main
  • in suites: woody
  • size: 1,156 kB
  • ctags: 1,962
  • sloc: ansic: 20,183; makefile: 186; sh: 3
file content (144 lines) | stat: -rw-r--r-- 4,640 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144

#include "window.h"
#include "palette.h"

unsigned palette_popup::palind(float min, float max, int i) {
  if (ncolors == 0) return 0;
  float f = (i * (max-min)) / ncolors;  
  int xi =  (int) (min + f);
  if (xi < 0) return 0;
  if (xi > 0xffff) return 0xffff; else return xi;
}

// not very efficient : if all scrollbars are set, this is called 3 times !!
void palette_popup::paint() { 
  for (int i = 0; i < ncolors; i++) { 
    XColor *xcol = &color_cells[i];
    unsigned r = palind(smin[0]->value,smax[0]->value,i);
    unsigned b = palind(smin[1]->value,smax[1]->value,i);
    unsigned g = palind(smin[2]->value,smax[2]->value,i);
    if (True_Color_Visual) xcol->pixel = alloc_color(r,g,b); 
    else {
      xcol->red = r; xcol->blue = b; xcol->green = g;
      XStoreColor(display,def_cmap,xcol);
    }
  }
  if (True_Color_Visual && redraw_win)  { // this should be really a list !
    redraw_win->redraw(); // printf("%x\n",redraw_win);
  }
}

// a window to display color bars
class palette_display : public window {
  GC gc;  
  XGCValues values; 
  palette_popup *pp;
public:
  palette_display(window &parent, int w, int h, int x, int y, 
		  palette_popup *pp) : 
  window(parent,w,h,x,y), pp(pp) { 
    values.foreground = 0;
    gc = CreateGC(GCForeground, &values); 
    pp->redraw_win = this; // I will be redrawed !!
  }
  virtual void redraw() { 
    int i, x = 0, nc = pp->ncolors; if (nc == 0) return;
    int dx = width/nc + 1;
    for (i = 0; i < nc; i++) { 
      values.foreground = pp->color_cells[i].pixel; 
      XChangeGC(display,gc, GCForeground, &values); 
      x = int(i*width/float(nc));
      XFillRectangle(display,Win,gc,x,0,dx,height); 
    }
  }
};

char * colstr[] = { "red", "blue", "green"};

class pal_text_win : public window {
public: 
  pal_text_win(window &parent, int h, int x, int y) : 
    window(parent, 70,h ,x,y,0) {}
  virtual void redraw() { 
    int x = 5, y = 15, i;
    for (i = 0; i<3; i++) { 
      DrawString(x+30,y+12,colstr[i]);
      DrawString(x,y,"xmin"); y+= 25; 
      DrawString(x,y,"xmax"); y+= 40; 
    } }
};
 
// must be static !
static
struct palstr fbar[] = { { "brown ", { {21, 4, 0 }, { 65, 65, 55} } },
			 { "rainbow", { { 0, 65, 0}, { 65, 0 , 22} } },
			 { "yellow", { {0,0,0}, { 65, 0, 65} } },
			 { "steel",  { {0,0,0}, {0,65,65} } },
			 { "violet", { {37,37,0}, {65,65,65} } },
			 { "gray", { {0,0,0}, {65,65,65} } }
                       };

static void pal_paint(palette_popup * pp) { pp->paint(); };

// 1. constructor for palette_popup : creates a color palette and
// a popup for displaying and manipulate the palettes   
palette_popup::palette_popup(int ncol, palstr* pinit) 
: main_window("palette",375,330) {
  redraw_win = NULL; // will be set in init_palette
  init_palette(ncol);
  long unsigned plane_mask; 
  if (! True_Color_Visual)
    for (int i = 0; i < ncol; i++) {
      // printf(" %d",i); fflush(stdout);
      if (0 == XAllocColorCells(display,def_cmap,TRUE,&plane_mask,0,
				&(color_cells[i].pixel),1)) {
	printf("warning : only %d color cells of %d free on display\n",i,ncol);
	ncolors = i; break;
      }
      color_cells[i].flags = DoRed | DoGreen | DoBlue;
      // cout << color_cells[i].pixel <<" "; 
    } 
  if (pinit == NULL) pinit = fbar+0; // def. = first element
  set_pal(pinit);  // initialization  
}

// 2. constructor : the ColorCells are already present  (pixels)
palette_popup::palette_popup(int ncol, long unsigned *pixels) : 
  main_window("palette",375,330) {
  init_palette(ncol);
  for (int i = 0; i < ncolors; i++) {
    color_cells[i].pixel = pixels[i];
    color_cells[i].flags = DoRed | DoGreen | DoBlue;
  }
}

void set_palstr(palette_popup *p, palstr *ps) { p->set_pal(ps); }

// used by the constructors     
void palette_popup::init_palette(int ncol) {
  ncolors = ncol;

  int ci,i,y = 5, w = 300, x= 5; 
  new pal_text_win(*this,180,w+x,y);
  for (ci = 0; ci<3; ci++) {
    smin[ci] = new scrollbar(*this,(VVP)&pal_paint,this,w,20,x,y,0,0xffff); y+= 25;
    smax[ci] = new scrollbar(*this,(VVP)&pal_paint,this,w,20,x,y,0,0xffff); y+= 40;
  }

  menu_bar *mb = new menu_bar(*this,370,20,x,y,50,100,0); y+= 25;
  int nbar = sizeof(fbar)/sizeof(palstr); // Elementzahl von fbar
  
  for (i=0; i < nbar; i++)
    new function_button(*mb,fbar[i].Name,(CB) set_palstr, this, fbar+i);

  new palette_display(*this,370,50,x,y,this); y+= 60;
  new unmap_button(*this,"close",100,20,130,y);
  color_cells = new XColor[ncolors];   
}

void palette_popup::set_pal(palstr *ps) { 
  for (int i=0; i< 3; i++) { 
   smin[i]->change(ps->limits[0][i]*1000); 
   smax[i]->change(ps->limits[1][i]*1000); }
}