more improvements on transparency

This commit is contained in:
fluxgen 2004-06-14 12:24:23 +00:00
parent 3890049e3c
commit 6ede6046d8

View file

@ -22,7 +22,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
// $Id: Menu.cc,v 1.66 2004/06/13 12:01:52 fluxgen Exp $ // $Id: Menu.cc,v 1.67 2004/06/14 12:24:23 fluxgen Exp $
//use GNU extensions //use GNU extensions
#ifndef _GNU_SOURCE #ifndef _GNU_SOURCE
@ -381,7 +381,6 @@ void Menu::enableTitle() {
} }
void Menu::update(int active_index) { void Menu::update(int active_index) {
if (title_vis) { if (title_vis) {
menu.item_w = theme().titleFont().textWidth(menu.label.c_str(), menu.item_w = theme().titleFont().textWidth(menu.label.c_str(),
menu.label.size()); menu.label.size());
@ -485,7 +484,7 @@ void Menu::update(int active_index) {
m_title_pm.width(), m_title_pm.height()); m_title_pm.width(), m_title_pm.height());
} }
} }
} }
@ -536,8 +535,8 @@ void Menu::update(int active_index) {
width(), menu.frame_h); width(), menu.frame_h);
if (m_need_update && (m_frame_pm.width() != menu.frame.width() || if (m_need_update || m_frame_pm.width() != menu.frame.width() ||
m_frame_pm.height() != menu.frame.height() )){ m_frame_pm.height() != menu.frame.height()){
m_frame_pm = FbTk::FbPixmap(menu.frame.window(), m_frame_pm = FbTk::FbPixmap(menu.frame.window(),
menu.frame.width(), menu.frame.height(), menu.frame.width(), menu.frame.height(),
@ -548,82 +547,61 @@ void Menu::update(int active_index) {
menu.frame.depth()); menu.frame.depth());
menu.frame.setBackgroundPixmap(m_real_frame_pm.drawable()); menu.frame.setBackgroundPixmap(m_real_frame_pm.drawable());
GContext def_gc(menu.frame);
if (m_frame_pm.drawable() == 0) { if (m_frame_pm.drawable() == 0) {
_FB_USES_NLS; _FB_USES_NLS;
cerr<<"FbTk::Menu: "<<_FBTKTEXT(Error, CreatePixmap, "Error creating pixmap", "Couldn't create a pixmap - image - for some reason")<<" ("<< cerr<<"FbTk::Menu: "<<_FBTKTEXT(Error, CreatePixmap, "Error creating pixmap", "Couldn't create a pixmap - image - for some reason")<<" ("<<
menu.frame.window()<<", "<<menu.frame.width()<<", "<< menu.frame.window()<<", "<<menu.frame.width()<<", "<<
menu.frame.height()<< menu.frame.height()<<
", "<<menu.frame.depth()<<") !"<<endl; ", "<<menu.frame.depth()<<") !"<<endl;
} else if (menu.sublevels > 0 && menu.persub * menu.sublevels != (int)menuitems.size()) { } else {
// TODO: fill only that part of the menuframe with the
// pixmap/color, that has actually NO buttons on it
// ??? did I made this comment ? (fluxgen)
// if so, what am I talking about?
GContext def_gc(menu.frame);
if (menu.frame_pixmap == 0) { if (menu.frame_pixmap == 0) {
def_gc.setForeground(theme().frameTexture().color()); def_gc.setForeground(theme().frameTexture().color());
m_frame_pm.fillRectangle(def_gc.gc(), m_frame_pm.fillRectangle(def_gc.gc(),
0, 0, 0, 0,
width(), menu.frame_h); width(), menu.frame_h);
m_real_frame_pm.fillRectangle(def_gc.gc(),
0, 0,
width(), menu.frame_h);
} else { } else {
m_frame_pm.copyArea(menu.frame_pixmap, def_gc.gc(), m_frame_pm.copyArea(menu.frame_pixmap, def_gc.gc(),
0, 0, 0, 0,
0, 0, 0, 0,
width(), menu.frame_h); width(), menu.frame_h);
m_real_frame_pm.copyArea(menu.frame_pixmap,
def_gc.gc(),
0, 0,
0, 0,
width(), menu.frame_h);
} }
} }
m_real_frame_pm.copyArea(m_frame_pm.drawable(),
def_gc.gc(),
0, 0,
0, 0,
m_frame_pm.width(), m_frame_pm.height());
} }
// if menu visible and title visible // if menu visible and title visible
if (title_vis && visible) if (title_vis && visible)
redrawTitle(); redrawTitle();
if (active_index >= 0 && isVisible()) { if (active_index >= 0 || m_need_update) {
move(x(), y());
renderTransp(0, 0, renderTransp(0, 0,
m_real_frame_pm.width(), m_real_frame_pm.height()); m_real_frame_pm.width(), m_real_frame_pm.height());
for (unsigned int i = 0; i < menuitems.size(); i++) { for (unsigned int i = 0; i < menuitems.size(); i++) {
if (i == (unsigned int)which_sub) { if (i == (unsigned int)which_sub) {
drawItem(i, true, // highlight drawItem(i, // index
true, // clear true, // highlight
true, // clear
false); // render_trans false); // render_trans
} else } else {
drawItem(i, drawItem(i, // index
// high light // highlight
(static_cast<signed>(i) == active_index && isItemEnabled(i)), (static_cast<signed>(i) == active_index && isItemEnabled(i)),
true, // clear true, // clear
false); // render transparent false); // render transparent
}
} }
// if (m_parent)
// m_parent->drawSubmenu(m_parent->which_sub);
/*
renderTransp(0, active_index*menu.item_h,
width(), menu.item_h);
*/
}
if (m_need_update) {
for (unsigned int i = 0; i < menuitems.size(); i++) {
if (i == (unsigned int)which_sub) {
drawItem(i, true, true, false);
} else
drawItem(i, (static_cast<signed>(i) == active_index && isItemEnabled(i)), true, true);
}
} }
m_need_update = false; m_need_update = false;
@ -633,6 +611,7 @@ void Menu::update(int active_index) {
void Menu::show() { void Menu::show() {
if (m_need_update) if (m_need_update)
update(); update();
menu.window.showSubwindows(); menu.window.showSubwindows();
menu.window.show(); menu.window.show();
raise(); raise();
@ -644,7 +623,7 @@ void Menu::show() {
shown = this; shown = this;
} }
} }
@ -707,6 +686,15 @@ void Menu::internal_hide() {
void Menu::move(int x, int y) { void Menu::move(int x, int y) {
if (x == this->x() && y == this->y())
return;
// if we're not visible and we do transparency
// we need to update transparency when we call
// show() next time
if (alpha() < 255)
m_need_update = true;
menu.window.move(x, y); menu.window.move(x, y);
if (!isVisible()) if (!isVisible())
@ -725,7 +713,7 @@ void Menu::move(int x, int y) {
true, // clear true, // clear
false); // transparent false); // transparent
} }
m_need_update = false;
} }
} }
@ -962,18 +950,20 @@ int Menu::drawItem(unsigned int index, bool highlight, bool clear, bool render_t
} }
if (render_trans) if (render_trans) {
renderTransp(item_x, item_y, renderTransp(item_x, item_y,
width(), theme().itemHeight()); width(), theme().itemHeight());
}
item->draw(m_real_frame_pm, theme(), highlight, item->draw(m_real_frame_pm, theme(), highlight,
item_x, item_y, item_x, item_y,
menu.item_w, theme().itemHeight()); menu.item_w, theme().itemHeight());
if (clear) if (clear) {
menu.frame.clearArea(item_x, item_y, menu.frame.clearArea(item_x, item_y,
menu.item_w, theme().itemHeight(), False); menu.item_w, theme().itemHeight(), False);
}
return item_y; return item_y;
@ -1072,7 +1062,22 @@ void Menu::buttonReleaseEvent(XButtonEvent &re) {
if (re.window == menu.title) { if (re.window == menu.title) {
if (moving) { if (moving) {
moving = false; moving = false;
move(x(), y());
if (which_sub != -1)
drawSubmenu(which_sub);
if (alpha() < 255) {
redrawTitle();
menu.title.clear();
renderTransp(0, 0,
m_real_frame_pm.width(), m_real_frame_pm.height());
for (size_t i=0; i < menuitems.size(); ++i) {
drawItem(i, false, // highlight
true, // clear
false); // transparent
}
}
} }
if (re.x >= 0 && re.x <= (signed) width() && if (re.x >= 0 && re.x <= (signed) width() &&
@ -1196,54 +1201,8 @@ void Menu::exposeEvent(XExposeEvent &ee) {
if (ee.window == menu.title) { if (ee.window == menu.title) {
redrawTitle(); redrawTitle();
menu.title.clearArea(ee.x, ee.y, ee.width, ee.height); menu.title.clearArea(ee.x, ee.y, ee.width, ee.height);
} else if (ee.window == menu.frame) { } else if (ee.window == menu.frame)
if (moving) {
menu.frame.clearArea(ee.x, ee.y, ee.width, ee.height);
return;
}
// this is a compilicated 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
// Simon was here :-) I think this all makes much more sense when
// we rename sbl to "start_col", sbl_d to "end_col", ditto id -> row
// a "sublevel" is basically a column in a multi-column menu (e.g. placement)
if (menu.item_w == 0)
menu.item_w = 1;
unsigned int
start_column = (ee.x / menu.item_w),
end_column = ((ee.x + ee.width) / menu.item_w),
start_row = (ee.y / theme().itemHeight()),
end_row = ((ee.y + ee.height) / theme().itemHeight());
if (static_cast<signed>(end_row) > menu.persub)
end_row = menu.persub;
// draw the sublevels and the number of items the exposure spans
unsigned int col, row;
int max_y = 0;
for (col = start_column; col <= end_column; col++) {
// set the iterator to the first item in the column needing redrawing
unsigned int index = start_row + col * menu.persub;
if (index < menuitems.size()) {
Menuitems::iterator it = menuitems.begin() + index;
Menuitems::iterator it_end = menuitems.end();
for (row = start_row; row <= end_row && it != it_end; ++it, row++) {
unsigned int index = row + (col * menu.persub);
max_y = max(drawItem(index,
(which_sub == static_cast<signed>(index)), // highlight
false, // clear
true), max_y); // render trans
}
}
}
menu.frame.clearArea(ee.x, ee.y, ee.width, ee.height); menu.frame.clearArea(ee.x, ee.y, ee.width, ee.height);
}
} }
@ -1375,6 +1334,7 @@ void Menu::reconfigure() {
update(); update();
} }
@ -1424,10 +1384,8 @@ void Menu::update(FbTk::Subject *subj) {
void Menu::renderTransp(int x, int y, void Menu::renderTransp(int x, int y,
unsigned int width, unsigned int height) { unsigned int width, unsigned int height) {
// no need to render transparent unless visible // even though we dont render transparency
if (!isVisible()) // we do need to copy the style background
return;
GContext def_gc(menu.frame); GContext def_gc(menu.frame);
m_real_frame_pm.copyArea(m_frame_pm.drawable(), m_real_frame_pm.copyArea(m_frame_pm.drawable(),
def_gc.gc(), def_gc.gc(),
@ -1435,9 +1393,14 @@ void Menu::renderTransp(int x, int y,
x, y, x, y,
width, height); width, height);
if (m_transp.get() == 0) // no need to render transparent unless visible
// but we do need to render it if we marked it as
// need update
if (!isVisible() && !m_need_update || m_transp.get() == 0)
return; return;
// render the root background
#ifdef HAVE_XRENDER #ifdef HAVE_XRENDER
Pixmap root = getRootPixmap(screenNumber()); Pixmap root = getRootPixmap(screenNumber());