2003-01-05 22:14:10 +00:00
|
|
|
// FbWinFrame.cc for Fluxbox Window Manager
|
2006-02-16 06:53:05 +00:00
|
|
|
// Copyright (c) 2003 - 2006 Henrik Kinnunen (fluxgen at fluxbox dot org)
|
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.
|
|
|
|
|
|
|
|
#include "FbWinFrame.hh"
|
2003-08-19 16:15:32 +00:00
|
|
|
|
|
|
|
#include "FbTk/ImageControl.hh"
|
|
|
|
#include "FbTk/EventManager.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"
|
2007-12-28 05:47:55 +00:00
|
|
|
#include "FbTk/CompareEqual.hh"
|
2008-08-15 12:19:40 +00:00
|
|
|
#include "FbTk/StringUtil.hh"
|
2008-01-15 07:45:57 +00:00
|
|
|
#include "FbTk/TextUtils.hh"
|
2008-01-07 20:08:56 +00:00
|
|
|
|
2003-07-10 11:36:21 +00:00
|
|
|
#include "FbWinFrameTheme.hh"
|
2006-03-20 11:31:24 +00:00
|
|
|
#include "Screen.hh"
|
2008-01-07 20:08:56 +00:00
|
|
|
#include "FocusableTheme.hh"
|
2007-10-13 21:51:37 +00:00
|
|
|
#include "IconButton.hh"
|
2005-06-19 12:12:54 +00:00
|
|
|
|
2003-04-14 15:01:55 +00:00
|
|
|
#include <algorithm>
|
2003-09-11 13:35:37 +00:00
|
|
|
#include <X11/X.h>
|
2003-01-05 22:14:10 +00:00
|
|
|
|
2006-10-27 06:57:43 +00:00
|
|
|
using std::mem_fun;
|
|
|
|
using std::string;
|
|
|
|
|
2008-01-05 01:39:19 +00:00
|
|
|
FbWinFrame::FbWinFrame(BScreen &screen,
|
2008-01-07 20:08:56 +00:00
|
|
|
FocusableTheme<FbWinFrameTheme> &theme,
|
2008-01-05 01:39:19 +00:00
|
|
|
FbTk::ImageControl &imgctrl,
|
2006-03-20 11:31:24 +00:00
|
|
|
FbTk::XLayer &layer,
|
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):
|
2006-03-20 11:31:24 +00:00
|
|
|
m_screen(screen),
|
2003-01-05 22:14:10 +00:00
|
|
|
m_theme(theme),
|
|
|
|
m_imagectrl(imgctrl),
|
2008-01-05 01:39:19 +00:00
|
|
|
m_window(theme->screenNum(), x, y, width, height,
|
2007-10-13 21:51:37 +00:00
|
|
|
ButtonPressMask | ButtonReleaseMask |
|
2007-11-22 20:21:47 +00:00
|
|
|
ButtonMotionMask | EnterWindowMask |
|
|
|
|
LeaveWindowMask, true),
|
2006-03-20 11:31:24 +00:00
|
|
|
m_layeritem(window(), layer),
|
2006-10-27 06:57:43 +00:00
|
|
|
m_titlebar(m_window, 0, 0, 100, 16,
|
2003-01-05 22:14:10 +00:00
|
|
|
ButtonPressMask | ButtonReleaseMask |
|
|
|
|
ButtonMotionMask | ExposureMask |
|
|
|
|
EnterWindowMask | LeaveWindowMask),
|
2005-06-19 12:12:54 +00:00
|
|
|
m_tab_container(m_titlebar),
|
2008-01-05 01:39:19 +00:00
|
|
|
m_label(m_titlebar, m_theme->font(), ""),
|
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,
|
2007-12-30 15:32:53 +00:00
|
|
|
ButtonPressMask | ButtonReleaseMask |
|
|
|
|
ButtonMotionMask | ExposureMask |
|
|
|
|
EnterWindowMask | LeaveWindowMask),
|
2003-01-05 22:14:10 +00:00
|
|
|
m_clientarea(m_window, 0, 0, 100, 100,
|
|
|
|
ButtonPressMask | ButtonReleaseMask |
|
|
|
|
ButtonMotionMask | ExposureMask |
|
|
|
|
EnterWindowMask | LeaveWindowMask),
|
|
|
|
m_bevel(1),
|
2006-10-27 06:57:43 +00:00
|
|
|
m_use_titlebar(true),
|
|
|
|
m_use_tabs(true),
|
2003-01-07 01:30:57 +00:00
|
|
|
m_use_handle(true),
|
2003-05-01 13:19:36 +00:00
|
|
|
m_visible(false),
|
2003-02-15 01:54:54 +00:00
|
|
|
m_button_pm(0),
|
2006-03-22 13:06:00 +00:00
|
|
|
m_tabmode(screen.getDefaultInternalTabs()?INTERNAL:EXTERNAL),
|
2006-07-17 20:55:20 +00:00
|
|
|
m_active_orig_client_bw(0),
|
2005-04-10 18:18:14 +00:00
|
|
|
m_need_render(true),
|
2006-07-17 20:55:20 +00:00
|
|
|
m_button_size(1),
|
|
|
|
m_height_before_shade(1),
|
2008-01-07 20:08:56 +00:00
|
|
|
m_focused_alpha(AlphaAcc(*theme.focusedTheme(), &FbWinFrameTheme::alpha)),
|
|
|
|
m_unfocused_alpha(AlphaAcc(*theme.unfocusedTheme(), &FbWinFrameTheme::alpha)),
|
2008-01-05 01:39:19 +00:00
|
|
|
m_shape(m_window, theme->shapePlace()),
|
2007-08-09 03:45:31 +00:00
|
|
|
m_disable_themeshape(false) {
|
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
|
|
|
FbWinFrame::~FbWinFrame() {
|
|
|
|
removeEventHandler();
|
|
|
|
removeAllButtons();
|
|
|
|
}
|
|
|
|
|
2006-03-20 11:31:24 +00:00
|
|
|
bool FbWinFrame::setTabMode(TabMode tabmode) {
|
|
|
|
if (m_tabmode == tabmode)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
bool ret = true;
|
|
|
|
|
2006-10-27 06:57:43 +00:00
|
|
|
// setting tabmode to notset forces it through when
|
2006-03-20 11:31:24 +00:00
|
|
|
// something is likely to change
|
|
|
|
if (tabmode == NOTSET)
|
|
|
|
tabmode = m_tabmode;
|
|
|
|
|
2006-03-22 12:23:17 +00:00
|
|
|
m_tabmode = tabmode;
|
|
|
|
|
2006-03-20 11:31:24 +00:00
|
|
|
// reparent tab container
|
|
|
|
if (tabmode == EXTERNAL) {
|
2006-03-22 12:23:17 +00:00
|
|
|
m_label.show();
|
2006-03-20 11:31:24 +00:00
|
|
|
m_tab_container.setBorderWidth(m_window.borderWidth());
|
|
|
|
m_tab_container.setEventMask(
|
|
|
|
ButtonPressMask | ButtonReleaseMask |
|
|
|
|
ButtonMotionMask | ExposureMask |
|
|
|
|
EnterWindowMask | LeaveWindowMask);
|
|
|
|
|
2006-03-26 12:32:15 +00:00
|
|
|
alignTabs();
|
2006-03-22 13:06:00 +00:00
|
|
|
|
2006-03-20 11:31:24 +00:00
|
|
|
// TODO: tab position
|
|
|
|
if (m_use_tabs && m_visible)
|
|
|
|
m_tab_container.show();
|
|
|
|
else {
|
|
|
|
ret = false;
|
|
|
|
m_tab_container.hide();
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
2006-03-26 12:32:15 +00:00
|
|
|
m_tab_container.setUpdateLock(true);
|
|
|
|
|
2007-12-28 05:47:55 +00:00
|
|
|
m_tab_container.setAlignment(FbTk::Container::RELATIVE);
|
2006-03-26 04:02:30 +00:00
|
|
|
m_tab_container.setOrientation(FbTk::ROT0);
|
2006-03-20 11:31:24 +00:00
|
|
|
if (m_tab_container.parent()->window() == m_screen.rootWindow().window()) {
|
|
|
|
m_layeritem.removeWindow(m_tab_container);
|
2006-06-24 14:05:19 +00:00
|
|
|
m_tab_container.hide();
|
2006-03-20 11:31:24 +00:00
|
|
|
m_tab_container.reparent(m_titlebar, m_label.x(), m_label.y());
|
2006-06-24 14:05:19 +00:00
|
|
|
m_tab_container.invalidateBackground();
|
2006-03-22 12:23:17 +00:00
|
|
|
m_tab_container.resize(m_label.width(), m_label.height());
|
2006-03-20 11:31:24 +00:00
|
|
|
m_tab_container.raise();
|
|
|
|
}
|
|
|
|
m_tab_container.setBorderWidth(0);
|
|
|
|
m_tab_container.setMaxTotalSize(0);
|
2006-03-22 13:06:00 +00:00
|
|
|
m_tab_container.setUpdateLock(false);
|
2006-03-20 11:31:24 +00:00
|
|
|
m_tab_container.setMaxSizePerClient(0);
|
2006-03-22 13:06:00 +00:00
|
|
|
|
|
|
|
renderTabContainer();
|
|
|
|
applyTabContainer();
|
|
|
|
m_tab_container.clear();
|
|
|
|
|
2006-03-23 02:06:51 +00:00
|
|
|
m_tab_container.raise();
|
|
|
|
m_tab_container.show();
|
2006-10-27 06:57:43 +00:00
|
|
|
|
2006-03-20 11:31:24 +00:00
|
|
|
if (!m_use_tabs)
|
|
|
|
ret = false;
|
2006-03-23 02:06:51 +00:00
|
|
|
|
2006-03-22 12:23:17 +00:00
|
|
|
m_label.hide();
|
2006-03-20 11:31:24 +00:00
|
|
|
// reconfigure();
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2003-01-05 22:14:10 +00:00
|
|
|
void FbWinFrame::hide() {
|
|
|
|
m_window.hide();
|
2006-03-20 11:31:24 +00:00
|
|
|
if (m_tabmode == EXTERNAL && m_use_tabs)
|
|
|
|
m_tab_container.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;
|
2005-04-10 18:18:14 +00:00
|
|
|
|
|
|
|
if (m_need_render) {
|
|
|
|
renderAll();
|
2007-08-09 03:45:31 +00:00
|
|
|
applyAll();
|
2005-04-10 18:18:14 +00:00
|
|
|
clearAll();
|
|
|
|
}
|
|
|
|
|
2006-03-20 11:31:24 +00:00
|
|
|
if (m_tabmode == EXTERNAL && m_use_tabs)
|
|
|
|
m_tab_container.show();
|
|
|
|
|
2003-01-05 22:14:10 +00:00
|
|
|
m_window.showSubwindows();
|
|
|
|
m_window.show();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
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
|
2008-08-15 11:36:02 +00:00
|
|
|
m_state.shaded = !m_state.shaded;
|
|
|
|
if (m_state.shaded) { // i.e. should be shaded now
|
2003-01-05 22:14:10 +00:00
|
|
|
m_height_before_shade = m_window.height();
|
2003-02-23 21:32:37 +00:00
|
|
|
m_window.resize(m_window.width(), m_titlebar.height());
|
2006-03-24 15:19:02 +00:00
|
|
|
alignTabs();
|
2006-07-06 20:09:23 +00:00
|
|
|
// need to update our shape
|
2007-08-09 03:45:31 +00:00
|
|
|
m_shape.update();
|
2003-04-03 22:37:43 +00:00
|
|
|
} else { // should be unshaded
|
2007-04-23 16:09:00 +00:00
|
|
|
m_window.resize(m_window.width(), m_height_before_shade);
|
2003-04-03 22:37:43 +00:00
|
|
|
reconfigure();
|
2003-01-05 22:14:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-07-03 17:18:17 +00:00
|
|
|
void FbWinFrame::move(int x, int y) {
|
|
|
|
moveResize(x, y, 0, 0, true, false);
|
2003-09-24 14:02:25 +00:00
|
|
|
}
|
2003-08-04 12:47:36 +00:00
|
|
|
|
2006-07-03 17:18:17 +00:00
|
|
|
void FbWinFrame::resize(unsigned int width, unsigned int height) {
|
|
|
|
moveResize(0, 0, width, height, false, true);
|
2003-09-24 14:02:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// need an atomic moveresize where possible
|
2006-10-27 06:57:43 +00:00
|
|
|
void FbWinFrame::moveResizeForClient(int x, int y,
|
|
|
|
unsigned int width, unsigned int height,
|
|
|
|
int win_gravity,
|
|
|
|
unsigned int client_bw,
|
2006-07-17 20:55:20 +00:00
|
|
|
bool move, bool resize) {
|
2003-09-24 14:02:25 +00:00
|
|
|
// total height for frame
|
2003-08-04 12:47:36 +00:00
|
|
|
|
2006-07-03 17:18:17 +00:00
|
|
|
if (resize) // these fns check if the elements are "on"
|
|
|
|
height += titlebarHeight() + handleHeight();
|
2003-08-04 12:47:36 +00:00
|
|
|
|
2006-07-03 17:18:17 +00:00
|
|
|
gravityTranslate(x, y, win_gravity, client_bw, false);
|
|
|
|
setActiveGravity(win_gravity, client_bw);
|
|
|
|
moveResize(x, y, width, height, move, resize);
|
2003-09-24 14:02:25 +00:00
|
|
|
}
|
2003-09-10 09:53:21 +00:00
|
|
|
|
2006-10-27 06:57:43 +00:00
|
|
|
void FbWinFrame::resizeForClient(unsigned int width, unsigned int height,
|
2006-07-17 20:55:20 +00:00
|
|
|
int win_gravity, unsigned int client_bw) {
|
2006-07-04 13:20:04 +00:00
|
|
|
moveResizeForClient(0, 0, width, height, win_gravity, client_bw, false, true);
|
2003-01-05 22:14:10 +00:00
|
|
|
}
|
|
|
|
|
2006-07-03 17:18:17 +00:00
|
|
|
void FbWinFrame::moveResize(int x, int y, unsigned int width, unsigned int height, bool move, bool resize) {
|
2006-10-27 06:57:43 +00:00
|
|
|
if (move && x == window().x() && y == window().y())
|
2003-09-24 14:02:25 +00:00
|
|
|
move = false;
|
|
|
|
|
2008-08-16 12:54:07 +00:00
|
|
|
if (resize && (m_state.shaded || (width == FbWinFrame::width() &&
|
|
|
|
height == FbWinFrame::height())))
|
2003-09-24 14:02:25 +00:00
|
|
|
resize = false;
|
|
|
|
|
|
|
|
if (!move && !resize)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (move && resize) {
|
|
|
|
m_window.moveResize(x, y, width, height);
|
2005-04-10 18:18:14 +00:00
|
|
|
notifyMoved(false); // will reconfigure
|
2003-09-24 14:02:25 +00:00
|
|
|
} else if (move) {
|
|
|
|
m_window.move(x, y);
|
|
|
|
// this stuff will be caught by reconfigure if resized
|
2005-04-10 18:18:14 +00:00
|
|
|
notifyMoved(true);
|
2003-01-05 22:14:10 +00:00
|
|
|
} else {
|
|
|
|
m_window.resize(width, height);
|
|
|
|
}
|
|
|
|
|
2008-08-18 08:45:44 +00:00
|
|
|
if (move || (resize && m_screen.getTabPlacement() != TOPLEFT &&
|
|
|
|
m_screen.getTabPlacement() != LEFTTOP))
|
2006-03-20 11:31:24 +00:00
|
|
|
alignTabs();
|
|
|
|
|
|
|
|
if (resize) {
|
2006-03-26 04:02:30 +00:00
|
|
|
if (m_tabmode == EXTERNAL) {
|
|
|
|
switch(m_screen.getTabPlacement()) {
|
|
|
|
case LEFTTOP:
|
|
|
|
case RIGHTTOP:
|
2008-08-18 08:45:44 +00:00
|
|
|
case LEFT:
|
|
|
|
case RIGHT:
|
2006-03-26 04:02:30 +00:00
|
|
|
case LEFTBOTTOM:
|
|
|
|
case RIGHTBOTTOM:
|
|
|
|
m_tab_container.setMaxTotalSize(height);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
m_tab_container.setMaxTotalSize(width);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2003-09-24 14:02:25 +00:00
|
|
|
reconfigure();
|
2006-03-20 11:31:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-10-27 06:57:43 +00:00
|
|
|
void FbWinFrame::quietMoveResize(int x, int y,
|
2006-03-20 11:31:24 +00:00
|
|
|
unsigned int width, unsigned int height) {
|
|
|
|
m_window.moveResize(x, y, width, height);
|
|
|
|
if (m_tabmode == EXTERNAL) {
|
2006-10-27 06:57:43 +00:00
|
|
|
|
2006-03-26 04:02:30 +00:00
|
|
|
switch(m_screen.getTabPlacement()) {
|
|
|
|
case LEFTTOP:
|
|
|
|
case RIGHTTOP:
|
2008-08-18 08:45:44 +00:00
|
|
|
case LEFT:
|
|
|
|
case RIGHT:
|
2006-03-26 04:02:30 +00:00
|
|
|
case LEFTBOTTOM:
|
|
|
|
case RIGHTBOTTOM:
|
|
|
|
m_tab_container.setMaxTotalSize(height);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
m_tab_container.setMaxTotalSize(width);
|
|
|
|
break;
|
|
|
|
}
|
2006-03-20 11:31:24 +00:00
|
|
|
alignTabs();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void FbWinFrame::alignTabs() {
|
2006-03-22 12:23:17 +00:00
|
|
|
if (m_tabmode != EXTERNAL)
|
|
|
|
return;
|
|
|
|
|
2006-04-04 12:16:26 +00:00
|
|
|
|
2006-03-26 12:32:15 +00:00
|
|
|
FbTk::Orientation orig_orient = m_tab_container.orientation();
|
|
|
|
unsigned int orig_tabwidth = m_tab_container.maxWidthPerClient();
|
|
|
|
|
|
|
|
if (orig_tabwidth != m_screen.getTabWidth())
|
2006-03-23 01:06:29 +00:00
|
|
|
m_tab_container.setMaxSizePerClient(m_screen.getTabWidth());
|
2006-03-22 13:06:00 +00:00
|
|
|
|
2006-03-22 12:23:17 +00:00
|
|
|
int tabx = 0, taby = 0;
|
2006-03-22 13:06:00 +00:00
|
|
|
switch (m_screen.getTabPlacement()) {
|
2006-03-22 12:23:17 +00:00
|
|
|
case TOPLEFT:
|
2006-03-26 12:32:15 +00:00
|
|
|
if (orig_orient != FbTk::ROT0) m_tab_container.hide();
|
2006-03-26 04:02:30 +00:00
|
|
|
m_tab_container.setOrientation(FbTk::ROT0);
|
2007-12-28 05:47:55 +00:00
|
|
|
m_tab_container.setAlignment(FbTk::Container::LEFT);
|
2006-06-10 16:31:47 +00:00
|
|
|
m_tab_container.setMaxTotalSize(m_window.width());
|
2006-03-22 12:23:17 +00:00
|
|
|
tabx = x();
|
|
|
|
taby = y() - yOffset();
|
|
|
|
break;
|
2008-08-18 08:45:44 +00:00
|
|
|
case TOP:
|
|
|
|
if (orig_orient != FbTk::ROT0) m_tab_container.hide();
|
|
|
|
m_tab_container.setOrientation(FbTk::ROT0);
|
|
|
|
m_tab_container.setAlignment(FbTk::Container::CENTER);
|
|
|
|
m_tab_container.setMaxTotalSize(m_window.width());
|
|
|
|
tabx = x() + (width() - m_tab_container.width())/2;
|
|
|
|
taby = y() - yOffset();
|
|
|
|
break;
|
2006-03-22 12:23:17 +00:00
|
|
|
case TOPRIGHT:
|
2006-03-26 12:32:15 +00:00
|
|
|
if (orig_orient != FbTk::ROT0) m_tab_container.hide();
|
2006-03-26 04:02:30 +00:00
|
|
|
m_tab_container.setOrientation(FbTk::ROT0);
|
2007-12-28 05:47:55 +00:00
|
|
|
m_tab_container.setAlignment(FbTk::Container::RIGHT);
|
2006-06-10 16:31:47 +00:00
|
|
|
m_tab_container.setMaxTotalSize(m_window.width());
|
2006-03-22 12:23:17 +00:00
|
|
|
tabx = x() + width() - m_tab_container.width();
|
|
|
|
taby = y() - yOffset();
|
|
|
|
break;
|
2006-03-26 04:02:30 +00:00
|
|
|
case LEFTTOP:
|
2006-03-26 12:32:15 +00:00
|
|
|
if (orig_orient != FbTk::ROT270) m_tab_container.hide();
|
2006-03-26 04:02:30 +00:00
|
|
|
m_tab_container.setOrientation(FbTk::ROT270);
|
2007-12-28 05:47:55 +00:00
|
|
|
m_tab_container.setAlignment(FbTk::Container::RIGHT);
|
2006-06-10 16:31:47 +00:00
|
|
|
m_tab_container.setMaxTotalSize(m_window.height());
|
2006-03-26 04:02:30 +00:00
|
|
|
tabx = x() - xOffset();
|
|
|
|
taby = y();
|
|
|
|
break;
|
2008-08-18 08:45:44 +00:00
|
|
|
case LEFT:
|
|
|
|
if (orig_orient != FbTk::ROT270) m_tab_container.hide();
|
|
|
|
m_tab_container.setOrientation(FbTk::ROT270);
|
|
|
|
m_tab_container.setAlignment(FbTk::Container::CENTER);
|
|
|
|
m_tab_container.setMaxTotalSize(m_window.height());
|
|
|
|
tabx = x() - xOffset();
|
|
|
|
taby = y() + (height() - m_tab_container.height())/2;
|
|
|
|
break;
|
2006-03-26 04:02:30 +00:00
|
|
|
case LEFTBOTTOM:
|
2006-03-26 12:32:15 +00:00
|
|
|
if (orig_orient != FbTk::ROT270) m_tab_container.hide();
|
2006-03-26 04:02:30 +00:00
|
|
|
m_tab_container.setOrientation(FbTk::ROT270);
|
2007-12-28 05:47:55 +00:00
|
|
|
m_tab_container.setAlignment(FbTk::Container::LEFT);
|
2006-06-10 16:31:47 +00:00
|
|
|
m_tab_container.setMaxTotalSize(m_window.height());
|
2006-03-26 04:02:30 +00:00
|
|
|
tabx = x() - xOffset();
|
|
|
|
taby = y() + height() - m_tab_container.height();
|
|
|
|
break;
|
|
|
|
case RIGHTTOP:
|
2006-03-26 12:32:15 +00:00
|
|
|
if (orig_orient != FbTk::ROT90) m_tab_container.hide();
|
2006-03-26 04:02:30 +00:00
|
|
|
m_tab_container.setOrientation(FbTk::ROT90);
|
2007-12-28 05:47:55 +00:00
|
|
|
m_tab_container.setAlignment(FbTk::Container::LEFT);
|
2006-06-10 16:31:47 +00:00
|
|
|
m_tab_container.setMaxTotalSize(m_window.height());
|
2006-04-04 12:16:26 +00:00
|
|
|
tabx = x() + width() + m_window.borderWidth();
|
2006-03-26 04:02:30 +00:00
|
|
|
taby = y();
|
|
|
|
break;
|
2008-08-18 08:45:44 +00:00
|
|
|
case RIGHT:
|
|
|
|
if (orig_orient != FbTk::ROT90) m_tab_container.hide();
|
|
|
|
m_tab_container.setOrientation(FbTk::ROT90);
|
|
|
|
m_tab_container.setAlignment(FbTk::Container::CENTER);
|
|
|
|
m_tab_container.setMaxTotalSize(m_window.height());
|
|
|
|
tabx = x() + width() + m_window.borderWidth();
|
|
|
|
taby = y() + (height() - m_tab_container.height())/2;
|
|
|
|
break;
|
2006-03-26 04:02:30 +00:00
|
|
|
case RIGHTBOTTOM:
|
2006-03-26 12:32:15 +00:00
|
|
|
if (orig_orient != FbTk::ROT90) m_tab_container.hide();
|
2006-03-26 04:02:30 +00:00
|
|
|
m_tab_container.setOrientation(FbTk::ROT90);
|
2007-12-28 05:47:55 +00:00
|
|
|
m_tab_container.setAlignment(FbTk::Container::RIGHT);
|
2006-06-10 16:31:47 +00:00
|
|
|
m_tab_container.setMaxTotalSize(m_window.height());
|
2006-04-04 12:16:26 +00:00
|
|
|
tabx = x() + width() + m_window.borderWidth();
|
2006-03-26 04:02:30 +00:00
|
|
|
taby = y() + height() - m_tab_container.height();
|
|
|
|
break;
|
2006-03-22 12:23:17 +00:00
|
|
|
case BOTTOMLEFT:
|
2006-03-26 12:32:15 +00:00
|
|
|
if (orig_orient != FbTk::ROT0) m_tab_container.hide();
|
2006-03-26 04:02:30 +00:00
|
|
|
m_tab_container.setOrientation(FbTk::ROT0);
|
2007-12-28 05:47:55 +00:00
|
|
|
m_tab_container.setAlignment(FbTk::Container::LEFT);
|
2006-06-10 16:31:47 +00:00
|
|
|
m_tab_container.setMaxTotalSize(m_window.width());
|
2006-03-22 12:23:17 +00:00
|
|
|
tabx = x();
|
|
|
|
taby = y() + height() + m_window.borderWidth();
|
|
|
|
break;
|
2008-08-18 08:45:44 +00:00
|
|
|
case BOTTOM:
|
|
|
|
if (orig_orient != FbTk::ROT0) m_tab_container.hide();
|
|
|
|
m_tab_container.setOrientation(FbTk::ROT0);
|
|
|
|
m_tab_container.setAlignment(FbTk::Container::CENTER);
|
|
|
|
m_tab_container.setMaxTotalSize(m_window.width());
|
|
|
|
tabx = x() + (width() - m_tab_container.width())/2;
|
|
|
|
taby = y() + height() + m_window.borderWidth();
|
|
|
|
break;
|
2006-03-22 12:23:17 +00:00
|
|
|
case BOTTOMRIGHT:
|
2006-03-26 12:32:15 +00:00
|
|
|
if (orig_orient != FbTk::ROT0) m_tab_container.hide();
|
2006-03-26 04:02:30 +00:00
|
|
|
m_tab_container.setOrientation(FbTk::ROT0);
|
2007-12-28 05:47:55 +00:00
|
|
|
m_tab_container.setAlignment(FbTk::Container::RIGHT);
|
2006-06-10 16:31:47 +00:00
|
|
|
m_tab_container.setMaxTotalSize(m_window.width());
|
2006-03-22 12:23:17 +00:00
|
|
|
tabx = x() + width() - m_tab_container.width();
|
|
|
|
taby = y() + height() + m_window.borderWidth();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2006-03-26 12:32:15 +00:00
|
|
|
unsigned int w = m_window.width(), h = m_window.height();
|
|
|
|
translateSize(m_tab_container.orientation(), w, h);
|
|
|
|
|
|
|
|
if (m_tab_container.orientation() != orig_orient ||
|
|
|
|
m_tab_container.maxWidthPerClient() != orig_tabwidth) {
|
2006-03-26 04:07:14 +00:00
|
|
|
renderTabContainer();
|
2006-03-26 12:32:15 +00:00
|
|
|
if (m_visible && m_use_tabs) {
|
|
|
|
applyTabContainer();
|
|
|
|
m_tab_container.clear();
|
|
|
|
m_tab_container.show();
|
2006-04-05 03:48:16 +00:00
|
|
|
}
|
2006-03-26 04:07:14 +00:00
|
|
|
}
|
|
|
|
|
2006-03-26 12:32:15 +00:00
|
|
|
if (m_tab_container.parent()->window() != m_screen.rootWindow().window()) {
|
|
|
|
m_tab_container.reparent(m_screen.rootWindow(), tabx, taby);
|
2006-06-24 14:05:19 +00:00
|
|
|
m_label.clear();
|
2006-03-26 12:32:15 +00:00
|
|
|
m_layeritem.addWindow(m_tab_container);
|
|
|
|
} else {
|
|
|
|
m_tab_container.move(tabx, taby);
|
|
|
|
}
|
2003-01-05 22:14:10 +00:00
|
|
|
}
|
|
|
|
|
2005-04-10 18:18:14 +00:00
|
|
|
void FbWinFrame::notifyMoved(bool clear) {
|
|
|
|
// not important if no alpha...
|
2008-08-15 11:36:02 +00:00
|
|
|
unsigned char alpha = getAlpha(m_state.focused);
|
2006-10-27 06:57:43 +00:00
|
|
|
if (alpha == 255)
|
2005-04-10 18:18:14 +00:00
|
|
|
return;
|
|
|
|
|
2008-08-16 12:54:07 +00:00
|
|
|
if ((m_tabmode == EXTERNAL && m_use_tabs) || m_use_titlebar) {
|
2006-03-20 11:31:24 +00:00
|
|
|
m_tab_container.parentMoved();
|
|
|
|
m_tab_container.for_each(mem_fun(&FbTk::Button::parentMoved));
|
|
|
|
}
|
|
|
|
|
2005-04-10 18:18:14 +00:00
|
|
|
if (m_use_titlebar) {
|
2006-04-09 13:38:13 +00:00
|
|
|
if (m_tabmode != INTERNAL)
|
2006-03-20 11:31:24 +00:00
|
|
|
m_label.parentMoved();
|
|
|
|
|
2005-04-10 18:18:14 +00:00
|
|
|
m_titlebar.parentMoved();
|
|
|
|
|
|
|
|
for_each(m_buttons_left.begin(),
|
|
|
|
m_buttons_left.end(),
|
|
|
|
mem_fun(&FbTk::Button::parentMoved));
|
|
|
|
for_each(m_buttons_right.begin(),
|
|
|
|
m_buttons_right.end(),
|
|
|
|
mem_fun(&FbTk::Button::parentMoved));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_use_handle) {
|
|
|
|
m_handle.parentMoved();
|
|
|
|
m_grip_left.parentMoved();
|
|
|
|
m_grip_right.parentMoved();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (clear && (m_use_handle || m_use_titlebar)) {
|
|
|
|
clearAll();
|
2006-03-20 11:31:24 +00:00
|
|
|
} else if (clear && m_tabmode == EXTERNAL && m_use_tabs)
|
|
|
|
m_tab_container.clear();
|
2005-04-10 18:18:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void FbWinFrame::clearAll() {
|
2005-04-13 14:39:25 +00:00
|
|
|
|
2005-04-10 18:18:14 +00:00
|
|
|
if (m_use_titlebar) {
|
|
|
|
redrawTitlebar();
|
|
|
|
|
|
|
|
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));
|
2006-03-20 11:31:24 +00:00
|
|
|
} else if (m_tabmode == EXTERNAL && m_use_tabs)
|
|
|
|
m_tab_container.clear();
|
2005-04-10 18:18:14 +00:00
|
|
|
|
|
|
|
if (m_use_handle) {
|
|
|
|
m_handle.clear();
|
|
|
|
m_grip_left.clear();
|
|
|
|
m_grip_right.clear();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-01-05 22:14:10 +00:00
|
|
|
void FbWinFrame::setFocus(bool newvalue) {
|
2008-08-15 11:36:02 +00:00
|
|
|
if (m_state.focused == newvalue)
|
2003-01-05 22:14:10 +00:00
|
|
|
return;
|
|
|
|
|
2008-08-15 11:36:02 +00:00
|
|
|
m_state.focused = newvalue;
|
2003-10-31 10:37:09 +00:00
|
|
|
|
2007-01-27 20:34:57 +00:00
|
|
|
if (FbTk::Transparent::haveRender() &&
|
|
|
|
getAlpha(true) != getAlpha(false)) { // different alpha for focused and unfocused
|
2008-08-15 11:36:02 +00:00
|
|
|
unsigned char alpha = getAlpha(m_state.focused);
|
2005-04-10 18:18:14 +00:00
|
|
|
if (FbTk::Transparent::haveComposite()) {
|
2007-01-06 19:03:33 +00:00
|
|
|
m_tab_container.setAlpha(255);
|
2005-04-10 18:18:14 +00:00
|
|
|
m_window.setOpaque(alpha);
|
|
|
|
} else {
|
2005-06-19 12:12:54 +00:00
|
|
|
m_tab_container.setAlpha(alpha);
|
2007-01-06 19:03:33 +00:00
|
|
|
m_window.setOpaque(255);
|
2005-04-10 18:18:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-05-24 08:03:59 +00:00
|
|
|
setBorderWidth();
|
2007-12-23 21:33:10 +00:00
|
|
|
|
2007-01-06 19:03:33 +00:00
|
|
|
applyAll();
|
2005-04-10 18:18:14 +00:00
|
|
|
clearAll();
|
2003-01-05 22:14:10 +00:00
|
|
|
}
|
|
|
|
|
2008-08-15 11:46:06 +00:00
|
|
|
void FbWinFrame::setFullscreen(bool newvalue) {
|
|
|
|
if (newvalue == m_state.fullscreen)
|
|
|
|
return;
|
|
|
|
|
|
|
|
m_state.fullscreen = newvalue;
|
|
|
|
applyDecorations();
|
|
|
|
}
|
|
|
|
|
2007-01-07 11:55:14 +00:00
|
|
|
void FbWinFrame::setAlpha(bool focused, unsigned char alpha) {
|
|
|
|
if (focused)
|
|
|
|
m_focused_alpha = alpha;
|
|
|
|
else
|
|
|
|
m_unfocused_alpha = alpha;
|
|
|
|
|
2008-08-15 11:36:02 +00:00
|
|
|
if (m_state.focused == focused)
|
2007-12-27 04:42:10 +00:00
|
|
|
applyAlpha();
|
2007-01-07 11:55:14 +00:00
|
|
|
}
|
|
|
|
|
2007-12-27 04:42:10 +00:00
|
|
|
void FbWinFrame::applyAlpha() {
|
2008-08-15 11:36:02 +00:00
|
|
|
unsigned char alpha = getAlpha(m_state.focused);
|
2007-02-02 19:04:57 +00:00
|
|
|
if (FbTk::Transparent::haveComposite())
|
2007-12-27 04:42:10 +00:00
|
|
|
m_window.setOpaque(alpha);
|
2007-02-02 19:04:57 +00:00
|
|
|
else {
|
|
|
|
// don't need to setAlpha, since apply updates them anyway
|
|
|
|
applyAll();
|
|
|
|
clearAll();
|
|
|
|
}
|
2007-01-07 11:55:14 +00:00
|
|
|
}
|
|
|
|
|
2007-12-27 04:42:10 +00:00
|
|
|
unsigned char FbWinFrame::getAlpha(bool focused) const {
|
|
|
|
return focused ? m_focused_alpha : m_unfocused_alpha;
|
|
|
|
}
|
|
|
|
|
|
|
|
void FbWinFrame::setDefaultAlpha() {
|
|
|
|
if (getUseDefaultAlpha())
|
|
|
|
return;
|
|
|
|
m_focused_alpha.restoreDefault();
|
|
|
|
m_unfocused_alpha.restoreDefault();
|
|
|
|
applyAlpha();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool FbWinFrame::getUseDefaultAlpha() const {
|
|
|
|
return m_focused_alpha.isDefault() && m_unfocused_alpha.isDefault();
|
|
|
|
}
|
|
|
|
|
2003-01-05 22:14:10 +00:00
|
|
|
void FbWinFrame::addLeftButton(FbTk::Button *btn) {
|
|
|
|
if (btn == 0) // valid button?
|
|
|
|
return;
|
|
|
|
|
2005-04-10 18:18:14 +00:00
|
|
|
applyButton(*btn); // setup theme and other stuff
|
2006-10-27 06:57:43 +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;
|
|
|
|
|
2005-04-10 18:18:14 +00:00
|
|
|
applyButton(*btn); // setup theme and other stuff
|
2003-01-05 22:14:10 +00:00
|
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2008-01-07 10:26:32 +00:00
|
|
|
void FbWinFrame::createTab(FbTk::Button &button) {
|
|
|
|
button.show();
|
|
|
|
button.setEventMask(ExposureMask | ButtonPressMask |
|
|
|
|
ButtonReleaseMask | ButtonMotionMask |
|
|
|
|
EnterWindowMask);
|
|
|
|
FbTk::EventManager::instance()->add(button, button.window());
|
|
|
|
|
|
|
|
m_tab_container.insertItem(&button);
|
2003-04-14 15:01:55 +00:00
|
|
|
}
|
|
|
|
|
2007-10-13 21:51:37 +00:00
|
|
|
void FbWinFrame::removeTab(IconButton *btn) {
|
2005-06-19 12:12:54 +00:00
|
|
|
if (m_tab_container.removeItem(btn))
|
|
|
|
delete btn;
|
|
|
|
}
|
2003-07-28 12:11:57 +00:00
|
|
|
|
|
|
|
|
2005-06-19 12:12:54 +00:00
|
|
|
void FbWinFrame::moveLabelButtonLeft(FbTk::TextButton &btn) {
|
|
|
|
m_tab_container.moveItem(&btn, -1);
|
2003-07-28 12:11:57 +00:00
|
|
|
}
|
|
|
|
|
2005-06-19 12:12:54 +00:00
|
|
|
void FbWinFrame::moveLabelButtonRight(FbTk::TextButton &btn) {
|
2005-07-25 23:17:41 +00:00
|
|
|
m_tab_container.moveItem(&btn, +1);
|
2003-07-28 12:11:57 +00:00
|
|
|
}
|
|
|
|
|
2004-11-24 23:27:28 +00:00
|
|
|
void FbWinFrame::moveLabelButtonTo(FbTk::TextButton &btn, int x, int y) {
|
2005-06-19 12:12:54 +00:00
|
|
|
m_tab_container.moveItemTo(&btn, x, y);
|
2004-11-24 23:27:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2005-06-19 12:12:54 +00:00
|
|
|
void FbWinFrame::moveLabelButtonLeftOf(FbTk::TextButton &btn, const FbTk::TextButton &dest) {
|
2005-10-19 04:46:05 +00:00
|
|
|
int dest_pos = m_tab_container.find(&dest);
|
|
|
|
int cur_pos = m_tab_container.find(&btn);
|
|
|
|
if (dest_pos < 0 || cur_pos < 0)
|
2005-05-03 09:25:46 +00:00
|
|
|
return;
|
2005-10-19 04:46:05 +00:00
|
|
|
int movement=dest_pos - cur_pos;
|
|
|
|
if(movement>0)
|
|
|
|
movement-=1;
|
|
|
|
// else
|
|
|
|
// movement-=1;
|
2005-05-03 09:25:46 +00:00
|
|
|
|
2005-10-19 04:46:05 +00:00
|
|
|
m_tab_container.moveItem(&btn, movement);
|
2004-11-24 23:27:28 +00:00
|
|
|
}
|
|
|
|
|
2005-06-19 12:12:54 +00:00
|
|
|
void FbWinFrame::moveLabelButtonRightOf(FbTk::TextButton &btn, const FbTk::TextButton &dest) {
|
2005-10-19 04:46:05 +00:00
|
|
|
int dest_pos = m_tab_container.find(&dest);
|
|
|
|
int cur_pos = m_tab_container.find(&btn);
|
|
|
|
if (dest_pos < 0 || cur_pos < 0 )
|
2005-05-03 09:25:46 +00:00
|
|
|
return;
|
2005-10-19 04:46:05 +00:00
|
|
|
int movement=dest_pos - cur_pos;
|
|
|
|
if(movement<0)
|
|
|
|
movement+=1;
|
2005-05-03 09:25:46 +00:00
|
|
|
|
2005-10-19 04:46:05 +00:00
|
|
|
m_tab_container.moveItem(&btn, movement);
|
2004-11-24 23:27:28 +00:00
|
|
|
}
|
|
|
|
|
2007-10-13 21:51:37 +00:00
|
|
|
void FbWinFrame::setLabelButtonFocus(IconButton &btn) {
|
2006-06-24 18:19:49 +00:00
|
|
|
if (btn.parent() != &m_tab_container)
|
|
|
|
return;
|
2007-10-13 21:51:37 +00:00
|
|
|
m_label.setText(btn.text());
|
2006-06-24 18:19: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
|
|
|
|
2004-01-02 13:26:44 +00:00
|
|
|
win.setBorderWidth(0);
|
|
|
|
|
2005-05-03 09:25:46 +00:00
|
|
|
XChangeSaveSet(win.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);
|
2008-08-21 14:05:44 +00:00
|
|
|
win.reparent(m_window, clientArea().x(), clientArea().y());
|
2004-01-02 13:26:44 +00:00
|
|
|
|
|
|
|
m_window.setEventMask(ButtonPressMask | ButtonReleaseMask |
|
2007-11-22 20:21:47 +00:00
|
|
|
ButtonMotionMask | EnterWindowMask |
|
|
|
|
LeaveWindowMask | SubstructureRedirectMask);
|
2003-01-05 22:14:10 +00:00
|
|
|
|
2005-05-03 09:25:46 +00:00
|
|
|
XFlush(win.display());
|
2003-01-05 22:14:10 +00:00
|
|
|
|
2008-08-21 14:05:44 +00:00
|
|
|
// remask window so we get events
|
2003-04-14 23:40:41 +00:00
|
|
|
XSetWindowAttributes attrib_set;
|
2008-08-21 14:05:44 +00:00
|
|
|
attrib_set.event_mask = PropertyChangeMask | StructureNotifyMask | FocusChangeMask | KeyPressMask;
|
2006-10-27 06:57:43 +00:00
|
|
|
attrib_set.do_not_propagate_mask = ButtonPressMask | ButtonReleaseMask |
|
2003-04-14 23:40:41 +00:00
|
|
|
ButtonMotionMask;
|
2003-01-05 22:14:10 +00:00
|
|
|
|
2005-05-03 09:25:46 +00:00
|
|
|
XChangeWindowAttributes(win.display(), win.window(), CWEventMask|CWDontPropagate, &attrib_set);
|
2003-01-05 22:14:10 +00:00
|
|
|
|
2007-10-13 21:51:37 +00:00
|
|
|
if (isVisible())
|
|
|
|
win.show();
|
2004-01-02 13:26:44 +00:00
|
|
|
win.raise();
|
2003-10-28 02:17:03 +00:00
|
|
|
m_window.showSubwindows();
|
2005-05-02 01:17:08 +00:00
|
|
|
|
2003-01-05 22:14:10 +00:00
|
|
|
}
|
|
|
|
|
2006-03-20 11:31:24 +00:00
|
|
|
bool FbWinFrame::hideTabs() {
|
|
|
|
if (m_tabmode == INTERNAL || !m_use_tabs) {
|
|
|
|
m_use_tabs = false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_use_tabs = false;
|
|
|
|
m_tab_container.hide();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool FbWinFrame::showTabs() {
|
|
|
|
if (m_tabmode == INTERNAL || m_use_tabs) {
|
|
|
|
m_use_tabs = true;
|
|
|
|
return false; // nothing changed
|
|
|
|
}
|
|
|
|
|
|
|
|
m_use_tabs = true;
|
|
|
|
if (m_visible)
|
|
|
|
m_tab_container.show();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
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());
|
2006-03-20 11:31:24 +00:00
|
|
|
|
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() {
|
2008-01-05 01:39:19 +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
|
|
|
|
2007-07-02 05:26:32 +00:00
|
|
|
m_use_handle = true;
|
|
|
|
|
2005-04-10 18:18:14 +00:00
|
|
|
// weren't previously rendered...
|
|
|
|
renderHandles();
|
2007-07-02 05:26:32 +00:00
|
|
|
applyHandles();
|
2004-01-23 10:38:25 +00:00
|
|
|
|
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-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();
|
2005-06-19 12:12:54 +00:00
|
|
|
evm.add(evh, m_tab_container);
|
2006-03-20 11:31:24 +00:00
|
|
|
evm.add(evh, m_label);
|
2003-01-05 22:14:10 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
remove event handler from windows
|
|
|
|
*/
|
|
|
|
void FbWinFrame::removeEventHandler() {
|
|
|
|
FbTk::EventManager &evm = *FbTk::EventManager::instance();
|
2005-06-19 12:12:54 +00:00
|
|
|
evm.remove(m_tab_container);
|
2006-03-20 11:31:24 +00:00
|
|
|
evm.remove(m_label);
|
2003-01-05 22:14:10 +00:00
|
|
|
evm.remove(m_titlebar);
|
|
|
|
evm.remove(m_handle);
|
|
|
|
evm.remove(m_grip_right);
|
|
|
|
evm.remove(m_grip_left);
|
|
|
|
evm.remove(m_window);
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
2005-06-19 12:12:54 +00:00
|
|
|
} else if (m_tab_container == event.window) {
|
|
|
|
m_tab_container.clearArea(event.x, event.y, event.width, event.height);
|
2006-03-20 11:31:24 +00:00
|
|
|
} else if (m_label == event.window) {
|
|
|
|
m_label.clearArea(event.x, event.y, event.width, event.height);
|
2003-09-12 22:49:14 +00:00
|
|
|
} 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);
|
|
|
|
} else if (m_grip_left == event.window) {
|
|
|
|
m_grip_left.clearArea(event.x, event.y, event.width, event.height);
|
|
|
|
} else if (m_grip_right == event.window) {
|
|
|
|
m_grip_right.clearArea(event.x, event.y, event.width, event.height);
|
|
|
|
} else {
|
2005-06-19 12:12:54 +00:00
|
|
|
|
|
|
|
if (m_tab_container.tryExposeEvent(event))
|
|
|
|
return;
|
|
|
|
|
2003-08-24 11:19:45 +00:00
|
|
|
// create compare function
|
2006-10-27 06:57:43 +00:00
|
|
|
// that we should use with find_if
|
2004-02-27 12:20:01 +00:00
|
|
|
FbTk::CompareEqual_base<FbTk::FbWindow, Window> compare(&FbTk::FbWindow::window,
|
|
|
|
event.window);
|
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() {
|
2005-06-19 12:12:54 +00:00
|
|
|
if (m_tab_container.empty())
|
2003-09-12 22:49:14 +00:00
|
|
|
return;
|
2003-01-09 18:03:33 +00:00
|
|
|
|
2006-07-03 17:18:17 +00:00
|
|
|
int grav_x=0, grav_y=0;
|
|
|
|
// negate gravity
|
2008-08-16 07:22:12 +00:00
|
|
|
gravityTranslate(grav_x, grav_y, -sizeHints().win_gravity, m_active_orig_client_bw, false);
|
2006-07-03 17:18:17 +00:00
|
|
|
|
2008-01-05 01:39:19 +00:00
|
|
|
m_bevel = theme()->bevelWidth();
|
2004-01-23 10:38:25 +00:00
|
|
|
|
|
|
|
unsigned int orig_handle_h = handle().height();
|
2008-01-05 01:39:19 +00:00
|
|
|
if (m_use_handle && orig_handle_h != theme()->handleWidth())
|
2004-01-23 10:38:25 +00:00
|
|
|
m_window.resize(m_window.width(), m_window.height() -
|
2008-01-05 01:39:19 +00:00
|
|
|
orig_handle_h + theme()->handleWidth());
|
2003-09-12 23:38:50 +00:00
|
|
|
|
2006-10-27 06:57:43 +00:00
|
|
|
handle().resize(handle().width(),
|
2008-01-05 01:39:19 +00:00
|
|
|
theme()->handleWidth());
|
2006-10-27 06:57:43 +00:00
|
|
|
gripLeft().resize(buttonHeight(),
|
2008-01-05 01:39:19 +00:00
|
|
|
theme()->handleWidth());
|
2006-10-27 06:57:43 +00:00
|
|
|
gripRight().resize(gripLeft().width(),
|
2003-09-12 23:38:50 +00:00
|
|
|
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();
|
2006-10-27 06:57:43 +00:00
|
|
|
} else
|
2003-10-28 02:17:03 +00:00
|
|
|
m_titlebar.lower();
|
|
|
|
|
2006-03-22 13:06:00 +00:00
|
|
|
if (m_tabmode == EXTERNAL) {
|
2006-03-26 04:02:30 +00:00
|
|
|
unsigned int neww, newh;
|
|
|
|
switch (m_screen.getTabPlacement()) {
|
|
|
|
case TOPLEFT:
|
2008-08-18 08:45:44 +00:00
|
|
|
case TOP:
|
2006-03-26 04:02:30 +00:00
|
|
|
case TOPRIGHT:
|
|
|
|
case BOTTOMLEFT:
|
2008-08-18 08:45:44 +00:00
|
|
|
case BOTTOM:
|
2006-03-26 04:02:30 +00:00
|
|
|
case BOTTOMRIGHT:
|
|
|
|
neww = m_tab_container.width();
|
|
|
|
newh = buttonHeight();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
neww = buttonHeight();
|
|
|
|
newh = m_tab_container.height();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
m_tab_container.resize(neww, newh);
|
2006-03-22 13:06:00 +00:00
|
|
|
alignTabs();
|
|
|
|
}
|
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)
|
2008-08-15 11:36:02 +00:00
|
|
|
if (!m_state.shaded) {
|
2003-04-03 22:37:43 +00:00
|
|
|
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;
|
|
|
|
}
|
2006-10-27 06:57:43 +00:00
|
|
|
|
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...
|
2006-06-24 14:05:19 +00:00
|
|
|
m_handle.invalidateBackground();
|
2004-01-23 10:38:25 +00:00
|
|
|
m_handle.moveResize(-handle_bw, ypos,
|
|
|
|
m_window.width(), grip_height);
|
|
|
|
|
2006-06-24 14:05:19 +00:00
|
|
|
m_grip_left.invalidateBackground();
|
2004-01-23 10:38:25 +00:00
|
|
|
m_grip_left.moveResize(-handle_bw, -handle_bw,
|
|
|
|
grip_width, grip_height);
|
|
|
|
|
2006-06-24 14:05:19 +00:00
|
|
|
m_grip_right.invalidateBackground();
|
2004-01-23 10:38:25 +00:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2008-08-16 07:22:12 +00:00
|
|
|
gravityTranslate(grav_x, grav_y, sizeHints().win_gravity, m_active_orig_client_bw, false);
|
2006-07-03 17:18:17 +00:00
|
|
|
// if the location changes, shift it
|
|
|
|
if (grav_x != 0 || grav_y != 0)
|
|
|
|
move(grav_x + x(), grav_y + y());
|
2003-01-05 22:14:10 +00:00
|
|
|
|
|
|
|
// render the theme
|
2005-04-13 14:39:25 +00:00
|
|
|
if (isVisible()) {
|
2007-01-06 19:03:33 +00:00
|
|
|
// update transparency settings
|
|
|
|
if (FbTk::Transparent::haveRender()) {
|
|
|
|
unsigned char alpha =
|
2008-08-15 11:36:02 +00:00
|
|
|
getAlpha(m_state.focused);
|
2007-01-06 19:03:33 +00:00
|
|
|
if (FbTk::Transparent::haveComposite()) {
|
|
|
|
m_tab_container.setAlpha(255);
|
|
|
|
m_window.setOpaque(alpha);
|
|
|
|
} else {
|
|
|
|
m_tab_container.setAlpha(alpha);
|
|
|
|
m_window.setOpaque(255);
|
|
|
|
}
|
|
|
|
}
|
2005-04-13 14:39:25 +00:00
|
|
|
renderAll();
|
|
|
|
applyAll();
|
|
|
|
clearAll();
|
|
|
|
} else {
|
|
|
|
m_need_render = true;
|
|
|
|
}
|
2003-07-10 11:36:21 +00:00
|
|
|
|
2007-08-09 03:45:31 +00:00
|
|
|
if (m_disable_themeshape)
|
2007-12-28 06:52:48 +00:00
|
|
|
m_shape.setPlaces(FbTk::Shape::NONE);
|
2007-08-09 03:45:31 +00:00
|
|
|
else
|
2008-01-05 01:39:19 +00:00
|
|
|
m_shape.setPlaces(theme()->shapePlace());
|
2003-07-10 11:36:21 +00:00
|
|
|
|
2007-08-09 03:45:31 +00:00
|
|
|
m_shape.setShapeOffsets(0, titlebarHeight());
|
2003-07-10 11:36:21 +00:00
|
|
|
|
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) {
|
2007-08-09 03:45:31 +00:00
|
|
|
m_disable_themeshape = !value;
|
|
|
|
|
|
|
|
if (m_disable_themeshape)
|
2007-12-28 06:52:48 +00:00
|
|
|
m_shape.setPlaces(FbTk::Shape::NONE);
|
2007-08-09 03:45:31 +00:00
|
|
|
else
|
2008-01-05 01:39:19 +00:00
|
|
|
m_shape.setPlaces(theme()->shapePlace());
|
2007-08-09 03:45:31 +00:00
|
|
|
|
|
|
|
}
|
2003-08-24 15:39:52 +00:00
|
|
|
|
2007-08-09 03:45:31 +00:00
|
|
|
void FbWinFrame::setShapingClient(FbTk::FbWindow *win, bool always_update) {
|
|
|
|
m_shape.setShapeSource(win, 0, titlebarHeight(), always_update);
|
2003-08-24 15:39:52 +00:00
|
|
|
}
|
|
|
|
|
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
|
|
|
|
*/
|
2005-04-26 01:41:55 +00:00
|
|
|
void FbWinFrame::redrawTitlebar() {
|
2005-06-19 12:12:54 +00:00
|
|
|
if (!m_use_titlebar || m_tab_container.empty())
|
2003-04-14 15:01:55 +00:00
|
|
|
return;
|
|
|
|
|
2004-02-27 12:20:01 +00:00
|
|
|
if (isVisible()) {
|
2005-06-19 12:12:54 +00:00
|
|
|
m_tab_container.clear();
|
2006-03-20 11:31:24 +00:00
|
|
|
m_label.clear();
|
2003-10-09 16:48:09 +00:00
|
|
|
m_titlebar.clear();
|
2003-04-14 15:01:55 +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
|
2008-01-05 01:39:19 +00:00
|
|
|
int title_height = theme()->font().height() == 0 ? 16 :
|
|
|
|
theme()->font().height() + m_bevel*2 + 2;
|
|
|
|
if (theme()->titleHeight() != 0)
|
|
|
|
title_height = theme()->titleHeight();
|
2003-08-22 15:20:32 +00:00
|
|
|
|
2003-10-05 09:03:43 +00:00
|
|
|
// if the titlebar grows in size, make sure the whole window does too
|
2006-10-27 06:57:43 +00:00
|
|
|
if (orig_height != title_height)
|
2003-10-05 09:03:43 +00:00
|
|
|
m_window.resize(m_window.width(), m_window.height()-orig_height+title_height);
|
2006-06-24 14:05:19 +00:00
|
|
|
m_titlebar.invalidateBackground();
|
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
|
2006-10-27 06:57:43 +00:00
|
|
|
unsigned int next_x = m_bevel;
|
2003-01-05 22:14:10 +00:00
|
|
|
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) {
|
2006-06-24 14:05:19 +00:00
|
|
|
// probably on theme reconfigure, leave bg alone for now
|
|
|
|
m_buttons_left[i]->invalidateBackground();
|
2006-10-27 06:57:43 +00:00
|
|
|
m_buttons_left[i]->moveResize(next_x, m_bevel,
|
2003-01-05 22:14:10 +00:00
|
|
|
button_size, button_size);
|
|
|
|
}
|
2006-10-27 06:57:43 +00:00
|
|
|
|
2003-01-05 22:14:10 +00:00
|
|
|
next_x += m_bevel;
|
2005-04-10 18:18:14 +00:00
|
|
|
|
2003-01-05 22:14:10 +00:00
|
|
|
// space left on titlebar between left and right buttons
|
2006-03-20 11:31:24 +00:00
|
|
|
int space_left = m_titlebar.width() - next_x;
|
|
|
|
|
2006-10-27 06:57:43 +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;
|
|
|
|
|
2006-03-20 11:31:24 +00:00
|
|
|
if (space_left <= 0)
|
|
|
|
space_left = 1;
|
|
|
|
|
2006-06-24 14:05:19 +00:00
|
|
|
m_label.invalidateBackground();
|
2006-03-20 11:31:24 +00:00
|
|
|
m_label.moveResize(next_x, m_bevel, space_left, button_size);
|
|
|
|
|
2006-06-24 14:05:19 +00:00
|
|
|
m_tab_container.invalidateBackground();
|
2006-03-20 11:31:24 +00:00
|
|
|
if (m_tabmode == INTERNAL)
|
|
|
|
m_tab_container.moveResize(next_x, m_bevel,
|
|
|
|
space_left, button_size);
|
2006-04-04 12:16:26 +00:00
|
|
|
else {
|
|
|
|
if (m_use_tabs) {
|
|
|
|
if (m_tab_container.orientation() == FbTk::ROT0) {
|
|
|
|
m_tab_container.resize(m_tab_container.width(), button_size);
|
|
|
|
} else {
|
|
|
|
m_tab_container.resize(button_size, m_tab_container.height());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2006-03-20 11:31:24 +00:00
|
|
|
|
|
|
|
next_x += m_label.width() + m_bevel;
|
2003-01-05 22:14:10 +00:00
|
|
|
|
|
|
|
// finaly set new buttons to the right
|
2006-10-27 06:57:43 +00:00
|
|
|
for (size_t i=0; i < m_buttons_right.size();
|
2003-01-05 22:14:10 +00:00
|
|
|
++i, next_x += button_size + m_bevel) {
|
2006-06-24 14:05:19 +00:00
|
|
|
m_buttons_right[i]->invalidateBackground();
|
2003-01-05 22:14:10 +00:00
|
|
|
m_buttons_right[i]->moveResize(next_x, m_bevel,
|
|
|
|
button_size, button_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
m_titlebar.raise(); // always on top
|
|
|
|
}
|
|
|
|
|
2005-04-10 18:18:14 +00:00
|
|
|
void FbWinFrame::renderAll() {
|
|
|
|
m_need_render = false;
|
|
|
|
|
|
|
|
renderTitlebar();
|
|
|
|
renderHandles();
|
2006-03-20 11:31:24 +00:00
|
|
|
renderTabContainer();
|
2005-04-10 18:18:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void FbWinFrame::applyAll() {
|
|
|
|
applyTitlebar();
|
|
|
|
applyHandles();
|
2006-03-20 11:31:24 +00:00
|
|
|
applyTabContainer();
|
2005-04-10 18:18:14 +00:00
|
|
|
}
|
|
|
|
|
2003-01-05 22:14:10 +00:00
|
|
|
void FbWinFrame::renderTitlebar() {
|
2003-09-12 22:49:14 +00:00
|
|
|
if (!m_use_titlebar)
|
2003-01-05 22:14:10 +00:00
|
|
|
return;
|
|
|
|
|
2005-04-10 18:18:14 +00:00
|
|
|
if (!isVisible()) {
|
|
|
|
m_need_render = true;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2003-01-05 22:14:10 +00:00
|
|
|
// render pixmaps
|
2008-01-07 20:08:56 +00:00
|
|
|
render(theme().focusedTheme()->titleTexture(), m_title_focused_color,
|
2003-01-05 22:14:10 +00:00
|
|
|
m_title_focused_pm,
|
|
|
|
m_titlebar.width(), m_titlebar.height());
|
|
|
|
|
2008-01-07 20:08:56 +00:00
|
|
|
render(theme().unfocusedTheme()->titleTexture(), m_title_unfocused_color,
|
2003-01-05 22:14:10 +00:00
|
|
|
m_title_unfocused_pm,
|
|
|
|
m_titlebar.width(), m_titlebar.height());
|
|
|
|
|
2006-03-20 11:31:24 +00:00
|
|
|
//!! TODO: don't render label if internal tabs
|
|
|
|
|
2008-01-07 20:08:56 +00:00
|
|
|
render(theme().focusedTheme()->iconbarTheme()->texture(),
|
|
|
|
m_label_focused_color, m_label_focused_pm,
|
2006-03-20 11:31:24 +00:00
|
|
|
m_label.width(), m_label.height());
|
2004-01-02 13:26:44 +00:00
|
|
|
|
2008-01-07 20:08:56 +00:00
|
|
|
render(theme().unfocusedTheme()->iconbarTheme()->texture(),
|
|
|
|
m_label_unfocused_color, m_label_unfocused_pm,
|
2006-03-20 11:31:24 +00:00
|
|
|
m_label.width(), m_label.height());
|
2003-01-05 22:14:10 +00:00
|
|
|
|
2005-04-10 18:18:14 +00:00
|
|
|
}
|
2003-12-09 08:48:08 +00:00
|
|
|
|
2006-03-20 11:31:24 +00:00
|
|
|
void FbWinFrame::renderTabContainer() {
|
|
|
|
if (!isVisible()) {
|
|
|
|
m_need_render = true;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2008-01-07 20:08:56 +00:00
|
|
|
const FbTk::Texture *tc_focused = &theme().focusedTheme()->iconbarTheme()->texture();
|
|
|
|
const FbTk::Texture *tc_unfocused = &theme().unfocusedTheme()->iconbarTheme()->texture();
|
2006-05-20 16:27:25 +00:00
|
|
|
|
|
|
|
if (m_tabmode == EXTERNAL && tc_focused->type() & FbTk::Texture::PARENTRELATIVE)
|
2008-01-07 20:08:56 +00:00
|
|
|
tc_focused = &theme().focusedTheme()->titleTexture();
|
2006-05-20 16:27:25 +00:00
|
|
|
if (m_tabmode == EXTERNAL && tc_unfocused->type() & FbTk::Texture::PARENTRELATIVE)
|
2008-01-07 20:08:56 +00:00
|
|
|
tc_unfocused = &theme().unfocusedTheme()->titleTexture();
|
2006-05-20 16:27:25 +00:00
|
|
|
|
2006-10-27 06:57:43 +00:00
|
|
|
render(*tc_focused, m_tabcontainer_focused_color,
|
2006-03-20 11:31:24 +00:00
|
|
|
m_tabcontainer_focused_pm,
|
2006-03-26 04:02:30 +00:00
|
|
|
m_tab_container.width(), m_tab_container.height(), m_tab_container.orientation());
|
2006-03-20 11:31:24 +00:00
|
|
|
|
2006-10-27 06:57:43 +00:00
|
|
|
render(*tc_unfocused, m_tabcontainer_unfocused_color,
|
2006-03-20 11:31:24 +00:00
|
|
|
m_tabcontainer_unfocused_pm,
|
2006-03-26 04:02:30 +00:00
|
|
|
m_tab_container.width(), m_tab_container.height(), m_tab_container.orientation());
|
2006-03-20 11:31:24 +00:00
|
|
|
|
2006-06-25 14:59:34 +00:00
|
|
|
renderButtons();
|
|
|
|
|
2006-03-20 11:31:24 +00:00
|
|
|
}
|
|
|
|
|
2005-04-10 18:18:14 +00:00
|
|
|
void FbWinFrame::applyTitlebar() {
|
2003-12-09 08:48:08 +00:00
|
|
|
|
2005-04-10 18:18:14 +00:00
|
|
|
// set up pixmaps for titlebar windows
|
2003-04-16 12:27:49 +00:00
|
|
|
Pixmap label_pm = None;
|
2006-10-27 06:57:43 +00:00
|
|
|
Pixmap title_pm = None;
|
2003-04-16 12:27:49 +00:00
|
|
|
FbTk::Color label_color;
|
|
|
|
FbTk::Color title_color;
|
|
|
|
getCurrentFocusPixmap(label_pm, title_pm,
|
|
|
|
label_color, title_color);
|
|
|
|
|
2008-08-15 11:36:02 +00:00
|
|
|
unsigned char alpha = getAlpha (m_state.focused);
|
2005-04-10 18:18:14 +00:00
|
|
|
m_titlebar.setAlpha(alpha);
|
2006-03-20 11:31:24 +00:00
|
|
|
m_label.setAlpha(alpha);
|
2005-04-10 18:18:14 +00:00
|
|
|
|
2006-04-17 14:24:11 +00:00
|
|
|
if (m_tabmode != INTERNAL) {
|
2008-01-07 20:08:56 +00:00
|
|
|
m_label.setGC(theme()->iconbarTheme()->text().textGC());
|
|
|
|
m_label.setJustify(theme()->iconbarTheme()->text().justify());
|
2006-03-22 12:23:17 +00:00
|
|
|
|
2006-03-26 12:32:15 +00:00
|
|
|
if (label_pm != 0)
|
|
|
|
m_label.setBackgroundPixmap(label_pm);
|
|
|
|
else
|
|
|
|
m_label.setBackgroundColor(label_color);
|
|
|
|
}
|
2006-03-20 11:31:24 +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
|
|
|
|
2005-04-10 18:18:14 +00:00
|
|
|
applyButtons();
|
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
|
|
|
|
2005-04-10 18:18:14 +00:00
|
|
|
if (!isVisible()) {
|
|
|
|
m_need_render = true;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2008-01-07 20:08:56 +00:00
|
|
|
render(theme().focusedTheme()->handleTexture(), m_handle_focused_color,
|
2003-01-05 22:14:10 +00:00
|
|
|
m_handle_focused_pm,
|
|
|
|
m_handle.width(), m_handle.height());
|
2006-10-27 06:57:43 +00:00
|
|
|
|
2008-01-07 20:08:56 +00:00
|
|
|
render(theme().unfocusedTheme()->handleTexture(), m_handle_unfocused_color,
|
2003-01-05 22:14:10 +00:00
|
|
|
m_handle_unfocused_pm,
|
|
|
|
m_handle.width(), m_handle.height());
|
|
|
|
|
2008-01-07 20:08:56 +00:00
|
|
|
render(theme().focusedTheme()->gripTexture(), m_grip_focused_color,
|
|
|
|
m_grip_focused_pm,
|
2003-01-05 22:14:10 +00:00
|
|
|
m_grip_left.width(), m_grip_left.height());
|
|
|
|
|
2008-01-07 20:08:56 +00:00
|
|
|
render(theme().unfocusedTheme()->gripTexture(), m_grip_unfocused_color,
|
2003-01-05 22:14:10 +00:00
|
|
|
m_grip_unfocused_pm,
|
|
|
|
m_grip_left.width(), m_grip_left.height());
|
|
|
|
|
2005-04-10 18:18:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void FbWinFrame::applyHandles() {
|
|
|
|
|
2008-08-15 11:36:02 +00:00
|
|
|
unsigned char alpha = getAlpha(m_state.focused);
|
2005-04-10 18:18:14 +00:00
|
|
|
m_handle.setAlpha(alpha);
|
|
|
|
m_grip_left.setAlpha(alpha);
|
|
|
|
m_grip_right.setAlpha(alpha);
|
|
|
|
|
2008-08-15 11:36:02 +00:00
|
|
|
if (m_state.focused) {
|
2005-04-10 18:18:14 +00:00
|
|
|
|
|
|
|
if (m_handle_focused_pm) {
|
|
|
|
m_handle.setBackgroundPixmap(m_handle_focused_pm);
|
|
|
|
} else {
|
|
|
|
m_handle.setBackgroundColor(m_handle_focused_color);
|
|
|
|
}
|
|
|
|
|
2003-01-05 22:14:10 +00:00
|
|
|
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);
|
2006-10-27 06:57:43 +00:00
|
|
|
}
|
2005-04-10 18:18:14 +00:00
|
|
|
|
2003-01-05 22:14:10 +00:00
|
|
|
} else {
|
2005-04-10 18:18:14 +00:00
|
|
|
|
|
|
|
if (m_handle_unfocused_pm) {
|
|
|
|
m_handle.setBackgroundPixmap(m_handle_unfocused_pm);
|
|
|
|
} else {
|
|
|
|
m_handle.setBackgroundColor(m_handle_unfocused_color);
|
2006-10-27 06:57:43 +00:00
|
|
|
}
|
2005-04-10 18:18:14 +00:00
|
|
|
|
2003-01-05 22:14:10 +00:00
|
|
|
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);
|
2006-10-27 06:57:43 +00:00
|
|
|
}
|
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::renderButtons() {
|
|
|
|
|
2005-04-10 18:18:14 +00:00
|
|
|
if (!isVisible()) {
|
|
|
|
m_need_render = true;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2008-01-07 20:08:56 +00:00
|
|
|
render(theme().focusedTheme()->buttonTexture(), m_button_color,
|
2005-04-10 18:18:14 +00:00
|
|
|
m_button_pm,
|
2003-01-05 22:14:10 +00:00
|
|
|
m_button_size, m_button_size);
|
2003-09-14 10:32:31 +00:00
|
|
|
|
2008-01-07 20:08:56 +00:00
|
|
|
render(theme().unfocusedTheme()->buttonTexture(), m_button_unfocused_color,
|
2003-01-05 22:14:10 +00:00
|
|
|
m_button_unfocused_pm,
|
|
|
|
m_button_size, m_button_size);
|
2006-10-27 06:57:43 +00:00
|
|
|
|
2008-01-05 01:39:19 +00:00
|
|
|
render(theme()->buttonPressedTexture(), m_button_pressed_color,
|
2003-01-05 22:14:10 +00:00
|
|
|
m_button_pressed_pm,
|
|
|
|
m_button_size, m_button_size);
|
2005-04-10 18:18:14 +00:00
|
|
|
}
|
2003-01-05 22:14:10 +00:00
|
|
|
|
2005-04-10 18:18:14 +00:00
|
|
|
void FbWinFrame::applyButtons() {
|
2003-01-05 22:14:10 +00:00
|
|
|
// setup left and right buttons
|
2004-02-27 12:20:01 +00:00
|
|
|
for (size_t i=0; i < m_buttons_left.size(); ++i)
|
2005-04-10 18:18:14 +00:00
|
|
|
applyButton(*m_buttons_left[i]);
|
2003-01-05 22:14:10 +00:00
|
|
|
|
2004-02-27 12:20:01 +00:00
|
|
|
for (size_t i=0; i < m_buttons_right.size(); ++i)
|
2005-04-10 18:18:14 +00:00
|
|
|
applyButton(*m_buttons_right[i]);
|
2003-01-05 22:14:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void FbWinFrame::init() {
|
2004-01-02 13:26:44 +00:00
|
|
|
|
2008-01-05 01:39:19 +00:00
|
|
|
if (theme()->handleWidth() == 0)
|
2003-10-30 20:27:51 +00:00
|
|
|
m_use_handle = false;
|
|
|
|
|
2007-08-09 03:45:31 +00:00
|
|
|
m_disable_themeshape = false;
|
2003-08-24 15:39:52 +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;
|
2005-04-10 18:18:14 +00:00
|
|
|
m_label_focused_pm = m_label_unfocused_pm = 0;
|
2006-03-20 11:31:24 +00:00
|
|
|
m_tabcontainer_focused_pm = m_tabcontainer_unfocused_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-05 22:14:10 +00:00
|
|
|
m_button_size = 26;
|
2003-06-23 14:18:54 +00:00
|
|
|
|
2006-03-20 11:31:24 +00:00
|
|
|
m_label.setBorderWidth(0);
|
2008-08-15 11:36:02 +00:00
|
|
|
m_state.shaded = false;
|
2006-03-20 11:31:24 +00:00
|
|
|
|
2006-03-22 13:06:00 +00:00
|
|
|
setTabMode(NOTSET);
|
2006-03-20 11:31:24 +00:00
|
|
|
|
|
|
|
m_label.setEventMask(ExposureMask | ButtonPressMask |
|
|
|
|
ButtonReleaseMask | ButtonMotionMask |
|
|
|
|
EnterWindowMask);
|
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);
|
2008-08-21 14:05:44 +00:00
|
|
|
|
|
|
|
// setup cursors for resize grips
|
|
|
|
gripLeft().setCursor(theme()->lowerLeftAngleCursor());
|
|
|
|
gripRight().setCursor(theme()->lowerRightAngleCursor());
|
2003-01-05 22:14:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Setups upp background, pressed pixmap/color of the button to current theme
|
|
|
|
*/
|
2005-04-10 18:18:14 +00:00
|
|
|
void FbWinFrame::applyButton(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);
|
2005-04-10 18:18:14 +00:00
|
|
|
else
|
|
|
|
btn.setPressedColor(m_button_pressed_color);
|
2003-01-05 22:14:10 +00:00
|
|
|
|
2008-08-15 11:36:02 +00:00
|
|
|
Pixmap pm = m_state.focused ? m_button_pm : m_button_unfocused_pm;
|
|
|
|
btn.setAlpha(getAlpha(m_state.focused));
|
2008-01-07 20:08:56 +00:00
|
|
|
btn.setGC(theme()->buttonPicGC());
|
|
|
|
if (pm)
|
|
|
|
btn.setBackgroundPixmap(pm);
|
|
|
|
else
|
2008-08-15 11:36:02 +00:00
|
|
|
btn.setBackgroundColor(m_state.focused ? m_button_color
|
2008-01-07 20:08:56 +00:00
|
|
|
: m_button_unfocused_color);
|
2003-01-05 22:14:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void FbWinFrame::render(const FbTk::Texture &tex, FbTk::Color &col, Pixmap &pm,
|
2006-03-26 04:02:30 +00:00
|
|
|
unsigned int w, unsigned int h, FbTk::Orientation orient) {
|
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 {
|
2006-03-26 04:02:30 +00:00
|
|
|
pm = m_imagectrl.renderImage(w, h, tex, orient);
|
2004-01-02 13:26:44 +00:00
|
|
|
}
|
2003-06-23 14:18:54 +00:00
|
|
|
|
2006-10-27 06:57:43 +00:00
|
|
|
if (tmp)
|
2003-01-05 22:14:10 +00:00
|
|
|
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) {
|
2008-08-15 11:36:02 +00:00
|
|
|
if (m_state.focused) {
|
2006-03-20 11:31:24 +00:00
|
|
|
if (m_label_focused_pm != 0)
|
|
|
|
label_pm = m_label_focused_pm;
|
2003-04-16 12:27:49 +00:00
|
|
|
else
|
2006-03-20 11:31:24 +00:00
|
|
|
label_color = m_label_focused_color;
|
2006-10-27 06:57:43 +00:00
|
|
|
|
2003-04-16 12:27:49 +00:00
|
|
|
if (m_title_focused_pm != 0)
|
|
|
|
title_pm = m_title_focused_pm;
|
|
|
|
else
|
|
|
|
title_color = m_title_focused_color;
|
|
|
|
} else {
|
2006-03-20 11:31:24 +00:00
|
|
|
if (m_label_unfocused_pm != 0)
|
|
|
|
label_pm = m_label_unfocused_pm;
|
|
|
|
else
|
|
|
|
label_color = m_label_unfocused_color;
|
2006-10-27 06:57:43 +00:00
|
|
|
|
2006-03-20 11:31:24 +00:00
|
|
|
if (m_title_unfocused_pm != 0)
|
|
|
|
title_pm = m_title_unfocused_pm;
|
|
|
|
else
|
|
|
|
title_color = m_title_unfocused_color;
|
2006-10-27 06:57:43 +00:00
|
|
|
}
|
2003-04-16 12:27:49 +00:00
|
|
|
}
|
|
|
|
|
2006-03-20 11:31:24 +00:00
|
|
|
void FbWinFrame::applyTabContainer() {
|
2008-08-15 11:36:02 +00:00
|
|
|
m_tab_container.setAlpha(getAlpha(m_state.focused));
|
2003-04-16 12:27:49 +00:00
|
|
|
|
2006-03-20 11:31:24 +00:00
|
|
|
// do the parent container
|
|
|
|
Pixmap tabcontainer_pm = None;
|
|
|
|
FbTk::Color *tabcontainer_color = NULL;
|
2008-08-15 11:36:02 +00:00
|
|
|
if (m_state.focused) {
|
2006-03-20 11:31:24 +00:00
|
|
|
if (m_tabcontainer_focused_pm != 0)
|
|
|
|
tabcontainer_pm = m_tabcontainer_focused_pm;
|
|
|
|
else
|
|
|
|
tabcontainer_color = &m_tabcontainer_focused_color;
|
|
|
|
} else {
|
|
|
|
if (m_tabcontainer_unfocused_pm != 0)
|
|
|
|
tabcontainer_pm = m_tabcontainer_unfocused_pm;
|
|
|
|
else
|
|
|
|
tabcontainer_color = &m_tabcontainer_unfocused_color;
|
2005-04-10 18:18:14 +00:00
|
|
|
}
|
2003-10-09 16:48:09 +00:00
|
|
|
|
2006-03-20 11:31:24 +00:00
|
|
|
if (tabcontainer_pm != 0)
|
|
|
|
m_tab_container.setBackgroundPixmap(tabcontainer_pm);
|
|
|
|
else
|
|
|
|
m_tab_container.setBackgroundColor(*tabcontainer_color);
|
2003-04-16 12:27:49 +00:00
|
|
|
|
2006-03-20 11:31:24 +00:00
|
|
|
// and the labelbuttons in it
|
2007-12-28 05:47:55 +00:00
|
|
|
FbTk::Container::ItemList::iterator btn_it = m_tab_container.begin();
|
|
|
|
FbTk::Container::ItemList::iterator btn_it_end = m_tab_container.end();
|
2003-04-16 12:27:49 +00:00
|
|
|
for (; btn_it != btn_it_end; ++btn_it) {
|
2007-10-13 21:51:37 +00:00
|
|
|
IconButton *btn = static_cast<IconButton *>(*btn_it);
|
|
|
|
btn->reconfigTheme();
|
2003-04-16 12:27:49 +00:00
|
|
|
}
|
|
|
|
}
|
2003-07-26 16:17:02 +00:00
|
|
|
|
2008-08-15 11:42:13 +00:00
|
|
|
int FbWinFrame::getDecoMaskFromString(const string &str_label) {
|
2008-08-15 12:19:40 +00:00
|
|
|
string label = FbTk::StringUtil::toLower(str_label);
|
|
|
|
if (label == "none")
|
2008-08-15 11:42:13 +00:00
|
|
|
return DECOR_NONE;
|
2008-08-15 12:19:40 +00:00
|
|
|
if (label == "normal")
|
2008-08-15 11:42:13 +00:00
|
|
|
return DECOR_NORMAL;
|
2008-08-15 12:19:40 +00:00
|
|
|
if (label == "tiny")
|
2008-08-15 11:42:13 +00:00
|
|
|
return DECOR_TINY;
|
2008-08-15 12:19:40 +00:00
|
|
|
if (label == "tool")
|
2008-08-15 11:42:13 +00:00
|
|
|
return DECOR_TOOL;
|
2008-08-15 12:19:40 +00:00
|
|
|
if (label == "border")
|
2008-08-15 11:42:13 +00:00
|
|
|
return DECOR_BORDER;
|
2008-08-15 12:19:40 +00:00
|
|
|
if (label == "tab")
|
2008-08-15 11:42:13 +00:00
|
|
|
return DECOR_TAB;
|
|
|
|
int mask = -1;
|
2008-08-16 12:54:07 +00:00
|
|
|
if ((str_label.size() > 1 && str_label[0] == '0' && str_label[1] == 'x') ||
|
|
|
|
(str_label.size() > 0 && isdigit(str_label[0])))
|
2008-08-15 11:42:13 +00:00
|
|
|
mask = strtol(str_label.c_str(), NULL, 0);
|
|
|
|
return mask;
|
|
|
|
}
|
|
|
|
|
2008-08-15 11:46:06 +00:00
|
|
|
bool FbWinFrame::useBorder() const {
|
|
|
|
return !m_state.fullscreen && m_state.deco_mask & DECORM_BORDER;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool FbWinFrame::useTabs() const {
|
|
|
|
return !m_state.fullscreen && m_state.deco_mask & DECORM_TAB;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool FbWinFrame::useTitlebar() const {
|
|
|
|
return !m_state.fullscreen && m_state.deco_mask & DECORM_TITLEBAR;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool FbWinFrame::useHandle() const {
|
|
|
|
return !m_state.fullscreen && m_state.deco_mask & DECORM_HANDLE;
|
|
|
|
}
|
|
|
|
|
2008-05-24 08:03:59 +00:00
|
|
|
void FbWinFrame::applyDecorations() {
|
2006-07-03 17:18:17 +00:00
|
|
|
int grav_x=0, grav_y=0;
|
|
|
|
// negate gravity
|
2008-08-16 07:22:12 +00:00
|
|
|
gravityTranslate(grav_x, grav_y, -sizeHints().win_gravity, m_active_orig_client_bw,
|
2008-05-24 08:03:59 +00:00
|
|
|
false);
|
|
|
|
|
|
|
|
bool client_move = setBorderWidth(false);
|
|
|
|
|
|
|
|
// tab deocration only affects if we're external
|
|
|
|
// must do before the setTabMode in case it goes
|
|
|
|
// to external and is meant to be hidden
|
2008-08-15 11:46:06 +00:00
|
|
|
if (useTabs())
|
2008-05-24 08:03:59 +00:00
|
|
|
client_move |= showTabs();
|
|
|
|
else
|
|
|
|
client_move |= hideTabs();
|
|
|
|
|
|
|
|
// we rely on frame not doing anything if it is already shown/hidden
|
2008-08-15 11:46:06 +00:00
|
|
|
if (useTitlebar()) {
|
2008-05-24 08:03:59 +00:00
|
|
|
client_move |= showTitlebar();
|
|
|
|
if (m_screen.getDefaultInternalTabs())
|
|
|
|
client_move |= setTabMode(INTERNAL);
|
|
|
|
else
|
|
|
|
client_move |= setTabMode(EXTERNAL);
|
|
|
|
} else {
|
|
|
|
client_move |= hideTitlebar();
|
2008-08-15 11:46:06 +00:00
|
|
|
if (useTabs())
|
2008-05-24 08:03:59 +00:00
|
|
|
client_move |= setTabMode(EXTERNAL);
|
|
|
|
}
|
|
|
|
|
2008-08-15 11:46:06 +00:00
|
|
|
if (useHandle())
|
2008-05-24 08:03:59 +00:00
|
|
|
client_move |= showHandle();
|
|
|
|
else
|
|
|
|
client_move |= hideHandle();
|
2006-07-03 17:18:17 +00:00
|
|
|
|
2008-05-24 08:03:59 +00:00
|
|
|
// apply gravity once more
|
2008-08-16 07:22:12 +00:00
|
|
|
gravityTranslate(grav_x, grav_y, sizeHints().win_gravity, m_active_orig_client_bw,
|
2008-05-24 08:03:59 +00:00
|
|
|
false);
|
2006-07-03 17:18:17 +00:00
|
|
|
|
2008-05-24 08:03:59 +00:00
|
|
|
// if the location changes, shift it
|
|
|
|
if (grav_x != 0 || grav_y != 0) {
|
|
|
|
move(grav_x + x(), grav_y + y());
|
|
|
|
client_move = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
reconfigure();
|
|
|
|
if (client_move)
|
|
|
|
frameExtentSig().notify();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool FbWinFrame::setBorderWidth(bool do_move) {
|
2008-06-04 15:48:43 +00:00
|
|
|
unsigned int border_width = theme()->border().width();
|
2008-08-15 11:46:06 +00:00
|
|
|
unsigned int win_bw = useBorder() ? border_width : 0;
|
2008-05-24 08:03:59 +00:00
|
|
|
|
|
|
|
if (border_width &&
|
|
|
|
theme()->border().color().pixel() != window().borderColor()) {
|
|
|
|
window().setBorderColor(theme()->border().color());
|
|
|
|
titlebar().setBorderColor(theme()->border().color());
|
|
|
|
handle().setBorderColor(theme()->border().color());
|
|
|
|
gripLeft().setBorderColor(theme()->border().color());
|
|
|
|
gripRight().setBorderColor(theme()->border().color());
|
2008-05-28 13:43:07 +00:00
|
|
|
tabcontainer().setBorderColor(theme()->border().color());
|
2008-05-24 08:03:59 +00:00
|
|
|
}
|
|
|
|
|
2008-06-04 15:48:43 +00:00
|
|
|
if (border_width == handle().borderWidth() &&
|
|
|
|
win_bw == window().borderWidth())
|
2008-05-24 08:03:59 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
int grav_x=0, grav_y=0;
|
|
|
|
// negate gravity
|
|
|
|
if (do_move)
|
2008-08-16 07:22:12 +00:00
|
|
|
gravityTranslate(grav_x, grav_y, -sizeHints().win_gravity,
|
2008-05-24 08:03:59 +00:00
|
|
|
m_active_orig_client_bw, false);
|
|
|
|
|
|
|
|
int bw_changes = 0;
|
2006-10-27 06:57:43 +00:00
|
|
|
// we need to change the size of the window
|
2003-07-26 16:17:02 +00:00
|
|
|
// if the border width changes...
|
2006-10-27 06:57:43 +00:00
|
|
|
if (m_use_titlebar)
|
2003-08-25 16:17:18 +00:00
|
|
|
bw_changes += static_cast<signed>(border_width - titlebar().borderWidth());
|
2006-10-27 06:57:43 +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
|
|
|
|
2008-06-04 15:48:43 +00:00
|
|
|
window().setBorderWidth(win_bw);
|
2003-08-25 13:15:53 +00:00
|
|
|
|
2006-03-20 11:31:24 +00:00
|
|
|
setTabMode(NOTSET);
|
|
|
|
|
2003-08-25 16:17:18 +00:00
|
|
|
titlebar().setBorderWidth(border_width);
|
|
|
|
handle().setBorderWidth(border_width);
|
|
|
|
gripLeft().setBorderWidth(border_width);
|
|
|
|
gripRight().setBorderWidth(border_width);
|
2003-07-26 16:17:02 +00:00
|
|
|
|
|
|
|
if (bw_changes != 0)
|
|
|
|
resize(width(), height() + bw_changes);
|
2006-03-20 11:31:24 +00:00
|
|
|
|
|
|
|
if (m_tabmode == EXTERNAL)
|
|
|
|
alignTabs();
|
2006-07-03 17:18:17 +00:00
|
|
|
|
2008-05-24 08:03:59 +00:00
|
|
|
if (do_move) {
|
|
|
|
frameExtentSig().notify();
|
2008-08-16 07:22:12 +00:00
|
|
|
gravityTranslate(grav_x, grav_y, sizeHints().win_gravity,
|
2008-05-24 08:03:59 +00:00
|
|
|
m_active_orig_client_bw, false);
|
|
|
|
// if the location changes, shift it
|
|
|
|
if (grav_x != 0 || grav_y != 0)
|
|
|
|
move(grav_x + x(), grav_y + y());
|
|
|
|
}
|
2006-07-03 17:18:17 +00:00
|
|
|
|
2008-05-24 08:03:59 +00:00
|
|
|
return true;
|
2003-07-26 16:17:02 +00:00
|
|
|
}
|
2003-08-04 12:47:36 +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
|
2006-10-27 06:57:43 +00:00
|
|
|
void FbWinFrame::gravityTranslate(int &x, int &y,
|
2006-07-17 20:55:20 +00:00
|
|
|
int win_gravity, unsigned int client_bw, bool move_frame) {
|
2003-09-11 13:17:14 +00:00
|
|
|
bool invert = false;
|
|
|
|
if (win_gravity < 0) {
|
|
|
|
invert = true;
|
|
|
|
win_gravity = -win_gravity; // make +ve
|
|
|
|
}
|
|
|
|
|
2006-10-27 06:57:43 +00:00
|
|
|
/* Ok, so, gravity says which point of the frame is put where the
|
2003-09-11 13:17:14 +00:00
|
|
|
* 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.
|
2006-10-27 06:57:43 +00:00
|
|
|
* i.e. east gravity says that the centre of the right hand side of the
|
2003-09-11 13:17:14 +00:00
|
|
|
* 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.
|
|
|
|
*
|
2006-10-27 06:57:43 +00:00
|
|
|
* NOTE: the gravity calculations are INDEPENDENT of the client
|
2006-07-03 17:18:17 +00:00
|
|
|
* window width/height.
|
|
|
|
*
|
2003-09-11 13:17:14 +00:00
|
|
|
* 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'
|
|
|
|
|
2006-07-03 17:18:17 +00:00
|
|
|
// These will be set to the resulting offsets for adjusting the frame position
|
2003-09-11 13:17:14 +00:00
|
|
|
int x_offset = 0;
|
|
|
|
int y_offset = 0;
|
|
|
|
|
2006-07-03 17:18:17 +00:00
|
|
|
// These are the amount that the frame is larger than the client window
|
|
|
|
// Note that the client window's x,y is offset by it's borderWidth, which
|
|
|
|
// is removed by fluxbox, so the gravity needs to account for this change
|
2005-03-16 23:19:36 +00:00
|
|
|
|
2006-07-03 17:18:17 +00:00
|
|
|
// these functions already check if the title/handle is used
|
|
|
|
int bw_diff = client_bw - m_window.borderWidth();
|
2008-05-25 23:08:40 +00:00
|
|
|
int height_diff = 2*bw_diff - titlebarHeight() - handleHeight();
|
|
|
|
int width_diff = 2*bw_diff;
|
2005-03-16 23:19:36 +00:00
|
|
|
|
2008-05-25 23:08:40 +00:00
|
|
|
if (win_gravity == SouthWestGravity || win_gravity == SouthGravity ||
|
|
|
|
win_gravity == SouthEastGravity)
|
|
|
|
y_offset = height_diff;
|
|
|
|
|
|
|
|
if (win_gravity == WestGravity || win_gravity == CenterGravity ||
|
|
|
|
win_gravity == EastGravity)
|
|
|
|
y_offset = height_diff/2;
|
|
|
|
|
|
|
|
if (win_gravity == NorthEastGravity || win_gravity == EastGravity ||
|
|
|
|
win_gravity == SouthEastGravity)
|
|
|
|
x_offset = width_diff;
|
|
|
|
|
|
|
|
if (win_gravity == NorthGravity || win_gravity == CenterGravity ||
|
|
|
|
win_gravity == SouthGravity)
|
|
|
|
x_offset = width_diff/2;
|
|
|
|
|
|
|
|
if (win_gravity == StaticGravity) {
|
|
|
|
x_offset = bw_diff;
|
|
|
|
y_offset = bw_diff - titlebarHeight();
|
2003-09-11 13:17:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (invert) {
|
|
|
|
x_offset = -x_offset;
|
|
|
|
y_offset = -y_offset;
|
|
|
|
}
|
|
|
|
|
|
|
|
x += x_offset;
|
|
|
|
y += y_offset;
|
2006-07-03 17:18:17 +00:00
|
|
|
|
2003-09-11 13:17:14 +00:00
|
|
|
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
|
|
|
}
|
|
|
|
}
|
2006-03-20 11:31:24 +00:00
|
|
|
|
2007-07-02 21:26:01 +00:00
|
|
|
unsigned int FbWinFrame::normalHeight() const {
|
2008-08-15 11:36:02 +00:00
|
|
|
if (m_state.shaded)
|
2007-07-02 21:26:01 +00:00
|
|
|
return m_height_before_shade;
|
|
|
|
return height();
|
|
|
|
}
|
|
|
|
|
2006-03-26 04:02:30 +00:00
|
|
|
int FbWinFrame::widthOffset() const {
|
2006-10-27 06:57:43 +00:00
|
|
|
if (m_tabmode != EXTERNAL || !m_use_tabs)
|
2006-03-20 11:31:24 +00:00
|
|
|
return 0;
|
2006-03-22 12:23:17 +00:00
|
|
|
|
|
|
|
// same height offset for top and bottom tabs
|
2006-03-26 04:02:30 +00:00
|
|
|
switch (m_screen.getTabPlacement()) {
|
|
|
|
case LEFTTOP:
|
|
|
|
case RIGHTTOP:
|
2008-08-18 08:45:44 +00:00
|
|
|
case LEFT:
|
|
|
|
case RIGHT:
|
2006-03-26 04:02:30 +00:00
|
|
|
case LEFTBOTTOM:
|
|
|
|
case RIGHTBOTTOM:
|
|
|
|
return m_tab_container.width() + m_window.borderWidth();
|
|
|
|
break;
|
2006-04-16 11:18:22 +00:00
|
|
|
default: // kill warning
|
|
|
|
break;
|
2006-03-26 04:02:30 +00:00
|
|
|
}
|
|
|
|
return 0;
|
2006-03-20 11:31:24 +00:00
|
|
|
}
|
|
|
|
|
2006-03-26 04:02:30 +00:00
|
|
|
int FbWinFrame::heightOffset() const {
|
2006-10-27 06:57:43 +00:00
|
|
|
if (m_tabmode != EXTERNAL || !m_use_tabs)
|
2006-03-22 12:23:17 +00:00
|
|
|
return 0;
|
|
|
|
|
2006-03-22 13:06:00 +00:00
|
|
|
switch (m_screen.getTabPlacement()) {
|
2006-03-22 12:23:17 +00:00
|
|
|
case TOPLEFT:
|
2008-08-18 08:45:44 +00:00
|
|
|
case TOP:
|
2006-03-22 12:23:17 +00:00
|
|
|
case TOPRIGHT:
|
|
|
|
case BOTTOMLEFT:
|
2008-08-18 08:45:44 +00:00
|
|
|
case BOTTOM:
|
2006-03-22 12:23:17 +00:00
|
|
|
case BOTTOMRIGHT:
|
2006-03-26 04:02:30 +00:00
|
|
|
return m_tab_container.height() + m_window.borderWidth();
|
|
|
|
break;
|
2006-04-16 11:18:22 +00:00
|
|
|
default: // kill warning
|
|
|
|
break;
|
2006-03-26 04:02:30 +00:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int FbWinFrame::xOffset() const {
|
2006-10-27 06:57:43 +00:00
|
|
|
if (m_tabmode != EXTERNAL || !m_use_tabs)
|
2006-03-20 11:31:24 +00:00
|
|
|
return 0;
|
2006-03-26 04:02:30 +00:00
|
|
|
|
|
|
|
switch (m_screen.getTabPlacement()) {
|
|
|
|
case LEFTTOP:
|
2008-08-18 08:45:44 +00:00
|
|
|
case LEFT:
|
2006-03-26 04:02:30 +00:00
|
|
|
case LEFTBOTTOM:
|
|
|
|
return m_tab_container.width() + m_window.borderWidth();
|
|
|
|
break;
|
2006-04-16 11:18:22 +00:00
|
|
|
default: // kill warning
|
|
|
|
break;
|
2006-03-26 04:02:30 +00:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int FbWinFrame::yOffset() const {
|
2006-10-27 06:57:43 +00:00
|
|
|
if (m_tabmode != EXTERNAL || !m_use_tabs)
|
2006-03-26 04:02:30 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
switch (m_screen.getTabPlacement()) {
|
|
|
|
case TOPLEFT:
|
2008-08-18 08:45:44 +00:00
|
|
|
case TOP:
|
2006-03-26 04:02:30 +00:00
|
|
|
case TOPRIGHT:
|
|
|
|
return m_tab_container.height() + m_window.borderWidth();
|
2006-03-22 12:23:17 +00:00
|
|
|
break;
|
2006-04-16 11:18:22 +00:00
|
|
|
default: // kill warning
|
|
|
|
break;
|
2006-03-22 12:23:17 +00:00
|
|
|
}
|
2006-03-26 04:02:30 +00:00
|
|
|
return 0;
|
2006-03-20 11:31:24 +00:00
|
|
|
}
|
|
|
|
|
2008-08-15 11:24:03 +00:00
|
|
|
void FbWinFrame::applySizeHints(unsigned int &width, unsigned int &height,
|
|
|
|
bool maximizing) const {
|
|
|
|
height -= titlebarHeight() + handleHeight();
|
|
|
|
sizeHints().apply(width, height, maximizing);
|
|
|
|
height += titlebarHeight() + handleHeight();
|
|
|
|
}
|
|
|
|
|
|
|
|
void FbWinFrame::displaySize(unsigned int width, unsigned int height) const {
|
|
|
|
unsigned int i, j;
|
|
|
|
sizeHints().displaySize(i, j,
|
|
|
|
width, height - titlebarHeight() - handleHeight());
|
|
|
|
m_screen.showGeometry(i, j);
|
|
|
|
}
|
|
|
|
|
2008-08-16 07:22:12 +00:00
|
|
|
void FbWinFrame::SizeHints::reset(const XSizeHints &sizehint) {
|
|
|
|
if (sizehint.flags & PMinSize) {
|
|
|
|
min_width = sizehint.min_width;
|
|
|
|
min_height = sizehint.min_height;
|
|
|
|
} else
|
|
|
|
min_width = min_height = 1;
|
|
|
|
|
|
|
|
if (sizehint.flags & PBaseSize) {
|
|
|
|
base_width = sizehint.base_width;
|
|
|
|
base_height = sizehint.base_height;
|
|
|
|
if (!(sizehint.flags & PMinSize)) {
|
|
|
|
min_width = base_width;
|
|
|
|
min_height = base_height;
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
base_width = base_height = 0;
|
|
|
|
|
|
|
|
if (sizehint.flags & PMaxSize) {
|
|
|
|
max_width = sizehint.max_width;
|
|
|
|
max_height = sizehint.max_height;
|
|
|
|
} else
|
|
|
|
max_width = max_height = 0; // unbounded
|
|
|
|
|
|
|
|
if (sizehint.flags & PResizeInc) {
|
|
|
|
width_inc = sizehint.width_inc;
|
|
|
|
height_inc = sizehint.height_inc;
|
|
|
|
} else
|
|
|
|
width_inc = height_inc = 1;
|
|
|
|
|
|
|
|
if (sizehint.flags & PAspect) {
|
|
|
|
min_aspect_x = sizehint.min_aspect.x;
|
|
|
|
min_aspect_y = sizehint.min_aspect.y;
|
|
|
|
max_aspect_x = sizehint.max_aspect.x;
|
|
|
|
max_aspect_y = sizehint.max_aspect.y;
|
|
|
|
} else
|
|
|
|
min_aspect_x = min_aspect_y = max_aspect_x = max_aspect_y = 0;
|
|
|
|
|
|
|
|
if (sizehint.flags & PWinGravity)
|
|
|
|
win_gravity = sizehint.win_gravity;
|
|
|
|
else
|
|
|
|
win_gravity = NorthWestGravity;
|
|
|
|
|
|
|
|
// some sanity checks
|
|
|
|
if (width_inc == 0)
|
|
|
|
width_inc = 1;
|
|
|
|
if (height_inc == 0)
|
|
|
|
height_inc = 1;
|
|
|
|
|
|
|
|
if (base_width > min_width)
|
|
|
|
min_width = base_width;
|
|
|
|
if (base_height > min_height)
|
|
|
|
min_height = base_height;
|
|
|
|
}
|
|
|
|
|
2008-08-15 11:09:15 +00:00
|
|
|
/* For aspect ratios
|
|
|
|
Note that its slightly simplified in that only the
|
|
|
|
line gradient is given - this is because for aspect
|
|
|
|
ratios, we always have the line going through the origin
|
|
|
|
|
|
|
|
* Based on this formula:
|
|
|
|
http://astronomy.swin.edu.au/~pbourke/geometry/pointline/
|
|
|
|
|
|
|
|
Note that a gradient from origin goes through ( grad , 1 )
|
|
|
|
*/
|
|
|
|
|
|
|
|
void closestPointToAspect(unsigned int &ret_x, unsigned int &ret_y,
|
|
|
|
unsigned int point_x, unsigned int point_y,
|
|
|
|
unsigned int aspect_x, unsigned int aspect_y) {
|
|
|
|
double u = static_cast<double>(point_x * aspect_x + point_y * aspect_y) /
|
|
|
|
static_cast<double>(aspect_x * aspect_x + aspect_y * aspect_y);
|
|
|
|
|
|
|
|
ret_x = static_cast<unsigned int>(u * aspect_x);
|
|
|
|
ret_y = static_cast<unsigned int>(u * aspect_y);
|
|
|
|
}
|
|
|
|
|
2008-08-15 11:16:30 +00:00
|
|
|
unsigned int increaseToMultiple(unsigned int val, unsigned int inc) {
|
|
|
|
return val % inc ? val + inc - (val % inc) : val;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int decreaseToMultiple(unsigned int val, unsigned int inc) {
|
|
|
|
return val % inc ? val - (val % inc) : val;
|
|
|
|
}
|
|
|
|
|
2008-08-15 11:09:15 +00:00
|
|
|
/**
|
|
|
|
* Changes width and height to the nearest (lower) value
|
|
|
|
* that conforms to it's size hints.
|
|
|
|
*
|
|
|
|
* display_* give the values that would be displayed
|
|
|
|
* to the user when resizing.
|
|
|
|
* We use pointers for display_* since they are optional.
|
|
|
|
*
|
|
|
|
* See ICCCM section 4.1.2.3
|
|
|
|
*/
|
|
|
|
void FbWinFrame::SizeHints::apply(unsigned int &width, unsigned int &height,
|
2008-08-15 11:16:30 +00:00
|
|
|
bool make_fit) const {
|
2008-08-15 11:09:15 +00:00
|
|
|
|
|
|
|
/* aspect ratios are applied exclusive to the base size
|
|
|
|
*
|
|
|
|
* min_aspect_x width max_aspect_x
|
|
|
|
* ------------ < ------- < ------------
|
|
|
|
* min_aspect_y height max_aspect_y
|
|
|
|
*
|
|
|
|
* The trick is how to get back to the aspect ratio with minimal
|
|
|
|
* change - do we modify x, y or both?
|
|
|
|
* A: we minimise the distance between the current point, and
|
|
|
|
* the target aspect ratio (consider them as x,y coordinates)
|
|
|
|
* Consider that the aspect ratio is a line, and the current
|
|
|
|
* w/h is a point, so we're just using the formula for
|
|
|
|
* shortest distance from a point to a line!
|
|
|
|
*/
|
|
|
|
|
2008-08-15 11:16:30 +00:00
|
|
|
// make respective to base_size
|
|
|
|
unsigned int w = width - base_width, h = height - base_height;
|
|
|
|
|
|
|
|
if (min_aspect_y > 0 && w * min_aspect_y < min_aspect_x * h) {
|
|
|
|
closestPointToAspect(w, h, w, h, min_aspect_x, min_aspect_y);
|
|
|
|
// new w must be > old w, new h must be < old h
|
|
|
|
w = increaseToMultiple(w, width_inc);
|
|
|
|
h = decreaseToMultiple(h, height_inc);
|
|
|
|
} else if (max_aspect_x > 0 && w * max_aspect_y > max_aspect_x * h) {
|
|
|
|
closestPointToAspect(w, h, w, h, max_aspect_x, max_aspect_y);
|
|
|
|
// new w must be < old w, new h must be > old h
|
|
|
|
w = decreaseToMultiple(w, width_inc);
|
|
|
|
h = increaseToMultiple(h, height_inc);
|
2008-08-15 11:09:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Check minimum size
|
2008-08-15 11:16:30 +00:00
|
|
|
if (w + base_width < min_width) {
|
|
|
|
w = increaseToMultiple(min_width - base_width, width_inc);
|
|
|
|
// need to check maximum aspect again
|
|
|
|
if (max_aspect_x > 0 && w * max_aspect_y > max_aspect_x * h)
|
|
|
|
h = increaseToMultiple(w * max_aspect_y / max_aspect_x, height_inc);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (h + base_height < min_height) {
|
|
|
|
h = increaseToMultiple(min_height - base_height, height_inc);
|
|
|
|
// need to check minimum aspect again
|
|
|
|
if (min_aspect_y > 0 && w * min_aspect_y < min_aspect_x * h)
|
|
|
|
w = increaseToMultiple(h * min_aspect_x / min_aspect_y, width_inc);
|
|
|
|
}
|
2008-08-15 11:09:15 +00:00
|
|
|
|
2008-08-15 11:16:30 +00:00
|
|
|
unsigned int max_w = make_fit && (width < max_width || max_width == 0) ?
|
|
|
|
width : max_width;
|
|
|
|
unsigned int max_h = make_fit && (height < max_height || max_height == 0) ?
|
|
|
|
height : max_height;
|
2008-08-15 11:09:15 +00:00
|
|
|
|
|
|
|
// Check maximum size
|
2008-08-15 11:16:30 +00:00
|
|
|
if (max_w > 0 && w + base_width > max_w)
|
|
|
|
w = max_w - base_width;
|
|
|
|
|
|
|
|
if (max_h > 0 && h + base_height > max_h)
|
|
|
|
h = max_h - base_height;
|
|
|
|
|
|
|
|
w = decreaseToMultiple(w, width_inc);
|
|
|
|
h = decreaseToMultiple(h, height_inc);
|
|
|
|
|
|
|
|
// need to check aspects one more time
|
|
|
|
if (min_aspect_y > 0 && w * min_aspect_y < min_aspect_x * h)
|
|
|
|
h = decreaseToMultiple(w * min_aspect_y / min_aspect_x, height_inc);
|
2008-08-15 11:09:15 +00:00
|
|
|
|
2008-08-15 11:16:30 +00:00
|
|
|
if (max_aspect_x > 0 && w * max_aspect_y > max_aspect_x * h)
|
|
|
|
w = decreaseToMultiple(h * max_aspect_x / max_aspect_y, width_inc);
|
2008-08-15 11:09:15 +00:00
|
|
|
|
2008-08-15 11:16:30 +00:00
|
|
|
width = w + base_width;
|
|
|
|
height = h + base_height;
|
2008-08-15 11:09:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// check if the given width and height satisfy the size hints
|
|
|
|
bool FbWinFrame::SizeHints::valid(unsigned int w, unsigned int h) const {
|
|
|
|
if (w < min_width || h < min_height)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (w > max_width || h > max_height)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if ((w - base_width) % width_inc != 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if ((h - base_height) % height_inc != 0)
|
|
|
|
return false;
|
|
|
|
|
2008-08-15 11:16:30 +00:00
|
|
|
if (min_aspect_x * (h - base_height) > (w - base_width) * min_aspect_y)
|
2008-08-15 11:09:15 +00:00
|
|
|
return false;
|
|
|
|
|
2008-08-15 11:16:30 +00:00
|
|
|
if (max_aspect_x * (h - base_height) < (w - base_width) * max_aspect_y)
|
2008-08-15 11:09:15 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2008-08-15 11:24:03 +00:00
|
|
|
void FbWinFrame::SizeHints::displaySize(unsigned int &i, unsigned int &j,
|
2008-08-15 11:09:15 +00:00
|
|
|
unsigned int width, unsigned int height) const {
|
2008-08-15 11:24:03 +00:00
|
|
|
i = (width - base_width) / width_inc;
|
|
|
|
j = (height - base_height) / height_inc;
|
2008-08-15 11:09:15 +00:00
|
|
|
}
|