Beispiel #1
0
	virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
	{
		switch (widget) {
			case WID_EM_MESSAGE: {
				CopyInDParam(0, this->decode_params, lengthof(this->decode_params));
				if (this->textref_stack_size > 0) StartTextRefStackUsage(this->textref_stack_grffile, this->textref_stack_size, this->textref_stack);

				int text_width = max(0, (int)size->width - WD_FRAMETEXT_LEFT - WD_FRAMETEXT_RIGHT);
				this->height_summary = GetStringHeight(this->summary_msg, text_width);
				this->height_detailed = (this->detailed_msg == INVALID_STRING_ID) ? 0 : GetStringHeight(this->detailed_msg, text_width);

				if (this->textref_stack_size > 0) StopTextRefStackUsage();

				uint panel_height = WD_FRAMERECT_TOP + this->height_summary + WD_FRAMERECT_BOTTOM;
				if (this->detailed_msg != INVALID_STRING_ID) panel_height += this->height_detailed + WD_PAR_VSEP_WIDE;

				size->height = max(size->height, panel_height);
				break;
			}
			case WID_EM_FACE: {
				Dimension face_size = GetSpriteSize(SPR_GRADIENT);
				size->width = max(size->width, face_size.width);
				size->height = max(size->height, face_size.height);
				break;
			}
		}
	}
Beispiel #2
0
	virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
	{
		switch (widget) {
			case WID_SGI_DIFFICULTIES: {
				Dimension textdim = {0, 0};
				for (uint i = STR_DIFFICULTY_LEVEL_EASY; i <= STR_DIFFICULTY_LEVEL_CUSTOM; i++) {
					SetDParam(0, i);
					textdim = maxdim(textdim, GetStringBoundingBox(STR_INTRO_DIFFICULTY));
				}
				textdim.width += padding.width;
				textdim.height += padding.height;
				*size = maxdim(*size, textdim);
				break;
			}

			case WID_SGI_TRANSLATION: {
				SetDParam(0, _current_language->missing);
				int height = GetStringHeight(STR_INTRO_TRANSLATION, size->width);
				if (height > 3 * FONT_HEIGHT_NORMAL) {
					/* Don't let the window become too high. */
					Dimension textdim = GetStringBoundingBox(STR_INTRO_TRANSLATION);
					textdim.height *= 3;
					textdim.width -= textdim.width / 2;
					*size = maxdim(*size, textdim);
				} else {
					size->height = height + padding.height;
				}
				break;
			}
		}
	}
