LCOV - code coverage report
Current view: top level - gdraw - gcolor.c (source / functions) Hit Total Coverage
Test: FontForge coverage report 2017-08-04 01:21:11+02:00 (commit d35f7e4107a9e1db65cce47c468fcc914cecb8fd) Lines: 0 487 0.0 %
Date: 2017-08-04 Functions: 0 15 0.0 %

          Line data    Source code
       1             : /* Copyright (C) 2008-2012 by George Williams */
       2             : /*
       3             :  * Redistribution and use in source and binary forms, with or without
       4             :  * modification, are permitted provided that the following conditions are met:
       5             : 
       6             :  * Redistributions of source code must retain the above copyright notice, this
       7             :  * list of conditions and the following disclaimer.
       8             : 
       9             :  * Redistributions in binary form must reproduce the above copyright notice,
      10             :  * this list of conditions and the following disclaimer in the documentation
      11             :  * and/or other materials provided with the distribution.
      12             : 
      13             :  * The name of the author may not be used to endorse or promote products
      14             :  * derived from this software without specific prior written permission.
      15             : 
      16             :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
      17             :  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
      18             :  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
      19             :  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      20             :  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
      21             :  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
      22             :  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
      23             :  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      24             :  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
      25             :  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      26             :  */
      27             : #include <ggadget.h>
      28             : #include <gwidget.h>
      29             : 
      30             : #include <string.h>
      31             : #include <stdlib.h>
      32             : #include <math.h>
      33             : 
      34           0 : static GImage *ColorWheel(int width,int height) {
      35             :     struct hslrgb col;
      36             :     GImage *wheel;
      37             :     struct _GImage *base;
      38             :     int i,j;
      39             :     double x,y, hh, hw;
      40             :     uint32 *row;
      41             : 
      42           0 :     memset(&col,0,sizeof(col));
      43           0 :     col.v = 1.0;
      44             : 
      45           0 :     if ( width<10 ) width = 10;
      46           0 :     if ( height<10 ) height = 10;
      47           0 :     hh = height/2.0; hw = width/2.0;
      48             : 
      49           0 :     wheel = GImageCreate(it_true,width,height);
      50           0 :     base = wheel->u.image;
      51           0 :     for ( i=0; i<height; ++i ) {
      52           0 :         row = (uint32 *) (base->data + i*base->bytes_per_line);
      53           0 :         y = (i-hh)/(hh-1);
      54           0 :         for ( j=0; j<width; ++j ) {
      55           0 :             x = (j-hw)/(hw-1);
      56           0 :             col.s = sqrt(x*x + y*y);
      57           0 :             if ( col.s>1.0 ) {
      58           0 :                 *row++ = 0xffffff;
      59             :             } else {
      60           0 :                 col.h = atan2(y,x)*180/3.1415926535897932;
      61           0 :                 if ( col.h < 0 ) col.h += 360;
      62           0 :                 gHSV2RGB(&col);
      63           0 :                 *row++ = COLOR_CREATE( (int) rint(255*col.r), (int) rint(255*col.g), (int) rint(255*col.b));
      64             :             }
      65             :         }
      66             :     }
      67           0 : return( wheel );        
      68             : }
      69             : 
      70             : #define GRAD_WIDTH      20
      71           0 : static GImage *Gradient(int height) {
      72             :     GImage *grad;
      73             :     struct _GImage *base;
      74             :     int i,j,c;
      75             :     uint32 *row;
      76             : 
      77           0 :     if ( height<10 ) height = 10;
      78             : 
      79           0 :     grad = GImageCreate(it_true,GRAD_WIDTH,height);
      80           0 :     base = grad->u.image;
      81           0 :     for ( i=0; i<height; ++i ) {
      82           0 :         row = (uint32 *) (base->data + i*base->bytes_per_line);
      83           0 :         c = 255*(height-1-i)/(height-1);
      84           0 :         for ( j=0; j<GRAD_WIDTH; ++j ) {
      85           0 :             *row++ = COLOR_CREATE(c,c,c);
      86             :         }
      87             :     }
      88           0 : return( grad );
      89             : }
      90             : 
      91             : /* ************************************************************************** */
      92             : #define USEFUL_MAX      6
      93             : 
      94             : static uint8 image_data[] = {
      95             :     0x00, 0x00,
      96             :     0x7f, 0xfe,
      97             :     0x7f, 0xfe,
      98             :     0x7f, 0xfe,
      99             :     0x7f, 0xfe,
     100             :     0x7f, 0xfe,
     101             :     0x7f, 0xfe,
     102             :     0x7f, 0xfe,
     103             :     0x7f, 0xfe,
     104             :     0x7f, 0xfe,
     105             :     0x7f, 0xfe,
     106             :     0x00, 0x00,
     107             : };
     108             : static GClut cluts[2*USEFUL_MAX] = {
     109             :     { 2, 0, COLOR_UNKNOWN, GCLUT_CLUT_EMPTY },
     110             :     { 2, 0, COLOR_UNKNOWN, GCLUT_CLUT_EMPTY },
     111             :     { 2, 0, COLOR_UNKNOWN, GCLUT_CLUT_EMPTY },
     112             :     { 2, 0, COLOR_UNKNOWN, GCLUT_CLUT_EMPTY },
     113             :     { 2, 0, COLOR_UNKNOWN, GCLUT_CLUT_EMPTY },
     114             :     { 2, 0, COLOR_UNKNOWN, GCLUT_CLUT_EMPTY },
     115             :     { 2, 0, COLOR_UNKNOWN, GCLUT_CLUT_EMPTY },
     116             :     { 2, 0, COLOR_UNKNOWN, GCLUT_CLUT_EMPTY },
     117             :     { 2, 0, COLOR_UNKNOWN, GCLUT_CLUT_EMPTY },
     118             :     { 2, 0, COLOR_UNKNOWN, GCLUT_CLUT_EMPTY },
     119             :     { 2, 0, COLOR_UNKNOWN, GCLUT_CLUT_EMPTY },
     120             :     { 2, 0, COLOR_UNKNOWN, GCLUT_CLUT_EMPTY }
     121             : };
     122             : static struct _GImage bases[2*USEFUL_MAX] = {
     123             :     { it_mono, 0,16,12,2, (uint8 *) image_data, &cluts[0], COLOR_UNKNOWN },
     124             :     { it_mono, 0,16,12,2, (uint8 *) image_data, &cluts[1], COLOR_UNKNOWN },
     125             :     { it_mono, 0,16,12,2, (uint8 *) image_data, &cluts[2], COLOR_UNKNOWN },
     126             :     { it_mono, 0,16,12,2, (uint8 *) image_data, &cluts[3], COLOR_UNKNOWN },
     127             :     { it_mono, 0,16,12,2, (uint8 *) image_data, &cluts[4], COLOR_UNKNOWN },
     128             :     { it_mono, 0,16,12,2, (uint8 *) image_data, &cluts[5], COLOR_UNKNOWN },
     129             :     { it_mono, 0,16,12,2, (uint8 *) image_data, &cluts[6], COLOR_UNKNOWN },
     130             :     { it_mono, 0,16,12,2, (uint8 *) image_data, &cluts[7], COLOR_UNKNOWN },
     131             :     { it_mono, 0,16,12,2, (uint8 *) image_data, &cluts[8], COLOR_UNKNOWN },
     132             :     { it_mono, 0,16,12,2, (uint8 *) image_data, &cluts[9], COLOR_UNKNOWN },
     133             :     { it_mono, 0,16,12,2, (uint8 *) image_data, &cluts[10], COLOR_UNKNOWN },
     134             :     { it_mono, 0,16,12,2, (uint8 *) image_data, &cluts[11], COLOR_UNKNOWN }
     135             : };
     136             : static GImage blanks[2*USEFUL_MAX] = {
     137             :     { 0, { &bases[0] }, NULL },
     138             :     { 0, { &bases[1] }, NULL },
     139             :     { 0, { &bases[2] }, NULL },
     140             :     { 0, { &bases[3] }, NULL },
     141             :     { 0, { &bases[4] }, NULL },
     142             :     { 0, { &bases[5] }, NULL },
     143             :     { 0, { &bases[6] }, NULL },
     144             :     { 0, { &bases[7] }, NULL },
     145             :     { 0, { &bases[8] }, NULL },
     146             :     { 0, { &bases[9] }, NULL },
     147             :     { 0, { &bases[10] }, NULL },
     148             :     { 0, { &bases[11] }, NULL }
     149             : };
     150             : /* ************************************************************************** */
     151             : struct hslrgba recent_cols[USEFUL_MAX+1];
     152             : 
     153             : struct gcol_data {
     154             :     GImage *wheel;
     155             :     GImage *grad;
     156             :     int wheel_width, wheel_height;
     157             :     GWindow gw;
     158             :     GWindow wheelw, gradw, colw;
     159             :     int done, pressed;
     160             :     struct hslrgba col, origcol;
     161             :     struct hslrgba user_cols[USEFUL_MAX+1];
     162             : };
     163             : 
     164             : #define CID_Red         1001
     165             : #define CID_Green       1002
     166             : #define CID_Blue        1003
     167             : 
     168             : #define CID_Hue         1011
     169             : #define CID_Saturation  1012
     170             : #define CID_Value       1013
     171             : 
     172             : #define CID_Alpha       1019
     173             : 
     174             : #define CID_Wheel       1021
     175             : #define CID_Grad        1022
     176             : #define CID_Color       1023
     177             : 
     178             : static int cids[] = { CID_Hue, CID_Saturation, CID_Value, CID_Red, CID_Green, CID_Blue, CID_Alpha, 0 };
     179             : static char *labnames[] = { N_("Hue:"), N_("Saturation:"), N_("Value:"), N_("Red:"), N_("Green:"), N_("Blue:"), N_("Opacity:") };
     180             : 
     181           0 : static int GCol_OK(GGadget *g, GEvent *e) {
     182           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
     183           0 :         struct gcol_data *d = GDrawGetUserData(GGadgetGetWindow(g));
     184           0 :         double *offs[7] = { &d->col.h, &d->col.s, &d->col.v, &d->col.r, &d->col.g, &d->col.b, &d->col.alpha };
     185           0 :         int err = false, i;
     186             :         double val;
     187             : 
     188           0 :         for ( i=0; i<7; ++i ) {
     189           0 :             val = GetReal8(d->gw,cids[i],_(labnames[i]),&err);
     190           0 :             if ( err )
     191           0 : return( true );
     192           0 :             if ( i==0 ) {
     193           0 :                 val = fmod(val,360);
     194           0 :                 if ( val<0 ) val += 360;
     195             :             } else {
     196           0 :                 if ( val<0 || val>1 ) {
     197           0 :                     gwwv_post_error(_("Value out of bounds"), _("Saturation and Value, and the three colors must be between 0 and 1"));
     198           0 : return( true );
     199             :                 }
     200             :             }
     201           0 :             *offs[i] = val;
     202             :         }
     203             : 
     204           0 :         d->done = true;
     205             :     }
     206           0 : return( true );
     207             : }
     208             : 
     209           0 : static int GCol_Cancel(GGadget *g, GEvent *e) {
     210           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
     211           0 :         struct gcol_data *d = GDrawGetUserData(GGadgetGetWindow(g));
     212           0 :         d->col.rgb = d->col.hsv = false;
     213           0 :         d->done = true;
     214             :     }
     215           0 : return( true );
     216             : }
     217             : 
     218           0 : static int GCol_TextChanged(GGadget *g, GEvent *e) {
     219           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_textchanged ) {
     220           0 :         struct gcol_data *d = GDrawGetUserData(GGadgetGetWindow(g));
     221           0 :         double *offs[7] = { &d->col.h, &d->col.s, &d->col.v, &d->col.r, &d->col.g, &d->col.b, &d->col.alpha };
     222           0 :         int i, err = false;
     223             :         int low, high;
     224             :         double val;
     225             :         char text[50];
     226             : 
     227           0 :         if ( GGadgetGetCid(g)==CID_Alpha ) {
     228           0 :             low = 3; high=7;
     229             :             /* Didn't actually change the rgb values, but parse them */
     230             :             /*  This is in case we need to clear the error flag */
     231           0 :             d->col.hsv = false;
     232           0 :             d->col.rgb = true;
     233           0 :         } else if ( GGadgetGetCid(g)>=CID_Hue ) {
     234           0 :             low = 0; high=3;
     235           0 :             d->col.hsv = true;
     236           0 :             d->col.rgb = false;
     237             :         } else {
     238           0 :             low = 3; high=6;
     239           0 :             d->col.hsv = false;
     240           0 :             d->col.rgb = true;
     241             :         }
     242           0 :         for ( i=low; i<high; ++i ) {
     243           0 :             val = GetCalmReal8(d->gw,cids[i],_(labnames[i]),&err);
     244           0 :             if ( err )
     245           0 :         break;
     246           0 :             if ( i==0 ) {
     247           0 :                 val = fmod(val,360);
     248           0 :                 if ( val<0 ) val += 360;
     249             :             } else {
     250           0 :                 if ( val<0 || val>1 ) {
     251           0 :                     err = true;
     252           0 :         break;
     253             :                 }
     254             :             }
     255           0 :             *offs[i] = val;
     256             :         }
     257           0 :         if ( err ) {
     258           0 :             d->col.hsv = d->col.rgb = false;
     259           0 :         } else if ( d->col.hsv ) {
     260           0 :             gHSV2RGB((struct hslrgb *) &d->col);
     261           0 :             for ( i=3; i<6; ++i ) {
     262           0 :                 sprintf( text, "%.2f", *offs[i]);
     263           0 :                 GGadgetSetTitle8(GWidgetGetControl(d->gw,cids[i]),text);
     264             :             }
     265             :         } else {
     266           0 :             gRGB2HSV((struct hslrgb *) &d->col);
     267           0 :             sprintf( text, "%3.0f", *offs[0]);
     268           0 :             GGadgetSetTitle8(GWidgetGetControl(d->gw,cids[0]),text);
     269           0 :             for ( i=1; i<3; ++i ) {
     270           0 :                 sprintf( text, "%.2f", *offs[i]);
     271           0 :                 GGadgetSetTitle8(GWidgetGetControl(d->gw,cids[i]),text);
     272             :             }
     273             :         }
     274           0 :         GDrawRequestExpose(d->wheelw,NULL,false);
     275           0 :         GDrawRequestExpose(d->gradw,NULL,false);
     276           0 :         GDrawRequestExpose(d->colw,NULL,false);
     277             :     }
     278           0 : return( true );
     279             : }
     280             : 
     281           0 : static void GCol_ShowTexts(struct gcol_data *d) {
     282           0 :     double *offs[7] = { &d->col.h, &d->col.s, &d->col.v, &d->col.r, &d->col.g, &d->col.b, &d->col.alpha };
     283             :     int i;
     284             :     char text[50];
     285             : 
     286           0 :     gHSV2RGB((struct hslrgb *) &d->col);
     287           0 :     sprintf( text, "%3.0f", *offs[0]);
     288           0 :     GGadgetSetTitle8(GWidgetGetControl(d->gw,cids[0]),text);
     289           0 :     for ( i=1; i<7; ++i ) {
     290           0 :         sprintf( text, "%.2f", *offs[i]);
     291           0 :         GGadgetSetTitle8(GWidgetGetControl(d->gw,cids[i]),text);
     292             :     }
     293           0 : }
     294             : 
     295           0 : static int wheel_e_h(GWindow gw, GEvent *event) {
     296           0 :     struct gcol_data *d = GDrawGetUserData(gw);
     297             :     GRect size;
     298           0 :     if ( event->type==et_expose ) {
     299             :         GRect circle;
     300           0 :         GDrawGetSize(d->wheelw,&size);
     301           0 :         if ( d->wheel==NULL || 
     302           0 :                 GImageGetHeight(d->wheel)!=size.height ||
     303           0 :                 GImageGetWidth(d->wheel)!=size.width ) {
     304           0 :             if ( d->wheel!=NULL )
     305           0 :                 GImageDestroy(d->wheel);
     306           0 :             d->wheel = ColorWheel(size.width,size.height);
     307             :         }
     308           0 :         GDrawDrawImage(gw,d->wheel,NULL,0,0);
     309           0 :         if ( d->col.hsv ) {
     310           0 :             double s = sin(d->col.h*3.1415926535897932/180.);
     311           0 :             double c = cos(d->col.h*3.1415926535897932/180.);
     312           0 :             int y = (int) rint(d->col.s*(size.height-1)*s/2.0) + size.height/2;
     313           0 :             int x = (int) rint(d->col.s*(size.width-1)*c/2.0) + size.width/2;
     314           0 :             circle.x = x-3; circle.y = y-3;
     315           0 :             circle.width = circle.height = 7;
     316           0 :             GDrawDrawElipse(gw,&circle,0x000000);
     317             :         }
     318           0 :     } else if ( event->type == et_mousedown ||
     319           0 :             (event->type==et_mousemove && d->pressed) ||
     320           0 :             event->type==et_mouseup ) {
     321             :         Color rgb;
     322             :         struct hslrgba temp;
     323           0 :         GDrawGetSize(d->wheelw,&size);
     324           0 :         if ( event->u.mouse.y>=0 && event->u.mouse.y<size.height &&
     325           0 :                 event->u.mouse.x>=0 && event->u.mouse.x<size.width ) {
     326           0 :             rgb = GImageGetPixelRGBA(d->wheel,event->u.mouse.x,event->u.mouse.y);
     327           0 :             temp.r = ((rgb>>16)&0xff)/255.;
     328           0 :             temp.g = ((rgb>>8)&0xff)/255.;
     329           0 :             temp.b = ((rgb   )&0xff)/255.;
     330           0 :             gRGB2HSV((struct hslrgb *) &temp);
     331           0 :             d->col.h = temp.h; d->col.s = temp.s;
     332           0 :             GCol_ShowTexts(d);
     333           0 :             GDrawRequestExpose(d->colw,NULL,false);
     334           0 :             GDrawRequestExpose(d->wheelw,NULL,false);
     335             :         }
     336           0 :         if ( event->type == et_mousedown )
     337           0 :             d->pressed = true;
     338           0 :         else if ( event->type == et_mouseup )
     339           0 :             d->pressed = false;
     340           0 :     } else if ( event->type==et_resize ) {
     341           0 :         GDrawRequestExpose(gw,NULL,false);
     342           0 :     } else if ( event->type == et_char ) {
     343           0 : return( false );
     344             :     }
     345           0 : return( true );
     346             : }
     347             : 
     348           0 : static int grad_e_h(GWindow gw, GEvent *event) {
     349           0 :     struct gcol_data *d = GDrawGetUserData(gw);
     350             :     GRect size;
     351           0 :     if ( event->type==et_expose ) {
     352           0 :         GDrawGetSize(d->wheelw,&size);
     353           0 :         if ( d->grad==NULL || GImageGetHeight(d->grad)!=size.height ) {
     354           0 :             if ( d->grad!=NULL )
     355           0 :                 GImageDestroy(d->grad);
     356           0 :             d->grad = Gradient(size.height);
     357             :         }
     358           0 :         GDrawDrawImage(gw,d->grad,NULL,0,0);
     359           0 :         if ( d->col.hsv ) {
     360           0 :             int y = size.height-1-(int) rint(size.height*d->col.v);
     361           0 :             int col = d->col.v>.5 ? 0x000000 : 0xffffff;
     362           0 :             GDrawDrawLine(gw,0,y,GRAD_WIDTH,y,col);
     363             :         }
     364           0 :     } else if ( event->type == et_mousedown ||
     365           0 :             (event->type==et_mousemove && d->pressed) ||
     366           0 :             event->type==et_mouseup ) {
     367           0 :         GDrawGetSize(d->wheelw,&size);
     368           0 :         if ( event->u.mouse.y<0 )
     369           0 :             event->u.mouse.y =0;
     370           0 :         else if ( event->u.mouse.y>=size.height )
     371           0 :             event->u.mouse.y = size.height-1;
     372           0 :         d->col.v = (size.height-1-event->u.mouse.y) / (double) (size.height-1);
     373           0 :         if ( d->col.v<0 ) d->col.v = 0;
     374           0 :         if ( d->col.v>1 ) d->col.v = 1;
     375           0 :         GCol_ShowTexts(d);
     376           0 :         GDrawRequestExpose(d->colw,NULL,false);
     377           0 :         GDrawRequestExpose(d->gradw,NULL,false);
     378           0 :         if ( event->type == et_mousedown )
     379           0 :             d->pressed = true;
     380           0 :         else if ( event->type == et_mouseup )
     381           0 :             d->pressed = false;
     382           0 :     } else if ( event->type==et_resize ) {
     383           0 :         GDrawRequestExpose(gw,NULL,false);
     384           0 :     } else if ( event->type == et_char ) {
     385           0 : return( false );
     386             :     }
     387           0 : return( true );
     388             : }
     389             : 
     390           0 : static void TranslucentRect(GWindow gw,GRect *size,int col,double alpha, int h) {
     391           0 :     if ( alpha==1.0 )
     392           0 :         GDrawFillRect(gw,size,col);
     393             :     else {
     394           0 :         int r = COLOR_RED(col), g = COLOR_GREEN(col), b = COLOR_BLUE(col);
     395           0 :         double white_bias = 255.*(1.0-alpha);
     396           0 :         Color dark = (((int) rint(r*alpha))<<16) |
     397           0 :                      (((int) rint(g*alpha))<<8 ) |
     398           0 :                      (((int) rint(b*alpha)) );
     399           0 :         Color light= (((int) rint(white_bias+r*alpha))<<16) |
     400           0 :                      (((int) rint(white_bias+g*alpha))<<8 ) |
     401           0 :                      (((int) rint(white_bias+b*alpha)) );
     402             :         GRect small, old;
     403             :         int x,y;
     404           0 :         int smallh = (h+1)/2;
     405             : 
     406           0 :         small.height = small.width = smallh;
     407           0 :         GDrawPushClip(gw,size,&old);
     408           0 :         for ( y=0; y<2; ++y ) {
     409           0 :             small.y = y*smallh;
     410           0 :             for ( x=size->x/smallh; x<=(size->x+size->width)/smallh; ++x ) {
     411           0 :                 small.x = x*smallh;
     412           0 :                 GDrawFillRect(gw,&small,((x+y)&1)?dark : light);
     413             :             }
     414             :         }
     415           0 :         GDrawPopClip(gw,&old);
     416             :     }
     417           0 : }
     418             : 
     419           0 : static int col_e_h(GWindow gw, GEvent *event) {
     420             :     GRect size, r;
     421           0 :     if ( event->type==et_expose ) {
     422           0 :         struct gcol_data *d = GDrawGetUserData(gw);
     423           0 :         GDrawGetSize(d->colw,&size);
     424           0 :         r = event->u.expose.rect;
     425           0 :         if ( r.x<size.width/2 ) {
     426           0 :             int col = (((int) rint(255*d->origcol.r))<<16) |
     427           0 :                       (((int) rint(255*d->origcol.g))<<8 ) |
     428           0 :                       (((int) rint(255*d->origcol.b))    );
     429           0 :             if ( r.x+r.width>size.width/2 )
     430           0 :                 r.width = size.width/2-r.x;
     431           0 :             TranslucentRect(gw,&r,col,d->origcol.alpha,size.height);
     432           0 :             r.width = event->u.expose.rect.width;
     433             :         }
     434           0 :         if ( r.x+r.width>size.width/2 ) {
     435           0 :             r.width = r.x+r.width - size.width/2;
     436           0 :             r.x = size.width/2;
     437           0 :             if ( d->col.rgb ) {
     438           0 :                 int col = (((int) rint(255*d->col.r))<<16) |
     439           0 :                           (((int) rint(255*d->col.g))<<8 ) |
     440           0 :                           (((int) rint(255*d->col.b))    );
     441           0 :                 TranslucentRect(gw,&r,col,d->col.alpha,size.height);
     442             :             } else {
     443           0 :                 GDrawSetStippled(gw,2,0,0);
     444           0 :                 GDrawSetBackground(gw,0xffff00);
     445           0 :                 GDrawFillRect(gw,&r,0x000000);
     446           0 :                 GDrawSetStippled(gw,0,0,0);
     447             :             }
     448             :         }
     449           0 :     } else if ( event->type == et_mousedown ) {
     450           0 :         struct gcol_data *d = GDrawGetUserData(gw);
     451           0 :         GDrawGetSize(d->colw,&size);
     452           0 :         if ( event->u.mouse.x<size.width/2 ) {
     453           0 :             d->col = d->origcol;
     454           0 :             GCol_ShowTexts(d);
     455           0 :             GDrawRequestExpose(d->wheelw,NULL,false);
     456           0 :             GDrawRequestExpose(d->colw,NULL,false);
     457           0 :             GDrawRequestExpose(d->gradw,NULL,false);
     458             :         }
     459           0 :     } else if ( event->type==et_resize ) {
     460           0 :         GDrawRequestExpose(gw,NULL,false);
     461           0 :     } else if ( event->type == et_char ) {
     462           0 : return( false );
     463             :     }
     464           0 : return( true );
     465             : }
     466             : 
     467           0 : static void do_popup_color(GWindow gw,struct gmenuitem *mi,GEvent *e) {
     468           0 :     struct gcol_data *d = GDrawGetUserData(gw);
     469           0 :     const struct hslrgba *col = mi->ti.userdata;
     470             : 
     471           0 :     d->col = *col;
     472           0 :     GCol_ShowTexts(d);
     473           0 :     GDrawRequestExpose(d->wheelw,NULL,false);
     474           0 :     GDrawRequestExpose(d->colw,NULL,false);
     475           0 :     GDrawRequestExpose(d->gradw,NULL,false);
     476           0 : }
     477             : 
     478           0 : static int popup_e_h(GWindow gw, GEvent *event) {
     479           0 :     struct gcol_data *d = GDrawGetUserData(gw);
     480           0 :     if ( recent_cols[0].hsv || d->user_cols[0].hsv ) {
     481           0 :         if ( event->type==et_expose ) {
     482           0 :             GDrawDrawLine(gw,1,1,GRAD_WIDTH-2,1,0x000000);
     483           0 :             GDrawDrawLine(gw,1,1,GRAD_WIDTH/2-1,GRAD_WIDTH-2,0x000000);
     484           0 :             GDrawDrawLine(gw,GRAD_WIDTH/2-1,GRAD_WIDTH-2,GRAD_WIDTH-2,1,0x000000);
     485           0 :         } else if ( event->type == et_mousedown ) {
     486             :             GMenuItem menu[2*USEFUL_MAX+2];
     487             :             int i,j,k;
     488             : 
     489           0 :             memset(menu,0,sizeof(menu));
     490           0 :             for ( i=0; i<USEFUL_MAX && recent_cols[i].hsv; ++i ) {
     491           0 :                 menu[i].ti.image = &blanks[i];
     492           0 :                 cluts[i].clut[1] = (((int) rint(255.*recent_cols[i].r))<<16 ) |
     493           0 :                                     (((int) rint(255.*recent_cols[i].g))<<8 ) |
     494           0 :                                     (((int) rint(255.*recent_cols[i].b)) );
     495           0 :                 menu[i].ti.fg = menu[i].ti.bg = COLOR_DEFAULT;
     496           0 :                 menu[i].ti.userdata = &recent_cols[i];
     497           0 :                 menu[i].invoke = do_popup_color;
     498             :             }
     499           0 :             j=i;
     500           0 :             if ( i!=0 && d->user_cols[0].hsv ) {
     501           0 :                 menu[i].ti.line = true;
     502           0 :                 menu[i].ti.fg = menu[i].ti.bg = COLOR_DEFAULT;
     503           0 :                 ++i;
     504             :             }
     505           0 :             for ( k=0; k<USEFUL_MAX && d->user_cols[k].hsv; ++k, ++i, ++j ) {
     506           0 :                 menu[i].ti.image = &blanks[j];
     507           0 :                 cluts[j].clut[1] = (((int) rint(255.*d->user_cols[k].r))<<16 ) |
     508           0 :                                     (((int) rint(255.*d->user_cols[k].g))<<8 ) |
     509           0 :                                     (((int) rint(255.*d->user_cols[k].b)) );
     510           0 :                 menu[i].ti.fg = menu[i].ti.bg = COLOR_DEFAULT;
     511           0 :                 menu[i].ti.userdata = &d->user_cols[k];
     512           0 :                 menu[i].invoke = do_popup_color;
     513             :             }
     514           0 :             GMenuCreatePopupMenu(gw,event, menu);
     515             :         }
     516             :     }
     517             : 
     518           0 :     if ( event->type == et_char )
     519           0 : return( false );
     520             : 
     521           0 : return( true );
     522             : }
     523             : 
     524           0 : static int e_h(GWindow gw, GEvent *event) {
     525           0 :     if ( event->type==et_close ) {
     526           0 :         struct gcol_data *d = GDrawGetUserData(gw);
     527           0 :         d->col.rgb = d->col.hsv = false;
     528           0 :         d->done = true;
     529           0 :     } else if ( event->type == et_char ) {
     530           0 : return( false );
     531             :     }
     532           0 : return( true );
     533             : }
     534             : 
     535           0 : struct hslrgba GWidgetColorA(const char *title,struct hslrgba *defcol,struct hslrgba *usercols) {
     536             :     GRect pos;
     537             :     GWindow gw;
     538             :     GWindowAttrs wattrs;
     539             :     GGadgetCreateData gcd[23], boxes[6], *txarray[9][3], *wheelarray[3][3], *barray[8], *hvarray[3][3];
     540             :     GTextInfo label[21];
     541             :     struct gcol_data d;
     542             :     int k, i;
     543           0 :     double *offs[7] = { &d.col.h, &d.col.s, &d.col.v, &d.col.r, &d.col.g, &d.col.b, &d.col.alpha };
     544             :     char values[7][40];
     545             : 
     546           0 :     GProgressPauseTimer();
     547           0 :     memset(&d,0,sizeof(d));
     548           0 :     memset(&wattrs,0,sizeof(wattrs));
     549           0 :     wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_restrict|wam_isdlg;
     550           0 :     wattrs.event_masks = ~(1<<et_charup);
     551           0 :     wattrs.restrict_input_to_me = 1;
     552           0 :     wattrs.undercursor = 1;
     553           0 :     wattrs.is_dlg = true;
     554           0 :     wattrs.cursor = ct_pointer;
     555           0 :     wattrs.utf8_window_title = title;
     556           0 :     pos.x = pos.y = 0;
     557           0 :     pos.width = pos.height = 200;
     558           0 :     d.gw = gw = GDrawCreateTopWindow(NULL,&pos,e_h,&d,&wattrs);
     559             : 
     560           0 :     if ( defcol!=NULL && (defcol->rgb || defcol->hsv || defcol->hsl ))
     561           0 :         d.col = *defcol;
     562           0 :     else if ( recent_cols[0].hsv ) {
     563           0 :         d.col = recent_cols[0];
     564           0 :         d.col.has_alpha = true;
     565           0 :     } else if ( usercols!=NULL && (usercols[0].rgb || usercols[0].hsv || usercols[0].hsl )) {
     566           0 :         d.col = usercols[0];
     567           0 :         d.col.has_alpha = true;
     568             :     } else {
     569           0 :         d.col.rgb = true;
     570           0 :         d.col.r = d.col.g = d.col.b = 1.0;
     571           0 :         d.col.alpha = 1.0;
     572           0 :         d.col.has_alpha = true;
     573             :     }
     574           0 :     if ( d.col.rgb ) {
     575           0 :         if ( !d.col.hsv )
     576           0 :             gRGB2HSV((struct hslrgb *) &d.col);
     577           0 :     } else if ( d.col.hsv )
     578           0 :         gHSV2RGB((struct hslrgb *) &d.col);
     579             :     else {
     580           0 :         gHSL2RGB((struct hslrgb *) &d.col);
     581           0 :         gRGB2HSV((struct hslrgb *) &d.col);
     582             :     }
     583           0 :     d.origcol = d.col;
     584           0 :     if ( usercols!=NULL ) {
     585           0 :         for ( i=0; i<6 && (usercols[i].rgb || usercols[i].hsv || usercols[i].hsl ); ++i ) {
     586           0 :             d.user_cols[i] = usercols[i];
     587           0 :             if ( d.user_cols[i].rgb ) {
     588           0 :                 if ( !d.user_cols[i].hsv )
     589           0 :                     gRGB2HSV((struct hslrgb *) &d.user_cols[i]);
     590           0 :             } else if ( d.user_cols[i].hsv )
     591           0 :                 gHSV2RGB((struct hslrgb *) &d.user_cols[i]);
     592             :             else {
     593           0 :                 gHSL2RGB((struct hslrgb *) &d.user_cols[i]);
     594           0 :                 gRGB2HSV((struct hslrgb *) &d.user_cols[i]);
     595             :             }
     596             :         }
     597             :     }
     598             : 
     599           0 :     k=0;
     600           0 :     memset(&gcd,0,sizeof(gcd));
     601           0 :     memset(&label,0,sizeof(label));
     602           0 :     memset(&boxes,0,sizeof(boxes));
     603             : 
     604           0 :     gcd[k].gd.pos.height = gcd[k].gd.pos.width = 150;
     605           0 :     if ( d.col.has_alpha )
     606           0 :         gcd[k].gd.pos.height = gcd[k].gd.pos.width = 170;
     607           0 :     gcd[k].gd.flags = gg_visible | gg_enabled;
     608           0 :     gcd[k].gd.u.drawable_e_h = wheel_e_h;
     609           0 :     gcd[k].gd.cid = CID_Wheel;
     610           0 :     gcd[k].creator = GDrawableCreate;
     611           0 :     wheelarray[0][0] = &gcd[k++];
     612             : 
     613           0 :     gcd[k].gd.pos.height = 150; gcd[k].gd.pos.width = GRAD_WIDTH;
     614           0 :     gcd[k].gd.flags = gg_visible | gg_enabled;
     615           0 :     gcd[k].gd.u.drawable_e_h = grad_e_h;
     616           0 :     gcd[k].gd.cid = CID_Grad;
     617           0 :     gcd[k].creator = GDrawableCreate;
     618           0 :     wheelarray[0][1] = &gcd[k++]; wheelarray[0][2] = NULL;
     619             : 
     620           0 :     gcd[k].gd.pos.width = 150; gcd[k].gd.pos.height = GRAD_WIDTH;
     621           0 :     gcd[k].gd.flags = gg_visible | gg_enabled;
     622           0 :     gcd[k].gd.u.drawable_e_h = col_e_h;
     623           0 :     gcd[k].gd.cid = CID_Color;
     624           0 :     gcd[k].creator = GDrawableCreate;
     625           0 :     wheelarray[1][0] = &gcd[k++];
     626             : 
     627           0 :     gcd[k].gd.pos.width = GRAD_WIDTH; gcd[k].gd.pos.height = GRAD_WIDTH;
     628           0 :     gcd[k].gd.flags = gg_visible | gg_enabled;
     629           0 :     gcd[k].gd.u.drawable_e_h = popup_e_h;
     630           0 :     gcd[k].creator = GDrawableCreate;
     631           0 :     wheelarray[1][1] = &gcd[k++]; wheelarray[1][2] = NULL;
     632           0 :     wheelarray[2][0] = NULL;
     633             : 
     634           0 :     boxes[2].gd.flags = gg_enabled|gg_visible;
     635           0 :     boxes[2].gd.u.boxelements = wheelarray[0];
     636           0 :     boxes[2].creator = GHVBoxCreate;
     637             : 
     638           0 :     for ( i=0; i<7; ++i ) {
     639           0 :         label[k].text = (unichar_t *) _(labnames[i]);
     640           0 :         label[k].text_is_1byte = true;
     641           0 :         label[k].text_in_resource = true;
     642           0 :         gcd[k].gd.label = &label[k];
     643           0 :         gcd[k].gd.flags = gg_visible | gg_enabled ;
     644           0 :         gcd[k++].creator = GLabelCreate;
     645           0 :         txarray[i][0] = &gcd[k-1];
     646             : 
     647           0 :         if ( i==0 )
     648           0 :             sprintf( values[0], "%3.0f", *offs[0]);
     649             :         else
     650           0 :             sprintf( values[i], "%.2f", *offs[i]);
     651           0 :         label[k].text = (unichar_t *) values[i];
     652           0 :         label[k].text_is_1byte = true;
     653           0 :         gcd[k].gd.label = &label[k];
     654           0 :         gcd[k].gd.pos.width = 60;
     655           0 :         gcd[k].gd.flags = gg_visible | gg_enabled;
     656           0 :         gcd[k].gd.cid = cids[i];
     657           0 :         gcd[k].gd.handle_controlevent = GCol_TextChanged;
     658           0 :         gcd[k++].creator = i==0 ? GNumericFieldCreate : GTextFieldCreate;
     659           0 :         txarray[i][1] = &gcd[k-1]; txarray[i][2] = NULL;
     660             :     }
     661           0 :     if ( !d.col.has_alpha ) {
     662           0 :         gcd[k-1].gd.flags &= ~gg_visible;
     663           0 :         gcd[k-2].gd.flags &= ~gg_visible;
     664             :     }
     665           0 :     txarray[i][0] = txarray[i][1] = GCD_Glue; txarray[i][2] = NULL;
     666           0 :     txarray[i+1][0] = NULL;
     667             : 
     668           0 :     boxes[3].gd.flags = gg_enabled|gg_visible;
     669           0 :     boxes[3].gd.u.boxelements = txarray[0];
     670           0 :     boxes[3].creator = GHVBoxCreate;
     671             : 
     672           0 :     gcd[k].gd.flags = gg_visible | gg_enabled | gg_but_default;
     673           0 :     label[k].text = (unichar_t *) _("_OK");
     674           0 :     label[k].text_is_1byte = true;
     675           0 :     label[k].text_in_resource = true;
     676           0 :     gcd[k].gd.label = &label[k];
     677           0 :     gcd[k].gd.handle_controlevent = GCol_OK;
     678           0 :     gcd[k++].creator = GButtonCreate;
     679           0 :     barray[0] = GCD_Glue; barray[1] = &gcd[k-1]; barray[2] = GCD_Glue;
     680             : 
     681           0 :     gcd[k].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
     682           0 :     label[k].text = (unichar_t *) _("_Cancel");
     683           0 :     label[k].text_is_1byte = true;
     684           0 :     label[k].text_in_resource = true;
     685           0 :     gcd[k].gd.label = &label[k];
     686           0 :     gcd[k].gd.handle_controlevent = GCol_Cancel;
     687           0 :     gcd[k].creator = GButtonCreate;
     688           0 :     barray[3] = GCD_Glue; barray[4] = &gcd[k]; barray[5] = GCD_Glue;
     689           0 :     barray[6] = NULL;
     690             : 
     691           0 :     boxes[4].gd.flags = gg_enabled|gg_visible;
     692           0 :     boxes[4].gd.u.boxelements = barray;
     693           0 :     boxes[4].creator = GHBoxCreate;
     694             : 
     695           0 :     hvarray[0][0] = &boxes[2];
     696           0 :     hvarray[0][1] = &boxes[3];
     697           0 :     hvarray[0][2] = NULL;
     698           0 :     hvarray[1][0] = &boxes[4];
     699           0 :     hvarray[1][1] = GCD_ColSpan;
     700           0 :     hvarray[1][2] = NULL;
     701           0 :     hvarray[2][0] = NULL;
     702             : 
     703           0 :     boxes[0].gd.pos.x = boxes[0].gd.pos.y = 2;
     704           0 :     boxes[0].gd.flags = gg_enabled|gg_visible;
     705           0 :     boxes[0].gd.u.boxelements = hvarray[0];
     706           0 :     boxes[0].creator = GHVGroupCreate;
     707           0 :     GGadgetsCreate(gw,boxes);
     708           0 :     GHVBoxSetExpandableRow(boxes[0].ret,0);
     709           0 :     GHVBoxSetExpandableCol(boxes[0].ret,0);
     710           0 :     GHVBoxSetExpandableRow(boxes[2].ret,0);
     711           0 :     GHVBoxSetExpandableCol(boxes[2].ret,0);
     712           0 :     GHVBoxSetExpandableRow(boxes[3].ret,gb_expandglue);
     713           0 :     GHVBoxSetExpandableCol(boxes[4].ret,gb_expandgluesame);
     714           0 :     GHVBoxFitWindow(boxes[0].ret);
     715           0 :     d.wheelw = GDrawableGetWindow(GWidgetGetControl(gw,CID_Wheel));
     716           0 :     d.gradw  = GDrawableGetWindow(GWidgetGetControl(gw,CID_Grad));
     717           0 :     d.colw   = GDrawableGetWindow(GWidgetGetControl(gw,CID_Color));
     718           0 :     GDrawSetVisible(gw,true);
     719             : 
     720           0 :     while ( !d.done )
     721           0 :         GDrawProcessOneEvent(NULL);
     722           0 :     GDrawDestroyWindow(gw);
     723           0 :     if ( d.grad!=NULL )
     724           0 :         GImageDestroy(d.grad);
     725           0 :     if ( d.wheel!=NULL )
     726           0 :         GImageDestroy(d.wheel);
     727           0 :     if ( d.col.hsv || d.col.rgb ) {
     728             :         int j;
     729           0 :         for ( j=0; j<USEFUL_MAX; ++j )
     730           0 :             if ( d.col.r==recent_cols[j].r && d.col.g==recent_cols[j].g &&
     731           0 :                     d.col.b==recent_cols[j].b &&
     732           0 :                     (!d.col.has_alpha || d.col.alpha==recent_cols[j].alpha))
     733             :         break;
     734           0 :         if ( j==USEFUL_MAX )
     735           0 :             --j;
     736           0 :         for ( ; j>0; --j )
     737           0 :             recent_cols[j] = recent_cols[j-1];
     738           0 :         recent_cols[0] = d.col;
     739             :     }
     740           0 : return( d.col );
     741             : }
     742             : 
     743           0 : struct hslrgb GWidgetColor(const char *title,struct hslrgb *defcol,struct hslrgb *usercols) {
     744             :     struct hslrgba def, users[USEFUL_MAX+1], *d, *u, temp;
     745             :     struct hslrgb ret;
     746             :     int i;
     747           0 :     if ( usercols==NULL )
     748           0 :         u = NULL;
     749             :     else {
     750           0 :         for ( i=0; i<6 && (usercols[i].rgb || usercols[i].hsv || usercols[i].hsl ); ++i ) {
     751           0 :             memcpy(&users[i],&usercols[i],sizeof(struct hslrgb));
     752           0 :             users[i].has_alpha = 0;
     753           0 :             users[i].alpha = 1.0;
     754             :         }
     755           0 :         u = users;
     756             :     }
     757             : 
     758           0 :     if ( defcol!=NULL )
     759           0 :         memcpy(&def,defcol,sizeof(*defcol));
     760           0 :     else if ( recent_cols[0].hsv )
     761           0 :         def = recent_cols[0];
     762           0 :     else if ( u!=NULL && (u[0].rgb || u[0].hsv || u[0].hsl ))
     763           0 :         def = u[0];
     764             :     else {
     765           0 :         def.rgb = true;
     766           0 :         def.r = def.g = def.b = 1.0;
     767             :     }
     768           0 :     def.has_alpha = false;
     769           0 :     def.alpha = 1.0;
     770           0 :     d = &def;
     771           0 :     temp = GWidgetColorA(title,d,u);
     772           0 :     memcpy(&ret,&temp,sizeof(ret));
     773           0 : return( ret );
     774             : }

Generated by: LCOV version 1.10