X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2FBasemenu.cc;h=322576c598d70270d135a53dea4a5107456b80f4;hb=5b8ec886237aff9ede99feb66721f8ac7a44d2ed;hp=57c10fcb65223defa2e2615fc55418b538247e95;hpb=90239e2bfa0fe28fa55b3c31a6c18ca7939291f7;p=chaz%2Fopenbox diff --git a/src/Basemenu.cc b/src/Basemenu.cc index 57c10fcb..322576c5 100644 --- a/src/Basemenu.cc +++ b/src/Basemenu.cc @@ -84,20 +84,20 @@ Basemenu::Basemenu(BScreen *scrn) { which_press = which_sbl = -1; + menu.sublevels = + menu.persub = + menu.minsub = 0; + menu.frame_pixmap = menu.title_pixmap = menu.hilite_pixmap = None; menu.bevel_w = screen->getBevelWidth(); - MenuStyle *style = screen->getMenuStyle(); + const MenuStyle* const style = screen->getMenuStyle(); menu.width = menu.title_h = menu.item_w = menu.frame_h = style->t_font->height() + (menu.bevel_w * 2); - menu.sublevels = - menu.persub = - menu.minsub = 0; - menu.item_h = style->f_font->height() + menu.bevel_w; menu.height = menu.title_h + screen->getBorderWidth() + menu.frame_h; @@ -142,26 +142,25 @@ Basemenu::Basemenu(BScreen *scrn) { // completely created. items must be inserted and it must be update()'d } + Basemenu::~Basemenu(void) { XUnmapWindow(display, menu.window); if (shown && shown->getWindowID() == getWindowID()) shown = (Basemenu *) 0; - MenuItems::const_iterator it = menuitems.begin(); - while (it != menuitems.end()) { - BasemenuItem *item = *it; - if ((! internal_menu)) { - Basemenu *tmp = (Basemenu *) item->submenu(); + MenuItems::const_iterator it = menuitems.begin(), + end = menuitems.end(); + for (; it != end; ++it) { + if (! internal_menu) { + Basemenu *tmp = (*it)->submenu(); if (tmp) { - if (! tmp->internal_menu) { + if (! tmp->internal_menu) delete tmp; - } else { + else tmp->internal_hide(); - } } } - ++it; } std::for_each(menuitems.begin(), menuitems.end(), PointerAssassin()); @@ -224,14 +223,13 @@ int Basemenu::remove(int index) { BasemenuItem *item = find(index); if (! item) return -1; - if ((! internal_menu)) { - Basemenu *tmp = (Basemenu *) item->submenu(); + if (! internal_menu) { + Basemenu *tmp = item->submenu(); if (tmp) { - if (! tmp->internal_menu) { + if (! tmp->internal_menu) delete tmp; - } else { + else tmp->internal_hide(); - } } } @@ -249,8 +247,9 @@ int Basemenu::remove(int index) { void Basemenu::update(void) { - MenuStyle *style = screen->getMenuStyle(); - menu.item_h = style->f_font->height() + menu.bevel_w; + const MenuStyle* const style = screen->getMenuStyle(); + menu.item_h = (style->f_font->height() < 9 ? 9 : style->f_font->height()) + + menu.bevel_w; // 9 for the menu pixmaps (checkmarks) menu.title_h = style->t_font->height() + menu.bevel_w * 2; if (title_vis) { @@ -272,7 +271,7 @@ void Basemenu::update(void) { if (! menuitems.empty()) { menu.sublevels = 1; - unsigned int menu_size = menuitems.size(); + const unsigned int menu_size = menuitems.size(); while (((menu.item_h * (menu_size + 1) / menu.sublevels) + menu.title_h + screen->getBorderWidth()) > screen->getHeight()) @@ -385,10 +384,10 @@ void Basemenu::show(void) { void Basemenu::hide(void) { - if ((! torn) && hide_tree && parent && parent->isVisible()) { + if (! torn && hide_tree && parent && parent->isVisible()) { Basemenu *p = parent; - while (p->isVisible() && (! p->torn) && p->parent) p = p->parent; + while (p->isVisible() && ! p->torn && p->parent) p = p->parent; p->internal_hide(); } else { internal_hide(); @@ -401,7 +400,7 @@ void Basemenu::internal_hide(void) { if (tmp) tmp->submenu()->internal_hide(); - if (parent && (! torn)) { + if (parent && ! torn) { parent->drawItem(parent->which_sub, False, True); parent->which_sub = -1; @@ -430,7 +429,7 @@ void Basemenu::redrawTitle(void) { i18n(BasemenuSet, BasemenuBlackboxMenu, "Blackbox Menu"); int dx = menu.bevel_w; unsigned int l; - MenuStyle *style = screen->getMenuStyle(); + const MenuStyle* const style = screen->getMenuStyle(); l = style->t_font->measureString(text) + menu.bevel_w * 2; @@ -462,12 +461,13 @@ void Basemenu::drawSubmenu(int index) { item = find(index); if (! item) return; + Basemenu *submenu = item->submenu(); if (submenu && visible && ! submenu->isTorn() && item->isEnabled()) { if (submenu->parent != this) submenu->parent = this; - int sbl = index / menu.persub, i = index - (sbl * menu.persub), - x = menu.x + ((menu.item_w * (sbl + 1)) + screen->getBorderWidth()), y; + const int sbl = index / menu.persub, i = index - (sbl * menu.persub); + int x = menu.x + ((menu.item_w * (sbl + 1)) + screen->getBorderWidth()), y; if (alignment == AlignTop) { y = (((shifted) ? menu.y_shift : menu.y) + @@ -525,15 +525,15 @@ void Basemenu::drawItem(int index, bool highlight, bool clear, BasemenuItem *item = find(index); if (! item) return; - bool dotext = True, dohilite = True, dosel = True; + bool dotext = True, dohilite = True, dosel = True, dooppsel = True; const char *text = item->label(); - int sbl = index / menu.persub, i = index - (sbl * menu.persub); + const int sbl = index / menu.persub, i = index - (sbl * menu.persub); + const unsigned int half_w = menu.item_h / 2, quarter_w = menu.item_h / 4; int item_x = (sbl * menu.item_w), item_y = (i * menu.item_h); int hilite_x = item_x, hilite_y = item_y, hoff_x = 0, hoff_y = 0; - int text_x = 0, text_y = 0, sel_x = 0, sel_y = 0; + int text_x = 0, text_y = 0, sel_x = 0, oppsel_x = 0, sel_y = 0; unsigned int hilite_w = menu.item_w, hilite_h = menu.item_h, text_w = 0, text_h = 0; - unsigned int half_w = menu.item_h / 2, quarter_w = menu.item_h / 4; if (text) { text_w = screen->getMenuStyle()->f_font->measureString(text); @@ -556,18 +556,23 @@ void Basemenu::drawItem(int index, bool highlight, bool clear, text_h = menu.item_h - menu.bevel_w; } - MenuStyle *style = screen->getMenuStyle(); - BPen hipen(style->hilite.color()); + const MenuStyle* const style = screen->getMenuStyle(); + const BPen hipen(style->hilite.color()); // match the text color - BPen pen((highlight ? style->h_text : - (item->isEnabled() ? style->f_text : - style->d_text))); + const BPen pen((highlight ? style->h_text : + (item->isEnabled() ? style->f_text : + style->d_text))); sel_x = item_x; if (screen->getMenuStyle()->bullet_pos == Right) sel_x += (menu.item_w - menu.item_h - menu.bevel_w); sel_x += quarter_w; + oppsel_x = sel_x; + if (screen->getMenuStyle()->bullet_pos == Right) + oppsel_x -= (menu.item_w - menu.item_h - menu.bevel_w); + else + oppsel_x += (menu.item_w - menu.item_h - menu.bevel_w); sel_y = item_y + quarter_w; if (clear) { @@ -588,7 +593,7 @@ void Basemenu::drawItem(int index, bool highlight, bool clear, } // check if we need to redraw the text - int text_ry = item_y + (menu.bevel_w / 2); + const int text_ry = item_y + (menu.bevel_w / 2); if (! (max(text_x, x) <= min(text_x + text_w, x + w) && max(text_ry, y) <= min(text_ry + text_h, y + h))) dotext = False; @@ -597,6 +602,12 @@ void Basemenu::drawItem(int index, bool highlight, bool clear, if (! (max(sel_x, x) <= min(sel_x + half_w, x + w) && max(sel_y, y) <= min(sel_y + half_w, y + h))) dosel = False; + + // check if we need to redraw the select pixmap/menu bullet + // on the opposite side of the menu + if (! (max(oppsel_x, x) <= min(oppsel_x + half_w, x + w) && + max(sel_y, y) <= min(sel_y + half_w, y + h))) + dooppsel = False; } if (dohilite && highlight && (menu.hilite_pixmap != ParentRelative)) { @@ -608,18 +619,29 @@ void Basemenu::drawItem(int index, bool highlight, bool clear, XFillRectangle(display, menu.frame, hipen.gc(), hilite_x, hilite_y, hilite_w, hilite_h); } - - if (dosel && item->isSelected()) { - XPoint pts[6]; - // put the check mark on the opposite side of the menu - int x = sel_x; - if (screen->getMenuStyle()->bullet_pos == Right) - x -= (menu.item_w - menu.item_h - menu.bevel_w); - else - x += (menu.item_w - menu.item_h - menu.bevel_w); + if (dooppsel && item->isSelected()) { +#ifdef BITMAPBUTTONS + if ( style->tick_image.mask != None) { + XSetClipOrigin(blackbox->getXDisplay(), pen.gc(), + oppsel_x, item_y + menu.item_h/2 - style->tick_image.h/2); + XSetClipMask(blackbox->getXDisplay(), pen.gc(), + style->tick_image.mask); + + XFillRectangle(blackbox->getXDisplay(), menu.frame, pen.gc(), + oppsel_x, item_y + menu.item_h/2 - style->tick_image.h/2, + style->tick_image.w, + style->tick_image.h); - pts[0].x = x + 0; + XSetClipMask(blackbox->getXDisplay(), pen.gc(), None); + + XSetClipOrigin(blackbox->getXDisplay(), pen.gc(), + 0, 0); + } else { +#endif // BITMAPBUTTONS + XPoint pts[6]; + + pts[0].x = oppsel_x + 0; pts[0].y = sel_y + 2; pts[1].x = 0; @@ -640,6 +662,9 @@ void Basemenu::drawItem(int index, bool highlight, bool clear, XFillPolygon(display, menu.frame, pen.gc(), pts, 6, Nonconvex, CoordModePrevious); +#ifdef BITMAPBUTTONS + } +#endif // BITMAPBUTTONS } if (dotext && text) { @@ -651,53 +676,73 @@ void Basemenu::drawItem(int index, bool highlight, bool clear, } if (dosel && item->submenu()) { - const int bullet_size = 3; - - switch (screen->getMenuStyle()->bullet) { - case Square: - XDrawRectangle(display, menu.frame, pen.gc(), sel_x, sel_y, - bullet_size * 2, bullet_size * 2); - break; - - case Triangle: - XPoint tri[3]; +#ifdef BITMAPBUTTONS + if ( style->bullet_image.mask != None) { + XSetClipOrigin(blackbox->getXDisplay(), pen.gc(), + sel_x, item_y + menu.item_h/2 - style->bullet_image.h/2); + XSetClipMask(blackbox->getXDisplay(), pen.gc(), + style->bullet_image.mask); + + XFillRectangle(blackbox->getXDisplay(), menu.frame, pen.gc(), + sel_x, item_y + menu.item_h/2 - style->bullet_image.h/2, + style->bullet_image.w, style->bullet_image.h); + + XSetClipMask(blackbox->getXDisplay(), pen.gc(), None); + + XSetClipOrigin(blackbox->getXDisplay(), pen.gc(), + 0, 0); + } else { +#endif // BITMAPBUTTONS + const int bullet_size = 3; + + switch (screen->getMenuStyle()->bullet) { + case Square: + XDrawRectangle(display, menu.frame, pen.gc(), sel_x, sel_y, + bullet_size * 2, bullet_size * 2); + break; + + case Triangle: + XPoint tri[3]; + + if (screen->getMenuStyle()->bullet_pos == Right) { + tri[0].x = sel_x + quarter_w - bullet_size; + tri[0].y = sel_y + quarter_w - bullet_size; + tri[1].x = 2 * bullet_size; + tri[1].y = bullet_size; + tri[2].x = -(2 * bullet_size); + tri[2].y = bullet_size; + } else { + tri[0].x = sel_x + quarter_w - bullet_size; + tri[0].y = item_y + half_w; + tri[1].x = 2 * bullet_size; + tri[1].y = bullet_size; + tri[2].x = 0; + tri[2].y = -(2 * bullet_size); + } - if (screen->getMenuStyle()->bullet_pos == Right) { - tri[0].x = sel_x + quarter_w - bullet_size; - tri[0].y = sel_y + quarter_w - bullet_size; - tri[1].x = 2 * bullet_size; - tri[1].y = bullet_size; - tri[2].x = -(2 * bullet_size); - tri[2].y = bullet_size; - } else { - tri[0].x = sel_x + quarter_w - bullet_size; - tri[0].y = item_y + half_w; - tri[1].x = 2 * bullet_size; - tri[1].y = bullet_size; - tri[2].x = 0; - tri[2].y = -(2 * bullet_size); + XFillPolygon(display, menu.frame, pen.gc(), tri, 3, Convex, + CoordModePrevious); + break; + + case Diamond: + XPoint dia[4]; + + dia[0].x = sel_x + quarter_w - bullet_size; + dia[0].y = item_y + half_w; + dia[1].x = bullet_size; + dia[1].y = -bullet_size; + dia[2].x = bullet_size; + dia[2].y = bullet_size; + dia[3].x = -bullet_size; + dia[3].y = bullet_size; + + XFillPolygon(display, menu.frame, pen.gc(), dia, 4, Convex, + CoordModePrevious); + break; } - - XFillPolygon(display, menu.frame, pen.gc(), tri, 3, Convex, - CoordModePrevious); - break; - - case Diamond: - XPoint dia[4]; - - dia[0].x = sel_x + quarter_w - bullet_size; - dia[0].y = item_y + half_w; - dia[1].x = bullet_size; - dia[1].y = -bullet_size; - dia[2].x = bullet_size; - dia[2].y = bullet_size; - dia[3].x = -bullet_size; - dia[3].y = bullet_size; - - XFillPolygon(display, menu.frame, pen.gc(), dia, 4, Convex, - CoordModePrevious); - break; +#ifdef BITMAPBUTTONS } +#endif // BITMAPBUTTONS } } @@ -747,9 +792,9 @@ bool Basemenu::isItemEnabled(int index) { void Basemenu::buttonPressEvent(XButtonEvent *be) { if (be->window == menu.frame) { - int sbl = (be->x / menu.item_w), i = (be->y / menu.item_h); - int w = (sbl * menu.persub) + i; - + const int sbl = (be->x / menu.item_w), i = (be->y / menu.item_h), + w = (sbl * menu.persub) + i; + BasemenuItem *item = find(w); if (item) { which_press = i; @@ -787,7 +832,7 @@ void Basemenu::buttonReleaseEvent(XButtonEvent *re) { if (re->button == 3) { hide(); } else { - int sbl = (re->x / menu.item_w), i = (re->y / menu.item_h), + const int sbl = (re->x / menu.item_w), i = (re->y / menu.item_h), ix = sbl * menu.item_w, iy = i * menu.item_h, w = (sbl * menu.persub) + i, p = (which_sbl * menu.persub) + which_press; @@ -813,7 +858,7 @@ void Basemenu::motionNotifyEvent(XMotionEvent *me) { if (me->window == menu.title && (me->state & Button1Mask)) { if (movable) { if (! moving) { - if (parent && (! torn)) { + if (parent && ! torn) { parent->drawItem(parent->which_sub, False, True); parent->which_sub = -1; } @@ -832,32 +877,34 @@ void Basemenu::motionNotifyEvent(XMotionEvent *me) { drawSubmenu(which_sub); } } - } else if ((! (me->state & Button1Mask)) && me->window == menu.frame && + } else if (me->window == menu.frame && me->x >= 0 && me->x < static_cast(menu.width) && me->y >= 0 && me->y < static_cast(menu.frame_h)) { - int sbl = (me->x / menu.item_w), i = (me->y / menu.item_h), + const int sbl = (me->x / menu.item_w), i = (me->y / menu.item_h), w = (sbl * menu.persub) + i; if ((i != which_press || sbl != which_sbl) && (w >= 0 && w < static_cast(menuitems.size()))) { if (which_press != -1 && which_sbl != -1) { - int p = (which_sbl * menu.persub) + which_press; + const int p = (which_sbl * menu.persub) + which_press; BasemenuItem *item = find(p); + if (! item) return; drawItem(p, False, True); - if (item->submenu()) - if (item->submenu()->isVisible() && - (! item->submenu()->isTorn())) { - item->submenu()->internal_hide(); - which_sub = -1; - } + if (item->submenu() && + item->submenu()->isVisible() && + ! item->submenu()->isTorn()) { + item->submenu()->internal_hide(); + which_sub = -1; + } } which_press = i; which_sbl = sbl; BasemenuItem *itmp = find(w); - + if (! itmp) return; + if (itmp->submenu()) drawSubmenu(w); else @@ -871,27 +918,26 @@ void Basemenu::exposeEvent(XExposeEvent *ee) { if (ee->window == menu.title) { redrawTitle(); } else if (ee->window == menu.frame) { - // this is a compilicated algorithm... lets do it step by step... + // this is a complicated algorithm... lets do it step by step... // first... we see in which sub level the expose starts... and how many // items down in that sublevel - int sbl = (ee->x / menu.item_w), id = (ee->y / menu.item_h), + const int sbl = (ee->x / menu.item_w), id = (ee->y / menu.item_h), // next... figure out how many sublevels over the redraw spans - sbl_d = ((ee->x + ee->width) / menu.item_w), + sbl_d = ((ee->x + ee->width) / menu.item_w); // then we see how many items down to redraw - id_d = ((ee->y + ee->height) / menu.item_h); + int id_d = ((ee->y + ee->height) / menu.item_h); if (id_d > menu.persub) id_d = menu.persub; // draw the sublevels and the number of items the exposure spans MenuItems::iterator it, end = menuitems.end(); - int i, ii; - for (i = sbl; i <= sbl_d; i++) { + for (int i = sbl; i <= sbl_d; i++) { // set the iterator to the first item in the sublevel needing redrawing it = menuitems.begin() + (id + (i * menu.persub)); - for (ii = id; ii <= id_d && it != end; ++it, ii++) { - int index = ii + (i * menu.persub); + for (int ii = id; ii <= id_d && it != end; ++it, ii++) { + const int index = ii + (i * menu.persub); // redraw the item drawItem(index, (which_sub == index), False, ee->x, ee->y, ee->width, ee->height); @@ -928,10 +974,10 @@ void Basemenu::enterNotifyEvent(XCrossingEvent *ce) { if (which_sub != -1) { BasemenuItem *tmp = find(which_sub); if (tmp->submenu()->isVisible()) { - int sbl = (ce->x / menu.item_w), i = (ce->y / menu.item_h), + const int sbl = (ce->x / menu.item_w), i = (ce->y / menu.item_h), w = (sbl * menu.persub) + i; - if (w != which_sub && (! tmp->submenu()->isTorn())) { + if (w != which_sub && ! tmp->submenu()->isTorn()) { tmp->submenu()->internal_hide(); drawItem(which_sub, False, True); @@ -946,7 +992,7 @@ void Basemenu::enterNotifyEvent(XCrossingEvent *ce) { void Basemenu::leaveNotifyEvent(XCrossingEvent *ce) { if (ce->window == menu.frame) { if (which_press != -1 && which_sbl != -1 && menuitems.size() > 0) { - int p = (which_sbl * menu.persub) + which_press; + const int p = (which_sbl * menu.persub) + which_press; drawItem(p, (p == which_sub), True); @@ -977,6 +1023,6 @@ void Basemenu::reconfigure(void) { void Basemenu::changeItemLabel(unsigned int index, const string& label) { BasemenuItem *item = find(index); - assert(item); - item->newLabel(label); + if (item) + item->newLabel(label); }