/*
* tbutton.cc
*
* Copyright (C) 1995, 1996, 1997, 1997, 1998, 1999, 2000, 2001, 2002 Kenichi Kourai
* Copyright (C) 1999, 2000, 2001, 2002 Luiz Blanes
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with blwm; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/xpm.h>
#include "main.h"
#include "misc.h"
#include "util.h"
#include "blwm.h"
#include "tbutton.h"
#include "sbutton.h"
#include "taskbar.h"
#include "startmenu.h"
#include "blwmrc.h"
#include "paging.h"
#include "desktop.h"
#include "pixmap_image.h"
#include "tooltip.h"
#include "bitmaps/tile0.xpm"
Rect TaskbarButton::rcTButton;
XFontSet* TaskbarButton::fsb;
BlImage* TaskbarButton::imgTile;
int TaskbarButton::BUTTON_HEIGHT;
TaskbarButton::TaskbarButton(Blwm* blwm, const Rect& rc, BlImage* image)
: Button(taskBar->w, rc), img(image), focus(False), blWm(blwm)
{
name = shortname = NULL;
if (blWm != rootBlwm)
ChangeName();
toolTip->SetString(name, &fsTaskbar);
}
TaskbarButton::~TaskbarButton()
{
delete [] shortname;
delete [] name;
BlImage::Destroy(img);
}
// image must be passed as a duplicated object
void TaskbarButton::SetImage(BlImage* image)
{
if (img)
BlImage::Destroy(img);
img = image;
}
void TaskbarButton::ChangeName()
{
XTextProperty xtp;
char** cl;
int n;
delete [] name;
if (XGetWMIconName(display, blWm->GetWin(), &xtp) != 0) {
XmbTextPropertyToTextList(display, &xtp, &cl, &n);
if (cl) {
name = new char[strlen(cl[0]) + 1];
strcpy(name, cl[0]);
XFreeStringList(cl);
}
else {
name = new char[9];
strcpy(name, "Untitled");
}
}
else {
name = new char[9];
strcpy(name, "Untitled");
}
CalcShortName();
toolTip->SetString(name, &fsTaskbar);
}
void TaskbarButton::CalcShortName()
{
delete [] shortname;
shortname = GetFixName(fsTaskbar, name,
rc.width - TB_MARGIN * 2 - SYMBOL_SIZE - 2);
}
/*
* MapButton --
* Map taskbar button.
*/
void TaskbarButton::MapButton()
{
ASSERT(blWm);
if (!blWm->CheckFlags(TRANSIENT)) {
taskBar->RedrawAllTaskbarButtons();
Button::MapButton();
}
}
/*
* UnmapButton --
* Unmap taskbar button.
*/
void TaskbarButton::UnmapButton()
{
ASSERT(blWm);
if (!blWm->CheckFlags(TRANSIENT)) {
Button::UnmapButton();
taskBar->RedrawAllTaskbarButtons();
}
}
/*
* DrawButton --
* Draw taskbar button.
*/
void TaskbarButton::DrawButton()
{
/*
* No button for the transient window.
*/
if (blWm->CheckFlags(TRANSIENT))
return;
FillBackground();
Point offset;
offset.x = TB_MARGIN;
offset.y = TB_MARGIN + (BUTTON_HEIGHT - TB_MARGIN * 2 - SYMBOL_SIZE) / 2;
/*
* Draw the pixmap of the taskbar button.
*/
if (CheckState(PUSH) & focus)
img->Display(frame, Point(offset.x, offset.y + 1));
else
img->Display(frame, offset);
// Draw the title of the taskbar button.
DrawName();
Button::DrawButton();
}
/*
* FillBackground --
* Paint the background of taskbar button gray or tile pattern.
*/
void TaskbarButton::FillBackground()
{
if (CheckState(PUSH) && focus) {
if (TaskbarImage) {
imgBack->SetBackground(None);
imgActiveBack->SetBackground(frame);
XClearWindow(display, frame);
}
else {
imgTile->SetBackground(frame);
XClearWindow(display, frame);
XSetForeground(display, gc, white.pixel);
XDrawLine(display, frame, gc, 2, 2, rc.width, 2);
}
}
else {
if (TaskbarImage) {
imgActiveBack->SetBackground(None);
imgBack->SetBackground(frame);
}
else {
if (CheckState(PUSH))
XSetWindowBackground(display, frame, ButtonActiveColor.pixel);
else
XSetWindowBackground(display, frame, ButtonColor.pixel);
}
XClearWindow(display, frame);
}
}
/*
* DrawName --
* Draw the text taskbar button.
*/
void TaskbarButton::DrawName()
{
ASSERT(blWm);
if (blWm->CheckFlags(TRANSIENT))
return;
XRectangle ink, log;
int y;
XmbTextExtents(fsTaskbar, shortname, strlen(shortname), &ink, &log);
y = (BUTTON_HEIGHT - log.height) / 2 - log.y;
if (CheckState(PUSH) & focus) {
if (UseBoldFont) {
XSetForeground(display, gc, ButtonStringActiveColor.pixel);
XmbDrawString(display, frame, *fsb, gc,
TB_MARGIN + SYMBOL_SIZE + 2, y + 1,
shortname, strlen(shortname));
}
else {
XSetForeground(display, gc, ButtonStringActiveColor.pixel);
XmbDrawString(display, frame, fsTaskbar, gc,
TB_MARGIN + SYMBOL_SIZE + 2, y + 1,
shortname, strlen(shortname));
XmbDrawString(display, frame, fsTaskbar, gc,
TB_MARGIN + SYMBOL_SIZE + 3, y + 1,
shortname, strlen(shortname));
}
if (strlen(name) > strlen(shortname)) {
XRectangle xr[3] =
{{TB_MARGIN + SYMBOL_SIZE + 2 + log.width + 2, y - 1, 2, 2},
{TB_MARGIN + SYMBOL_SIZE + 2 + log.width + 5, y - 1, 2, 2},
{TB_MARGIN + SYMBOL_SIZE + 2 + log.width + 8, y - 1, 2, 2}};
XFillRectangles(display, frame, gc, xr, 3);
}
}
else {
XSetForeground(display, gc, ButtonStringColor.pixel);
XmbDrawString(display, frame, fsTaskbar, gc,
TB_MARGIN + SYMBOL_SIZE + 2, y,
shortname, strlen(shortname));
if (strlen(name) > strlen(shortname)) {
XRectangle xr[3] =
{{TB_MARGIN + SYMBOL_SIZE + 2 + log.width + 2, y - 2, 1, 2},
{TB_MARGIN + SYMBOL_SIZE + 2 + log.width + 5, y - 2, 1, 2},
{TB_MARGIN + SYMBOL_SIZE + 2 + log.width + 8, y - 2, 1, 2}};
XFillRectangles(display, frame, gc, xr, 3);
}
}
}
/*
* Button1Press --
* Process the press of button1(mouse left button).
*/
void TaskbarButton::Button1Press()
{
Menu::UnmapAllMenus(False);
Button::Button1Press();
}
/*
* ExecButtonFunc --
* Give the focus to the taskbar button and the corresponding window.
*/
void TaskbarButton::ExecButtonFunc(ButtonState bs)
{
if (bs == PUSH) {
ASSERT(blWm);
if (focus) {
if (RestoreMinimize) {
blWm->MinimizeWindow();
return;
}
}
else {
if (blWm->CheckStatus(MINIMIZE_WINDOW))
blWm->RestoreWindow();
else {
if (!blWm->CheckFocus() && !blWm->CheckFlags(NO_FOCUS))
blWm->SetFocus();
blWm->RaiseWindow(True);
blWm->AdjustPage();
}
}
/*
* When button is released, state is set to NORMAL in default.
* So state sets to PUSH here.
*/
if (blWm->CheckFlags(NO_FOCUS))
state = NORMAL;
else
state = PUSH;
}
}
/*
* Button3Release --
* Process the release of button3(mouse right button).
*/
void TaskbarButton::Button3Release(const Point& ptRoot)
{
Point ptNew;
Bool noFocus = False;
int dir;
/*
* When button3 is released, map menu if start menu isn't mapped.
*/
if (startMenu == NULL || !startMenu->CheckMapped()) {
ASSERT(Blwm::focusBlwm);
if (Blwm::focusBlwm->CheckMenuMapped())
Blwm::focusBlwm->UnmapMenu();
ASSERT(blWm);
/*
* Temporarily, give the focus.
*/
if (blWm->CheckFlags(NO_FOCUS)) {
blWm->ResetFlags(NO_FOCUS);
noFocus = True;
}
if (!blWm->CheckFocus())
blWm->SetFocus();
blWm->RaiseWindow(True);
blWm->AdjustPage();
ASSERT(blWm->ctrlMenu);
blWm->ctrlMenu->SetBlwm(blWm);
ptNew = blWm->ctrlMenu->GetFixedMenuPos(ptRoot, dir);
blWm->ctrlMenu->MapMenu(ptNew.x, ptNew.y, dir);
if (noFocus)
blWm->SetFlags(NO_FOCUS);
}
}
void TaskbarButton::Enter()
{
// if a start menu or abbreviated by ...
if (shortname == NULL || strcmp(name, shortname) != 0)
Button::Enter();
}
void TaskbarButton::MoveResizeButton(const Rect& rect)
{
rc = rect;
XMoveResizeWindow(display, frame, rc.x, rc.y, rc.width, rc.height);
CalcShortName();
}
void TaskbarButton::Initialize()
{
fsb = UseBoldFont ? &fsBoldTaskbar : &fsTaskbar;
BUTTON_HEIGHT = TaskbarButtonHeight;
rcTButton = Rect(0, 0, 160, TaskbarButton::BUTTON_HEIGHT);
imgTile = new PixmapImage(tile0);
}
syntax highlighted by Code2HTML, v. 0.9.1