<commit_before>/** \file
 * \brief Gauge control
 *
 * See Copyright Notice in "iup.h"
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#include "iup.h"
#include "iupcbs.h"
#include "iupkey.h"

#include <cd.h>
#include <cdiup.h>
#include <cddbuf.h>

#include "iup_object.h"
#include "iup_attrib.h"
#include "iup_str.h"
#include "iup_drv.h"
#include "iup_stdcontrols.h"
#include "iup_controls.h"
#include "iup_cdutil.h"
#include "iup_register.h"
#include "iup_image.h"


#define IGAUGE_DEFAULTCOLOR "64 96 192"
#define IGAUGE_DEFAULTSIZE  "120x14"

#define IGAUGE_GAP     3
#define IGAUGE_BLOCKS 20

#define gaugeround(_) ((int)((_)+.5))


struct _IcontrolData
{
  iupCanvas canvas;  /* from IupCanvas (must reserve it) */

  int w;
  int h;

  int show_text;
  int dashed;
  int horiz_padding, vert_padding;  /* internal margin */

  long bgcolor;
  long fgcolor;
  long light_shadow;
  long mid_shadow;
  long dark_shadow; 

  double value;  /* min<=value<max */
  double vmin;
  double vmax;

  char* text;

  cdCanvas *cddbuffer;
  cdCanvas *cdcanvas;
};

static void iGaugeDrawText(Ihandle* ih, int xmid, long fgcolor)
{
  int x, y, xmin, xmax, ymin, ymax;
  char* text = ih->data->text;
  char buffer[30];

  cdIupSetFont(ih, ih->data->cddbuffer, IupGetAttribute(ih, "FONT"));
  cdCanvasTextAlignment(ih->data->cddbuffer, CD_CENTER);
  cdCanvasBackOpacity(ih->data->cddbuffer, CD_TRANSPARENT);

  x = (int)(0.5 * ih->data->w);
  y = (int)(0.5 * ih->data->h);

  if (text == NULL)
  {
    sprintf(buffer, "%.1f%%", 100 * (ih->data->value - ih->data->vmin) / (ih->data->vmax - ih->data->vmin));
    text = buffer;
  }

  cdCanvasGetTextBox(ih->data->cddbuffer, x, y, text, &xmin, &xmax, &ymin, &ymax);

  if(xmid < xmin)
  {
    cdCanvasForeground(ih->data->cddbuffer, fgcolor);
    cdCanvasText(ih->data->cddbuffer, x, y, text);
  }
  else if(xmid > xmax)
  {
    cdCanvasForeground(ih->data->cddbuffer, ih->data->bgcolor);
    cdCanvasText(ih->data->cddbuffer, x, y, text);
  }
  else
  {
    cdCanvasClip(ih->data->cddbuffer, CD_CLIPAREA);
    cdCanvasClipArea(ih->data->cddbuffer, xmin, xmid, ymin, ymax);
    cdCanvasForeground(ih->data->cddbuffer, ih->data->bgcolor);
    cdCanvasText(ih->data->cddbuffer, x, y, text);

    cdCanvasClipArea(ih->data->cddbuffer, xmid, xmax, ymin, ymax);
    cdCanvasForeground(ih->data->cddbuffer, fgcolor);
    cdCanvasText(ih->data->cddbuffer, x, y, text);
    cdCanvasClip(ih->data->cddbuffer, CD_CLIPOFF);
  }
}

