merged bitmap buttons
@@ -145,4 +145,4 @@ an alternate menu. The default menu used is
~/.openbox/menu. If the default, or the file you specify does not exist, the global menu is tried. And if the global menu also does not exist, a - simple, internal menu is used instead.+ simple, internal menu is used instead.
@@ -339,6 +339,31 @@ delete resource.mstyle.f_font;
if (resource.tstyle.font) delete resource.tstyle.font; + if (resource.wstyle.close_button.mask != None) + XFreePixmap(blackbox->getXDisplay(), resource.wstyle.close_button.mask); + if (resource.wstyle.max_button.mask != None) + XFreePixmap(blackbox->getXDisplay(), resource.wstyle.max_button.mask); + if (resource.wstyle.icon_button.mask != None) + XFreePixmap(blackbox->getXDisplay(), resource.wstyle.icon_button.mask); + if (resource.wstyle.stick_button.mask != None) + XFreePixmap(blackbox->getXDisplay(), resource.wstyle.stick_button.mask); + + if (resource.tstyle.left_button.mask != None) + XFreePixmap(blackbox->getXDisplay(), resource.tstyle.left_button.mask); + if (resource.tstyle.right_button.mask != None) + XFreePixmap(blackbox->getXDisplay(), resource.tstyle.right_button.mask); + + if (resource.mstyle.bullet_image.mask != None) + XFreePixmap(blackbox->getXDisplay(), resource.mstyle.bullet_image.mask); + if (resource.mstyle.tick_image.mask != None) + XFreePixmap(blackbox->getXDisplay(), resource.mstyle.tick_image.mask); + + resource.wstyle.max_button.mask = resource.wstyle.close_button.mask = + resource.wstyle.icon_button.mask = + resource.wstyle.stick_button.mask = None; + resource.tstyle.left_button.mask = resource.tstyle.right_button.mask = None; + resource.mstyle.bullet_image.mask = resource.mstyle.tick_image.mask = None; + XFreeGC(blackbox->getXDisplay(), opGC); }@@ -1037,6 +1062,28 @@ readDatabaseTexture("window.button.unfocus", "black", style);
resource.wstyle.b_pressed = readDatabaseTexture("window.button.pressed", "black", style); + if (resource.wstyle.close_button.mask != None) + XFreePixmap(blackbox->getXDisplay(), resource.wstyle.close_button.mask); + if (resource.wstyle.max_button.mask != None) + XFreePixmap(blackbox->getXDisplay(), resource.wstyle.max_button.mask); + if (resource.wstyle.icon_button.mask != None) + XFreePixmap(blackbox->getXDisplay(), resource.wstyle.icon_button.mask); + if (resource.wstyle.stick_button.mask != None) + XFreePixmap(blackbox->getXDisplay(), resource.wstyle.stick_button.mask); + + resource.wstyle.close_button.mask = resource.wstyle.max_button.mask = + resource.wstyle.icon_button.mask = + resource.wstyle.icon_button.mask = None; + + readDatabaseMask("window.button.close_mask", resource.wstyle.close_button, + style); + readDatabaseMask("window.button.max_mask", resource.wstyle.max_button, + style); + readDatabaseMask("window.button.icon_mask", resource.wstyle.icon_button, + style); + readDatabaseMask("window.button.stick_mask", resource.wstyle.stick_button, + style); + // we create the window.frame texture by hand because it exists only to // make the code cleaner and is not actually used for display BColor color = readDatabaseColor("window.frame.focusColor", "white", style);@@ -1076,7 +1123,12 @@ resource.wstyle.h_focus = resource.wstyle.f_focus;
if (resource.wstyle.h_unfocus.texture() == BTexture::Parent_Relative) resource.wstyle.h_unfocus = resource.wstyle.f_unfocus; -// load toolbar config + // load toolbar config + if (resource.tstyle.left_button.mask != None) + XFreePixmap(blackbox->getXDisplay(), resource.tstyle.left_button.mask); + if (resource.tstyle.right_button.mask != None) + XFreePixmap(blackbox->getXDisplay(), resource.tstyle.right_button.mask); + resource.tstyle.toolbar = readDatabaseTexture("toolbar", "black", style); resource.tstyle.label =@@ -1097,7 +1149,11 @@ resource.tstyle.c_text =
readDatabaseColor("toolbar.clock.textColor", "white", style); resource.tstyle.b_pic = readDatabaseColor("toolbar.button.picColor", "black", style); - + readDatabaseMask("toolbar.button.left_mask", resource.tstyle.left_button, + style); + readDatabaseMask("toolbar.button.right_mask", resource.tstyle.right_button, + style); + resource.tstyle.justify = LeftJustify; if (style.getValue("toolbar.justify", s)) { if (s == "right" || s == "Right")@@ -1115,6 +1171,11 @@ getScreenNumber()));
} // load menu config + if (resource.mstyle.bullet_image.mask != None) + XFreePixmap(blackbox->getXDisplay(), resource.mstyle.bullet_image.mask); + if (resource.mstyle.tick_image.mask != None) + XFreePixmap(blackbox->getXDisplay(), resource.mstyle.tick_image.mask); + resource.mstyle.title = readDatabaseTexture("menu.title", "white", style); resource.mstyle.frame =@@ -1129,7 +1190,9 @@ resource.mstyle.d_text =
readDatabaseColor("menu.frame.disableColor", "black", style); resource.mstyle.h_text = readDatabaseColor("menu.hilite.textColor", "black", style); - + readDatabaseMask("menu.bullet.mask", resource.mstyle.bullet_image, style); + readDatabaseMask("menu.selected.mask", resource.mstyle.tick_image, style); + resource.mstyle.t_justify = LeftJustify; if (style.getValue("menu.title.justify", s)) { if (s == "right" || s == "Right")@@ -2566,6 +2629,32 @@ std::for_each(windowList.begin(), windowList.end(),
std::mem_fun(&BlackboxWindow::grabButtons)); } +void BScreen::readDatabaseMask(const string &rname, PixmapMask &pixmapMask, + const Configuration &style) { + string s; + int hx, hy; //ignored + int ret = BitmapOpenFailed; //default to failure. + + if (style.getValue(rname, s)) + { + if (s[0] != '/' && s[0] != '~') + { + std::string xbmFile = std::string("~/.openbox/buttons/") + s; + ret = XReadBitmapFile(blackbox->getXDisplay(), getRootWindow(), + expandTilde(xbmFile).c_str(), &pixmapMask.w, + &pixmapMask.h, &pixmapMask.mask, &hx, &hy); + } else + ret = XReadBitmapFile(blackbox->getXDisplay(), getRootWindow(), + expandTilde(s).c_str(), &pixmapMask.w, + &pixmapMask.h, &pixmapMask.mask, &hx, &hy); + + if (ret == BitmapSuccess) + return; + } + + pixmapMask.mask = None; + pixmapMask.w = pixmapMask.h = 0; +} BTexture BScreen::readDatabaseTexture(const string &rname, const string &default_color,
@@ -61,12 +61,19 @@ struct Strut;
enum TextJustify { LeftJustify = 1, RightJustify, CenterJustify }; +struct PixmapMask { + Pixmap mask; + unsigned int w, h; +}; + struct WindowStyle { BColor l_text_focus, l_text_unfocus, b_pic_focus, b_pic_unfocus; BTexture f_focus, f_unfocus, t_focus, t_unfocus, l_focus, l_unfocus, h_focus, h_unfocus, b_focus, b_unfocus, b_pressed, g_focus, g_unfocus; + PixmapMask close_button, max_button, icon_button, stick_button; + BFont *font; TextJustify justify;@@ -79,6 +86,8 @@ struct ToolbarStyle {
BColor l_text, w_text, c_text, b_pic; BTexture toolbar, label, window, button, pressed, clock; + PixmapMask left_button, right_button; //these should probably be the same + BFont *font; TextJustify justify;@@ -91,6 +100,8 @@ struct MenuStyle {
BColor t_text, f_text, h_text, d_text; BTexture title, frame, hilite; + PixmapMask bullet_image, tick_image; + BFont *t_font, *f_font; TextJustify t_justify, f_justify;@@ -180,6 +191,9 @@ BScreen& operator=(const BScreen&);
bool parseMenuFile(FILE *file, Rootmenu *menu); + void readDatabaseMask(const string &rname, + PixmapMask &pixmapMask, + const Configuration &style); BTexture readDatabaseTexture(const std::string &rname, const std::string &default_color, const Configuration &style);
@@ -623,28 +623,67 @@ }
void Toolbar::drawArrow(Drawable surface, bool left) const { + ToolbarStyle *style = screen->getToolbarStyle(); + + BPen pen(style->b_pic); + int hh = frame.button_w / 2, hw = frame.button_w / 2; XPoint pts[3]; const int bullet_size = 3; + if (left) { - pts[0].x = hw - bullet_size; - pts[0].y = hh; - pts[1].x = 2 * bullet_size; - pts[1].y = bullet_size; - pts[2].x = 0; - pts[2].y = -(2 * bullet_size); + if (style->left_button.mask == None) { + pts[0].x = hw - bullet_size; + pts[0].y = hh; + pts[1].x = 2 * bullet_size; + pts[1].y = bullet_size; + pts[2].x = 0; + pts[2].y = -(2 * bullet_size); + XFillPolygon(display, surface, pen.gc(), pts, 3, Convex, + CoordModePrevious); + } else { + XSetClipMask(blackbox->getXDisplay(), pen.gc(), style->left_button.mask); + XSetClipOrigin(blackbox->getXDisplay(), pen.gc(), + (frame.button_w - style->left_button.w)/2, + (frame.button_w - style->left_button.h)/2); + + XFillRectangle(blackbox->getXDisplay(), surface, pen.gc(), + (frame.button_w - style->left_button.w)/2, + (frame.button_w - style->left_button.h)/2, + (frame.button_w + style->left_button.w)/2, + (frame.button_w + style->left_button.h)/2); + + XSetClipMask(blackbox->getXDisplay(), pen.gc(), None); + XSetClipOrigin(blackbox->getXDisplay(), pen.gc(), 0, 0); + } } else { - pts[0].x = hw - bullet_size; - pts[0].y = hh - bullet_size; - pts[1].x = (2 * bullet_size); - pts[1].y = bullet_size; - pts[2].x = -(2 * bullet_size); - pts[2].y = bullet_size; + if (style->right_button.mask == None) { + pts[0].x = hw - bullet_size; + pts[0].y = hh - bullet_size; + pts[1].x = (2 * bullet_size); + pts[1].y = bullet_size; + pts[2].x = -(2 * bullet_size); + pts[2].y = bullet_size; + XFillPolygon(display, surface, pen.gc(), pts, 3, Convex, + CoordModePrevious); + } else { + XSetClipMask(blackbox->getXDisplay(), pen.gc(), + style->right_button.mask); + XSetClipOrigin(blackbox->getXDisplay(), pen.gc(), + (frame.button_w - style->right_button.w)/2, + (frame.button_w - style->right_button.h)/2); + + XFillRectangle(blackbox->getXDisplay(), surface, pen.gc(), + (frame.button_w - style->right_button.w)/2, + (frame.button_w - style->right_button.h)/2, + (frame.button_w + style->right_button.w)/2, + (frame.button_w + style->right_button.h)/2); + + XSetClipMask(blackbox->getXDisplay(), pen.gc(), None); + XSetClipOrigin(blackbox->getXDisplay(), pen.gc(), 0, 0); + } } - - BPen pen(screen->getToolbarStyle()->b_pic); - XFillPolygon(display, surface, pen.gc(), pts, 3, Convex, CoordModePrevious); }
@@ -728,7 +728,7 @@ destroyMaximizeButton();
if (frame.stick_button) destroyStickyButton(); - + if (frame.ftitle) screen->getImageControl()->removeImage(frame.ftitle);@@ -2614,12 +2614,29 @@ else
XSetWindowBackground(blackbox->getXDisplay(), frame.iconify_button, frame.pbutton_pixel); } + XClearWindow(blackbox->getXDisplay(), frame.iconify_button); + BPen pen((flags.focused) ? screen->getWindowStyle()->b_pic_focus : + screen->getWindowStyle()->b_pic_unfocus); + + PixmapMask pm = screen->getWindowStyle()->icon_button; + + if (screen->getWindowStyle()->icon_button.mask != None) { + XSetClipMask(blackbox->getXDisplay(), pen.gc(), pm.mask); + XSetClipOrigin(blackbox->getXDisplay(), pen.gc(), + (frame.button_w - pm.w)/2, (frame.button_w - pm.h)/2); - BPen pen((flags.focused) ? screen->getWindowStyle()->b_pic_focus : - screen->getWindowStyle()->b_pic_unfocus); - XDrawRectangle(blackbox->getXDisplay(), frame.iconify_button, pen.gc(), - 2, (frame.button_w - 5), (frame.button_w - 5), 2); + XFillRectangle(blackbox->getXDisplay(), frame.iconify_button, pen.gc(), + (frame.button_w - pm.w)/2, (frame.button_w - pm.h)/2, + (frame.button_w + pm.w)/2, (frame.button_w + pm.h)/2); + + XSetClipMask(blackbox->getXDisplay(), pen.gc(), None); + XSetClipOrigin(blackbox->getXDisplay(), pen.gc(), 0, 0); + } else { + + XDrawRectangle(blackbox->getXDisplay(), frame.iconify_button, pen.gc(), + 2, (frame.button_w - 5), (frame.button_w - 5), 2); + } }@@ -2652,10 +2669,26 @@ XClearWindow(blackbox->getXDisplay(), frame.maximize_button);
BPen pen((flags.focused) ? screen->getWindowStyle()->b_pic_focus : screen->getWindowStyle()->b_pic_unfocus); - XDrawRectangle(blackbox->getXDisplay(), frame.maximize_button, pen.gc(), - 2, 2, (frame.button_w - 5), (frame.button_w - 5)); - XDrawLine(blackbox->getXDisplay(), frame.maximize_button, pen.gc(), - 2, 3, (frame.button_w - 3), 3); + + PixmapMask pm = screen->getWindowStyle()->max_button; + + if (pm.mask != None) { + XSetClipMask(blackbox->getXDisplay(), pen.gc(), pm.mask); + XSetClipOrigin(blackbox->getXDisplay(), pen.gc(), + (frame.button_w - pm.w)/2, (frame.button_w - pm.h)/2); + + XFillRectangle(blackbox->getXDisplay(), frame.maximize_button, pen.gc(), + (frame.button_w - pm.w)/2, (frame.button_w - pm.h)/2, + (frame.button_w + pm.w)/2, (frame.button_w + pm.h)/2); + + XSetClipOrigin(blackbox->getXDisplay(), pen.gc(), 0, 0 ); + XSetClipMask( blackbox->getXDisplay(), pen.gc(), None ); + } else { + XDrawRectangle(blackbox->getXDisplay(), frame.maximize_button, pen.gc(), + 2, 2, (frame.button_w - 5), (frame.button_w - 5)); + XDrawLine(blackbox->getXDisplay(), frame.maximize_button, pen.gc(), + 2, 3, (frame.button_w - 3), 3); + } }@@ -2663,8 +2696,8 @@ void BlackboxWindow::redrawCloseButton(bool pressed) const {
if (! pressed) { if (flags.focused) { if (frame.fbutton) - XSetWindowBackgroundPixmap(blackbox->getXDisplay(), frame.close_button, - frame.fbutton); + XSetWindowBackgroundPixmap(blackbox->getXDisplay(), + frame.close_button, frame.fbutton); else XSetWindowBackground(blackbox->getXDisplay(), frame.close_button, frame.fbutton_pixel);@@ -2724,9 +2757,25 @@ XClearWindow(blackbox->getXDisplay(), frame.stick_button);
BPen pen((flags.focused) ? screen->getWindowStyle()->b_pic_focus : screen->getWindowStyle()->b_pic_unfocus); + + PixmapMask pm = screen->getWindowStyle()->stick_button; + + if (pm.mask != None) { + XSetClipMask(blackbox->getXDisplay(), pen.gc(), pm.mask); + XSetClipOrigin(blackbox->getXDisplay(), pen.gc(), + (frame.button_w - pm.w)/2, (frame.button_w - pm.h)/2); + + XFillRectangle(blackbox->getXDisplay(), frame.stick_button, pen.gc(), + (frame.button_w - pm.w)/2, (frame.button_w - pm.h)/2, + (frame.button_w + pm.w)/2, (frame.button_w + pm.h)/2); + - XFillRectangle(blackbox->getXDisplay(), frame.stick_button, pen.gc(), - frame.button_w/2 - 1, frame.button_w/2 -1, 2, 2 ); + XSetClipOrigin(blackbox->getXDisplay(), pen.gc(), 0, 0 ); + XSetClipMask( blackbox->getXDisplay(), pen.gc(), None ); + } else { + XFillRectangle(blackbox->getXDisplay(), frame.stick_button, pen.gc(), + frame.button_w/2 - 1, frame.button_w/2 -1, 2, 2 ); + } } void BlackboxWindow::mapRequestEvent(const XMapRequestEvent *re) {