Beispiel #3
0
/** Update all task bars. */
void UpdateTaskBar(void)
{
   TaskBarType *bp;
   int lastHeight = -1;

   if(JUNLIKELY(shouldExit)) {
      return;
   }

   for(bp = bars; bp; bp = bp->next) {
      if(bp->layout == LAYOUT_VERTICAL) {
         TaskEntry *tp;
         lastHeight = bp->cp->requestedHeight;
         if(bp->userHeight > 0) {
            bp->itemHeight = bp->userHeight;
         } else {
            bp->itemHeight = GetStringHeight(FONT_TASKLIST) + 12;
         }
         bp->cp->requestedHeight = 0;
         for(tp = taskEntries; tp; tp = tp->next) {
            if(ShouldShowEntry(tp)) {
               bp->cp->requestedHeight += bp->itemHeight;
            }
         }
         bp->cp->requestedHeight = Max(1, bp->cp->requestedHeight);
         if(lastHeight != bp->cp->requestedHeight) {
            ResizeTray(bp->cp->tray);
         }
      }
      ComputeItemSize(bp);
      Render(bp);
   }
}
Beispiel #4
0
/** Determine the size of items in the task bar. */
void ComputeItemSize(TaskBarType *tp)
{
   TrayComponentType *cp = tp->cp;
   if(tp->layout == LAYOUT_VERTICAL) {

      if(tp->userHeight > 0) {
         tp->itemHeight = tp->userHeight;
      } else {
         tp->itemHeight = GetStringHeight(FONT_TASKLIST) + 12;
      }
      tp->itemWidth = cp->width;

   } else {

      TaskEntry *ep;
      unsigned itemCount = 0;

      tp->itemHeight = cp->height;
      for(ep = taskEntries; ep; ep = ep->next) {
         if(ShouldShowEntry(ep)) {
            itemCount += 1;
         }
      }
      if(itemCount == 0) {
         return;
      }

      tp->itemWidth = Max(1, cp->width / itemCount);
      if(tp->maxItemWidth > 0) {
         tp->itemWidth = Min(tp->maxItemWidth, tp->itemWidth);
      }
   }
}
Beispiel #5
0
/** Startup tray buttons. */
void StartupTrayButtons(void)
{
   TrayButtonType *bp;
   for(bp = buttons; bp; bp = bp->next) {
      if(bp->label) {
         bp->cp->requestedWidth
            = GetStringWidth(FONT_TRAY, bp->label) + 4;
         bp->cp->requestedHeight = GetStringHeight(FONT_TRAY);
      } else {
         bp->cp->requestedWidth = 0;
         bp->cp->requestedHeight = 0;
      }
      if(bp->iconName) {
         bp->icon = LoadNamedIcon(bp->iconName, 1, 1);
         if(JLIKELY(bp->icon)) {
            bp->cp->requestedWidth += bp->icon->images->width + 4;
            if(bp->label) {
               bp->cp->requestedWidth -= 2;
            }
            bp->cp->requestedHeight
               = Max(bp->icon->images->height + 4, bp->cp->requestedHeight);
         } else {
            Warning(_("could not load tray icon: \"%s\""), bp->iconName);
         }
      }
   }
}
Beispiel #6
0
/** Startup tray buttons. */
void StartupTrayButtons() {

   TrayButtonType *bp;

   for(bp = buttons; bp; bp = bp->next) {
      if(bp->label) {
         bp->cp->requestedWidth
            = GetStringWidth(FONT_TRAYBUTTON, bp->label) + 4;
         bp->cp->requestedHeight
            = GetStringHeight(FONT_TRAYBUTTON);
      } else {
         bp->cp->requestedWidth = 0;
         bp->cp->requestedHeight = 0;
      }
      if(bp->iconName) {
         bp->icon = LoadNamedIcon(bp->iconName);
         if(JLIKELY(bp->icon)) {
            bp->cp->requestedWidth += bp->icon->image->width;
            bp->cp->requestedHeight += bp->icon->image->height;
         } else {
            Warning(_("could not load tray icon: \"%s\""), bp->iconName);
         }
      }
      bp->cp->requestedWidth += 2 * BUTTON_SIZE;
      bp->cp->requestedHeight += 2 * BUTTON_SIZE;
   }

}
Beispiel #7
0
/** Compute the size of a dialog window. */
void ComputeDimensions(const ClientNode *np)
{

    const ScreenType *sp;
    int width;
    int x;

    Assert(dialog);

    /* Get the min width from the size of the buttons. */
    if(!minWidth) {
        minWidth = GetStringWidth(FONT_MENU, GetCancelString()) * 3;
        width = GetStringWidth(FONT_MENU, GetOKString()) * 3;
        if(width > minWidth) {
            minWidth = width;
        }
        minWidth += 16 * 3;
    }
    dialog->width = minWidth;

    /* Take into account the size of the message. */
    for(x = 0; x < dialog->lineCount; x++) {
        width = GetStringWidth(FONT_MENU, dialog->message[x]);
        if(width > dialog->width) {
            dialog->width = width;
        }
    }
    dialog->lineHeight = GetStringHeight(FONT_MENU);
    dialog->width += 8;
    dialog->height = (dialog->lineCount + 2) * dialog->lineHeight;

    if(np) {

        dialog->x = np->x + (np->width - dialog->width) / 2;
        dialog->y = np->y + (np->height - dialog->height) / 2;

        if(dialog->x < 0) {
            dialog->x = 0;
        }
        if(dialog->y < 0) {
            dialog->y = 0;
        }
        if(dialog->x + dialog->width >= rootWidth) {
            dialog->x = rootWidth - dialog->width - (settings.borderWidth * 2);
        }
        if(dialog->y + dialog->height >= rootHeight) {
            dialog->y = rootHeight - dialog->height
                        - (settings.borderWidth * 2 + settings.titleHeight);
        }

    } else {

        sp = GetMouseScreen();

        dialog->x = (sp->width - dialog->width) / 2 + sp->x;
        dialog->y = (sp->height - dialog->height) / 2 + sp->y;

    }

}
Beispiel #8
0
/** Compute the size of a dialog window. */
void ComputeDimensions(DialogType *dp) {

   const ScreenType *sp;
   int width;
   int x;

   Assert(dp);

   /* Get the min width from the size of the buttons. */
   if(!minWidth) {
      minWidth = GetStringWidth(FONT_MENU, CANCEL_STRING) * 3;
      width = GetStringWidth(FONT_MENU, OK_STRING) * 3;
      if(width > minWidth) {
         minWidth = width;
      }
      minWidth += 16 * 3;
   }
   dp->width = minWidth;

   /* Take into account the size of the message. */
   for(x = 0; x < dp->lineCount; x++) {
      width = GetStringWidth(FONT_MENU, dp->message[x]);
      if(width > dp->width) {
         dp->width = width;
      }
   }
   dp->lineHeight = GetStringHeight(FONT_MENU);
   dp->width += 8;
   dp->height = (dp->lineCount + 2) * dp->lineHeight;

   if(dp->client) {

      dp->x = dp->client->x + (dp->client->width - dp->width) / 2;
      dp->y = dp->client->y + (dp->client->height - dp->height) / 2;

      if(dp->x < 0) {
         dp->x = 0;
      }
      if(dp->y < 0) {
         dp->y = 0;
      }
      if(dp->x + dp->width >= rootWidth) {
         dp->x = rootWidth - dp->width - (borderWidth * 2);
      }
      if(dp->y + dp->height >= rootHeight) {
         dp->y = rootHeight - dp->height - (borderWidth * 2 + titleHeight);
      }

   } else {

      sp = GetMouseScreen();

      dp->x = (sp->width - dp->width) / 2 + sp->x;
      dp->y = (sp->height - dp->height) / 2 + sp->y;

   }

}
Beispiel #9
0
	virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
	{
		if (widget != WID_EM_MESSAGE) return;

		CopyInDParam(0, this->decode_params, lengthof(this->decode_params));
		if (this->textref_stack_size > 0) StartTextRefStackUsage(this->textref_stack_size, this->textref_stack);

		int text_width = max(0, (int)size->width - WD_FRAMETEXT_LEFT - WD_FRAMETEXT_RIGHT);
		this->height_summary  = GetStringHeight(this->summary_msg, text_width);
		this->height_detailed = (this->detailed_msg == INVALID_STRING_ID) ? 0 : GetStringHeight(this->detailed_msg, text_width);

		if (this->textref_stack_size > 0) StopTextRefStackUsage();

		uint panel_height = WD_FRAMERECT_TOP + this->height_summary + WD_FRAMERECT_BOTTOM;
		if (this->detailed_msg != INVALID_STRING_ID) panel_height += this->height_detailed + WD_PAR_VSEP_WIDE;

		size->height = max(size->height, panel_height);
	}
Beispiel #10
0
int	GetStringHeight(char *szString, char* font, int size)
{
	int brect[8];
	char* err;
	gdFontPtr	pFont;

	if(font && strlen(font) != 0 && size > 0)
	{
		err = gdImageStringFT(NULL, brect, 0, font,size,0.,0,0,szString);
		if (err) 
		{
			/* if error occur, use native font */				
			return GetStringHeight(szString, "", size);	
		}
		return brect[3]-brect[5];		
	}
	else
	{		
		/* negative size */
		switch(size) {
			case UF_TINY:
				pFont = gdFontGetTiny();
				break;
			case UF_SMALL:
				pFont = gdFontGetSmall();
				break;
			case UF_MEDIUM:
				pFont = gdFontGetMediumBold();
				break;
			case UF_LARGE:
				pFont = gdFontGetLarge();
				break;
			case UF_GIANT:
				pFont = gdFontGetGiant();
				break;		
			default:
				pFont = gdFontGetMediumBold();
				break;
		}
		/* positive size */
		if(size > 0)
		{
			if(size > 9)
			{
				pFont = gdFontGetGiant();
			}
			else
			{
				pFont = gdFontGetSmall();
			}
		}
		return pFont->h;
	}	
	
}
Beispiel #11
0
/** Start clock(s). */
void StartupClock(void)
{
   ClockType *clk;
   for(clk = clocks; clk; clk = clk->next) {
      if(clk->cp->requestedWidth == 0) {
         clk->cp->requestedWidth = 1;
      }
      if(clk->cp->requestedHeight == 0) {
         clk->cp->requestedHeight = GetStringHeight(FONT_CLOCK) + 4;
      }
   }
}
Beispiel #12
0
	virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
	{
		/* There is only one widget. */
		for (uint i = 0; i != this->paramcount; i++) SetDParam(i, this->params[i]);

		size->width  = min(GetStringBoundingBox(this->string_id).width, 194);
		size->height = GetStringHeight(this->string_id, size->width);

		/* Increase slightly to have some space around the box. */
		size->width  += 2 + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
		size->height += 2 + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
	}