static void iGaugeDrawGauge(Ihandle* ih)
{
  int border = 3;  /* includes the pixel used to draw the 3D border */
  int xstart = ih->data->horiz_padding+border;
  int ystart = ih->data->vert_padding+border;
  int xend   = ih->data->w-1 - (ih->data->horiz_padding+border);
  int yend   = ih->data->h-1 - (ih->data->vert_padding+border);
  long fgcolor = ih->data->fgcolor;

  if (!iupdrvIsActive(ih))
  {
    unsigned char r, g, b, bg_r, bg_g, bg_b;
    cdDecodeColor(fgcolor, &r, &g, &b);
    cdDecodeColor(ih->data->bgcolor, &bg_r, &bg_g, &bg_b);
    iupImageColorMakeInactive(&r, &g, &b, bg_r, bg_g, bg_b);
    fgcolor = cdEncodeColor(r, g, b);
  }

  cdCanvasBackground(ih->data->cddbuffer, ih->data->bgcolor);
  cdCanvasClear(ih->data->cddbuffer);

  cdIupDrawSunkenRect(ih->data->cddbuffer, 0, 0, ih->data->w-1, ih->data->h-1,
                        ih->data->light_shadow, ih->data->mid_shadow, ih->data->dark_shadow);

  cdCanvasForeground(ih->data->cddbuffer, fgcolor);

  if (ih->data->dashed)
  {
    float step = (xend - xstart + 1) / (float)IGAUGE_BLOCKS;
    float boxw = step - IGAUGE_GAP;
    float vx   = (float)((xend-xstart + 1) * (ih->data->value - ih->data->vmin) / (ih->data->vmax - ih->data->vmin));
    int intvx  = (int)(100 * vx);
    float i = 0;

    if(ih->data->value == ih->data->vmin)
      return;

    while(gaugeround(100*(i + boxw)) <= intvx)
    {
      cdCanvasBox(ih->data->cddbuffer, xstart + gaugeround(i),
             xstart + gaugeround(i + boxw) - 1, ystart, yend);
      i += step;
    }
  }
  else
  {
    int xmid = xstart + gaugeround((xend-xstart + 1) * (ih->data->value - ih->data->vmin) / (ih->data->vmax - ih->data->vmin));

    if(ih->data->value != ih->data->vmin)
      cdCanvasBox(ih->data->cddbuffer, xstart, xmid, ystart, yend );

    if(ih->data->show_text)
      iGaugeDrawText(ih, xmid, fgcolor);
  }
}

static int iGaugeResize_CB(Ihandle* ih)
{
  if (!ih->data->cddbuffer)
  {
    /* update canvas size */
    cdCanvasActivate(ih->data->cdcanvas);

    /* this can fail if canvas size is zero */
    ih->data->cddbuffer = cdCreateCanvas(CD_DBUFFER, ih->data->cdcanvas);
  }

  if (!ih->data->cddbuffer)
    return IUP_DEFAULT;

  /* update size */
  cdCanvasActivate(ih->data->cddbuffer);
  cdCanvasGetSize(ih->data->cddbuffer,&ih->data->w,&ih->data->h,NULL,NULL);

  /* update render */<commit_msg>*** empty log message ***<commit_after>/** \file
 * \brief Gauge control
 *
 * See Copyright Notice in "iup.h"
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#include "iup.h"
#include "iupcbs.h"
#include "iupkey.h"

#include <cd.h>
#include <cdiup.h>
#include <cddbuf.h>

#include "iup_object.h"
#include "iup_attrib.h"
#include "iup_str.h"
#include "iup_drv.h"
#include "iup_stdcontrols.h"
#include "iup_controls.h"
#include "iup_cdutil.h"
#include "iup_register.h"
#include "iup_image.h"


#define IGAUGE_DEFAULTCOLOR "64 96 192"
#define IGAUGE_DEFAULTSIZE  "120x14"

#define IGAUGE_GAP     3
#define IGAUGE_BLOCKS 20

#define gaugeround(_) ((int)((_)+.5))


struct _IcontrolData
{
  iupCanvas canvas;  /* from IupCanvas (must reserve it) */

  int w;
  int h;

  int show_text;
  int dashed;
  int horiz_padding, vert_padding;  /* internal margin */

  long bgcolor;
  long fgcolor;
  long light_shadow;
  long mid_shadow;
  long dark_shadow; 

  double value;  /* min<=value<max */
  double vmin;
  double vmax;

  char* text;

  cdCanvas *cddbuffer;
  cdCanvas *cdcanvas;
};

