2003-01-05 22:14:10 +00:00
|
|
|
// FbWinFrame.cc for Fluxbox Window Manager
|
2004-01-21 19:47:30 +00:00
|
|
|
// Copyright (c) 2003-2004 Henrik Kinnunen (fluxgen at users.sourceforge.net)
|
2003-01-05 22:14:10 +00:00
|
|
|
//
|
|
|
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
// copy of this software and associated documentation files (the "Software"),
|
|
|
|
// to deal in the Software without restriction, including without limitation
|
|
|
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
// and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
// Software is furnished to do so, subject to the following conditions:
|
|
|
|
//
|
|
|
|
// The above copyright notice and this permission notice shall be included in
|
|
|
|
// all copies or substantial portions of the Software.
|
|
|
|
//
|
|
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
|
|
// DEALINGS IN THE SOFTWARE.
|
|
|
|
|
2004-11-19 11:37:27 +00:00
|
|
|
// $Id$
|
2003-01-05 22:14:10 +00:00
|
|
|
|
|
|
|
#include "FbWinFrame.hh"
|
2003-08-19 16:15:32 +00:00
|
|
|
|
|
|
|
#include "FbTk/ImageControl.hh"
|
|
|
|
#include "FbTk/EventManager.hh"
|
|
|
|
#include "FbTk/TextButton.hh"
|
|
|
|
#include "FbTk/App.hh"
|
2003-09-10 09:53:21 +00:00
|
|
|
#include "FbTk/SimpleCommand.hh"
|
2004-02-28 16:54:04 +00:00
|
|
|
#include "FbTk/Compose.hh"
|
2004-09-12 14:56:20 +00:00
|
|
|
#include "FbTk/Transparent.hh"
|
2004-02-27 12:20:01 +00:00
|
|
|
#include "CompareWindow.hh"
|
2003-07-10 11:36:21 +00:00
|
|
|
#include "FbWinFrameTheme.hh"
|
2004-10-10 16:12:48 +00:00
|
|
|
#include "fluxbox.hh"
|
2004-02-27 12:20:01 +00:00
|
|
|
|
2003-02-17 22:45:42 +00:00
|
|
|
#ifdef SHAPE
|
2003-07-10 11:36:21 +00:00
|
|
|
#include "Shape.hh"
|
2003-02-17 22:45:42 +00:00
|
|
|
#endif // SHAPE
|
2003-01-05 22:14:10 +00:00
|
|
|
|
2003-08-24 11:19:45 +00:00
|
|
|
|
2003-04-14 15:01:55 +00:00
|
|
|
#include <algorithm>
|
2003-01-05 22:14:10 +00:00
|
|
|
#include <iostream>
|
2003-09-11 13:35:37 +00:00
|
|
|
#include <X11/X.h>
|
|
|
|
|
2003-01-05 22:14:10 +00:00
|
|
|
using namespace std;
|
|
|
|
|
2003-02-17 22:57:52 +00:00
|
|
|
FbWinFrame::FbWinFrame(FbWinFrameTheme &theme, FbTk::ImageControl &imgctrl,
|
2003-12-18 18:03:23 +00:00
|
|
|
int x, int y,
|
2003-01-05 22:14:10 +00:00
|
|
|
unsigned int width, unsigned int height):
|
|
|
|
m_theme(theme),
|
|
|
|
m_imagectrl(imgctrl),
|
2003-12-18 18:03:23 +00:00
|
|
|
m_window(theme.screenNum(), x, y, width, height, ButtonPressMask | ButtonReleaseMask |
|
2003-01-05 22:14:10 +00:00
|
|
|
ButtonMotionMask | EnterWindowMask, true),
|
|
|
|
m_titlebar(m_window, 0, 0, 100, 16,
|
|
|
|
ButtonPressMask | ButtonReleaseMask |
|
|
|
|
ButtonMotionMask | ExposureMask |
|
|
|
|
EnterWindowMask | LeaveWindowMask),
|
|
|
|
m_label(m_titlebar, 0, 0, 100, 16,
|
|
|
|
ButtonPressMask | ButtonReleaseMask |
|
|
|
|
ButtonMotionMask | ExposureMask |
|
|
|
|
EnterWindowMask | LeaveWindowMask),
|
2003-10-02 14:14:46 +00:00
|
|
|
m_handle(m_window, 0, 0, 100, 5,
|
|
|
|
ButtonPressMask | ButtonReleaseMask |
|
|
|
|
ButtonMotionMask | ExposureMask |
|
|
|
|
EnterWindowMask | LeaveWindowMask),
|
|
|
|
m_grip_right(m_handle, 0, 0, 10, 4,
|
2003-01-05 22:14:10 +00:00
|
|
|
ButtonPressMask | ButtonReleaseMask |
|
|
|
|
ButtonMotionMask | ExposureMask |
|
|
|
|
EnterWindowMask | LeaveWindowMask),
|
2003-10-02 14:14:46 +00:00
|
|
|
m_grip_left(m_handle, 0, 0, 10, 4,
|
2003-01-05 22:14:10 +00:00
|
|
|
ButtonPressMask | ButtonReleaseMask |
|
|
|
|
ButtonMotionMask | ExposureMask |
|
|
|
|
EnterWindowMask | LeaveWindowMask),
|
|
|
|
m_clientarea(m_window, 0, 0, 100, 100,
|
|
|
|
ButtonPressMask | ButtonReleaseMask |
|
|
|
|
ButtonMotionMask | ExposureMask |
|
|
|
|
EnterWindowMask | LeaveWindowMask),
|
|
|
|
m_bevel(1),
|
|
|
|
m_use_titlebar(true),
|
2003-01-07 01:30:57 +00:00
|
|
|
m_use_handle(true),
|
2003-04-09 17:20:06 +00:00
|
|
|
m_focused(false),
|
2003-05-01 13:19:36 +00:00
|
|
|
m_visible(false),
|
2003-02-15 01:54:54 +00:00
|
|
|
m_button_pm(0),
|
2003-07-10 11:36:21 +00:00
|
|
|
m_themelistener(*this),
|
|
|
|
m_shape(new Shape(m_window, theme.shapePlace())) {
|
2004-01-02 13:26:44 +00:00
|
|
|
m_theme.reconfigSig().attach(&m_themelistener);
|
2003-01-05 22:14:10 +00:00
|
|
|
init();
|
|
|
|
}
|
2003-04-14 15:01:55 +00:00
|
|
|
|
2003-01-05 22:14:10 +00:00
|
|
|
/*
|
2003-01-09 22:08:27 +00:00
|
|
|
FbWinFrame::FbWinFrame(FbWinFrameTheme &theme, FbTk::ImageControl &imgctrl, const FbTk::FbWindow &parent, int x, int y,
|
2003-01-05 22:14:10 +00:00
|
|
|
unsigned int width, unsigned int height):
|
|
|
|
m_theme(theme),
|
|
|
|
m_imagectrl(imgctrl),
|
|
|
|
m_window(parent, x, y, width, height, ExposureMask | StructureNotifyMask),
|
|
|
|
m_titlebar(m_window, 0, 0, 100, 16,
|
|
|
|
ExposureMask | ButtonPressMask | ButtonReleaseMask),
|
|
|
|
m_label(m_titlebar, 0, 0, 100, 16,
|
|
|
|
ExposureMask | ButtonPressMask | ButtonReleaseMask),
|
|
|
|
m_grip_right(m_window, 0, 0, 100, 100, ExposureMask | ButtonPressMask | ButtonReleaseMask),
|
|
|
|
m_grip_left(m_window, 0, 0, 100, 100, ExposureMask | ButtonPressMask | ButtonReleaseMask),
|
|
|
|
m_handle(m_window, 0, 0, 100, 100, ExposureMask | ButtonPressMask | ButtonReleaseMask),
|
|
|
|
m_clientarea(m_window, 0, 0, 100, 100, SubstructureRedirectMask),
|
|
|
|
m_bevel(1),
|
|
|
|
m_use_titlebar(true),
|
|
|
|
m_use_handles(true),
|
|
|
|
m_button_pm(0) {
|
|
|
|
|
|
|
|
init();
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
FbWinFrame::~FbWinFrame() {
|
2003-09-12 22:49:14 +00:00
|
|
|
m_update_timer.stop();
|
2003-01-05 22:14:10 +00:00
|
|
|
removeEventHandler();
|
|
|
|
removeAllButtons();
|
|
|
|
}
|
|
|
|
|
2003-01-07 01:30:57 +00:00
|
|
|
bool FbWinFrame::setOnClickTitlebar(FbTk::RefCount<FbTk::Command> &ref, int mousebutton_num,
|
|
|
|
bool double_click, bool pressed) {
|
|
|
|
// find mousebutton_num
|
|
|
|
if (mousebutton_num < 1 || mousebutton_num > 5)
|
|
|
|
return false;
|
|
|
|
if (double_click)
|
|
|
|
m_commands[mousebutton_num - 1].double_click = ref;
|
|
|
|
else {
|
|
|
|
if (pressed)
|
|
|
|
m_commands[mousebutton_num - 1].click_pressed = ref;
|
|
|
|
else
|
|
|
|
m_commands[mousebutton_num - 1].click = ref;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2003-01-05 22:14:10 +00:00
|
|
|
void FbWinFrame::hide() {
|
|
|
|
m_window.hide();
|
2003-05-01 13:19:36 +00:00
|
|
|
m_visible = false;
|
2003-01-05 22:14:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void FbWinFrame::show() {
|
2003-05-01 13:19:36 +00:00
|
|
|
m_visible = true;
|
2003-01-05 22:14:10 +00:00
|
|
|
m_window.showSubwindows();
|
|
|
|
m_window.show();
|
2004-02-28 16:54:04 +00:00
|
|
|
updateTransparent();
|
2003-01-05 22:14:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Toggle shade state, and resize window
|
|
|
|
*/
|
|
|
|
void FbWinFrame::shade() {
|
2003-02-20 23:21:23 +00:00
|
|
|
if (!m_use_titlebar)
|
|
|
|
return;
|
|
|
|
|
2003-04-03 22:37:43 +00:00
|
|
|
// toggle shade
|
|
|
|
m_shaded = !m_shaded;
|
|
|
|
if (m_shaded) { // i.e. should be shaded now
|
2003-01-05 22:14:10 +00:00
|
|
|
m_width_before_shade = m_window.width();
|
|
|
|
m_height_before_shade = m_window.height();
|
2003-02-23 21:32:37 +00:00
|
|
|
m_window.resize(m_window.width(), m_titlebar.height());
|
2003-04-03 22:37:43 +00:00
|
|
|
} else { // should be unshaded
|
2003-01-05 22:14:10 +00:00
|
|
|
m_window.resize(m_width_before_shade, m_height_before_shade);
|
2003-04-03 22:37:43 +00:00
|
|
|
reconfigure();
|
2003-01-05 22:14:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void FbWinFrame::move(int x, int y) {
|
2003-09-24 14:02:25 +00:00
|
|
|
moveResize(x, y, 0, 0, true, false);
|
|
|
|
}
|
2003-08-04 12:47:36 +00:00
|
|
|
|
2003-09-24 14:02:25 +00:00
|
|
|
void FbWinFrame::resize(unsigned int width, unsigned int height) {
|
|
|
|
moveResize(0, 0, width, height, false, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
// need an atomic moveresize where possible
|
|
|
|
void FbWinFrame::moveResizeForClient(int x, int y, unsigned int width, unsigned int height, bool move, bool resize) {
|
|
|
|
// total height for frame
|
2003-08-04 12:47:36 +00:00
|
|
|
|
2003-09-24 14:02:25 +00:00
|
|
|
unsigned int total_height = height;
|
2003-08-04 12:47:36 +00:00
|
|
|
|
2003-09-24 14:02:25 +00:00
|
|
|
if (resize) {
|
|
|
|
// having a titlebar = 1 extra border + titlebar height
|
|
|
|
if (m_use_titlebar)
|
|
|
|
total_height += m_titlebar.height() + m_titlebar.borderWidth();
|
|
|
|
// having a handle = 1 extra border + handle height
|
|
|
|
if (m_use_handle)
|
|
|
|
total_height += m_handle.height() + m_handle.borderWidth();
|
|
|
|
}
|
|
|
|
moveResize(x, y, width, total_height, move, resize);
|
|
|
|
}
|
2003-09-10 09:53:21 +00:00
|
|
|
|
2003-09-24 14:02:25 +00:00
|
|
|
void FbWinFrame::resizeForClient(unsigned int width, unsigned int height) {
|
|
|
|
moveResizeForClient(0, 0, width, height, false, true);
|
2003-01-05 22:14:10 +00:00
|
|
|
}
|
|
|
|
|
2003-09-24 14:02:25 +00:00
|
|
|
void FbWinFrame::moveResize(int x, int y, unsigned int width, unsigned int height, bool move, bool resize) {
|
|
|
|
if (move && x == window().x() && y == window().y())
|
|
|
|
move = false;
|
|
|
|
|
|
|
|
if (resize && width == FbWinFrame::width() && height == FbWinFrame::height())
|
|
|
|
resize = false;
|
|
|
|
|
|
|
|
if (!move && !resize)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (resize && m_shaded) {
|
|
|
|
// update unshaded size if we're in shaded state and just resize width
|
2003-01-05 22:14:10 +00:00
|
|
|
m_width_before_shade = width;
|
|
|
|
m_height_before_shade = height;
|
2003-09-24 14:02:25 +00:00
|
|
|
height = m_window.height();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (move && resize) {
|
|
|
|
m_window.moveResize(x, y, width, height);
|
|
|
|
} else if (move) {
|
|
|
|
m_window.move(x, y);
|
|
|
|
// this stuff will be caught by reconfigure if resized
|
2004-09-12 14:56:20 +00:00
|
|
|
unsigned char alpha = (m_focused?theme().focusedAlpha():theme().unfocusedAlpha());
|
|
|
|
if (alpha != 255) {
|
2003-09-24 14:02:25 +00:00
|
|
|
// restart update timer
|
|
|
|
m_update_timer.start();
|
|
|
|
}
|
2003-01-05 22:14:10 +00:00
|
|
|
} else {
|
|
|
|
m_window.resize(width, height);
|
|
|
|
}
|
|
|
|
|
2003-09-24 14:02:25 +00:00
|
|
|
if (resize)
|
|
|
|
reconfigure();
|
2003-01-05 22:14:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void FbWinFrame::setFocus(bool newvalue) {
|
2003-09-14 10:32:31 +00:00
|
|
|
if (m_focused == newvalue)
|
2003-01-05 22:14:10 +00:00
|
|
|
return;
|
|
|
|
|
2003-10-31 10:37:09 +00:00
|
|
|
m_focused = newvalue;
|
|
|
|
|
2003-09-14 10:32:31 +00:00
|
|
|
if (currentLabel()) {
|
|
|
|
if (newvalue) // focused
|
|
|
|
renderButtonFocus(*m_current_label);
|
|
|
|
else // unfocused
|
2003-12-09 08:48:08 +00:00
|
|
|
renderButtonActive(*m_current_label);
|
2003-09-12 22:49:14 +00:00
|
|
|
}
|
|
|
|
|
2004-09-12 14:56:20 +00:00
|
|
|
if (theme().focusedAlpha() != theme().unfocusedAlpha() && FbTk::Transparent::haveComposite()) {
|
|
|
|
if (m_focused)
|
|
|
|
m_window.setOpaque(theme().focusedAlpha());
|
|
|
|
else
|
|
|
|
m_window.setOpaque(theme().unfocusedAlpha());
|
|
|
|
}
|
|
|
|
|
2003-10-09 16:48:09 +00:00
|
|
|
renderTitlebar();
|
2003-10-31 10:37:09 +00:00
|
|
|
renderButtons(); // parent relative buttons -> need render after titlebar
|
2003-09-12 22:49:14 +00:00
|
|
|
renderHandles();
|
2003-01-05 22:14:10 +00:00
|
|
|
}
|
|
|
|
|
2003-01-07 01:30:57 +00:00
|
|
|
void FbWinFrame::setDoubleClickTime(unsigned int time) {
|
|
|
|
m_double_click_time = time;
|
|
|
|
}
|
|
|
|
|
2003-01-05 22:14:10 +00:00
|
|
|
void FbWinFrame::addLeftButton(FbTk::Button *btn) {
|
|
|
|
if (btn == 0) // valid button?
|
|
|
|
return;
|
|
|
|
|
|
|
|
setupButton(*btn); // setup theme and other stuff
|
2003-09-14 10:32:31 +00:00
|
|
|
|
2003-01-05 22:14:10 +00:00
|
|
|
m_buttons_left.push_back(btn);
|
|
|
|
}
|
|
|
|
|
|
|
|
void FbWinFrame::addRightButton(FbTk::Button *btn) {
|
|
|
|
if (btn == 0) // valid button?
|
|
|
|
return;
|
|
|
|
|
|
|
|
setupButton(*btn); // setup theme and other stuff
|
|
|
|
|
|
|
|
m_buttons_right.push_back(btn);
|
|
|
|
}
|
|
|
|
|
|
|
|
void FbWinFrame::removeAllButtons() {
|
|
|
|
// destroy left side
|
|
|
|
while (!m_buttons_left.empty()) {
|
|
|
|
delete m_buttons_left.back();
|
|
|
|
m_buttons_left.pop_back();
|
|
|
|
}
|
|
|
|
// destroy right side
|
|
|
|
while (!m_buttons_right.empty()) {
|
|
|
|
delete m_buttons_right.back();
|
|
|
|
m_buttons_right.pop_back();
|
|
|
|
}
|
2003-04-14 15:01:55 +00:00
|
|
|
}
|
|
|
|
|
2003-08-19 16:15:32 +00:00
|
|
|
void FbWinFrame::addLabelButton(FbTk::TextButton &btn) {
|
2003-07-28 12:11:57 +00:00
|
|
|
LabelList::iterator found_it = find(m_labelbuttons.begin(),
|
|
|
|
m_labelbuttons.end(),
|
|
|
|
&btn);
|
2003-04-14 15:01:55 +00:00
|
|
|
|
|
|
|
if (found_it != m_labelbuttons.end())
|
|
|
|
return;
|
2004-10-10 16:12:48 +00:00
|
|
|
|
|
|
|
btn.setTextPadding(Fluxbox::instance()->getTabsPadding());
|
2003-04-14 15:01:55 +00:00
|
|
|
m_labelbuttons.push_back(&btn);
|
2003-12-09 08:48:08 +00:00
|
|
|
|
|
|
|
if (currentLabel() == 0)
|
|
|
|
setLabelButtonFocus(btn);
|
2003-04-14 15:01:55 +00:00
|
|
|
}
|
|
|
|
|
2003-08-19 16:15:32 +00:00
|
|
|
void FbWinFrame::removeLabelButton(FbTk::TextButton &btn) {
|
2003-07-28 12:11:57 +00:00
|
|
|
LabelList::iterator erase_it = remove(m_labelbuttons.begin(),
|
|
|
|
m_labelbuttons.end(),
|
|
|
|
&btn);
|
2003-04-14 15:01:55 +00:00
|
|
|
if (erase_it == m_labelbuttons.end())
|
|
|
|
return;
|
|
|
|
|
2004-03-21 09:00:25 +00:00
|
|
|
if (&btn == m_current_label)
|
|
|
|
m_current_label = 0;
|
|
|
|
|
2003-04-14 15:01:55 +00:00
|
|
|
m_labelbuttons.erase(erase_it);
|
2003-09-12 22:49:14 +00:00
|
|
|
|
2003-04-14 15:01:55 +00:00
|
|
|
}
|
2003-01-05 22:14:10 +00:00
|
|
|
|
2003-07-28 12:11:57 +00:00
|
|
|
|
2003-08-19 16:15:32 +00:00
|
|
|
void FbWinFrame::moveLabelButtonLeft(const FbTk::TextButton &btn) {
|
2003-07-28 12:11:57 +00:00
|
|
|
LabelList::iterator it = find(m_labelbuttons.begin(),
|
2003-09-12 22:49:14 +00:00
|
|
|
m_labelbuttons.end(),
|
|
|
|
&btn);
|
2003-07-28 12:11:57 +00:00
|
|
|
// make sure we found it and we're not at the begining
|
|
|
|
if (it == m_labelbuttons.end() || it == m_labelbuttons.begin())
|
|
|
|
return;
|
|
|
|
|
|
|
|
LabelList::iterator new_pos = it;
|
|
|
|
new_pos--;
|
2003-08-19 16:15:32 +00:00
|
|
|
FbTk::TextButton *item = *it;
|
2003-07-28 12:11:57 +00:00
|
|
|
// remove from list
|
|
|
|
m_labelbuttons.erase(it);
|
|
|
|
// insert on the new place
|
|
|
|
m_labelbuttons.insert(new_pos, item);
|
|
|
|
// update titlebar
|
|
|
|
redrawTitle();
|
|
|
|
}
|
|
|
|
|
2003-08-19 16:15:32 +00:00
|
|
|
void FbWinFrame::moveLabelButtonRight(const FbTk::TextButton &btn) {
|
2003-07-28 12:11:57 +00:00
|
|
|
LabelList::iterator it = find(m_labelbuttons.begin(),
|
|
|
|
m_labelbuttons.end(),
|
|
|
|
&btn);
|
|
|
|
// make sure we found it and we're not at the last item
|
|
|
|
if (it == m_labelbuttons.end() || *it == m_labelbuttons.back())
|
|
|
|
return;
|
|
|
|
|
2003-08-19 16:15:32 +00:00
|
|
|
FbTk::TextButton *item = *it;
|
2003-07-28 12:11:57 +00:00
|
|
|
// remove from list
|
|
|
|
LabelList::iterator new_pos = m_labelbuttons.erase(it);
|
|
|
|
new_pos++;
|
|
|
|
// insert on the new place
|
|
|
|
m_labelbuttons.insert(new_pos, item);
|
|
|
|
// update titlebar
|
|
|
|
redrawTitle();
|
|
|
|
}
|
|
|
|
|
2003-08-19 16:15:32 +00:00
|
|
|
void FbWinFrame::setLabelButtonFocus(FbTk::TextButton &btn) {
|
2003-09-14 10:32:31 +00:00
|
|
|
if (&btn == currentLabel())
|
|
|
|
return;
|
2003-07-28 12:11:57 +00:00
|
|
|
LabelList::iterator it = find(m_labelbuttons.begin(),
|
|
|
|
m_labelbuttons.end(),
|
|
|
|
&btn);
|
2003-04-16 12:27:49 +00:00
|
|
|
if (it == m_labelbuttons.end())
|
|
|
|
return;
|
|
|
|
|
2003-08-13 16:36:37 +00:00
|
|
|
// render label buttons
|
2003-09-12 22:49:14 +00:00
|
|
|
if (currentLabel() != 0)
|
2003-08-13 16:36:37 +00:00
|
|
|
renderButtonUnfocus(*m_current_label);
|
|
|
|
|
2003-04-16 12:27:49 +00:00
|
|
|
m_current_label = *it; // current focused button
|
2003-08-13 16:36:37 +00:00
|
|
|
|
2003-12-09 08:48:08 +00:00
|
|
|
if (m_focused)
|
|
|
|
renderButtonFocus(*m_current_label);
|
|
|
|
else
|
|
|
|
renderButtonActive(*m_current_label);
|
2003-04-16 12:27:49 +00:00
|
|
|
}
|
|
|
|
|
2003-04-14 15:01:55 +00:00
|
|
|
void FbWinFrame::setClientWindow(FbTk::FbWindow &win) {
|
2003-01-05 22:14:10 +00:00
|
|
|
|
|
|
|
Display *display = FbTk::App::instance()->display();
|
|
|
|
|
2004-01-02 13:26:44 +00:00
|
|
|
win.setBorderWidth(0);
|
|
|
|
|
|
|
|
XChangeSaveSet(display, win.window(), SetModeInsert);
|
2003-10-28 02:17:03 +00:00
|
|
|
|
2004-01-02 13:26:44 +00:00
|
|
|
m_window.setEventMask(NoEventMask);
|
2003-10-28 02:17:03 +00:00
|
|
|
|
2003-04-14 23:40:41 +00:00
|
|
|
// we need to mask this so we don't get unmap event
|
2004-01-02 13:26:44 +00:00
|
|
|
win.setEventMask(NoEventMask);
|
|
|
|
win.reparent(m_window, 0, clientArea().y());
|
2003-04-14 23:40:41 +00:00
|
|
|
// remask window so we get events
|
2004-01-02 13:26:44 +00:00
|
|
|
win.setEventMask(PropertyChangeMask | StructureNotifyMask |
|
|
|
|
FocusChangeMask);
|
|
|
|
|
|
|
|
m_window.setEventMask(ButtonPressMask | ButtonReleaseMask |
|
|
|
|
ButtonMotionMask | EnterWindowMask | SubstructureRedirectMask);
|
2003-01-05 22:14:10 +00:00
|
|
|
|
|
|
|
XFlush(display);
|
|
|
|
|
2003-04-14 23:40:41 +00:00
|
|
|
XSetWindowAttributes attrib_set;
|
2003-01-05 22:14:10 +00:00
|
|
|
attrib_set.event_mask = PropertyChangeMask | StructureNotifyMask | FocusChangeMask;
|
2003-04-14 23:40:41 +00:00
|
|
|
attrib_set.do_not_propagate_mask = ButtonPressMask | ButtonReleaseMask |
|
|
|
|
ButtonMotionMask;
|
2003-01-05 22:14:10 +00:00
|
|
|
|
2004-01-02 13:26:44 +00:00
|
|
|
XChangeWindowAttributes(display, win.window(), CWEventMask|CWDontPropagate, &attrib_set);
|
2003-01-05 22:14:10 +00:00
|
|
|
|
|
|
|
m_clientarea.raise();
|
2004-01-02 13:26:44 +00:00
|
|
|
win.raise();
|
2003-10-28 02:17:03 +00:00
|
|
|
m_window.showSubwindows();
|
2003-01-05 22:14:10 +00:00
|
|
|
}
|
|
|
|
|
2003-10-05 09:03:43 +00:00
|
|
|
bool FbWinFrame::hideTitlebar() {
|
2003-02-20 23:21:23 +00:00
|
|
|
if (!m_use_titlebar)
|
2003-10-05 09:03:43 +00:00
|
|
|
return false;
|
2003-02-20 23:21:23 +00:00
|
|
|
|
2003-01-05 22:14:10 +00:00
|
|
|
m_titlebar.hide();
|
2003-01-07 01:30:57 +00:00
|
|
|
m_use_titlebar = false;
|
2004-01-21 19:47:30 +00:00
|
|
|
if (static_cast<signed int>(m_window.height() - m_titlebar.height() -
|
|
|
|
m_titlebar.borderWidth()) <= 0) {
|
|
|
|
m_window.resize(m_window.width(), 1);
|
|
|
|
} else {
|
|
|
|
// only take away one borderwidth (as the other border is still the "top" border)
|
|
|
|
m_window.resize(m_window.width(), m_window.height() - m_titlebar.height() -
|
|
|
|
m_titlebar.borderWidth());
|
|
|
|
}
|
2003-02-23 13:40:22 +00:00
|
|
|
|
2003-10-05 09:03:43 +00:00
|
|
|
return true;
|
2003-01-05 22:14:10 +00:00
|
|
|
}
|
|
|
|
|
2003-10-05 09:03:43 +00:00
|
|
|
bool FbWinFrame::showTitlebar() {
|
2003-02-20 23:21:23 +00:00
|
|
|
if (m_use_titlebar)
|
2003-10-05 09:03:43 +00:00
|
|
|
return false;
|
2003-02-20 23:21:23 +00:00
|
|
|
|
2003-01-05 22:14:10 +00:00
|
|
|
m_titlebar.show();
|
2003-01-07 01:30:57 +00:00
|
|
|
m_use_titlebar = true;
|
2003-02-23 13:40:22 +00:00
|
|
|
|
|
|
|
// only add one borderwidth (as the other border is still the "top" border)
|
|
|
|
m_window.resize(m_window.width(), m_window.height() + m_titlebar.height() +
|
|
|
|
m_titlebar.borderWidth());
|
2003-10-05 09:03:43 +00:00
|
|
|
return true;
|
2003-02-23 13:40:22 +00:00
|
|
|
|
2003-01-05 22:14:10 +00:00
|
|
|
}
|
|
|
|
|
2003-10-05 09:03:43 +00:00
|
|
|
bool FbWinFrame::hideHandle() {
|
2003-02-23 13:40:22 +00:00
|
|
|
if (!m_use_handle)
|
2003-10-05 09:03:43 +00:00
|
|
|
return false;
|
2003-01-05 22:14:10 +00:00
|
|
|
m_handle.hide();
|
2003-01-07 01:30:57 +00:00
|
|
|
m_grip_left.hide();
|
|
|
|
m_grip_right.hide();
|
|
|
|
m_use_handle = false;
|
2004-01-21 19:47:30 +00:00
|
|
|
|
|
|
|
if (static_cast<signed int>(m_window.height() - m_handle.height() -
|
2004-01-23 11:04:05 +00:00
|
|
|
m_handle.borderWidth()) <= 0) {
|
2004-01-21 19:47:30 +00:00
|
|
|
m_window.resize(m_window.width(), 1);
|
|
|
|
} else {
|
|
|
|
// only take away one borderwidth (as the other border is still the "top" border)
|
|
|
|
m_window.resize(m_window.width(), m_window.height() - m_handle.height() -
|
|
|
|
m_handle.borderWidth());
|
|
|
|
}
|
|
|
|
|
2003-10-05 09:03:43 +00:00
|
|
|
return true;
|
2003-02-23 13:40:22 +00:00
|
|
|
|
2003-01-05 22:14:10 +00:00
|
|
|
}
|
|
|
|
|
2003-10-05 09:03:43 +00:00
|
|
|
bool FbWinFrame::showHandle() {
|
2003-10-30 20:27:51 +00:00
|
|
|
if (m_use_handle || theme().handleWidth() == 0)
|
2003-10-05 09:03:43 +00:00
|
|
|
return false;
|
2003-10-02 14:14:46 +00:00
|
|
|
|
2004-01-23 10:38:25 +00:00
|
|
|
m_use_handle = true;
|
|
|
|
|
|
|
|
renderHandles();
|
2003-01-05 22:14:10 +00:00
|
|
|
m_handle.show();
|
2003-10-02 14:14:46 +00:00
|
|
|
m_handle.showSubwindows(); // shows grips
|
|
|
|
|
2003-02-23 13:40:22 +00:00
|
|
|
m_window.resize(m_window.width(), m_window.height() + m_handle.height() +
|
|
|
|
m_handle.borderWidth());
|
2003-10-05 09:03:43 +00:00
|
|
|
return true;
|
2003-01-07 01:30:57 +00:00
|
|
|
}
|
|
|
|
|
2003-10-05 09:03:43 +00:00
|
|
|
bool FbWinFrame::hideAllDecorations() {
|
|
|
|
bool changed = false;
|
|
|
|
changed |= hideHandle();
|
|
|
|
changed |= hideTitlebar();
|
2003-02-23 13:40:22 +00:00
|
|
|
// resize done by hide*
|
2003-01-07 01:30:57 +00:00
|
|
|
reconfigure();
|
2003-10-05 09:03:43 +00:00
|
|
|
|
|
|
|
return changed;
|
2003-01-07 01:30:57 +00:00
|
|
|
}
|
|
|
|
|
2003-10-05 09:03:43 +00:00
|
|
|
bool FbWinFrame::showAllDecorations() {
|
|
|
|
bool changed = false;
|
2003-01-07 01:30:57 +00:00
|
|
|
if (!m_use_handle)
|
2003-10-05 09:03:43 +00:00
|
|
|
changed |= showHandle();
|
2003-01-07 01:30:57 +00:00
|
|
|
if (!m_use_titlebar)
|
2003-10-05 09:03:43 +00:00
|
|
|
changed |= showTitlebar();
|
2003-02-23 13:40:22 +00:00
|
|
|
// resize shouldn't be necessary
|
2003-02-22 18:31:00 +00:00
|
|
|
reconfigure();
|
2003-10-05 09:03:43 +00:00
|
|
|
|
|
|
|
return changed;
|
2003-01-05 22:14:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Set new event handler for the frame's windows
|
|
|
|
*/
|
|
|
|
void FbWinFrame::setEventHandler(FbTk::EventHandler &evh) {
|
|
|
|
|
|
|
|
FbTk::EventManager &evm = *FbTk::EventManager::instance();
|
|
|
|
evm.add(evh, m_label);
|
|
|
|
evm.add(evh, m_titlebar);
|
|
|
|
evm.add(evh, m_handle);
|
|
|
|
evm.add(evh, m_grip_right);
|
|
|
|
evm.add(evh, m_grip_left);
|
|
|
|
evm.add(evh, m_window);
|
|
|
|
evm.add(evh, m_clientarea);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
remove event handler from windows
|
|
|
|
*/
|
|
|
|
void FbWinFrame::removeEventHandler() {
|
|
|
|
FbTk::EventManager &evm = *FbTk::EventManager::instance();
|
|
|
|
evm.remove(m_label);
|
|
|
|
evm.remove(m_titlebar);
|
|
|
|
evm.remove(m_handle);
|
|
|
|
evm.remove(m_grip_right);
|
|
|
|
evm.remove(m_grip_left);
|
|
|
|
evm.remove(m_window);
|
|
|
|
evm.remove(m_clientarea);
|
|
|
|
}
|
|
|
|
|
|
|
|
void FbWinFrame::buttonPressEvent(XButtonEvent &event) {
|
2003-04-14 15:01:55 +00:00
|
|
|
// we can ignore which window the event was generated for
|
2003-07-28 12:11:57 +00:00
|
|
|
LabelList::iterator btn_it = m_labelbuttons.begin();
|
|
|
|
LabelList::iterator btn_it_end = m_labelbuttons.end();
|
2003-04-14 15:01:55 +00:00
|
|
|
for (; btn_it != btn_it_end; ++btn_it) {
|
|
|
|
if ((*btn_it)->window() == event.window) {
|
|
|
|
(*btn_it)->buttonPressEvent(event);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2003-04-15 14:36:12 +00:00
|
|
|
if (event.window == m_grip_right.window() ||
|
|
|
|
event.window == m_grip_left.window() ||
|
|
|
|
event.window == m_clientarea.window() ||
|
|
|
|
event.window == m_window.window())
|
|
|
|
return;
|
2003-08-04 12:47:36 +00:00
|
|
|
// we handle only buttons 0 to 5
|
2003-01-07 01:30:57 +00:00
|
|
|
if (event.button > 5 || event.button < 1)
|
|
|
|
return;
|
|
|
|
|
2003-01-09 18:03:33 +00:00
|
|
|
if (*m_commands[event.button - 1].click_pressed)
|
2003-01-07 01:30:57 +00:00
|
|
|
m_commands[event.button - 1].click_pressed->execute();
|
|
|
|
}
|
|
|
|
|
|
|
|
void FbWinFrame::buttonReleaseEvent(XButtonEvent &event) {
|
2003-04-14 15:01:55 +00:00
|
|
|
// we can ignore which window the event was generated for
|
|
|
|
|
2003-08-24 11:19:45 +00:00
|
|
|
LabelList::iterator button_it = find_if(m_labelbuttons.begin(),
|
|
|
|
m_labelbuttons.end(),
|
2004-02-27 12:20:01 +00:00
|
|
|
CompareWindow(&FbTk::Button::window,
|
|
|
|
event.window));
|
2003-08-24 11:19:45 +00:00
|
|
|
if (button_it != m_labelbuttons.end())
|
|
|
|
(*button_it)->buttonReleaseEvent(event);
|
|
|
|
|
2003-04-15 14:36:12 +00:00
|
|
|
if (event.window == m_grip_right.window() ||
|
|
|
|
event.window == m_grip_left.window() ||
|
|
|
|
event.window == m_clientarea.window() ||
|
|
|
|
event.window == m_handle.window() ||
|
|
|
|
event.window == m_window.window())
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (event.button < 1 || event.button > 5)
|
2003-01-07 01:30:57 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
static int last_release_time = 0;
|
|
|
|
bool double_click = (event.time - last_release_time <= m_double_click_time);
|
|
|
|
last_release_time = event.time;
|
|
|
|
int real_button = event.button - 1;
|
|
|
|
|
|
|
|
if (double_click && *m_commands[real_button].double_click)
|
|
|
|
m_commands[real_button].double_click->execute();
|
|
|
|
else if (*m_commands[real_button].click)
|
|
|
|
m_commands[real_button].click->execute();
|
|
|
|
|
2003-01-05 22:14:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void FbWinFrame::exposeEvent(XExposeEvent &event) {
|
2004-01-10 00:37:35 +00:00
|
|
|
if (m_titlebar == event.window) {
|
|
|
|
m_titlebar.clearArea(event.x, event.y, event.width, event.height);
|
|
|
|
m_titlebar.updateTransparent(event.x, event.y, event.width, event.height);
|
|
|
|
} else if (m_label == event.window) {
|
2003-09-12 22:49:14 +00:00
|
|
|
m_label.clearArea(event.x, event.y, event.width, event.height);
|
|
|
|
m_label.updateTransparent(event.x, event.y, event.width, event.height);
|
|
|
|
} else if (m_handle == event.window) {
|
2003-08-04 12:47:36 +00:00
|
|
|
m_handle.clearArea(event.x, event.y, event.width, event.height);
|
2003-09-15 20:14:49 +00:00
|
|
|
m_handle.updateTransparent(event.x, event.y, event.width, event.height);
|
2003-08-04 12:47:36 +00:00
|
|
|
} else if (m_grip_left == event.window) {
|
|
|
|
m_grip_left.clearArea(event.x, event.y, event.width, event.height);
|
2003-09-15 20:14:49 +00:00
|
|
|
m_grip_left.updateTransparent(event.x, event.y, event.width, event.height);
|
2003-08-04 12:47:36 +00:00
|
|
|
} else if (m_grip_right == event.window) {
|
|
|
|
m_grip_right.clearArea(event.x, event.y, event.width, event.height);
|
2003-09-15 20:14:49 +00:00
|
|
|
m_grip_right.updateTransparent(event.x, event.y, event.width, event.height);
|
2003-08-04 12:47:36 +00:00
|
|
|
} else {
|
2003-08-24 11:19:45 +00:00
|
|
|
// create compare function
|
2004-02-27 12:20:01 +00:00
|
|
|
// that we should use with find_if
|
|
|
|
FbTk::CompareEqual_base<FbTk::FbWindow, Window> compare(&FbTk::FbWindow::window,
|
|
|
|
event.window);
|
2003-08-24 11:19:45 +00:00
|
|
|
|
|
|
|
LabelList::iterator btn_it = find_if(m_labelbuttons.begin(),
|
|
|
|
m_labelbuttons.end(),
|
|
|
|
compare);
|
|
|
|
if (btn_it != m_labelbuttons.end()) {
|
|
|
|
(*btn_it)->exposeEvent(event);
|
|
|
|
return;
|
2003-08-04 12:47:36 +00:00
|
|
|
}
|
|
|
|
|
2003-08-24 11:19:45 +00:00
|
|
|
ButtonList::iterator it = find_if(m_buttons_left.begin(),
|
|
|
|
m_buttons_left.end(),
|
|
|
|
compare);
|
|
|
|
if (it != m_buttons_left.end()) {
|
|
|
|
(*it)->exposeEvent(event);
|
|
|
|
return;
|
2003-08-04 12:47:36 +00:00
|
|
|
}
|
|
|
|
|
2003-08-24 11:19:45 +00:00
|
|
|
it = find_if(m_buttons_right.begin(),
|
|
|
|
m_buttons_right.end(),
|
|
|
|
compare);
|
2003-08-04 12:47:36 +00:00
|
|
|
|
2003-08-24 11:19:45 +00:00
|
|
|
if (it != m_buttons_right.end())
|
|
|
|
(*it)->exposeEvent(event);
|
|
|
|
}
|
2003-09-12 22:49:14 +00:00
|
|
|
|
2003-01-05 22:14:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void FbWinFrame::handleEvent(XEvent &event) {
|
2003-08-23 15:46:06 +00:00
|
|
|
if (event.type == ConfigureNotify && event.xconfigure.window == window().window())
|
2003-01-05 22:14:10 +00:00
|
|
|
configureNotifyEvent(event.xconfigure);
|
|
|
|
}
|
|
|
|
|
|
|
|
void FbWinFrame::configureNotifyEvent(XConfigureEvent &event) {
|
|
|
|
resize(event.width, event.height);
|
|
|
|
}
|
|
|
|
|
|
|
|
void FbWinFrame::reconfigure() {
|
2004-01-21 14:14:40 +00:00
|
|
|
if (m_labelbuttons.empty())
|
2003-09-12 22:49:14 +00:00
|
|
|
return;
|
2003-01-09 18:03:33 +00:00
|
|
|
|
2003-09-12 23:38:50 +00:00
|
|
|
m_bevel = theme().bevelWidth();
|
2004-01-23 10:38:25 +00:00
|
|
|
// reconfigure can't set borderwidth, as it doesn't know
|
|
|
|
// if it's meant to be borderless or not
|
|
|
|
|
|
|
|
unsigned int orig_handle_h = handle().height();
|
|
|
|
if (m_use_handle && orig_handle_h != theme().handleWidth())
|
|
|
|
m_window.resize(m_window.width(), m_window.height() -
|
|
|
|
orig_handle_h + theme().handleWidth());
|
2003-09-12 23:38:50 +00:00
|
|
|
|
|
|
|
handle().resize(handle().width(),
|
|
|
|
theme().handleWidth());
|
|
|
|
gripLeft().resize(buttonHeight(),
|
|
|
|
theme().handleWidth());
|
|
|
|
gripRight().resize(gripLeft().width(),
|
|
|
|
gripLeft().height());
|
|
|
|
|
2003-01-05 22:14:10 +00:00
|
|
|
// align titlebar and render it
|
2003-10-28 02:17:03 +00:00
|
|
|
if (m_use_titlebar) {
|
2003-01-07 01:30:57 +00:00
|
|
|
reconfigureTitlebar();
|
2003-10-28 02:17:03 +00:00
|
|
|
m_titlebar.raise();
|
|
|
|
} else
|
|
|
|
m_titlebar.lower();
|
|
|
|
|
2003-02-20 23:21:23 +00:00
|
|
|
|
2003-04-03 22:37:43 +00:00
|
|
|
// leave client+grips alone if we're shaded (it'll get fixed when we unshade)
|
|
|
|
if (!m_shaded) {
|
|
|
|
int client_top = 0;
|
|
|
|
int client_height = m_window.height();
|
|
|
|
if (m_use_titlebar) {
|
|
|
|
// only one borderwidth as titlebar is really at -borderwidth
|
|
|
|
int titlebar_height = m_titlebar.height() + m_titlebar.borderWidth();
|
|
|
|
client_top += titlebar_height;
|
|
|
|
client_height -= titlebar_height;
|
|
|
|
}
|
|
|
|
|
2004-01-23 10:38:25 +00:00
|
|
|
// align handle and grips
|
|
|
|
const int grip_height = m_handle.height();
|
|
|
|
const int grip_width = 20; //TODO
|
|
|
|
const int handle_bw = static_cast<signed>(m_handle.borderWidth());
|
2003-10-02 14:14:46 +00:00
|
|
|
|
2004-01-23 10:38:25 +00:00
|
|
|
int ypos = m_window.height();
|
2004-01-02 13:26:44 +00:00
|
|
|
|
2004-01-23 10:38:25 +00:00
|
|
|
// if the handle isn't on, it's actually below the window
|
|
|
|
if (m_use_handle)
|
|
|
|
ypos -= grip_height + handle_bw;
|
|
|
|
|
|
|
|
// we do handle settings whether on or not so that if they get toggled
|
|
|
|
// then things are ok...
|
|
|
|
m_handle.moveResize(-handle_bw, ypos,
|
|
|
|
m_window.width(), grip_height);
|
|
|
|
|
|
|
|
m_grip_left.moveResize(-handle_bw, -handle_bw,
|
|
|
|
grip_width, grip_height);
|
|
|
|
|
|
|
|
m_grip_right.moveResize(m_handle.width() - grip_width - handle_bw, -handle_bw,
|
|
|
|
grip_width, grip_height);
|
2004-01-02 13:26:44 +00:00
|
|
|
|
2004-01-23 10:38:25 +00:00
|
|
|
if (m_use_handle) {
|
|
|
|
m_handle.raise();
|
|
|
|
client_height -= m_handle.height() + m_handle.borderWidth();
|
2003-10-28 02:17:03 +00:00
|
|
|
} else {
|
|
|
|
m_handle.lower();
|
2003-04-16 10:56:37 +00:00
|
|
|
}
|
2004-01-02 13:26:44 +00:00
|
|
|
|
|
|
|
m_clientarea.moveResize(0, client_top,
|
|
|
|
m_window.width(), client_height);
|
2003-10-28 02:17:03 +00:00
|
|
|
}
|
|
|
|
|
2003-01-05 22:14:10 +00:00
|
|
|
|
|
|
|
// render the theme
|
|
|
|
renderButtons();
|
2003-04-03 22:37:43 +00:00
|
|
|
if (!m_shaded)
|
|
|
|
renderHandles();
|
2003-07-10 11:36:21 +00:00
|
|
|
|
2003-08-24 15:39:52 +00:00
|
|
|
if (m_shape.get() && theme().shapePlace() == Shape::NONE || m_disable_shape)
|
2003-07-10 11:36:21 +00:00
|
|
|
m_shape.reset(0);
|
|
|
|
else if (m_shape.get() == 0 && theme().shapePlace() != Shape::NONE)
|
|
|
|
m_shape.reset(new Shape(window(), theme().shapePlace()));
|
|
|
|
else if (m_shape.get())
|
|
|
|
m_shape->setPlaces(theme().shapePlace());
|
|
|
|
|
|
|
|
if (m_shape.get())
|
|
|
|
m_shape->update();
|
|
|
|
|
2003-05-01 13:19:36 +00:00
|
|
|
// titlebar stuff rendered already by reconftitlebar
|
2003-01-05 22:14:10 +00:00
|
|
|
}
|
|
|
|
|
2003-08-24 15:39:52 +00:00
|
|
|
void FbWinFrame::setUseShape(bool value) {
|
|
|
|
m_disable_shape = !value;
|
|
|
|
|
|
|
|
if (m_shape.get() && m_disable_shape)
|
|
|
|
m_shape.reset(0);
|
|
|
|
else if (m_shape.get() == 0 && !m_disable_shape)
|
|
|
|
m_shape.reset(new Shape(window(), theme().shapePlace()));
|
|
|
|
}
|
|
|
|
|
2003-01-05 22:14:10 +00:00
|
|
|
unsigned int FbWinFrame::buttonHeight() const {
|
|
|
|
return m_titlebar.height() - m_bevel*2;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------- private area
|
|
|
|
|
|
|
|
/**
|
|
|
|
aligns and redraws title
|
|
|
|
*/
|
|
|
|
void FbWinFrame::redrawTitle() {
|
2004-01-21 14:14:40 +00:00
|
|
|
if (m_labelbuttons.empty())
|
2003-04-14 15:01:55 +00:00
|
|
|
return;
|
|
|
|
|
2004-10-10 16:12:48 +00:00
|
|
|
int focus_button_min_percent = Fluxbox::instance()->getFocusedTabMinWidth();
|
|
|
|
int button_count = m_labelbuttons.size();
|
|
|
|
int label_width = label().width();
|
|
|
|
|
|
|
|
/* force sane value */
|
|
|
|
if (focus_button_min_percent > 90)
|
|
|
|
focus_button_min_percent = 90;
|
|
|
|
if (focus_button_min_percent < 1)
|
|
|
|
focus_button_min_percent = 1;
|
|
|
|
|
|
|
|
int focus_button_width, unfocus_button_width;
|
|
|
|
if (100 < (focus_button_min_percent * button_count)) {
|
|
|
|
focus_button_width = label_width * focus_button_min_percent / 100;
|
|
|
|
if (button_count > 1) {
|
|
|
|
unfocus_button_width = label_width *
|
|
|
|
(100 - focus_button_min_percent) / (100 * (button_count - 1));
|
|
|
|
} else {
|
|
|
|
/* should never happen */
|
|
|
|
unfocus_button_width = 0;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
focus_button_width = label_width / button_count;
|
|
|
|
unfocus_button_width = focus_button_width;
|
|
|
|
}
|
|
|
|
|
|
|
|
int rounding_error = label_width - focus_button_width -
|
|
|
|
((button_count - 1) * unfocus_button_width);
|
|
|
|
|
2003-04-14 15:01:55 +00:00
|
|
|
//!! TODO: bevel
|
2003-06-24 14:05:00 +00:00
|
|
|
//int border_width = m_labelbuttons.front()->window().borderWidth();
|
2004-01-21 14:14:40 +00:00
|
|
|
int border_width = m_labelbuttons.empty() ? 0 : m_labelbuttons.front()->borderWidth();
|
2003-04-16 10:56:37 +00:00
|
|
|
|
2003-07-28 12:11:57 +00:00
|
|
|
LabelList::iterator btn_it = m_labelbuttons.begin();
|
|
|
|
LabelList::iterator btn_it_end = m_labelbuttons.end();
|
2004-10-10 16:12:48 +00:00
|
|
|
int extra = 0, dx = 0;
|
2003-04-14 15:01:55 +00:00
|
|
|
for (unsigned int last_x = 0;
|
|
|
|
btn_it != btn_it_end;
|
2004-10-10 16:12:48 +00:00
|
|
|
++btn_it, last_x += dx) {
|
|
|
|
|
2003-10-31 10:37:09 +00:00
|
|
|
if (rounding_error != 0) {
|
|
|
|
extra = 1;
|
|
|
|
--rounding_error;
|
|
|
|
} else
|
|
|
|
extra = 0;
|
|
|
|
|
2004-10-10 16:12:48 +00:00
|
|
|
if (currentLabel() == *btn_it) {
|
|
|
|
dx = focus_button_width;
|
|
|
|
} else {
|
|
|
|
dx = unfocus_button_width;
|
|
|
|
}
|
|
|
|
dx += border_width + extra;
|
|
|
|
|
2003-06-24 14:05:00 +00:00
|
|
|
(*btn_it)->moveResize(last_x - border_width, - border_width,
|
2004-10-10 16:12:48 +00:00
|
|
|
dx - border_width,
|
2003-04-16 10:56:37 +00:00
|
|
|
label().height() + border_width);
|
2004-02-27 12:20:01 +00:00
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isVisible()) {
|
|
|
|
for_each(m_labelbuttons.begin(),
|
|
|
|
m_labelbuttons.end(),
|
|
|
|
mem_fun(&FbTk::Button::clear));
|
2003-09-14 10:32:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (isVisible()) {
|
|
|
|
m_label.clear();
|
|
|
|
m_label.updateTransparent();
|
2003-10-09 16:48:09 +00:00
|
|
|
m_titlebar.clear();
|
|
|
|
m_titlebar.updateTransparent();
|
2003-04-14 15:01:55 +00:00
|
|
|
}
|
2003-01-05 22:14:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void FbWinFrame::redrawTitlebar() {
|
2003-09-12 22:49:14 +00:00
|
|
|
if (!m_use_titlebar)
|
2003-02-20 23:21:23 +00:00
|
|
|
return;
|
2003-08-04 12:47:36 +00:00
|
|
|
|
2003-01-05 22:14:10 +00:00
|
|
|
redrawTitle();
|
2003-06-05 13:09:08 +00:00
|
|
|
|
2003-05-01 13:19:36 +00:00
|
|
|
}
|
2003-01-05 22:14:10 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
Align buttons with title text window
|
|
|
|
*/
|
|
|
|
void FbWinFrame::reconfigureTitlebar() {
|
2003-02-20 23:21:23 +00:00
|
|
|
if (!m_use_titlebar)
|
|
|
|
return;
|
|
|
|
|
2003-10-05 09:03:43 +00:00
|
|
|
int orig_height = m_titlebar.height();
|
2003-01-05 22:14:10 +00:00
|
|
|
// resize titlebar to window size with font height
|
2003-08-22 15:20:32 +00:00
|
|
|
int title_height = m_theme.font().height() == 0 ? 16 :
|
|
|
|
m_theme.font().height() + m_bevel*2 + 2;
|
|
|
|
if (m_theme.titleHeight() != 0)
|
|
|
|
title_height = m_theme.titleHeight();
|
|
|
|
|
2003-10-05 09:03:43 +00:00
|
|
|
// if the titlebar grows in size, make sure the whole window does too
|
|
|
|
if (orig_height != title_height)
|
|
|
|
m_window.resize(m_window.width(), m_window.height()-orig_height+title_height);
|
2003-02-17 22:45:42 +00:00
|
|
|
m_titlebar.moveResize(-m_titlebar.borderWidth(), -m_titlebar.borderWidth(),
|
2003-08-22 15:20:32 +00:00
|
|
|
m_window.width(), title_height);
|
2003-01-05 22:14:10 +00:00
|
|
|
|
|
|
|
// draw left buttons first
|
|
|
|
unsigned int next_x = m_bevel;
|
|
|
|
unsigned int button_size = buttonHeight();
|
|
|
|
m_button_size = button_size;
|
|
|
|
for (size_t i=0; i < m_buttons_left.size(); i++, next_x += button_size + m_bevel) {
|
|
|
|
m_buttons_left[i]->moveResize(next_x, m_bevel,
|
|
|
|
button_size, button_size);
|
|
|
|
}
|
2003-04-14 15:01:55 +00:00
|
|
|
|
2003-01-05 22:14:10 +00:00
|
|
|
next_x += m_bevel;
|
|
|
|
|
|
|
|
// space left on titlebar between left and right buttons
|
|
|
|
unsigned int space_left = m_titlebar.width() - next_x;
|
2004-01-21 14:14:40 +00:00
|
|
|
if (!m_buttons_right.empty())
|
2003-02-17 22:45:42 +00:00
|
|
|
space_left -= m_buttons_right.size() * (button_size + m_bevel);
|
|
|
|
|
2003-01-05 22:14:10 +00:00
|
|
|
space_left -= m_bevel;
|
|
|
|
|
2003-08-04 12:47:36 +00:00
|
|
|
m_label.moveResize(next_x, m_bevel,
|
2003-01-05 22:14:10 +00:00
|
|
|
space_left, button_size);
|
|
|
|
|
|
|
|
next_x += m_label.width() + m_bevel;;
|
|
|
|
|
|
|
|
// finaly set new buttons to the right
|
|
|
|
for (size_t i=0; i < m_buttons_right.size();
|
|
|
|
++i, next_x += button_size + m_bevel) {
|
|
|
|
m_buttons_right[i]->moveResize(next_x, m_bevel,
|
|
|
|
button_size, button_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
renderTitlebar();
|
|
|
|
m_titlebar.raise(); // always on top
|
|
|
|
}
|
|
|
|
|
|
|
|
void FbWinFrame::renderTitlebar() {
|
2003-09-12 22:49:14 +00:00
|
|
|
if (!m_use_titlebar)
|
2003-01-05 22:14:10 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
// render pixmaps
|
|
|
|
render(m_theme.titleFocusTexture(), m_title_focused_color,
|
|
|
|
m_title_focused_pm,
|
|
|
|
m_titlebar.width(), m_titlebar.height());
|
|
|
|
|
|
|
|
render(m_theme.titleUnfocusTexture(), m_title_unfocused_color,
|
|
|
|
m_title_unfocused_pm,
|
|
|
|
m_titlebar.width(), m_titlebar.height());
|
|
|
|
|
|
|
|
|
|
|
|
render(m_theme.labelFocusTexture(), m_label_focused_color,
|
|
|
|
m_label_focused_pm,
|
|
|
|
m_label.width(), m_label.height());
|
|
|
|
|
2004-01-02 13:26:44 +00:00
|
|
|
|
2003-01-05 22:14:10 +00:00
|
|
|
render(m_theme.labelUnfocusTexture(), m_label_unfocused_color,
|
|
|
|
m_label_unfocused_pm,
|
|
|
|
m_label.width(), m_label.height());
|
|
|
|
|
2003-12-09 08:48:08 +00:00
|
|
|
render(m_theme.labelActiveTexture(), m_label_active_color,
|
|
|
|
m_label_active_pm,
|
|
|
|
m_label.width(), m_label.height());
|
|
|
|
|
|
|
|
|
2003-01-05 22:14:10 +00:00
|
|
|
// finaly set up pixmaps for titlebar windows
|
2003-04-16 12:27:49 +00:00
|
|
|
Pixmap label_pm = None;
|
|
|
|
Pixmap title_pm = None;
|
|
|
|
FbTk::Color label_color;
|
|
|
|
FbTk::Color title_color;
|
|
|
|
getCurrentFocusPixmap(label_pm, title_pm,
|
|
|
|
label_color, title_color);
|
|
|
|
|
|
|
|
if (label_pm != 0)
|
|
|
|
m_label.setBackgroundPixmap(label_pm);
|
|
|
|
else
|
|
|
|
m_label.setBackgroundColor(label_color);
|
2003-04-14 15:01:55 +00:00
|
|
|
|
2003-04-16 12:27:49 +00:00
|
|
|
if (title_pm != 0)
|
|
|
|
m_titlebar.setBackgroundPixmap(title_pm);
|
|
|
|
else
|
|
|
|
m_titlebar.setBackgroundColor(title_color);
|
2003-01-05 22:14:10 +00:00
|
|
|
|
2004-09-12 14:56:20 +00:00
|
|
|
unsigned char alpha = (m_focused?theme().focusedAlpha():theme().unfocusedAlpha());
|
|
|
|
m_titlebar.setAlpha(alpha);
|
|
|
|
m_label.setAlpha(alpha);
|
2004-01-10 00:37:35 +00:00
|
|
|
|
2004-10-22 09:43:53 +00:00
|
|
|
LabelList::iterator btn_it = m_labelbuttons.begin();
|
|
|
|
LabelList::iterator btn_it_end = m_labelbuttons.end();
|
|
|
|
for (; btn_it != btn_it_end; ++btn_it) {
|
|
|
|
(*btn_it)->setAlpha(alpha);
|
|
|
|
}
|
|
|
|
|
2003-04-16 12:27:49 +00:00
|
|
|
renderLabelButtons();
|
2003-05-01 13:19:36 +00:00
|
|
|
redrawTitlebar();
|
2003-01-05 22:14:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void FbWinFrame::renderHandles() {
|
2003-10-06 09:28:35 +00:00
|
|
|
if (!m_use_handle)
|
2003-01-05 22:14:10 +00:00
|
|
|
return;
|
2003-06-23 14:18:54 +00:00
|
|
|
|
2003-01-05 22:14:10 +00:00
|
|
|
render(m_theme.handleFocusTexture(), m_handle_focused_color,
|
|
|
|
m_handle_focused_pm,
|
|
|
|
m_handle.width(), m_handle.height());
|
|
|
|
|
|
|
|
render(m_theme.handleUnfocusTexture(), m_handle_unfocused_color,
|
|
|
|
m_handle_unfocused_pm,
|
|
|
|
m_handle.width(), m_handle.height());
|
|
|
|
|
|
|
|
if (m_focused) {
|
|
|
|
if (m_handle_focused_pm) {
|
|
|
|
m_handle.setBackgroundPixmap(m_handle_focused_pm);
|
|
|
|
} else {
|
|
|
|
m_handle.setBackgroundColor(m_handle_focused_color);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (m_handle_unfocused_pm) {
|
|
|
|
m_handle.setBackgroundPixmap(m_handle_unfocused_pm);
|
|
|
|
} else {
|
|
|
|
m_handle.setBackgroundColor(m_handle_unfocused_color);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
render(m_theme.gripFocusTexture(), m_grip_focused_color, m_grip_focused_pm,
|
|
|
|
m_grip_left.width(), m_grip_left.height());
|
|
|
|
|
|
|
|
render(m_theme.gripUnfocusTexture(), m_grip_unfocused_color,
|
|
|
|
m_grip_unfocused_pm,
|
|
|
|
m_grip_left.width(), m_grip_left.height());
|
|
|
|
|
|
|
|
if (m_focused) {
|
|
|
|
if (m_grip_focused_pm) {
|
|
|
|
m_grip_left.setBackgroundPixmap(m_grip_focused_pm);
|
|
|
|
m_grip_right.setBackgroundPixmap(m_grip_focused_pm);
|
|
|
|
} else {
|
|
|
|
m_grip_left.setBackgroundColor(m_grip_focused_color);
|
|
|
|
m_grip_right.setBackgroundColor(m_grip_focused_color);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (m_grip_unfocused_pm) {
|
|
|
|
m_grip_left.setBackgroundPixmap(m_grip_unfocused_pm);
|
|
|
|
m_grip_right.setBackgroundPixmap(m_grip_unfocused_pm);
|
|
|
|
} else {
|
|
|
|
m_grip_left.setBackgroundColor(m_grip_unfocused_color);
|
|
|
|
m_grip_right.setBackgroundColor(m_grip_unfocused_color);
|
|
|
|
}
|
|
|
|
}
|
2003-08-04 12:47:36 +00:00
|
|
|
|
2004-09-12 14:56:20 +00:00
|
|
|
unsigned char alpha = (m_focused?theme().focusedAlpha():theme().unfocusedAlpha());
|
|
|
|
m_handle.setAlpha(alpha);
|
|
|
|
m_grip_left.setAlpha(alpha);
|
|
|
|
m_grip_right.setAlpha(alpha);
|
2003-10-02 13:09:24 +00:00
|
|
|
|
2004-01-10 20:22:05 +00:00
|
|
|
m_grip_left.clear();
|
|
|
|
m_grip_left.updateTransparent();
|
|
|
|
m_grip_right.clear();
|
|
|
|
m_grip_right.updateTransparent();
|
|
|
|
m_handle.clear();
|
|
|
|
m_handle.updateTransparent();
|
|
|
|
|
2003-01-05 22:14:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void FbWinFrame::renderButtons() {
|
|
|
|
|
|
|
|
render(m_theme.buttonFocusTexture(), m_button_color, m_button_pm,
|
|
|
|
m_button_size, m_button_size);
|
2003-09-14 10:32:31 +00:00
|
|
|
|
2003-01-05 22:14:10 +00:00
|
|
|
render(m_theme.buttonUnfocusTexture(), m_button_unfocused_color,
|
|
|
|
m_button_unfocused_pm,
|
|
|
|
m_button_size, m_button_size);
|
|
|
|
|
|
|
|
render(m_theme.buttonPressedTexture(), m_button_pressed_color,
|
|
|
|
m_button_pressed_pm,
|
|
|
|
m_button_size, m_button_size);
|
|
|
|
|
|
|
|
// setup left and right buttons
|
2004-02-27 12:20:01 +00:00
|
|
|
for (size_t i=0; i < m_buttons_left.size(); ++i)
|
2003-01-05 22:14:10 +00:00
|
|
|
setupButton(*m_buttons_left[i]);
|
|
|
|
|
2004-02-27 12:20:01 +00:00
|
|
|
for (size_t i=0; i < m_buttons_right.size(); ++i)
|
2003-01-05 22:14:10 +00:00
|
|
|
setupButton(*m_buttons_right[i]);
|
2004-02-27 12:20:01 +00:00
|
|
|
|
|
|
|
if (isVisible()) {
|
|
|
|
for_each(m_buttons_left.begin(),
|
|
|
|
m_buttons_left.end(),
|
|
|
|
mem_fun(&FbTk::Button::clear));
|
|
|
|
for_each(m_buttons_right.begin(),
|
|
|
|
m_buttons_right.end(),
|
|
|
|
mem_fun(&FbTk::Button::clear));
|
2003-09-14 10:32:31 +00:00
|
|
|
}
|
|
|
|
|
2003-01-05 22:14:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void FbWinFrame::init() {
|
2004-01-02 13:26:44 +00:00
|
|
|
|
2004-09-12 14:56:20 +00:00
|
|
|
if (FbTk::Transparent::haveComposite()) {
|
|
|
|
if (m_focused)
|
|
|
|
m_window.setOpaque(theme().focusedAlpha());
|
|
|
|
else
|
|
|
|
m_window.setOpaque(theme().unfocusedAlpha());
|
|
|
|
} else {
|
|
|
|
// setup update timer
|
|
|
|
FbTk::RefCount<FbTk::Command> update_transp(new FbTk::SimpleCommand<FbWinFrame>(*this,
|
|
|
|
&FbWinFrame::updateTransparent));
|
|
|
|
m_update_timer.setCommand(update_transp);
|
|
|
|
m_update_timer.setTimeout(10L);
|
|
|
|
m_update_timer.fireOnce(true);
|
|
|
|
}
|
2003-06-23 14:18:54 +00:00
|
|
|
|
2003-10-30 20:27:51 +00:00
|
|
|
if (theme().handleWidth() == 0)
|
|
|
|
m_use_handle = false;
|
|
|
|
|
2003-08-24 15:39:52 +00:00
|
|
|
m_disable_shape = false;
|
|
|
|
|
2003-04-16 12:27:49 +00:00
|
|
|
m_current_label = 0; // no focused button at first
|
2003-06-23 14:18:54 +00:00
|
|
|
|
2003-10-02 14:14:46 +00:00
|
|
|
m_handle.showSubwindows();
|
|
|
|
|
2003-06-23 14:18:54 +00:00
|
|
|
// clear pixmaps
|
2003-01-05 22:14:10 +00:00
|
|
|
m_title_focused_pm = m_title_unfocused_pm = 0;
|
2003-12-09 08:48:08 +00:00
|
|
|
m_label_focused_pm = m_label_unfocused_pm = m_label_active_pm = 0;
|
2003-06-23 14:18:54 +00:00
|
|
|
m_handle_focused_pm = m_handle_unfocused_pm = 0;
|
|
|
|
m_button_pm = m_button_unfocused_pm = m_button_pressed_pm = 0;
|
|
|
|
m_grip_unfocused_pm = m_grip_focused_pm = 0;
|
|
|
|
|
2003-01-07 01:30:57 +00:00
|
|
|
m_double_click_time = 200;
|
2003-01-05 22:14:10 +00:00
|
|
|
m_button_size = 26;
|
2003-06-23 14:18:54 +00:00
|
|
|
|
2003-04-16 22:15:22 +00:00
|
|
|
m_clientarea.setBorderWidth(0);
|
2003-01-05 22:14:10 +00:00
|
|
|
m_shaded = false;
|
|
|
|
m_label.show();
|
2003-01-07 01:30:57 +00:00
|
|
|
|
2003-01-09 18:03:33 +00:00
|
|
|
showHandle();
|
2003-01-07 01:30:57 +00:00
|
|
|
showTitlebar();
|
2003-01-09 18:03:33 +00:00
|
|
|
|
2003-06-23 14:18:54 +00:00
|
|
|
// Note: we don't show clientarea yet
|
2003-01-05 22:14:10 +00:00
|
|
|
|
|
|
|
setEventHandler(*this);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Setups upp background, pressed pixmap/color of the button to current theme
|
|
|
|
*/
|
|
|
|
void FbWinFrame::setupButton(FbTk::Button &btn) {
|
2003-09-14 10:32:31 +00:00
|
|
|
if (m_button_pressed_pm)
|
2003-01-05 22:14:10 +00:00
|
|
|
btn.setPressedPixmap(m_button_pressed_pm);
|
2003-08-04 12:47:36 +00:00
|
|
|
|
|
|
|
//!! TODO button pressed color
|
2003-01-05 22:14:10 +00:00
|
|
|
|
2003-09-14 10:32:31 +00:00
|
|
|
if (focused()) { // focused
|
2003-02-23 00:57:55 +00:00
|
|
|
btn.setGC(m_theme.buttonPicFocusGC());
|
2003-01-05 22:14:10 +00:00
|
|
|
if (m_button_pm)
|
|
|
|
btn.setBackgroundPixmap(m_button_pm);
|
|
|
|
else
|
|
|
|
btn.setBackgroundColor(m_button_color);
|
2004-09-12 14:56:20 +00:00
|
|
|
btn.setAlpha(theme().focusedAlpha());
|
2003-09-14 10:32:31 +00:00
|
|
|
} else { // unfocused
|
2003-02-23 00:57:55 +00:00
|
|
|
btn.setGC(m_theme.buttonPicUnfocusGC());
|
2003-01-05 22:14:10 +00:00
|
|
|
if (m_button_unfocused_pm)
|
|
|
|
btn.setBackgroundPixmap(m_button_unfocused_pm);
|
|
|
|
else
|
2003-09-14 10:32:31 +00:00
|
|
|
btn.setBackgroundColor(m_button_unfocused_color);
|
2003-08-04 12:47:36 +00:00
|
|
|
|
2004-09-12 14:56:20 +00:00
|
|
|
btn.setAlpha(theme().unfocusedAlpha());
|
2003-01-05 22:14:10 +00:00
|
|
|
}
|
2003-08-04 12:47:36 +00:00
|
|
|
|
2003-01-05 22:14:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void FbWinFrame::render(const FbTk::Texture &tex, FbTk::Color &col, Pixmap &pm,
|
|
|
|
unsigned int w, unsigned int h) {
|
2003-10-09 16:48:09 +00:00
|
|
|
|
2003-01-05 22:14:10 +00:00
|
|
|
Pixmap tmp = pm;
|
2003-12-07 16:39:43 +00:00
|
|
|
if (!tex.usePixmap()) {
|
2003-01-05 22:14:10 +00:00
|
|
|
pm = None;
|
|
|
|
col = tex.color();
|
2004-01-02 13:26:44 +00:00
|
|
|
} else {
|
2003-01-05 22:14:10 +00:00
|
|
|
pm = m_imagectrl.renderImage(w, h, tex);
|
2004-01-02 13:26:44 +00:00
|
|
|
}
|
2003-06-23 14:18:54 +00:00
|
|
|
|
2003-01-05 22:14:10 +00:00
|
|
|
if (tmp)
|
|
|
|
m_imagectrl.removeImage(tmp);
|
|
|
|
|
|
|
|
}
|
2003-04-16 12:27:49 +00:00
|
|
|
|
|
|
|
void FbWinFrame::getCurrentFocusPixmap(Pixmap &label_pm, Pixmap &title_pm,
|
2003-08-13 09:34:40 +00:00
|
|
|
FbTk::Color &label_color, FbTk::Color &title_color) {
|
2003-04-16 12:27:49 +00:00
|
|
|
if (m_focused) {
|
|
|
|
if (m_label_focused_pm != 0)
|
|
|
|
label_pm = m_label_focused_pm;
|
|
|
|
else
|
|
|
|
label_color = m_label_focused_color;
|
|
|
|
|
|
|
|
if (m_title_focused_pm != 0)
|
|
|
|
title_pm = m_title_focused_pm;
|
|
|
|
else
|
|
|
|
title_color = m_title_focused_color;
|
|
|
|
|
|
|
|
} else {
|
2003-12-09 08:48:08 +00:00
|
|
|
getActiveLabelPixmap(label_pm, title_pm,
|
|
|
|
label_color, title_color);
|
2003-04-16 12:27:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2003-12-09 08:48:08 +00:00
|
|
|
// only called if not focused
|
|
|
|
void FbWinFrame::getActiveLabelPixmap(Pixmap &label_pm, Pixmap &title_pm,
|
2003-06-23 14:18:54 +00:00
|
|
|
FbTk::Color &label_color,
|
|
|
|
FbTk::Color &title_color) {
|
2003-12-09 08:48:08 +00:00
|
|
|
|
|
|
|
if (m_label_active_pm != 0)
|
|
|
|
label_pm = m_label_active_pm;
|
|
|
|
else
|
|
|
|
label_color = m_label_active_color;
|
2003-04-16 12:27:49 +00:00
|
|
|
|
|
|
|
if (m_title_unfocused_pm != 0)
|
|
|
|
title_pm = m_title_unfocused_pm;
|
|
|
|
else
|
|
|
|
title_color = m_title_unfocused_color;
|
|
|
|
}
|
|
|
|
|
|
|
|
void FbWinFrame::renderLabelButtons() {
|
2003-10-09 16:48:09 +00:00
|
|
|
|
2003-06-23 14:18:54 +00:00
|
|
|
Pixmap label_pm = 0;
|
|
|
|
Pixmap not_used_pm = 0;
|
2003-04-16 12:27:49 +00:00
|
|
|
FbTk::Color label_color;
|
|
|
|
FbTk::Color not_used_color;
|
|
|
|
getCurrentFocusPixmap(label_pm, not_used_pm,
|
|
|
|
label_color, not_used_color);
|
|
|
|
|
2003-07-28 12:11:57 +00:00
|
|
|
LabelList::iterator btn_it = m_labelbuttons.begin();
|
|
|
|
LabelList::iterator btn_it_end = m_labelbuttons.end();
|
2003-04-16 12:27:49 +00:00
|
|
|
for (; btn_it != btn_it_end; ++btn_it) {
|
2003-12-09 08:48:08 +00:00
|
|
|
if (*btn_it == m_current_label) {
|
|
|
|
if (m_focused)
|
|
|
|
renderButtonFocus(**btn_it);
|
|
|
|
else
|
|
|
|
renderButtonActive(**btn_it);
|
|
|
|
} else
|
2003-08-13 16:36:37 +00:00
|
|
|
renderButtonUnfocus(**btn_it);
|
|
|
|
|
2003-04-16 12:27:49 +00:00
|
|
|
}
|
2004-01-02 13:26:44 +00:00
|
|
|
|
2003-06-05 13:09:08 +00:00
|
|
|
if (m_current_label != 0) {
|
|
|
|
|
|
|
|
if (label_pm) {
|
|
|
|
m_current_label->setBackgroundPixmap(label_pm);
|
|
|
|
} else
|
|
|
|
m_current_label->setBackgroundColor(label_color);
|
2003-06-23 14:18:54 +00:00
|
|
|
|
2003-06-05 13:09:08 +00:00
|
|
|
}
|
2004-01-02 13:26:44 +00:00
|
|
|
|
2003-04-16 12:27:49 +00:00
|
|
|
}
|
2003-07-26 16:17:02 +00:00
|
|
|
|
2003-08-25 16:17:18 +00:00
|
|
|
void FbWinFrame::setBorderWidth(unsigned int border_width) {
|
2003-07-26 16:17:02 +00:00
|
|
|
int bw_changes = 0;
|
|
|
|
// we need to change the size of the window
|
|
|
|
// if the border width changes...
|
|
|
|
if (m_use_titlebar)
|
2003-08-25 16:17:18 +00:00
|
|
|
bw_changes += static_cast<signed>(border_width - titlebar().borderWidth());
|
2003-07-26 16:17:02 +00:00
|
|
|
if (m_use_handle)
|
2003-08-25 16:17:18 +00:00
|
|
|
bw_changes += static_cast<signed>(border_width - handle().borderWidth());
|
2003-07-26 16:17:02 +00:00
|
|
|
|
2003-08-25 16:17:18 +00:00
|
|
|
window().setBorderWidth(border_width);
|
|
|
|
window().setBorderColor(theme().border().color());
|
2003-08-25 13:15:53 +00:00
|
|
|
|
2003-08-25 16:17:18 +00:00
|
|
|
titlebar().setBorderWidth(border_width);
|
|
|
|
titlebar().setBorderColor(theme().border().color());
|
2003-08-25 13:15:53 +00:00
|
|
|
|
2003-08-25 16:17:18 +00:00
|
|
|
handle().setBorderWidth(border_width);
|
|
|
|
handle().setBorderColor(theme().border().color());
|
2003-08-25 13:15:53 +00:00
|
|
|
|
2003-08-25 16:17:18 +00:00
|
|
|
gripLeft().setBorderWidth(border_width);
|
|
|
|
gripLeft().setBorderColor(theme().border().color());
|
2003-08-25 13:15:53 +00:00
|
|
|
|
2003-08-25 16:17:18 +00:00
|
|
|
gripRight().setBorderWidth(border_width);
|
|
|
|
gripRight().setBorderColor(theme().border().color());
|
2003-07-26 16:17:02 +00:00
|
|
|
|
|
|
|
if (bw_changes != 0)
|
|
|
|
resize(width(), height() + bw_changes);
|
|
|
|
}
|
2003-08-04 12:47:36 +00:00
|
|
|
|
2003-08-19 16:15:32 +00:00
|
|
|
void FbWinFrame::renderButtonFocus(FbTk::TextButton &button) {
|
2003-08-13 16:36:37 +00:00
|
|
|
|
|
|
|
button.setGC(theme().labelTextFocusGC());
|
|
|
|
button.setJustify(theme().justify());
|
|
|
|
button.setBorderWidth(1);
|
|
|
|
|
2003-09-12 22:49:14 +00:00
|
|
|
if (m_label_focused_pm != 0) {
|
|
|
|
// already set
|
2003-12-09 08:48:08 +00:00
|
|
|
if (button.backgroundPixmap() != m_label_focused_pm)
|
|
|
|
button.setBackgroundPixmap(m_label_focused_pm);
|
2003-09-12 22:49:14 +00:00
|
|
|
} else
|
2003-08-13 16:36:37 +00:00
|
|
|
button.setBackgroundColor(m_label_focused_color);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2003-12-09 08:48:08 +00:00
|
|
|
void FbWinFrame::renderButtonActive(FbTk::TextButton &button) {
|
|
|
|
|
|
|
|
button.setGC(theme().labelTextActiveGC());
|
|
|
|
button.setJustify(theme().justify());
|
|
|
|
button.setBorderWidth(1);
|
|
|
|
|
|
|
|
if (m_label_active_pm != 0) {
|
|
|
|
// already set
|
|
|
|
if (button.backgroundPixmap() != m_label_active_pm)
|
|
|
|
button.setBackgroundPixmap(m_label_active_pm);
|
|
|
|
} else
|
|
|
|
button.setBackgroundColor(m_label_active_color);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2003-08-19 16:15:32 +00:00
|
|
|
void FbWinFrame::renderButtonUnfocus(FbTk::TextButton &button) {
|
2003-10-09 16:48:09 +00:00
|
|
|
|
|
|
|
button.setGC(theme().labelTextUnfocusGC());
|
2003-08-13 16:36:37 +00:00
|
|
|
button.setJustify(theme().justify());
|
|
|
|
button.setBorderWidth(1);
|
|
|
|
|
2003-09-12 22:49:14 +00:00
|
|
|
if (m_label_unfocused_pm != 0) {
|
|
|
|
// already set
|
2003-12-09 08:48:08 +00:00
|
|
|
if (button.backgroundPixmap() != m_label_unfocused_pm)
|
|
|
|
button.setBackgroundPixmap(m_label_unfocused_pm);
|
2003-09-12 22:49:14 +00:00
|
|
|
} else
|
2003-08-13 16:36:37 +00:00
|
|
|
button.setBackgroundColor(m_label_unfocused_color);
|
|
|
|
|
|
|
|
}
|
2004-02-28 16:54:04 +00:00
|
|
|
namespace {
|
|
|
|
class IgnoreEvent {
|
|
|
|
public:
|
|
|
|
typedef void result_type;
|
|
|
|
typedef Window argument_type;
|
|
|
|
explicit IgnoreEvent(long eventmask):
|
|
|
|
m_display(FbTk::App::instance()->display()),
|
|
|
|
m_event_mask(eventmask) {
|
|
|
|
}
|
|
|
|
|
|
|
|
void operator()(Window win) const {
|
|
|
|
static XEvent event;
|
|
|
|
while (XCheckWindowEvent(m_display, win, m_event_mask, &event))
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
private:
|
|
|
|
Display *m_display;
|
|
|
|
long m_event_mask;
|
|
|
|
};
|
|
|
|
}
|
2003-08-24 15:39:52 +00:00
|
|
|
|
2003-09-10 09:53:21 +00:00
|
|
|
void FbWinFrame::updateTransparent() {
|
2004-09-12 14:56:20 +00:00
|
|
|
if (FbTk::Transparent::haveComposite())
|
|
|
|
return;
|
2004-02-28 16:54:04 +00:00
|
|
|
|
|
|
|
m_label.clear();
|
|
|
|
m_label.updateTransparent();
|
|
|
|
m_titlebar.clear();
|
|
|
|
m_titlebar.updateTransparent();
|
2003-09-12 23:38:50 +00:00
|
|
|
|
2004-02-28 16:54:04 +00:00
|
|
|
for_each(m_labelbuttons.begin(),
|
|
|
|
m_labelbuttons.end(),
|
|
|
|
mem_fun(&FbTk::Button::clear));
|
|
|
|
|
2004-02-27 12:20:01 +00:00
|
|
|
for_each(m_buttons_left.begin(),
|
|
|
|
m_buttons_left.end(),
|
|
|
|
mem_fun(&FbTk::Button::clear));
|
2004-02-28 16:54:04 +00:00
|
|
|
|
2004-02-27 12:20:01 +00:00
|
|
|
for_each(m_buttons_right.begin(),
|
|
|
|
m_buttons_right.end(),
|
|
|
|
mem_fun(&FbTk::Button::clear));
|
2004-02-28 16:54:04 +00:00
|
|
|
// ignore exposure events, since we already cleared
|
|
|
|
// and redrawn the windows
|
|
|
|
IgnoreEvent ign(ExposureMask);
|
|
|
|
|
|
|
|
// base windows
|
|
|
|
ign(m_label.window());
|
|
|
|
ign(m_titlebar.window());
|
|
|
|
|
|
|
|
// labels
|
|
|
|
for_each(m_labelbuttons.begin(),
|
|
|
|
m_labelbuttons.end(),
|
|
|
|
FbTk::Compose(ign, mem_fun(&FbTk::Button::window)));
|
|
|
|
// win buttons
|
|
|
|
for_each(m_buttons_right.begin(),
|
|
|
|
m_buttons_right.end(),
|
|
|
|
FbTk::Compose(ign, mem_fun(&FbTk::Button::window)));
|
|
|
|
for_each(m_buttons_left.begin(),
|
|
|
|
m_buttons_left.end(),
|
|
|
|
FbTk::Compose(ign, mem_fun(&FbTk::Button::window)));
|
2003-09-12 23:38:50 +00:00
|
|
|
|
2003-09-14 10:32:31 +00:00
|
|
|
m_grip_left.clear();
|
2003-09-10 09:53:21 +00:00
|
|
|
m_grip_left.updateTransparent();
|
2004-02-28 16:54:04 +00:00
|
|
|
ign(m_grip_left.window());
|
2003-09-14 10:32:31 +00:00
|
|
|
m_grip_right.clear();
|
2003-09-10 09:53:21 +00:00
|
|
|
m_grip_right.updateTransparent();
|
2004-02-28 16:54:04 +00:00
|
|
|
ign(m_grip_right.window());
|
2003-09-14 10:32:31 +00:00
|
|
|
m_handle.clear();
|
2003-09-10 09:53:21 +00:00
|
|
|
m_handle.updateTransparent();
|
2004-02-28 16:54:04 +00:00
|
|
|
ign(m_handle.window());
|
2003-09-10 09:53:21 +00:00
|
|
|
}
|
2003-09-11 13:17:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
// this function translates its arguments according to win_gravity
|
|
|
|
// if win_gravity is negative, it does an inverse translation
|
2003-09-11 19:55:27 +00:00
|
|
|
// This function should be used when a window is mapped/unmapped/pos configured
|
2003-09-11 13:17:14 +00:00
|
|
|
void FbWinFrame::gravityTranslate(int &x, int &y, int win_gravity, bool move_frame) {
|
|
|
|
bool invert = false;
|
|
|
|
if (win_gravity < 0) {
|
|
|
|
invert = true;
|
|
|
|
win_gravity = -win_gravity; // make +ve
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Ok, so, gravity says which point of the frame is put where the
|
|
|
|
* corresponding bit of window would have been
|
|
|
|
* Thus, x,y always refers to where top left of the WINDOW would be placed
|
|
|
|
* but given that we're wrapping it in a frame, we actually place
|
|
|
|
* it so that the given reference point is in the same spot as the
|
|
|
|
* window's reference point would have been.
|
|
|
|
* i.e. east gravity says that the centre of the right hand side of the
|
|
|
|
* frame is placed where the centre of the rhs of the window would
|
|
|
|
* have been if there was no frame.
|
|
|
|
* Hope that makes enough sense.
|
|
|
|
*
|
|
|
|
* If you get confused with the calculations, draw a picture.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
// We calculate offsets based on the gravity and frame aspects
|
|
|
|
// and at the end apply those offsets +ve or -ve depending on 'invert'
|
|
|
|
|
|
|
|
int x_offset = 0;
|
|
|
|
int y_offset = 0;
|
|
|
|
|
2003-09-16 13:11:42 +00:00
|
|
|
// mostly no X offset, since we don't have extra frame on the sides
|
2003-09-11 13:17:14 +00:00
|
|
|
switch (win_gravity) {
|
2003-09-11 13:35:37 +00:00
|
|
|
case NorthWestGravity:
|
|
|
|
case NorthGravity:
|
|
|
|
case NorthEastGravity:
|
2003-09-11 13:17:14 +00:00
|
|
|
// no offset, since the top point is still the same
|
|
|
|
break;
|
2003-09-11 13:35:37 +00:00
|
|
|
case SouthWestGravity:
|
|
|
|
case SouthGravity:
|
|
|
|
case SouthEastGravity:
|
|
|
|
// window shifted down by height of titlebar, and the handle
|
|
|
|
// since that's necessary to get the bottom of the frame
|
|
|
|
// all the way up
|
2003-09-16 13:11:42 +00:00
|
|
|
if (m_use_titlebar)
|
|
|
|
y_offset -= m_titlebar.height() + m_titlebar.borderWidth();
|
|
|
|
if (m_use_handle)
|
|
|
|
y_offset -= m_handle.height() + m_handle.borderWidth();
|
2003-09-11 13:35:37 +00:00
|
|
|
break;
|
|
|
|
case WestGravity:
|
|
|
|
case EastGravity:
|
|
|
|
case CenterGravity:
|
|
|
|
// these centered ones are a little more interesting
|
2003-09-16 13:11:42 +00:00
|
|
|
if (m_use_titlebar)
|
|
|
|
y_offset -= m_titlebar.height() + m_titlebar.borderWidth();
|
|
|
|
if (m_use_handle)
|
|
|
|
y_offset -= m_handle.height() + m_handle.borderWidth();
|
|
|
|
y_offset /= 2;
|
2003-09-11 13:35:37 +00:00
|
|
|
break;
|
|
|
|
case StaticGravity:
|
2003-09-16 13:11:42 +00:00
|
|
|
if (m_use_titlebar)
|
|
|
|
y_offset -= m_titlebar.height() + m_titlebar.borderWidth();
|
|
|
|
// static is the only one that also has the
|
|
|
|
// border taken into account
|
|
|
|
x_offset -= m_window.borderWidth();
|
|
|
|
y_offset -= m_window.borderWidth();
|
2003-09-11 13:17:14 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (invert) {
|
|
|
|
x_offset = -x_offset;
|
|
|
|
y_offset = -y_offset;
|
|
|
|
}
|
|
|
|
|
|
|
|
x += x_offset;
|
|
|
|
y += y_offset;
|
|
|
|
|
|
|
|
if (move_frame && (x_offset != 0 || y_offset != 0)) {
|
2004-08-11 13:17:56 +00:00
|
|
|
move(x, y);
|
2003-09-11 13:17:14 +00:00
|
|
|
}
|
|
|
|
}
|