Beispiel #13
0
	virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
	{
		if (widget != CW_PANEL) return;

		uint width = 0;
		for (int i = 0; i != lengthof(_cheats_ui); i++) {
			const CheatEntry *ce = &_cheats_ui[i];
			switch (ce->type) {
				case SLE_BOOL:
					SetDParam(0, STR_CONFIG_SETTING_ON);
					width = max(width, GetStringBoundingBox(ce->str).width);
					SetDParam(0, STR_CONFIG_SETTING_OFF);
					width = max(width, GetStringBoundingBox(ce->str).width);
					break;

				default:
					switch (ce->str) {
						/* Display date for change date cheat */
						case STR_CHEAT_CHANGE_DATE:
							SetDParam(0, ConvertYMDToDate(MAX_YEAR, 11, 31));
							width = max(width, GetStringBoundingBox(ce->str).width);
							break;

						/* Draw coloured flag for change company cheat */
						case STR_CHEAT_CHANGE_COMPANY:
							SetDParam(0, 15);
							width = max(width, GetStringBoundingBox(ce->str).width + 10 + 10);
							break;

						/* Set correct string for switch climate cheat */
						case STR_CHEAT_SWITCH_CLIMATE:
							for (StringID i = STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE; i <= STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE; i++) {
								SetDParam(0, i);
								width = max(width, GetStringBoundingBox(ce->str).width);
							}
							break;

						default:
							SetDParam(0, INT64_MAX);
							width = max(width, GetStringBoundingBox(ce->str).width);
							break;
					}
					break;
			}
		}

		size->width = width + 50 /* stuff on the left */ + 10 /* extra spacing on right */;
		this->header_height = GetStringHeight(STR_CHEATS_WARNING, size->width - WD_FRAMERECT_LEFT - WD_FRAMERECT_RIGHT) + WD_PAR_VSEP_WIDE;
		size->height = this->header_height + WD_FRAMERECT_TOP + WD_PAR_VSEP_NORMAL + WD_FRAMERECT_BOTTOM + (FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL) * lengthof(_cheats_ui);
	}