static void iGaugeDrawText(Ihandle* ih, int xmid)
{
  int x, y, xmin, xmax, ymin, ymax;
  char* text = ih->data->text;
  char buffer[30];

  cdIupSetFont(ih, ih->data->cddbuffer, IupGetAttribute(ih, "FONT"));
  cdCanvasTextAlignment(ih->data->cddbuffer, CD_CENTER);
  cdCanvasBackOpacity(ih->data->cddbuffer, CD_TRANSPARENT);

  x = (int)(0.5 * ih->data->w);
  y = (int)(0.5 * ih->data->h);

  if (text == NULL)
  {
    sprintf(buffer, "%.1f%%", 100 * (ih->data->value - ih->data->vmin) / (ih->data->vmax - ih->data->vmin));
    text = buffer;
  }

  cdCanvasGetTextBox(ih->data->cddbuffer, x, y, text, &xmin, &xmax, &ymin, &ymax);

  if(xmid < xmin)
  {
    cdCanvasForeground(ih->data->cddbuffer, ih->data->fgcolor);
    cdCanvasText(ih->data->cddbuffer, x, y, text);
  }
  else if(xmid > xmax)
  {
    cdCanvasForeground(ih->data->cddbuffer, ih->data->bgcolor);
    cdCanvasText(ih->data->cddbuffer, x, y, text);
  }
  else
  {
    cdCanvasClip(ih->data->cddbuffer, CD_CLIPAREA);
    cdCanvasClipArea(ih->data->cddbuffer, xmin, xmid, ymin, ymax);
    cdCanvasForeground(ih->data->cddbuffer, ih->data->bgcolor);
    cdCanvasText(ih->data->cddbuffer, x, y, text);

    cdCanvasClipArea(ih->data->cddbuffer, xmid, xmax, ymin, ymax);
    cdCanvasForeground(ih->data->cddbuffer, ih->data->fgcolor);
    cdCanvasText(ih->data->cddbuffer, x, y, text);
    cdCanvasClip(ih->data->cddbuffer, CD_CLIPOFF);
  }
}

static void iGaugeDrawGauge(Ihandle* ih)
{
  int border = 3;  /* includes the pixel used to draw the 3D border */
  int xstart = ih->data->horiz_padding+border;
  int ystart = ih->data->vert_padding+border;
  int xend   = ih->data->w-1 - (ih->data->horiz_padding+border);
  int yend   = ih->data->h-1 - (ih->data->vert_padding+border);

  cdCanvasBackground(ih->data->cddbuffer, ih->data->bgcolor);
  cdCanvasClear(ih->data->cddbuffer);

  cdIupDrawSunkenRect(ih->data->cddbuffer, 0, 0, ih->data->w-1, ih->data->h-1,
                        ih->data->light_shadow, ih->data->mid_shadow, ih->data->dark_shadow);

  cdCanvasForeground(ih->data->cddbuffer, ih->data->fgcolor);

  if (ih->data->dashed)
  {
    float step = (xend - xstart + 1) / (float)IGAUGE_BLOCKS;
    float boxw = step - IGAUGE_GAP;
    float vx   = (float)((xend-xstart + 1) * (ih->data->value - ih->data->vmin) / (ih->data->vmax - ih->data->vmin));
    int intvx  = (int)(100 * vx);
    float i = 0;

    if(ih->data->value == ih->data->vmin)
      return;

    while(gaugeround(100*(i + boxw)) <= intvx)
    {
      cdCanvasBox(ih->data->cddbuffer, xstart + gaugeround(i),
             xstart + gaugeround(i + boxw) - 1, ystart, yend);
      i += step;
    }
  }
  else
  {
    int xmid = xstart + gaugeround((xend-xstart + 1) * (ih->data->value - ih->data->vmin) / (ih->data->vmax - ih->data->vmin));

    if(ih->data->value != ih->data->vmin)
      cdCanvasBox(ih->data->cddbuffer, xstart, xmid, ystart, yend );

    if(ih->data->show_text)
      iGaugeDrawText(ih, xmid);
  }
}

static int iGaugeResize_CB(Ihandle* ih)
{
  if (!ih->data->cddbuffer)
  {
    /* update canvas size */
    cdCanvasActivate(ih->data->cdcanvas);

    /* this can fail if canvas size is zero */
    ih->data->cddbuffer = cdCreateCanvas(CD_DBUFFER, ih->data->cdcanvas);
  }

  if (!ih->data->cddbuffer)
    return IUP_DEFAULT;

  /* update size */
  cdCanvasActivate(ih->data->cddbuffer);
  cdCanvasGetSize(ih->data->cddbuffer,&ih->data->w,&ih->data->h,NULL,NULL);

  /* update render */
{'fraction_non_alphanumeric': 0.1786700658593584, 'fraction_numerical': 0.009560229445506692, 'mean_word_length': 3.4918893129770994, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 293, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '886970', 'n_tokens_mistral': 3882, 'n_tokens_neox': 3761, 'n_words': 726}