/** Draw a specific tray. */ void DrawSpecificTray(const TrayType *tp) { TrayComponentType *cp; for(cp = tp->components; cp; cp = cp->next) { UpdateSpecificTray(tp, cp); } if(settings.trayDecorations == DECO_MOTIF) { JXSetForeground(display, rootGC, colors[COLOR_TRAY_UP]); JXDrawLine(display, tp->window, rootGC, 0, 0, tp->width - 1, 0); JXDrawLine(display, tp->window, rootGC, 0, tp->height - 1, 0, 0); JXSetForeground(display, rootGC, colors[COLOR_TRAY_DOWN]); JXDrawLine(display, tp->window, rootGC, 0, tp->height - 1, tp->width - 1, tp->height - 1); JXDrawLine(display, tp->window, rootGC, tp->width - 1, 0, tp->width - 1, tp->height - 1); } else { JXSetForeground(display, rootGC, colors[COLOR_TRAY_DOWN]); JXDrawRectangle(display, tp->window, rootGC, 0, 0, tp->width - 1, tp->height - 1); } }
/** Draw a specific tray. */ void DrawSpecificTray(const TrayType *tp) { TrayComponentType *cp; int x; Assert(tp); /* Draw components. */ for(cp = tp->components; cp; cp = cp->next) { UpdateSpecificTray(tp, cp); } /* Draw the border. */ for(x = 0; x < tp->border; x++) { /* Top */ JXSetForeground(display, rootGC, colors[COLOR_TRAY_UP]); JXDrawLine(display, tp->window, rootGC, 0, x, tp->width - x - 1, x); /* Bottom */ JXSetForeground(display, rootGC, colors[COLOR_TRAY_DOWN]); JXDrawLine(display, tp->window, rootGC, x + 1, tp->height - x - 1, tp->width - x - 2, tp->height - x - 1); /* Left */ JXSetForeground(display, rootGC, colors[COLOR_TRAY_UP]); JXDrawLine(display, tp->window, rootGC, x, x, x, tp->height - x - 1); /* Right */ JXSetForeground(display, rootGC, colors[COLOR_TRAY_DOWN]); JXDrawLine(display, tp->window, rootGC, tp->width - x - 1, x + 1, tp->width - x - 1, tp->height - x - 1); } }
/** Draw a horizontal gradient. */ void DrawHorizontalGradient(Drawable d, GC g, long fromColor, long toColor, int x, int y, unsigned int width, unsigned int height) { const int shift = 15; unsigned int line; XColor colors[2]; int red, green, blue; int ared, agreen, ablue; int bred, bgreen, bblue; int redStep, greenStep, blueStep; /* Return if there's nothing to do. */ if(width == 0 || height == 0) { return; } /* Here we assume that the background was filled elsewhere. */ if(fromColor == toColor) { return; } /* Query the from/to colors. */ colors[0].pixel = fromColor; colors[1].pixel = toColor; JXQueryColors(display, rootColormap, colors, 2); /* Set the "from" color. */ ared = (unsigned int)colors[0].red << shift; agreen = (unsigned int)colors[0].green << shift; ablue = (unsigned int)colors[0].blue << shift; /* Set the "to" color. */ bred = (unsigned int)colors[1].red << shift; bgreen = (unsigned int)colors[1].green << shift; bblue = (unsigned int)colors[1].blue << shift; /* Determine the step. */ redStep = (bred - ared) / (int)height; greenStep = (bgreen - agreen) / (int)height; blueStep = (bblue - ablue) / (int)height; /* Loop over each line. */ red = ared; blue = ablue; green = agreen; for(line = 0; line < height; line++) { /* Determine the color for this line. */ colors[0].red = (unsigned short)(red >> shift); colors[0].green = (unsigned short)(green >> shift); colors[0].blue = (unsigned short)(blue >> shift); GetColor(&colors[0]); /* Draw the line. */ JXSetForeground(display, g, colors[0].pixel); JXDrawLine(display, d, g, x, y + line, x + width - 1, y + line); red += redStep; green += greenStep; blue += blueStep; } }
/** 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); }