Beispiel #14
0
/** Draw a clock tray component. */
void DrawClock(ClockType *clk, const TimeType *now)
{

   TrayComponentType *cp;
   const char *timeString;
   int width;
   int rwidth;

   /* Only draw if the time changed. */
   if(now->seconds == clk->lastTime.seconds) {
      return;
   }

   /* Clear the area. */
   cp = clk->cp;
   if(colors[COLOR_CLOCK_BG1] == colors[COLOR_CLOCK_BG2]) {
      JXSetForeground(display, rootGC, colors[COLOR_CLOCK_BG1]);
      JXFillRectangle(display, cp->pixmap, rootGC, 0, 0,
                      cp->width, cp->height);
   } else {
      DrawHorizontalGradient(cp->pixmap, rootGC,
                             colors[COLOR_CLOCK_BG1], colors[COLOR_CLOCK_BG2],
                             0, 0, cp->width, cp->height);
   }

   /* Determine if the clock is the right size. */
   timeString = GetTimeString(clk->format, clk->zone);
   width = GetStringWidth(FONT_CLOCK, timeString);
   rwidth = width + 4;
   if(rwidth == clk->cp->requestedWidth || clk->userWidth) {

      /* Draw the clock. */
      RenderString(cp->pixmap, FONT_CLOCK, COLOR_CLOCK_FG,
                   (cp->width - width) / 2,
                   (cp->height - GetStringHeight(FONT_CLOCK)) / 2,
                   cp->width, timeString);

      UpdateSpecificTray(clk->cp->tray, clk->cp);

   } else {

      /* Wrong size. Resize. */
      clk->cp->requestedWidth = rwidth;
      ResizeTray(clk->cp->tray);

   }

}
Beispiel #15
0
int AvHFont::DrawString(int inX, int inY, const char* inString, int r, int g, int b, int inRenderMode) const
{

    int theX = inX;
    int theY = inY;
        
    int theCharHeight = GetStringHeight();

    AvHSpriteBeginFrame();

    AvHSpriteSetVGUIOffset(0,0);

    AvHSpriteSetRenderMode(inRenderMode);
    AvHSpriteSetColor(r / 256.0f, g / 256.0f, b / 256.0f);

    int charWidth  = mSpriteWidth / 16;
    int charHeight = mSpriteHeight / 16;

    for (int i = 0; inString[i] != 0 && inString[i] != '\n'; ++i)
    {

        unsigned char c = inString[i];

        if (c < 32)
        {
            // Unprintable.
            continue;
        }

        theX += mCharWidth[c].a;
        
        float theU = ((c % kNumCharsPerRow) * charWidth) / float(mSpriteWidth);
        float theV = ((c / kNumCharsPerRow) * charHeight) / float(mSpriteHeight);

        AvHSpriteDraw(mSprite, 0, theX, theY, theX + mCharWidth[c].b, theY + theCharHeight,
            theU, theV, theU + mCharWidth[c].b / 256.0f, theV + theCharHeight / 256.0f);
        
        theX += mCharWidth[c].b + mCharWidth[c].c;

    }
    
    AvHSpriteEndFrame();
    AvHSpriteSetColor(1, 1, 1);

    return theX;

}
Beispiel #16
0
int AvHFont::DrawStringReverse(int inX, int inY, const char* inString, int r, int g, int b, int inRenderMode) const
{

    int length = strlen(inString) - 1;

    int theX = inX;
    int theY = inY;
        
    int theCharHeight = GetStringHeight();

    AvHSpriteBeginFrame();
    AvHSpriteSetRenderMode(inRenderMode);
    AvHSpriteSetColor(r / 256.0f, g / 256.0f, b / 256.0f);

    int charWidth  = mSpriteWidth / 16;
    int charHeight = mSpriteHeight / 16;

    for (int i = length; i >= 0; --i)
    {
        
        char c = inString[i];

        if (c < 32)
        {
            // Unprintable.
            continue;
        }

        theX -= mCharWidth[c].c + mCharWidth[c].b;
        
        float theU = ((c % kNumCharsPerRow) * charWidth) / float(mSpriteWidth);
        float theV = ((c / kNumCharsPerRow) * charHeight) / float(mSpriteHeight);

        AvHSpriteDraw(mSprite, 0, theX, theY, theX + mCharWidth[c].b, theY + theCharHeight,
            theU, theV, theU + mCharWidth[c].b / 256.0f, theV + theCharHeight / 256.0f);

        theX -= mCharWidth[c].a;

    }

    AvHSpriteEndFrame();

    return theX;

}
Beispiel #17
0
/** Set the size of a button tray component. */
void SetSize(TrayComponentType *cp, int width, int height) {

   TrayButtonType *bp;
   int labelWidth, labelHeight;
   int iconWidth, iconHeight;
   int ratio;

   bp = (TrayButtonType*)cp->object;

   if(bp->icon) {

      if(bp->label) {
         labelWidth = GetStringWidth(FONT_TRAYBUTTON, bp->label) + 4;
         labelHeight = GetStringHeight(FONT_TRAYBUTTON);
      } else {
         labelWidth = 0;
         labelHeight = 0;
      }

      iconWidth = bp->icon->image->width;
      iconHeight = bp->icon->image->height;

      /* Fixed point with 16 bit fraction. */
      ratio = (iconWidth << 16) / iconHeight;

      if(width > 0) {

         /* Compute height from width. */
         iconWidth = width - labelWidth - 2 * BUTTON_SIZE;
         iconHeight = (iconWidth << 16) / ratio;
         height = Max(iconHeight, labelHeight) + 2 * BUTTON_SIZE;

      } else if(height > 0) {

         /* Compute width from height. */
         iconHeight = height - 2 * BUTTON_SIZE;
         iconWidth = (iconHeight * ratio) >> 16;
         width = iconWidth + labelWidth + 2 * BUTTON_SIZE;

      }

      cp->width = width;
      cp->height = height;

   }
Beispiel #18
0
	virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
	{
		switch (widget) {
			case WID_SGI_TRANSLATION: {
				SetDParam(0, _current_language->missing);
				int height = GetStringHeight(STR_INTRO_TRANSLATION, size->width);
				if (height > 3 * FONT_HEIGHT_NORMAL) {
					/* Don't let the window become too high. */
					Dimension textdim = GetStringBoundingBox(STR_INTRO_TRANSLATION);
					textdim.height *= 3;
					textdim.width -= textdim.width / 2;
					*size = maxdim(*size, textdim);
				} else {
					size->height = height + padding.height;
				}
				break;
			}
		}
	}
Beispiel #19
0
/** Set the size of a button tray component. */
void SetSize(TrayComponentType *cp, int width, int height)
{

   TrayButtonType *bp;

   bp = (TrayButtonType*)cp->object;

   if(bp->icon) {

      int labelWidth, labelHeight;
      int iconWidth, iconHeight;
      int ratio;

      if(bp->label) {
         labelWidth = GetStringWidth(FONT_TRAY, bp->label) + 6;
         labelHeight = GetStringHeight(FONT_TRAY) + 6;
      } else {
         labelWidth = 4;
         labelHeight = 4;
      }

      iconWidth = bp->icon->images->width;
      iconHeight = bp->icon->images->height;

      /* Fixed point with 16 bit fraction. */
      ratio = (iconWidth << 16) / iconHeight;

      if(width > 0) {

         /* Compute height from width. */
         iconWidth = width - labelWidth;
         iconHeight = (iconWidth << 16) / ratio;
         height = Max(labelHeight, iconHeight + 4);

      } else if(height > 0) {

         /* Compute width from height. */
         iconHeight = height - 4;
         iconWidth = (iconHeight * ratio) >> 16;
         width = iconWidth + labelWidth;

      }
Beispiel #20
0
	virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
	{
		if (widget != WID_LI_BACKGROUND) return;

		size->height = WD_TEXTPANEL_TOP + WD_TEXTPANEL_BOTTOM;
		for (uint i = 0; i < LAND_INFO_CENTERED_LINES; i++) {
			if (StrEmpty(this->landinfo_data[i])) break;

			uint width = GetStringBoundingBox(this->landinfo_data[i]).width + WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT;
			size->width = max(size->width, width);

			size->height += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL;
			if (i == 0) size->height += 4;
		}

		if (!StrEmpty(this->landinfo_data[LAND_INFO_MULTICENTER_LINE])) {
			uint width = GetStringBoundingBox(this->landinfo_data[LAND_INFO_MULTICENTER_LINE]).width + WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT;
			size->width = max(size->width, min(300u, width));
			SetDParamStr(0, this->landinfo_data[LAND_INFO_MULTICENTER_LINE]);
			size->height += GetStringHeight(STR_JUST_RAW_STRING, size->width - WD_FRAMETEXT_LEFT - WD_FRAMETEXT_RIGHT);
		}
	}
Beispiel #21
0
	virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
	{
		/* We cache the button size. This is safe as no reinit can happen here. */
		if (this->button_size.width == 0) {
			this->button_size = maxdim(GetStringBoundingBox(STR_MISSING_GRAPHICS_YES_DOWNLOAD), GetStringBoundingBox(STR_MISSING_GRAPHICS_NO_QUIT));
			this->button_size.width += WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT;
			this->button_size.height += WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM;
		}

		switch (widget) {
			case WID_BAFD_QUESTION:
				/* The question is twice as wide as the buttons, and determine the height based on the width. */
				size->width = this->button_size.width * 2;
				size->height = GetStringHeight(STR_MISSING_GRAPHICS_SET_MESSAGE, size->width - WD_FRAMETEXT_LEFT - WD_FRAMETEXT_RIGHT) + WD_FRAMETEXT_BOTTOM + WD_FRAMETEXT_TOP;
				break;

			case WID_BAFD_YES:
			case WID_BAFD_NO:
				*size = this->button_size;
				break;
		}
	}
Beispiel #22
0
/** Show a popup window. */
void ShowPopup(int x, int y, const char *text,
               const PopupMaskType context)
{

   const ScreenType *sp;

   Assert(text);

   if(!(settings.popupMask & context)) {
      return;
   }

   if(popup.text) {
      if(x == popup.x && y == popup.y && !strcmp(popup.text, text)) {
         // This popup is already shown.
         return;
      }
      Release(popup.text);
      popup.text = NULL;
   }

   if(text[0] == 0) {
      return;
   }

   GetMousePosition(&popup.mx, &popup.my, &popup.mw);
   popup.text = CopyString(text);
   popup.height = GetStringHeight(FONT_POPUP) + 2;
   popup.width = GetStringWidth(FONT_POPUP, popup.text) + 9;

   sp = GetCurrentScreen(x, y);

   if(popup.width > sp->width) {
      popup.width = sp->width;
   }

   popup.x = x;
   if(y + 2 * popup.height + 2 >= sp->height) {
      popup.y = y - popup.height - 2;
   } else {
      popup.y = y + popup.height + 2;
   }

   if(popup.width + popup.x > sp->x + sp->width) {
      popup.x = sp->x + sp->width - popup.width - 2;
   }
   if(popup.height + popup.y > sp->y + sp->height) {
      popup.y = sp->y + sp->height - popup.height - 2;
   }
   if(popup.x < 2) {
      popup.x = 2;
   }
   if(popup.y < 2) {
      popup.y = 2;
   }

   if(popup.window == None) {

      XSetWindowAttributes attr;
      unsigned long attrMask = 0;

      attrMask |= CWEventMask;
      attr.event_mask = ExposureMask
                      | PointerMotionMask | PointerMotionHintMask;

      attrMask |= CWSaveUnder;
      attr.save_under = True;

      attrMask |= CWDontPropagate;
      attr.do_not_propagate_mask = PointerMotionMask
                                 | ButtonPressMask
                                 | ButtonReleaseMask;

      popup.window = JXCreateWindow(display, rootWindow, popup.x, popup.y,
                                    popup.width, popup.height, 0,
                                    CopyFromParent, InputOutput,
                                    CopyFromParent, attrMask, &attr);
      SetAtomAtom(popup.window, ATOM_NET_WM_WINDOW_TYPE,
                  ATOM_NET_WM_WINDOW_TYPE_NOTIFICATION);
      JXMapRaised(display, popup.window);

   } else {

      JXMoveResizeWindow(display, popup.window, popup.x, popup.y,
                         popup.width, popup.height);
      JXFreePixmap(display, popup.pmap);

   }

   popup.pmap = JXCreatePixmap(display, popup.window,
                               popup.width, popup.height,
                               rootDepth);

   JXSetForeground(display, rootGC, colors[COLOR_POPUP_BG]);
   JXFillRectangle(display, popup.pmap, rootGC, 0, 0,
                   popup.width - 1, popup.height - 1);
   JXSetForeground(display, rootGC, colors[COLOR_POPUP_OUTLINE]);
   JXDrawRectangle(display, popup.pmap, rootGC, 0, 0,
                   popup.width - 1, popup.height - 1);
   RenderString(popup.pmap, FONT_POPUP, COLOR_POPUP_FG, 4, 1,
                popup.width, popup.text);
   JXCopyArea(display, popup.pmap, popup.window, rootGC,
              0, 0, popup.width, popup.height, 0, 0);

}
Beispiel #23
0
int Viewer::GetStringYTopLeft(const int row, void *font) {
  return VW_STRING_BORDER_Y + VW_STRING_HEIGHT + (VW_STRING_GAP_Y + GetStringHeight(font)) * row;
}
Beispiel #24
0
/** Draw a button. */
void DrawButton(ButtonNode *bp)
{

   ColorType fg;
   long bg1, bg2;
   long up, down;
   DecorationsType decorations;

   Drawable drawable;
   GC gc;
   int x, y;
   int width, height;
   int xoffset, yoffset;

   int iconWidth, iconHeight;
   int textWidth, textHeight;
   
   Assert(bp);

   char *printableName = bp->text;

   /* Check for E2 80 AA (LEFT-TO-RIGHT-EMBEDDING) character
      in the beginning and trim it (for Midori) */
   if(strncmp(printableName, "\xe2\x80\xaa", 3) == 0) {
     printableName += 3;
   }

   drawable = bp->drawable;
   x = bp->x;
   y = bp->y;
   width = bp->width;
   height = bp->height;
   gc = JXCreateGC(display, drawable, 0, NULL);

   /* Determine the colors to use. */
   switch(bp->type) {
   case BUTTON_LABEL:
      fg = COLOR_MENU_FG;
      bg1 = colors[COLOR_MENU_BG];
      bg2 = colors[COLOR_MENU_BG];
      up = colors[COLOR_MENU_UP];
      down = colors[COLOR_MENU_DOWN];
      decorations = settings.menuDecorations;
      break;
   case BUTTON_MENU_ACTIVE:
      fg = COLOR_MENU_ACTIVE_FG;
      bg1 = colors[COLOR_MENU_ACTIVE_BG1];
      bg2 = colors[COLOR_MENU_ACTIVE_BG2];
      down = colors[COLOR_MENU_ACTIVE_UP];
      up = colors[COLOR_MENU_ACTIVE_DOWN];
      decorations = settings.menuDecorations;
      break;
   case BUTTON_TRAY:
   case BUTTON_TASK:
      fg = COLOR_TRAY_FG;
      bg1 = colors[COLOR_TRAY_BG1];
      bg2 = colors[COLOR_TRAY_BG2];
      up = colors[COLOR_TRAY_UP];
      down = colors[COLOR_TRAY_DOWN];
      decorations = settings.trayDecorations;
      break;
   case BUTTON_TRAY_ACTIVE:
   case BUTTON_TASK_ACTIVE:
      fg = COLOR_TRAY_ACTIVE_FG;
      bg1 = colors[COLOR_TRAY_ACTIVE_BG1];
      bg2 = colors[COLOR_TRAY_ACTIVE_BG2];
      down = colors[COLOR_TRAY_ACTIVE_UP];
      up = colors[COLOR_TRAY_ACTIVE_DOWN];
      decorations = settings.trayDecorations;
      break;
   case BUTTON_MENU:
   default:
      fg = COLOR_MENU_FG;
      bg1 = colors[COLOR_MENU_BG];
      bg2 = colors[COLOR_MENU_BG];
      up = colors[COLOR_MENU_UP];
      down = colors[COLOR_MENU_DOWN];
      decorations = settings.menuDecorations;
      break;
   }

   /* Draw the background. */
   if(bp->fill) {

      /* Draw the button background. */
      JXSetForeground(display, gc, bg1);
      /* single color */
      JXFillRectangle(display, drawable, gc, x, y, width, height);

   }

   /* Draw the border. */
   if(bp->border) {
     JXSetForeground(display, gc, down);
     JXDrawRectangle(display, drawable, gc, x, y, width - 1, height - 1);
   }

   /* Determine the size of the icon (if any) to display. */
   iconWidth = 0;
   iconHeight = 0;
   if(bp->icon) {
      if(bp->icon == &emptyIcon) {
         iconWidth = Min(width/2, height/2);
         iconHeight = iconWidth;
      } else {
         const int ratio = (bp->icon->images->width << 16)
                         / bp->icon->images->height;
         iconHeight = height/2;
         iconWidth = (iconHeight * ratio) >> 16;
         if(iconWidth > width/2) {
            iconWidth = width/2;
            iconHeight = (iconWidth << 16) / ratio;
         }
      }
   }

   /* Determine how much room is left for text. */
   textWidth = 0;
   textHeight = 0;
   if(printableName) {
      textWidth = GetStringWidth(bp->font, printableName);
      textHeight = GetStringHeight(bp->font);
      if(iconWidth > 0 && textWidth + iconWidth + 7 > width) {
         textWidth = width - iconWidth - textHeight*3/2;
      } else if(iconWidth == 0 && textWidth + 5 > width) {
         textWidth = width - 5;
      }
      textWidth = textWidth < 0 ? 0 : textWidth;
   }

   /* Determine the offset of the text in the button. */
   if(bp->alignment == ALIGN_CENTER) {
      xoffset = (width - iconWidth - textWidth + 1) / 2;
      if(xoffset < 0) {
         xoffset = 0;
      }
   } else {
      xoffset = textHeight/2;
   }

   /* Display the icon. */
   if(bp->icon) {
      yoffset = (height - iconHeight + 1) / 2;
      PutIcon(bp->icon, drawable, colors[fg],
              x + xoffset, y + yoffset,
              iconWidth, iconHeight);
      xoffset += iconWidth + textHeight/2;
   }

   /* Display the label. */
   if(textWidth > 0) {
      yoffset = (height - textHeight + 1) / 2;
      RenderString(drawable, bp->font, fg,
                   x + xoffset, y + yoffset,
                   textWidth, printableName);
   }

   JXFreeGC(display, gc);

}
Beispiel #25
0
/** Draw a button. */
void DrawButton(ButtonNode *bp)
{

   ColorType fg;
   long bg1, bg2;
   long up, down;
   DecorationsType decorations;

   Drawable drawable;
   GC gc;
   int x, y;
   int width, height;
   int xoffset, yoffset;

   int iconWidth, iconHeight;
   int textWidth, textHeight;
   
   Assert(bp);

   drawable = bp->drawable;
   x = bp->x;
   y = bp->y;
   width = bp->width;
   height = bp->height;
   gc = JXCreateGC(display, drawable, 0, NULL);

   /* Determine the colors to use. */
   switch(bp->type) {
   case BUTTON_LABEL:
      fg = COLOR_MENU_FG;
      bg1 = colors[COLOR_MENU_BG];
      bg2 = colors[COLOR_MENU_BG];
      up = colors[COLOR_MENU_UP];
      down = colors[COLOR_MENU_DOWN];
      decorations = settings.menuDecorations;
      break;
   case BUTTON_MENU_ACTIVE:
      fg = COLOR_MENU_ACTIVE_FG;
      bg1 = colors[COLOR_MENU_ACTIVE_BG1];
      bg2 = colors[COLOR_MENU_ACTIVE_BG2];
      down = colors[COLOR_MENU_ACTIVE_UP];
      up = colors[COLOR_MENU_ACTIVE_DOWN];
      decorations = settings.menuDecorations;
      break;
   case BUTTON_TRAY:
      fg = COLOR_TRAYBUTTON_FG;
      bg1 = colors[COLOR_TRAYBUTTON_BG1];
      bg2 = colors[COLOR_TRAYBUTTON_BG2];
      up = colors[COLOR_TRAYBUTTON_UP];
      down = colors[COLOR_TRAYBUTTON_DOWN];
      decorations = settings.trayDecorations;
      break;
   case BUTTON_TRAY_ACTIVE:
      fg = COLOR_TRAYBUTTON_ACTIVE_FG;
      bg1 = colors[COLOR_TRAYBUTTON_ACTIVE_BG1];
      bg2 = colors[COLOR_TRAYBUTTON_ACTIVE_BG2];
      down = colors[COLOR_TRAYBUTTON_ACTIVE_UP];
      up = colors[COLOR_TRAYBUTTON_ACTIVE_DOWN];
      decorations = settings.trayDecorations;
      break;
   case BUTTON_TASK:
      fg = COLOR_TASKLIST_FG;
      bg1 = colors[COLOR_TASKLIST_BG1];
      bg2 = colors[COLOR_TASKLIST_BG2];
      up = colors[COLOR_TASKLIST_UP];
      down = colors[COLOR_TASKLIST_DOWN];
      decorations = settings.trayDecorations;
      break;
   case BUTTON_TASK_ACTIVE:
      fg = COLOR_TASKLIST_ACTIVE_FG;
      bg1 = colors[COLOR_TASKLIST_ACTIVE_BG1];
      bg2 = colors[COLOR_TASKLIST_ACTIVE_BG2];
      down = colors[COLOR_TASKLIST_ACTIVE_UP];
      up = colors[COLOR_TASKLIST_ACTIVE_DOWN];
      decorations = settings.trayDecorations;
      break;
   case BUTTON_MENU:
   default:
      fg = COLOR_MENU_FG;
      bg1 = colors[COLOR_MENU_BG];
      bg2 = colors[COLOR_MENU_BG];
      up = colors[COLOR_MENU_UP];
      down = colors[COLOR_MENU_DOWN];
      decorations = settings.menuDecorations;
      break;
   }

   /* Draw the background. */
   if(bp->fill) {

      /* Draw the button background. */
      JXSetForeground(display, gc, bg1);
      if(bg1 == bg2) {
         /* single color */
         JXFillRectangle(display, drawable, gc, x, y, width, height);
      } else {
         /* gradient */
         DrawHorizontalGradient(drawable, gc, bg1, bg2,
                                x, y, width, height);
      }

   }

   /* Draw the border. */
   if(bp->border) {
      if(decorations == DECO_MOTIF) {
         JXSetForeground(display, gc, up);
         JXDrawLine(display, drawable, gc, x, y, x + width - 1, y);
         JXDrawLine(display, drawable, gc, x, y, x, y + height - 1);
         JXSetForeground(display, gc, down);
         JXDrawLine(display, drawable, gc, x, y + height - 1,
                    x + width - 1, y + height - 1);
         JXDrawLine(display, drawable, gc, x + width - 1, y,
                    x + width - 1, y + height - 1);
      } else {
         JXSetForeground(display, gc, down);
         JXDrawRectangle(display, drawable, gc, x, y, width - 1, height - 1);
      }
   }

   /* Determine the size of the icon (if any) to display. */
   iconWidth = 0;
   iconHeight = 0;
   if(bp->icon) {
      if(bp->icon == &emptyIcon) {
         iconWidth = Min(width - 4, height - 4);
         iconHeight = iconWidth;
      } else {
         const int ratio = (bp->icon->width << 16) / bp->icon->height;
         iconHeight = height - 4;
         iconWidth = (iconHeight * ratio) >> 16;
         if(iconWidth > width - 4) {
            iconWidth = width - 4;
            iconHeight = (iconWidth << 16) / ratio;
         }
      }
   }

   /* Determine how much room is left for text. */
   textWidth = 0;
   textHeight = 0;
   if(bp->text && (width > height || !bp->icon)) {
      textWidth = GetStringWidth(bp->font, bp->text);
      textHeight = GetStringHeight(bp->font);
      if(iconWidth > 0 && textWidth + iconWidth + 7 > width) {
         textWidth = width - iconWidth - 7;
      } else if(iconWidth == 0 && textWidth + 5 > width) {
         textWidth = width - 5;
      }
      textWidth = textWidth < 0 ? 0 : textWidth;
   }

   /* Determine the offset of the text in the button. */
   if(bp->alignment == ALIGN_CENTER || width <= height) {
      xoffset = (width - iconWidth - textWidth + 1) / 2;
      if(xoffset < 0) {
         xoffset = 0;
      }
   } else {
      xoffset = 2;
   }

   /* Display the icon. */
   if(bp->icon) {
      yoffset = (height - iconHeight + 1) / 2;
      PutIcon(bp->icon, drawable, colors[fg],
              x + xoffset, y + yoffset,
              iconWidth, iconHeight);
      xoffset += iconWidth + 2;
   }

   /* Display the label. */
   if(textWidth > 0) {
      yoffset = (height - textHeight + 1) / 2;
      RenderString(drawable, bp->font, fg,
                   x + xoffset, y + yoffset,
                   textWidth, bp->text);
   }

   JXFreeGC(display, gc);

}
Beispiel #26
0
/** Display a string. */
void RenderString(Drawable d, FontType font, ColorType color,
                  int x, int y, int width, const char *str)
{

#ifdef USE_ICONV
   static char isUTF8 = -1;
#endif
   XRectangle rect;
   Region renderRegion;
   int len;
   char *output;
#ifdef USE_FRIBIDI
   FriBidiChar *temp_i;
   FriBidiChar *temp_o;
   FriBidiParType type = FRIBIDI_PAR_ON;
   int unicodeLength;
#endif
#ifdef USE_XFT
   XGlyphInfo extents;
#endif
   char *utf8String;

   /* Early return for empty strings. */
   if(!str || !str[0]) {
      return;
   }

   /* Convert to UTF-8 if necessary. */
   utf8String = GetUTF8String(str);

   /* Get the length of the UTF-8 string. */
   len = strlen(utf8String);

   /* Apply the bidi algorithm if requested. */
#ifdef USE_FRIBIDI
   temp_i = AllocateStack((len + 1) * sizeof(FriBidiChar));
   temp_o = AllocateStack((len + 1) * sizeof(FriBidiChar));
   unicodeLength = fribidi_charset_to_unicode(FRIBIDI_CHAR_SET_UTF8,
                                              utf8String, len, temp_i);
   fribidi_log2vis(temp_i, unicodeLength, &type, temp_o, NULL, NULL, NULL);
   output = AllocateStack(4 * len + 1);
   fribidi_unicode_to_charset(FRIBIDI_CHAR_SET_UTF8, temp_o, unicodeLength,
                              (char*)output);
   len = strlen(output);
#else
   output = utf8String;
#endif

   /* Get the bounds for the string based on the specified width. */
   rect.x = x;
   rect.y = y;
   rect.height = GetStringHeight(font);
#ifdef USE_XFT
   JXftTextExtentsUtf8(display, fonts[font], (const unsigned char*)output,
                       len, &extents);
   rect.width = extents.xOff;
#else
   rect.width = XTextWidth(fonts[font], output, len);
#endif
   rect.width = Min(rect.width, width) + 2;

   /* Combine the width bounds with the region to use. */
   renderRegion = XCreateRegion();
   XUnionRectWithRegion(&rect, renderRegion, renderRegion);

   /* Display the string. */
#ifdef USE_XFT
   JXftDrawChange(xd, d);
   JXftDrawSetClip(xd, renderRegion);
   JXftDrawStringUtf8(xd, GetXftColor(color), fonts[font],
                      x, y + fonts[font]->ascent,
                      (const unsigned char*)output, len);
   JXftDrawChange(xd, rootWindow);
#else
   JXSetForeground(display, fontGC, colors[color]);
   JXSetRegion(display, fontGC, renderRegion);
   JXSetFont(display, fontGC, fonts[font]->fid);
   JXDrawString(display, d, fontGC, x, y + fonts[font]->ascent, output, len);
#endif

   /* Free any memory used for UTF conversion. */
#ifdef USE_FRIBIDI
   ReleaseStack(temp_i);
   ReleaseStack(temp_o);
   ReleaseStack(output);
#endif
   ReleaseUTF8String(utf8String);

   XDestroyRegion(renderRegion);

}
Beispiel #27
0
/** Draw a button. */
void DrawButton(ButtonNode *bp) {

   long outlinePixel;
   long topPixel, bottomPixel;
   ColorType fg;
   long bg1, bg2;

   Drawable drawable;
   GC gc;
   int x, y;
   int width, height;
   int xoffset, yoffset;

   int iconWidth, iconHeight;
   int textWidth, textHeight;
   
   Assert(bp);

   drawable = bp->drawable;
   gc = bp->gc;
   x = bp->x;
   y = bp->y;
   width = bp->width;
   height = bp->height;

   /* Determine the colors to use. */
   switch(bp->type) {
   case BUTTON_LABEL:
      fg = COLOR_MENU_FG;
      bg1 = colors[COLOR_MENU_BG];
      bg2 = colors[COLOR_MENU_BG];
      outlinePixel = colors[COLOR_MENU_BG];
      topPixel = colors[COLOR_MENU_BG];
      bottomPixel = colors[COLOR_MENU_BG];
      break;
   case BUTTON_MENU_ACTIVE:
      fg = COLOR_MENU_ACTIVE_FG;
      bg1 = colors[COLOR_MENU_ACTIVE_BG1];
      bg2 = colors[COLOR_MENU_ACTIVE_BG2];
      if(bg1 == bg2) {
         outlinePixel = colors[COLOR_MENU_ACTIVE_OL];
      } else {
         outlinePixel = colors[COLOR_MENU_ACTIVE_DOWN];
      }
      topPixel = colors[COLOR_MENU_ACTIVE_UP];
      bottomPixel = colors[COLOR_MENU_ACTIVE_DOWN];
      break;
   case BUTTON_TASK:
      fg = COLOR_TASK_FG;
      bg1 = colors[COLOR_TASK_BG1];
      bg2 = colors[COLOR_TASK_BG2];
      topPixel = colors[COLOR_TASK_UP];
      bottomPixel = colors[COLOR_TASK_DOWN];
      outlinePixel = bottomPixel;
      break;
   case BUTTON_TASK_ACTIVE:
      fg = COLOR_TASK_ACTIVE_FG;
      bg1 = colors[COLOR_TASK_ACTIVE_BG1];
      bg2 = colors[COLOR_TASK_ACTIVE_BG2];
      topPixel = colors[COLOR_TASK_ACTIVE_DOWN];
      bottomPixel = colors[COLOR_TASK_ACTIVE_UP];
      outlinePixel = bottomPixel;
      break;
   case BUTTON_MENU:
   default:
      fg = COLOR_MENU_FG;
      bg1 = colors[COLOR_MENU_BG];
      bg2 = colors[COLOR_MENU_BG];
      outlinePixel = colors[COLOR_MENU_DOWN];
      topPixel = colors[COLOR_MENU_UP];
      bottomPixel = colors[COLOR_MENU_DOWN];
      break;
   }

   /* Draw the background. */
   switch(bp->type) {
   case BUTTON_TASK:
      /* Flat taskbuttons (only icon) for widths < 48 */
      if(width < 48) {
         break;
      }
      /* conditional fallthrough is intended */  
   default:

      /* Draw the button background. */
      JXSetForeground(display, gc, bg1);
      if(bg1 == bg2) {
         /* single color */
         JXFillRectangle(display, drawable, gc,
            x + 1, y + 1, width - 1, height - 1);
      } else {
         /* gradient */
         DrawHorizontalGradient(drawable, gc, bg1, bg2,
            x + 1, y + 1, width - 2, height - 1);
      }

      /* Draw the outline. */
      JXSetForeground(display, gc, outlinePixel);
#ifdef USE_XMU
      XmuDrawRoundedRectangle(display, drawable, gc, x, y, 
         width, height, 3, 3);
#else
      JXDrawRectangle(display, drawable, gc, x, y, width, height);
#endif

      break;
   }

   /* Determine the size of the icon (if any) to display. */
   iconWidth = 0;
   iconHeight = 0;
   if (bp->icon) {
      if(width < height) {
         GetScaledIconSize(bp->icon, width - 5, &iconWidth, &iconHeight);
      } else {
         GetScaledIconSize(bp->icon, height - 5, &iconWidth, &iconHeight);
      }
   }

   /* Determine how much room is left for text. */
   textWidth = 0;
   textHeight = 0;
   if(bp->text) {
      textWidth = GetStringWidth(bp->font, bp->text);
      textHeight = GetStringHeight(bp->font);
      if(textWidth + iconWidth + 8 > width) {
         textWidth = width - iconWidth - 8;
         if(textWidth < 0) {
            textWidth = 0;
         }
      }
   }

   /* Determine the offset of the text in the button. */
   switch(bp->alignment) {
   case ALIGN_CENTER:
      xoffset = width / 2 - (iconWidth + textWidth) / 2;
      if(xoffset < 0) {
         xoffset = 0;
      }
      break;
   case ALIGN_LEFT:
   default:
      xoffset = 3;
      break;
   }

   /* Display the icon. */
   if(bp->icon) {
      yoffset = height / 2 - iconHeight / 2;
      PutIcon(bp->icon, drawable, x + xoffset, y + yoffset,
         iconWidth, iconHeight);
      xoffset += iconWidth + 2;
   }

   /* Display the label. */
   if(bp->text && textWidth) {
      yoffset = height / 2 - textHeight / 2;
      RenderString(drawable, bp->font, fg, x + xoffset, y + yoffset,
         textWidth, NULL, bp->text);
   }

}