diff options
author | Michele Calgaro <michele.calgaro@yahoo.it> | 2023-10-17 19:57:10 +0900 |
---|---|---|
committer | Michele Calgaro <michele.calgaro@yahoo.it> | 2023-10-17 19:57:10 +0900 |
commit | 0eec68a32197fcf878eabe4434badcf73e2d4741 (patch) | |
tree | 6b468db129339c1a6c67222507291dc16199b67c /client | |
download | twin-style-fahrenheit-0eec68a32197fcf878eabe4434badcf73e2d4741.tar.gz twin-style-fahrenheit-0eec68a32197fcf878eabe4434badcf73e2d4741.zip |
Initial code import from https://www.trinity-look.org/p/1100374. As per note on the website, the code has been abandoned. There is no license file in the source code, but given the package was available on the KDE3 store back in the days, it is reasonable to assume it was distributed under GPL2 license
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
Diffstat (limited to 'client')
-rw-r--r-- | client/Makefile.am | 20 | ||||
-rw-r--r-- | client/fahrenheit.desktop | 5 | ||||
-rw-r--r-- | client/fahrenheitclient.cc | 1211 | ||||
-rw-r--r-- | client/fahrenheitclient.h | 166 | ||||
-rw-r--r-- | client/pics/Makefile.am | 11 | ||||
-rw-r--r-- | client/pics/close.png | bin | 0 -> 264 bytes | |||
-rw-r--r-- | client/pics/help.png | bin | 0 -> 248 bytes | |||
-rw-r--r-- | client/pics/maximize.png | bin | 0 -> 292 bytes | |||
-rw-r--r-- | client/pics/minimize.png | bin | 0 -> 258 bytes | |||
-rw-r--r-- | client/pics/minmax.png | bin | 0 -> 235 bytes | |||
-rw-r--r-- | client/pics/sticky.png | bin | 0 -> 277 bytes | |||
-rw-r--r-- | client/pics/unsticky.png | bin | 0 -> 280 bytes |
12 files changed, 1413 insertions, 0 deletions
diff --git a/client/Makefile.am b/client/Makefile.am new file mode 100644 index 0000000..c742a27 --- /dev/null +++ b/client/Makefile.am @@ -0,0 +1,20 @@ +AUTOMAKE_OPTIONS = foreign + +SUBDIRS = pics + +KDE_CXXFLAGS = -DQT_PLUGIN + +INCLUDES = $(all_includes) -I$(kde_includes)/kwin + +kwindir = $(kde_datadir)/kwin/ +kwin_DATA = fahrenheit.desktop + +noinst_HEADERS = fahrenheitclient.h + +kde_module_LTLIBRARIES = kwin3_fahrenheit.la +kwin3_fahrenheit_la_SOURCES = fahrenheitclient.cc +kwin3_fahrenheit_la_LIBADD = $(kde_libraries)/libkdecorations.la +kwin3_fahrenheit_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -lkdecore -module +kwin3_fahrenheit_la_METASOURCES = AUTO + +DISTCLEANFILES = $(kwin3_fahrenheit_la_METASOURCES) diff --git a/client/fahrenheit.desktop b/client/fahrenheit.desktop new file mode 100644 index 0000000..d0cfde1 --- /dev/null +++ b/client/fahrenheit.desktop @@ -0,0 +1,5 @@ +# KDE Desktop Entry +[Desktop Entry] +Encoding=UTF-8 +Name=Fahrenheit +X-KDE-Library=kwin3_fahrenheit diff --git a/client/fahrenheitclient.cc b/client/fahrenheitclient.cc new file mode 100644 index 0000000..e8f846a --- /dev/null +++ b/client/fahrenheitclient.cc @@ -0,0 +1,1211 @@ +////////////////////////////////////////////////////////////////////////////// +// fahrenheitclient.cc +// ------------------- +// Fahrenheit window decoration for KDE +// ------------------- +// Copyright (c) 2004 Peter Clark +// Please see the header file for copyright and license information. +////////////////////////////////////////////////////////////////////////////// + +#include <kconfig.h> +#include <kglobal.h> +#include <kglobalsettings.h> +#include <klocale.h> +#include <kstandarddirs.h> + +#include <qbitmap.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qpainter.h> +#include <qtooltip.h> + +#include "fahrenheitclient.h" + +using namespace Fahrenheit; + +// global constants + +static const int borderSize_ = 5; +int titleHeight_ = 24; + +////////////////////////////////////////////////////////////////////////////// +// FahrenheitFactory Class // +////////////////////////////////////////////////////////////////////////////// + +bool FahrenheitFactory::initialized_ = false; +Qt::AlignmentFlags FahrenheitFactory::titlealign_ = Qt::AlignLeft; + +extern "C" KDecorationFactory* create_factory() +{ + return new Fahrenheit::FahrenheitFactory(); +} + +////////////////////////////////////////////////////////////////////////////// +// FahrenheitFactory() +// ---------------- +// Constructor + +FahrenheitFactory::FahrenheitFactory() +{ + readConfig(); + initialized_ = true; +} + +////////////////////////////////////////////////////////////////////////////// +// ~FahrenheitFactory() +// ----------------- +// Destructor + +FahrenheitFactory::~FahrenheitFactory() { initialized_ = false; } + +////////////////////////////////////////////////////////////////////////////// +// createDecoration() +// ----------------- +// Create the decoration + +KDecoration* FahrenheitFactory::createDecoration(KDecorationBridge* b) +{ + return new FahrenheitClient(b, this); +} + +////////////////////////////////////////////////////////////////////////////// +// reset() +// ------- +// Reset the handler. Returns true if decorations need to be remade, false if +// only a repaint is necessary + +bool FahrenheitFactory::reset(unsigned long changed) +{ + // read in the configuration + initialized_ = false; + bool confchange = readConfig(); + initialized_ = true; + + if (confchange || + (changed & (SettingDecoration | SettingButtons | SettingBorder))) { + return true; + } else { + resetDecorations(changed); + return false; + } +} + +////////////////////////////////////////////////////////////////////////////// +// readConfig() +// ------------ +// Read in the configuration file + +bool FahrenheitFactory::readConfig() +{ + // create a config object + KConfig config("kwinfahrenheitrc"); + config.setGroup("General"); + + // grab settings + Qt::AlignmentFlags oldalign = titlealign_; + QString value = config.readEntry("TitleAlignment", "AlignLeft"); + if (value == "AlignLeft") titlealign_ = Qt::AlignLeft; + else if (value == "AlignHCenter") titlealign_ = Qt::AlignHCenter; + else if (value == "AlignRight") titlealign_ = Qt::AlignRight; + + if (oldalign == titlealign_) + return false; + else + return true; +} + +////////////////////////////////////////////////////////////////////////////// +// FahrenheitButton Class // +////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////// +// FahrenheitButton() +// --------------- +// Constructor + +FahrenheitButton::FahrenheitButton(FahrenheitClient *parent, const char *name, + const QString& tip, ButtonType type, + QString pixmap) + : QButton(parent->widget(), name), client_(parent), type_(type), + deco_(0), lastmouse_(0) +{ + setBackgroundMode(NoBackground); + setFixedWidth(16); + setCursor(arrowCursor); + if (pixmap) setPixmap(pixmap); + QToolTip::add(this, tip); +} + +FahrenheitButton::~FahrenheitButton() +{ + if (deco_) delete deco_; +} + +////////////////////////////////////////////////////////////////////////////// +// setPixmap() +// ----------- +// Create pixmap button decorations + +void FahrenheitButton::setPixmap(QString pixmap) +{ + if (!pixmap) return; // probably the menu button + + QString buttonLocation_ = KGlobal::dirs()->findResource ("data", + QString("kwin/fahrenheit/") + pixmap + ".png"); + + if (deco_) delete deco_; + deco_ = new QPixmap(buttonLocation_); + repaint(false); +} + +////////////////////////////////////////////////////////////////////////////// +// sizeHint() +// ---------- +// Return size hint + +QSize FahrenheitButton::sizeHint() const +{ + return QSize(11, 9); +} + +////////////////////////////////////////////////////////////////////////////// +// enterEvent() +// ------------ +// Mouse has entered the button + +void FahrenheitButton::enterEvent(QEvent *e) +{ + // if we wanted to do mouseovers, we would keep track of it here + QButton::enterEvent(e); +} + +////////////////////////////////////////////////////////////////////////////// +// leaveEvent() +// ------------ +// Mouse has left the button + +void FahrenheitButton::leaveEvent(QEvent *e) +{ + // if we wanted to do mouseovers, we would keep track of it here + QButton::leaveEvent(e); +} + +////////////////////////////////////////////////////////////////////////////// +// mousePressEvent() +// ----------------- +// Button has been pressed + +void FahrenheitButton::mousePressEvent(QMouseEvent* e) +{ + lastmouse_ = e->button(); + + // translate and pass on mouse event + int button = LeftButton; + if ((type_ != ButtonMax) && (e->button() != LeftButton)) { + button = NoButton; // middle & right buttons inappropriate + } + QMouseEvent me(e->type(), e->pos(), e->globalPos(), + button, e->state()); + QButton::mousePressEvent(&me); +} + +////////////////////////////////////////////////////////////////////////////// +// mouseReleaseEvent() +// ----------------- +// Button has been released + +void FahrenheitButton::mouseReleaseEvent(QMouseEvent* e) +{ + lastmouse_ = e->button(); + + // translate and pass on mouse event + int button = LeftButton; + if ((type_ != ButtonMax) && (e->button() != LeftButton)) { + button = NoButton; // middle & right buttons inappropriate + } + QMouseEvent me(e->type(), e->pos(), e->globalPos(), button, e->state()); + QButton::mouseReleaseEvent(&me); +} + +////////////////////////////////////////////////////////////////////////////// +// drawButton() +// ------------ +// Draw the button + +void FahrenheitButton::drawButton(QPainter *painter) +{ + if (!FahrenheitFactory::initialized()) return; + + QColorGroup titleColor; + QColorGroup borderColor; + int dx, dy; + + if (type_ == ButtonMenu) { + // we paint the mini icon (which is 16 pixels high) + titleColor = KDecoration::options()->colorGroup( + KDecoration::ColorTitleBar, client_->isActive()); + + painter->fillRect(rect(), titleColor.background()); + painter->setPen(titleColor.dark()); + painter->drawLine(0, 0, width(), 0); + painter->setPen(titleColor.light()); + painter->drawLine(0, 1, width(), 1); + painter->drawPixmap(0, 3, client_->icon().pixmap(QIconSet::Small, + QIconSet::Normal)); + } else if (deco_) { + // otherwise we paint the deco + borderColor = KDecoration::options()->colorGroup( + KDecoration::ColorFrame, client_->isActive()); + dx = 2; + dy = 0; + if (isDown()) { dx++; dy++; } + painter->fillRect(rect(), borderColor.background()); + + if (!client_->isShade()) { + painter->setPen(borderColor.mid()); + painter->drawLine(0, 9, width(), 9); + painter->setPen(borderColor.dark()); + painter->drawLine(0, 10, width(), 10); + } + painter->drawPixmap(dx, dy, *deco_); + } +} + +////////////////////////////////////////////////////////////////////////////// +// FahrenheitClient Class // +////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////// +// FahrenheitClient() +// --------------- +// Constructor + +FahrenheitClient::FahrenheitClient(KDecorationBridge *b, KDecorationFactory *f) + : KDecoration(b, f), mainLayout_ (0), titleSpacer_ (0) +{ ; } + +FahrenheitClient::~FahrenheitClient() +{ + for (int n=0; n<ButtonTypeCount; n++) { + if (button[n]) delete button[n]; + } +} + +////////////////////////////////////////////////////////////////////////////// +// init() +// ------ +// Actual initializer for class + +void FahrenheitClient::init() +{ + createMainWidget(WResizeNoErase | WRepaintNoErase); + widget()->installEventFilter(this); + + // for flicker-free redraws + widget()->setBackgroundMode(NoBackground); + + // setup layout + delete mainLayout_; + + mainLayout_ = new QVBoxLayout(widget(), 0, 0); + topLayout_ = new QBoxLayout(mainLayout_, QBoxLayout::LeftToRight, 0, 0); + + titleSpacer_ = new QSpacerItem ( 0, 24, + QSizePolicy::Preferred, + QSizePolicy::Fixed); + barSpacer_ = new QSpacerItem ( 14, 24, + QSizePolicy::MinimumExpanding, + QSizePolicy::Fixed); + + menuLayout_ = new QBoxLayout(topLayout_, QBoxLayout::LeftToRight, 0, 0); + menuLayout_->addSpacing(16); + + recalcTitlebar(); + + QBoxLayout * titleLayout_ = new QBoxLayout(topLayout_, + QBoxLayout::LeftToRight, 0, 0); + buttonLayout_ = new QBoxLayout(topLayout_, + QBoxLayout::LeftToRight, 0, 0); + QBoxLayout * barLayout_ = new QBoxLayout(topLayout_, + QBoxLayout::LeftToRight, 0, 0); + titleLayout_->addItem(titleSpacer_); + + for (int n=0; n<ButtonTypeCount; n++) { + button[n] = 0; + } + + addButtons(buttonLayout_, options()->titleButtonsLeft()); + addButtons(buttonLayout_, options()->titleButtonsRight()); + barLayout_->addItem(barSpacer_); + + QHBoxLayout * midLayout = new QHBoxLayout(mainLayout_, 0, 0); + + midLayout->addSpacing(borderSize_ + 9); + if( isPreview()) { + midLayout->addWidget( + new QLabel( i18n( "<center><b>Fahrenheit</b></center>" ), + widget())); + } else { + midLayout->addItem( new QSpacerItem( 0, 0 )); + } + + midLayout->addSpacing(borderSize_ + (isResizable() ? 2 : 0)); + mainLayout_->addSpacing(borderSize_ + (isResizable() ? 2 : 0)); + + // Make sure that topLayout doesn't stretch - midLayout should take + // all spare space. + mainLayout_->setStretchFactor(topLayout_, 0); + mainLayout_->setStretchFactor(midLayout, 1); +} + +////////////////////////////////////////////////////////////////////////////// +// recalcTitlebar() +// ------------ +// Calculate the width of the caption for the titlebar + +void FahrenheitClient::recalcTitlebar() +{ + QFontMetrics fm(options()->font(isActive())); + titleHeight_ = fm.height(); + QString cap = caption(); + if (cap.length() < 5) // make sure the titlebar has sufficiently wide + cap = "XXXXX"; // area for dragging the window + int textLen_ = fm.width( cap ); + titleSpacer_->changeSize(4 + textLen_ + 16, + 24, QSizePolicy::Preferred, QSizePolicy::Fixed); + +} + + +////////////////////////////////////////////////////////////////////////////// +// addButtons() +// ------------ +// Add buttons to title layout + +void FahrenheitClient::addButtons(QBoxLayout *layout, const QString& s) +{ + QString pixmap; + QString tip; + + if (s.length() > 0) { + for (unsigned n=0; n < s.length(); n++) { + switch (s[n]) { + case 'M': // Menu button + if (!button[ButtonMenu]) { + button[ButtonMenu] = + new FahrenheitButton(this, "menu", i18n("Menu"), + ButtonMenu, 0); + connect(button[ButtonMenu], SIGNAL(pressed()), + this, SLOT(menuButtonPressed())); + button[ButtonMenu]->setFixedHeight(19); + menuLayout_->insertWidget(-1, button[ButtonMenu], + 0, Qt::AlignTop); + menuLayout_->addSpacing(4); + } + break; + + case 'S': // Sticky button + if (!button[ButtonSticky]) { + if (isOnAllDesktops()) { + pixmap = "unsticky"; + tip = i18n("Un-Sticky"); + } else { + pixmap = "sticky"; + tip = i18n("Sticky"); + } + button[ButtonSticky] = + new FahrenheitButton(this, "sticky", tip, + ButtonSticky, pixmap); + connect(button[ButtonSticky], SIGNAL(clicked()), + this, SLOT(toggleOnAllDesktops())); + button[ButtonSticky]->setFixedHeight(11); + layout->insertWidget(-1, button[ButtonSticky], + 0, Qt::AlignBottom); + } + break; + + case 'H': // Help button + if ((!button[ButtonHelp]) && providesContextHelp()) { + button[ButtonHelp] = + new FahrenheitButton(this, "help", i18n("Help"), + ButtonHelp, "help"); + connect(button[ButtonHelp], SIGNAL(clicked()), + this, SLOT(showContextHelp())); + button[ButtonHelp]->setFixedHeight(11); + layout->insertWidget(-1, button[ButtonHelp], + 0, Qt::AlignBottom); + } + break; + + case 'I': // Minimize button + if ((!button[ButtonMin]) && isMinimizable()) { + button[ButtonMin] = + new FahrenheitButton(this, "iconify", + i18n("Minimize"), + ButtonMin, "minimize"); + connect(button[ButtonMin], SIGNAL(clicked()), + this, SLOT(minimize())); + button[ButtonMin]->setFixedHeight(11); + layout->insertWidget(-1, button[ButtonMin], + 0, Qt::AlignBottom); + } + break; + + case 'A': // Maximize button + if ((!button[ButtonMax]) && isMaximizable()) { + if (maximizeMode() == MaximizeFull) { + pixmap = "minmax"; + tip = i18n("Restore"); + } else { + pixmap = "maximize"; + tip = i18n("Maximize"); + } + button[ButtonMax] = + new FahrenheitButton(this, "maximize", tip, + ButtonMax, pixmap); + connect(button[ButtonMax], SIGNAL(clicked()), + this, SLOT(maxButtonPressed())); + button[ButtonMax]->setFixedHeight(11); + layout->insertWidget(-1, button[ButtonMax], + 0, Qt::AlignBottom); + } + break; + + case 'X': // Close button + if ((!button[ButtonClose]) && isCloseable()) { + button[ButtonClose] = + new FahrenheitButton(this, "close", i18n("Close"), + ButtonClose, "close"); + connect(button[ButtonClose], SIGNAL(clicked()), + this, SLOT(closeWindow())); + button[ButtonClose]->setFixedHeight(11); + layout->insertWidget(-1, button[ButtonClose], + 0, Qt::AlignBottom); + } + break; + + case '_': // Spacer item + layout->addSpacing(4); + } + } + } +} + +////////////////////////////////////////////////////////////////////////////// +// activeChange() +// -------------- +// window active state has changed + +void FahrenheitClient::activeChange() +{ + for (int n=0; n<ButtonTypeCount; n++) + if (button[n]) button[n]->reset(); + widget()->repaint(false); +} + +////////////////////////////////////////////////////////////////////////////// +// captionChange() +// --------------- +// The title has changed + +void FahrenheitClient::captionChange() +{ + recalcTitlebar(); + mainLayout_->activate(); + doShape(); + widget()->repaint(topLayout_->geometry(), false); +} + +////////////////////////////////////////////////////////////////////////////// +// desktopChange() +// --------------- +// Called when desktop/sticky changes + +void FahrenheitClient::desktopChange() +{ + bool d = isOnAllDesktops(); + if (button[ButtonSticky]) { + //button[ButtonSticky]->setBitmap(d ? stickydown_bits : sticky_bits); + button[ButtonSticky]->setPixmap(d ? "unsticky" : "sticky"); + QToolTip::remove(button[ButtonSticky]); + QToolTip::add(button[ButtonSticky], d ? i18n("Un-Sticky") : i18n("Sticky")); + } +} + +////////////////////////////////////////////////////////////////////////////// +// iconChange() +// ------------ +// The title has changed + +void FahrenheitClient::iconChange() +{ + if (button[ButtonMenu]) { + button[ButtonMenu]->setPixmap(0); + button[ButtonMenu]->repaint(false); + } +} + +////////////////////////////////////////////////////////////////////////////// +// maximizeChange() +// ---------------- +// Maximized state has changed + +void FahrenheitClient::maximizeChange() +{ + bool m = (maximizeMode() == MaximizeFull); + if (button[ButtonMax]) { + //button[ButtonMax]->setBitmap(m ? minmax_bits : max_bits); + button[ButtonMax]->setPixmap(m ? "minmax" : "maximize"); + QToolTip::remove(button[ButtonMax]); + QToolTip::add(button[ButtonMax], m ? i18n("Restore") : i18n("Maximize")); + } +} + +////////////////////////////////////////////////////////////////////////////// +// shadeChange() +// ------------- +// Called when window shading changes + +void FahrenheitClient::shadeChange() +{ + // Workhere + for (int n=0; n<ButtonTypeCount; n++) + if (button[n]) button[n]->reset(); +} + +////////////////////////////////////////////////////////////////////////////// +// borders() +// ---------- +// Get the size of the borders + +void FahrenheitClient::borders(int &l, int &r, int &t, int &b) const +{ + int handle = (isResizable() ? 2 : 0); + l = 9 + borderSize_; + r = borderSize_ + handle; + t = 24; + b = borderSize_ + handle; +} + +////////////////////////////////////////////////////////////////////////////// +// resize() +// -------- +// Called to resize the window + +void FahrenheitClient::resize(const QSize &size) +{ + widget()->resize(size); +} + +////////////////////////////////////////////////////////////////////////////// +// minimumSize() +// ------------- +// Return the minimum allowable size for this decoration + +QSize FahrenheitClient::minimumSize() const +{ + return QSize(100, 50); +} + +////////////////////////////////////////////////////////////////////////////// +// mousePosition() +// --------------- +// Return logical mouse position + +KDecoration::Position FahrenheitClient::mousePosition(const QPoint &point) const +{ + //const int corner = 24; + Position pos; + int x = point.x(); + int y = point.y(); + + if (y < titleSpacer_->geometry().height()) { + pos = PositionCenter; + } + else if (y < height() - 22) + { + if (x < borderSize_ + 9) + pos = PositionLeft; + else + if (x > width() - borderSize_ - 2) + pos = PositionRight; + else + pos = PositionCenter; + } + else + { + if (x < 29) + pos = PositionBottomLeft; + else + if (x > width() - 22) + pos = PositionBottomRight; + else + pos = PositionBottom; + } + return pos; +} + +////////////////////////////////////////////////////////////////////////////// +// isTool() +// ------------- +// + +const int SUPPORTED_WINDOW_TYPES_MASK = NET::NormalMask | NET::DesktopMask | NET::DockMask + | NET::ToolbarMask | NET::MenuMask | NET::DialogMask | NET::OverrideMask | NET::TopMenuMask + | NET::UtilityMask | NET::SplashMask; + +bool FahrenheitClient::isTool() +{ + NET::WindowType type = windowType( SUPPORTED_WINDOW_TYPES_MASK ); + return ((type==NET::Toolbar)||(type==NET::Utility)||(type==NET::Menu)); +} + +////////////////////////////////////////////////////////////////////////////// +// eventFilter() +// ------------- +// Event filter + +bool FahrenheitClient::eventFilter(QObject *obj, QEvent *e) +{ + if (obj != widget()) return false; + + switch (e->type()) { + case QEvent::MouseButtonDblClick: { + mouseDoubleClickEvent(static_cast<QMouseEvent *>(e)); + return true; + } + case QEvent::MouseButtonPress: { + processMousePressEvent(static_cast<QMouseEvent *>(e)); + return true; + } + case QEvent::Paint: { + paintEvent(static_cast<QPaintEvent *>(e)); + return true; + } + case QEvent::Resize: { + resizeEvent(static_cast<QResizeEvent *>(e)); + return true; + } + case QEvent::Show: { + showEvent(static_cast<QShowEvent *>(e)); + return true; + } + default: { + return false; + } + } + + return false; +} + +////////////////////////////////////////////////////////////////////////////// +// mouseDoubleClickEvent() +// ----------------------- +// Doubleclick on title + +void FahrenheitClient::mouseDoubleClickEvent(QMouseEvent *e) +{ + if (titleSpacer_->geometry().contains(e->pos())) titlebarDblClickOperation(); +} + +////////////////////////////////////////////////////////////////////////////// +// paintEvent() +// ------------ +// Repaint the window + +void FahrenheitClient::paintEvent(QPaintEvent*) +{ + QColorGroup titleColor = options()->colorGroup(ColorTitleBar, isActive()); + QColorGroup handleColor = options()->colorGroup(ColorHandle, isActive()); + QColorGroup borderColor = options()->colorGroup(ColorFrame, isActive()); + + QRect t = titleSpacer_->geometry(); + QRect buttonRect = buttonLayout_->geometry(); + QRect barRect = barSpacer_->geometry(); + + t.setTop(1); + int handle = (isResizable() ? 2 : 0); + int barWidth = barRect.width() - handle; + int tr = t.right(); + int tt = t.top(); + int r = width() - handle; + int b = height() - handle; + int w = width(); + int h = height(); + QPainter p(widget()); + + p.setPen(Qt::black); + p.setBrush(borderColor.background()); + p.drawRect(9, 13, width() - 9 - handle, height() - 13 - handle); // Outer edge + + // Draw behind button area + p.fillRect(buttonRect, borderColor.background()); + + p.drawLine(width() - 6, 9, 12, 9); // Top edge to left of button area + + p.setPen(borderColor.dark()); + p.drawLine(width() - 2 - handle, 14, width() - 2 - handle, + height() - handle); // Right bevel edge + p.drawLine(11, height() - 2 - handle, width() - handle, + height() - 2 - handle); // Bottom bevel edge + + // Draw edge of bottom-left corner inside the area removed by the mask. + // We draw this now, instead of later with the rest, so that it doesn't + // cover up part of the grip bar. + p.setPen(Qt::black); + p.drawPoint(10, b - 5); + p.drawPoint(10, b - 4); + p.drawPoint(11, b - 3); + p.drawPoint(12, b - 2); + p.drawPoint(13, b - 2); + p.setPen(borderColor.mid()); + p.drawPoint(11, b - 5); + p.drawPoint(11, b - 4); + p.drawPoint(12, b - 3); + p.drawPoint(13, b - 3); + + p.setPen(borderColor.light()); + p.drawLine(t.width() + buttonRect.width(), 14, + width() - handle - 6, 14); // Top bevel edge of bar + //p.drawLine(10, 14, 10, height() - 6 - handle); // Left bevel edge + p.drawLine(12, 10, width() - handle - 6, 10); // Bevel edge to left of button area + + // Draw to the right of the button area + p.setPen(Qt::black); + p.drawLine(r - barWidth, 10, r - barWidth + 5, 12); + p.setPen(borderColor.mid()); + p.drawLine(r - barWidth, 11, r - barWidth + 5, 13); + p.setPen(borderColor.background()); + p.drawLine(r - barWidth, 12, r - barWidth + 5, 14); + p.drawLine(r - barWidth, 13, r - barWidth + 3, 14); + p.drawLine(r - barWidth, 14, r - barWidth + 1, 14); + + //p.setClipRegion(pe->region()); + + // Fill in area behind rounded portion of title bar + p.fillRect(tr - 11, 11, 12, 9, borderColor.background()); + + // Draw inner edge of border + if (!isShade()) + { + p.setPen(borderColor.dark()); + p.drawLine(9 + borderSize_, 23, w - borderSize_ - handle - 1, 23); + p.drawLine(8 + borderSize_, 24, 8 + borderSize_, + h - borderSize_ - handle - 1); + + p.setPen(borderColor.mid()); + p.drawLine(9 + borderSize_, 22, w - borderSize_ - handle - 2, 22); + p.drawLine(7 + borderSize_, 24, 7 + borderSize_, + h - borderSize_ - handle - 2); + p.drawPoint(8 + borderSize_, 23); + p.drawLine(w - borderSize_ - handle - 1, 22, w - borderSize_ - handle + 1, 24); + p.drawLine(7 + borderSize_, h - borderSize_ - handle - 1, 9 + borderSize_, + h - borderSize_ - handle + 1); + + p.setPen(borderColor.light()); + p.drawLine(w - borderSize_ - handle, 24, w - borderSize_ - handle, + h - borderSize_ - handle - 1); + p.drawLine(9 + borderSize_, h - borderSize_ - handle, + w - borderSize_ - handle - 1, + h - borderSize_ - handle); + p.setPen(borderColor.midlight()); + p.drawLine(w - borderSize_ - handle + 1, 25, w - borderSize_ - handle + 1, + h - borderSize_ - handle - 2); + p.drawLine(10 + borderSize_, h - borderSize_ - handle + 1, + w - borderSize_ - handle - 2, h - borderSize_ - handle + 1); + p.drawLine(w - borderSize_ - handle - 1, h - borderSize_ - handle + 1, + w - borderSize_ - handle + 1, h - borderSize_ - handle - 1); + } + + // Draw title bar + //p.fillRect(t.left() + 1, tt, tr - 12, t.bottom() - 3, titleColor.background()); + p.fillRect(1, tt, tr - 12, t.bottom() - 3, titleColor.background()); + + // Draw lower portion of grip + if (isShade()) + { + p.fillRect(0, 20, 11, 4, titleColor.background()); + } else { + p.fillRect(0, 20, 11, 14, titleColor.background()); + } + + // Draw rounded portion of title bar + p.fillRect(tr - 11, tt + 1, 3, 17, titleColor.background()); + p.setPen(titleColor.background()); + p.drawLine(tr - 8, tt + 2, tr - 8, tt + 16); + p.drawLine(tr - 7, tt + 3, tr - 7, tt + 15); + p.drawLine(tr - 6, tt + 4, tr - 6, tt + 14); + p.drawLine(tr - 5, tt + 7, tr - 5, tt + 11); + + // Draw top edge and left curve of title bar + //p.setPen(Qt::black); + p.setPen(titleColor.dark()); + p.drawPoint(3, 1); + p.drawPoint(4, 1); + p.drawPoint(2, 2); + p.drawPoint(1, 3); + p.drawPoint(1, 4); + p.drawLine(5, 0, tr - 12, 0); + + p.setPen(titleColor.light()); + p.drawPoint(3, 2); + p.drawPoint(4, 2); + p.drawPoint(2, 3); + p.drawPoint(2, 4); + p.drawLine(5, 1, tr - 12, 1); + + // Draw rounded edge of title bar + p.setPen(titleColor.dark()); + p.drawLine(tr - 11, tt, tr - 9, tt); + p.drawLine(tr - 8, tt + 1, tr - 5, tt + 4); + p.drawLine(tr - 5, tt + 5, tr - 5, tt + 6); + p.drawLine(tr - 4, tt + 7, tr - 4, tt + 11); + p.drawLine(tr - 5, tt + 12, tr - 5, tt + 13); + p.drawLine(tr - 5, tt + 14, tr - 8, tt + 17); + p.drawLine(tr - 9, tt + 18, tr - 11, tt + 18); + + p.setPen(titleColor.midlight()); + p.drawLine(tr - 11, tt+ 1, tr - 9, tt + 1); + p.drawLine(tr - 8, tt + 2, tr - 7, tt + 3); + p.setPen(titleColor.mid()); + p.drawLine(tr - 6, tt + 4, tr - 6, tt + 6); + p.drawLine(tr - 5, tt + 7, tr - 5, tt + 11); + p.drawLine(tr - 6, tt + 12, tr - 6, tt + 13); + p.drawLine(tr - 6, tt + 14, tr - 9, tt + 17); + p.drawLine(tr - 10, tt + 17, tr - 11, tt + 17); + + // Draw bottom of title bar + p.setPen(titleColor.dark()); + p.drawLine(tr - 12, tt + 19, 12, tt + 19); + p.setPen(titleColor.mid()); + p.drawLine(tr - 12, tt + 18, 12, tt + 18); + + // Draw grip and grip edges + p.setPen(titleColor.dark()); + p.drawLine(0, tt + 4, 0, tt + 27); + p.setPen(titleColor.light()); + p.drawLine(1, tt + 4, 1, tt + 27); + + p.setPen(titleColor.dark()); + if (isShade()) + { +//WORKHERE + p.drawPoint(1, 20); + p.drawPoint(1, 21); + p.drawPoint(2, 22); + p.drawPoint(3, 23); + p.drawPoint(4, 23); + p.drawLine(5, 24, 10, 24); + p.drawLine(11, 23, 11, 21); + p.setPen(titleColor.midlight()); + p.drawLine(2, 20, 2, 21); + p.setPen(titleColor.mid()); + p.drawLine(3, 22, 4, 22); + p.drawLine(5, 23, 9, 23); + p.drawLine(10, 23, 10, 21); + p.drawPoint(11, 20); + p.setPen(borderColor.mid()); + p.drawPoint(11, 24); + + //p.setPen(titleColor.light()); + p.setPen(handleColor.light()); + p.drawLine(8, 3, 3, 8); + p.drawLine(12, 3, 3, 12); + p.drawLine(12, 7, 3, 16); + p.drawLine(12, 11, 4, 19); + p.drawLine(12, 15, 6, 21); + + //p.setPen(titleColor.midlight()); + p.setPen(handleColor.midlight()); + p.drawLine(6, 3, 3, 6); + p.drawLine(7, 3, 3, 7); + p.drawLine(10, 3, 3, 10); + p.drawLine(11, 3, 3, 11); + p.drawLine(12, 5, 3, 14); + p.drawLine(12, 6, 3, 15); + p.drawLine(12, 9, 4, 17); + p.drawLine(12, 10, 4, 18); + p.drawLine(12, 13, 6, 19); + p.drawLine(12, 14, 6, 20); + p.drawLine(12, 17, 8, 21); + } else { + p.drawPoint(1, 29); + p.drawPoint(1, 30); + p.drawPoint(2, 31); + p.drawPoint(3, 32); + p.drawPoint(4, 32); + p.drawPoint(5, 33); + p.drawPoint(6, 33); + p.drawLine(7, 34, 9, 34); + p.drawLine(10, 33, 10, 22); + p.drawPoint(11, 21); + p.setPen(titleColor.midlight()); + p.drawLine(2, 29, 2, 30); + p.setPen(titleColor.mid()); + p.drawLine(3, 31, 4, 31); + p.drawLine(5, 32, 6, 32); + p.drawLine(7, 33, 9, 33); + p.drawLine(9, 32, 9, 23); + p.drawLine(9, 22, 11, 20); + + //p.setPen(titleColor.light()); + p.setPen(handleColor.light()); + p.drawLine(8, 3, 3, 8); + p.drawLine(12, 3, 3, 12); + p.drawLine(12, 7, 3, 16); + p.drawLine(12, 11, 3, 20); + p.drawLine(12, 15, 3, 24); + p.drawLine(8, 23, 3, 28); + p.drawLine(8, 27, 5, 30); + + //p.setPen(titleColor.midlight()); + p.setPen(handleColor.midlight()); + p.drawLine(6, 3, 3, 6); + p.drawLine(7, 3, 3, 7); + p.drawLine(10, 3, 3, 10); + p.drawLine(11, 3, 3, 11); + p.drawLine(12, 5, 3, 14); + p.drawLine(12, 6, 3, 15); + p.drawLine(12, 9, 3, 18); + p.drawLine(12, 10, 3, 19); + p.drawLine(12, 13, 3, 22); + p.drawLine(12, 14, 3, 23); + p.drawLine(8, 21, 3, 26); + p.drawLine(8, 22, 3, 27); + p.drawLine(8, 25, 5, 28); + p.drawLine(8, 26, 5, 29); + } + + p.setPen(Qt::black); + //p.setPen(borderColor.dark()); + + // Draw edge of top-right corner inside the area removed by the mask. + + p.drawPoint(r - 5, 14); + p.drawPoint(r - 4, 14); + p.drawPoint(r - 3, 15); + p.drawPoint(r - 2, 16); + p.drawPoint(r - 2, 17); + + p.setPen(borderColor.mid()); + p.drawPoint(r - 5, 15); + p.drawPoint(r - 4, 15); + p.drawPoint(r - 3, 16); + p.drawPoint(r - 3, 17); + + // Draw edge of bottom-right corner inside the area removed by the mask. + + p.setPen(Qt::black); + p.drawPoint(r - 2, b - 5); + p.drawPoint(r - 2, b - 4); + p.drawPoint(r - 3, b - 3); + p.drawPoint(r - 4, b - 2); + p.drawPoint(r - 5, b - 2); + p.setPen(borderColor.dark()); + p.drawPoint(r - 3, b - 5); + p.drawPoint(r - 3, b - 4); + p.drawPoint(r - 4, b - 3); + p.drawPoint(r - 5, b - 3); + + if (isResizable()) { + if (!isShade()) { // Draw handle bar + p.setPen(Qt::black); + p.fillRect(w - 5, h - 20, 3, 17, borderColor.background()); + p.fillRect(w - 20, h - 5, 17, 3, borderColor.background()); + + // Border edge, moving from top right to left bottom + p.drawLine(w - 2, h - 20, w - 1, h - 17); + p.drawLine(w - 1, h - 16, w - 1, h - 8); + p.drawLine(w - 1, h - 7, w - 2, h - 4); + p.drawPoint(w - 3, h - 3); + p.drawLine(w - 4, h - 2, w - 7, h - 1); + p.drawLine(w - 8, h - 1, w - 16, h - 1); + p.drawLine(w - 17, h - 1, w - 20, h - 2); + + // Create handle shadow + p.setPen(borderColor.dark()); + + p.drawLine(w - 3, h - 20, w - 2, h - 17); + p.drawLine(w - 2, h - 16, w - 2, h - 8); + p.drawLine(w - 2, h - 7, w - 3, h - 4); + p.drawLine(w - 4, h - 3, w - 7, h - 2); + p.drawLine(w - 8, h - 2, w - 16, h - 2); + p.drawLine(w - 17, h - 2, w - 20, h - 3); + } + } + + p.setFont(options()->font(isActive(), isTool())); + p.setPen(options()->color(ColorFont, isActive())); +/* + p.drawText(20, 0, t.width() - 36, 20, Qt::AlignVCenter, caption()); +*/ + p.drawText(menuLayout_->geometry().width(), 0, t.width() - 16, 20, + Qt::AlignVCenter, caption()); + +} + +////////////////////////////////////////////////////////////////////////////// +// doShape() +// ------------ +// Shape the window + +void FahrenheitClient::doShape() +{ + QRegion mask(0, 0, width(), height()); + QRect t(titleSpacer_->geometry()); + int handle = (isResizable() ? 2 : 0); + int tr = t.right(); + QRect barRect(barSpacer_->geometry()); + QRect buttonRect(buttonLayout_->geometry()); + + int barWidth = barRect.width() - handle; + int buttonWidth = buttonRect.width(); + int w = width(); + int h = height(); + int r = width() - handle; + int b = height() - handle; + + // Remove top-left corner. + + mask -= QRegion(0, 0, 5, 1); + mask -= QRegion(0, 1, 3, 1); + mask -= QRegion(0, 2, 2, 1); + mask -= QRegion(0, 3, 1, 2); + + // Remove area above rounded portion of title bar + mask -= QRegion(tr - 11, 0, 12, 1); + mask -= QRegion(tr - 8, 1, 9, 1); + mask -= QRegion(tr - 7, 2, 8, 1); + mask -= QRegion(tr - 6, 3, 7, 1); + mask -= QRegion(tr - 5, 4, 6, 1); + mask -= QRegion(tr - 4, 5, 5, 3); + mask -= QRegion(tr - 3, 8, 4, 1); + + // Remove area above button area + mask -= QRegion(r - buttonWidth - barWidth, 0, buttonWidth + 6, 9); + + // Remove top area above blank bar and top-right corner. + mask -= QRegion(r - barWidth + 6, 0, barWidth, 13); + + mask -= QRegion(r - barWidth, 9, 6, 1); + mask -= QRegion(r - barWidth + 2, 10, 4, 1); + mask -= QRegion(r - barWidth + 4, 11, 2, 1); + mask -= QRegion(r - 5, 13, 5, 1); + mask -= QRegion(r - 3, 14, 3, 1); + mask -= QRegion(r - 2, 15, 2, 1); + mask -= QRegion(r - 1, 16, 1, 2); + + // Remove left side below grip bar + if (isShade()) + { + mask -= QRegion(0, 20, 1, 5); + mask -= QRegion(1, 22, 1, 3); + mask -= QRegion(2, 23, 1, 2); + mask -= QRegion(3, 24, 2, 1); + } else { + mask -= QRegion(0, 29, 1, 2); + mask -= QRegion(0, 31, 2, 1); + mask -= QRegion(0, 32, 3, 1); + mask -= QRegion(0, 33, 5, 1); + mask -= QRegion(0, 34, 7, 1); + } + mask -= QRegion(0, 35, 9, b - 35); + + // Remove bottom-left corner + //mask -= QRegion(0, b - 5, 10, 3); + mask -= QRegion(0, b - 4, 10, 3); + mask -= QRegion(0, b - 3, 11, 1); + mask -= QRegion(0, b - 2, 12, 1); + mask -= QRegion(0, b - 1, 14, 1); + + // Remove bottom-right corner. + + mask -= QRegion(w - 5, h - 1, 5, 1); + mask -= QRegion(w - 3, h - 2, 3, 1); + mask -= QRegion(w - 2, h - 3, 2, 1); + mask -= QRegion(w - 1, h - 5, 1, 2); + + if (isResizable()) { + if (isShade()) { // We don't have a handle bar to worry about + mask -= QRect(w - 2, 0, w - 1, h); // right side + mask -= QRect(0, h - 2, w, h - 1); // bottom + mask -= QRegion(r - 5, b - 1, 5, 1); + mask -= QRegion(r - 3, b - 2, 3, 1); + mask -= QRegion(r - 2, b - 3, 2, 1); + mask -= QRegion(r - 1, b - 5, 1, 2); + } else { // Leave area for handle bar + mask -= QRect(w - 2, 0, w - 1, h - 20); // right side + mask -= QRect(0, h - 2, w - 20, h - 1); // bottom + mask -= QRegion(w - 1, h - 20, 1, 2); + mask -= QRegion(w - 20, h - 1, 2, 1); + } + } + setMask(mask); +} + +////////////////////////////////////////////////////////////////////////////// +// resizeEvent() +// ------------- +// Window is being resized + +void FahrenheitClient::resizeEvent(QResizeEvent *) +{ + if (widget()->isShown()) { + QRegion region = widget()->rect(); + region = region.subtract(titleSpacer_->geometry()); + doShape(); + widget()->erase(region); + } +} + +////////////////////////////////////////////////////////////////////////////// +// showEvent() +// ----------- +// Window is being shown + +void FahrenheitClient::showEvent(QShowEvent *) +{ + doShape(); + widget()->repaint(); +} + +////////////////////////////////////////////////////////////////////////////// +// maxButtonPressed() +// ----------------- +// Max button was pressed + +void FahrenheitClient::maxButtonPressed() +{ + if (button[ButtonMax]) { + switch (button[ButtonMax]->lastMousePress()) { + case MidButton: + maximize(maximizeMode() ^ MaximizeVertical); + break; + case RightButton: + maximize(maximizeMode() ^ MaximizeHorizontal); + break; + default: + (maximizeMode() == MaximizeFull) ? maximize(MaximizeRestore) + : maximize(MaximizeFull); + } + } +} + +////////////////////////////////////////////////////////////////////////////// +// menuButtonPressed() +// ------------------- +// Menu button was pressed (popup the menu) + +void FahrenheitClient::menuButtonPressed() +{ + if (button[ButtonMenu]) { + QPoint p(button[ButtonMenu]->rect().bottomLeft().x(), + button[ButtonMenu]->rect().bottomLeft().y()); + KDecorationFactory* f = factory(); + showWindowMenu(button[ButtonMenu]->mapToGlobal(p)); + if (!f->exists(this)) return; // decoration was destroyed + button[ButtonMenu]->setDown(false); + } +} + +#include "fahrenheitclient.moc" diff --git a/client/fahrenheitclient.h b/client/fahrenheitclient.h new file mode 100644 index 0000000..a3c6552 --- /dev/null +++ b/client/fahrenheitclient.h @@ -0,0 +1,166 @@ +////////////////////////////////////////////////////////////////////////////// +// fahrenheitclient.h +// ------------------- +// Fahrenheit window decoration for KDE +// ------------------- +// Copyright (c) 2003, 2004 David Johnson <david@usermode.org> +// +// 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. +////////////////////////////////////////////////////////////////////////////// + +#ifndef FAHRENHEITCLIENT_H +#define FAHRENHEITCLIENT_H + +#include <qbutton.h> +#include <kdecoration.h> +#include <kdecorationfactory.h> + +class QSpacerItem; +class QPoint; + +namespace Fahrenheit { + +class FahrenheitClient; + +enum ButtonType { + ButtonHelp=0, + ButtonMax, + ButtonMin, + ButtonClose, + ButtonMenu, + ButtonSticky, + ButtonTypeCount +}; + +// FahrenheitFactory ///////////////////////////////////////////////////////////// + +class FahrenheitFactory: public KDecorationFactory +{ +public: + FahrenheitFactory(); + virtual ~FahrenheitFactory(); + virtual KDecoration *createDecoration(KDecorationBridge *b); + virtual bool reset(unsigned long changed); + + static bool initialized(); + static Qt::AlignmentFlags titleAlign(); + +private: + bool readConfig(); + +private: + static bool initialized_; + static Qt::AlignmentFlags titlealign_; +}; + +inline bool FahrenheitFactory::initialized() + { return initialized_; } + +inline Qt::AlignmentFlags FahrenheitFactory::titleAlign() + { return titlealign_; } + +// FahrenheitButton ////////////////////////////////////////////////////////////// + +class FahrenheitButton : public QButton +{ +public: + FahrenheitButton(FahrenheitClient *parent=0, const char *name=0, + const QString &tip=NULL, + ButtonType type=ButtonHelp, + QString pixmap=NULL); + ~FahrenheitButton(); + + void setPixmap(QString pixmap); + QSize sizeHint() const; + int lastMousePress() const; + void reset(); + +private: + void enterEvent(QEvent *e); + void leaveEvent(QEvent *e); + void mousePressEvent(QMouseEvent *e); + void mouseReleaseEvent(QMouseEvent *e); + void drawButton(QPainter *painter); + +private: + FahrenheitClient *client_; + ButtonType type_; + QPixmap *deco_; + int lastmouse_; +}; + +inline int FahrenheitButton::lastMousePress() const + { return lastmouse_; } + +inline void FahrenheitButton::reset() + { repaint(false); } + +// FahrenheitClient ////////////////////////////////////////////////////////////// + +class FahrenheitClient : public KDecoration +{ + Q_OBJECT +public: + FahrenheitClient(KDecorationBridge *b, KDecorationFactory *f); + virtual ~FahrenheitClient(); + + virtual void init(); + + virtual void recalcTitlebar(); + virtual void activeChange(); + virtual void desktopChange(); + virtual void captionChange(); + virtual void iconChange(); + virtual void maximizeChange(); + virtual void shadeChange(); + virtual void doShape(); + + virtual void borders(int &l, int &r, int &t, int &b) const; + virtual void resize(const QSize &size); + virtual QSize minimumSize() const; + virtual Position mousePosition(const QPoint &point) const; + +private: + void addButtons(QBoxLayout* layout, const QString& buttons); + + bool isTool(); + bool eventFilter(QObject *obj, QEvent *e); + void mouseDoubleClickEvent(QMouseEvent *e); + void paintEvent(QPaintEvent *e); + void resizeEvent(QResizeEvent *); + void showEvent(QShowEvent *); + +private slots: + void maxButtonPressed(); + void menuButtonPressed(); + +private: + int buttonWidth_; + FahrenheitButton *button[ButtonTypeCount]; + QBoxLayout *mainLayout_; + QBoxLayout *topLayout_; + QBoxLayout *menuLayout_; + QBoxLayout *buttonLayout_; + QSpacerItem *titleSpacer_; + QSpacerItem *barSpacer_; +}; + +} // namespace Fahrenheit + +#endif // FAHRENHEITCLIENT_H diff --git a/client/pics/Makefile.am b/client/pics/Makefile.am new file mode 100644 index 0000000..cd202c8 --- /dev/null +++ b/client/pics/Makefile.am @@ -0,0 +1,11 @@ +linkdir = $(kde_datadir)/kwin/fahrenheit + +link_DATA = close.png maximize.png minmax.png minimize.png \ + sticky.png unsticky.png help.png + +EXTRA_DIST = $(link_DATA) + +###KMAKE-start (don't edit or delete this block) + +###KMAKE-end + diff --git a/client/pics/close.png b/client/pics/close.png Binary files differnew file mode 100644 index 0000000..65f7135 --- /dev/null +++ b/client/pics/close.png diff --git a/client/pics/help.png b/client/pics/help.png Binary files differnew file mode 100644 index 0000000..950fa0d --- /dev/null +++ b/client/pics/help.png diff --git a/client/pics/maximize.png b/client/pics/maximize.png Binary files differnew file mode 100644 index 0000000..118327d --- /dev/null +++ b/client/pics/maximize.png diff --git a/client/pics/minimize.png b/client/pics/minimize.png Binary files differnew file mode 100644 index 0000000..c0c9a3d --- /dev/null +++ b/client/pics/minimize.png diff --git a/client/pics/minmax.png b/client/pics/minmax.png Binary files differnew file mode 100644 index 0000000..e63406c --- /dev/null +++ b/client/pics/minmax.png diff --git a/client/pics/sticky.png b/client/pics/sticky.png Binary files differnew file mode 100644 index 0000000..61fdc59 --- /dev/null +++ b/client/pics/sticky.png diff --git a/client/pics/unsticky.png b/client/pics/unsticky.png Binary files differnew file mode 100644 index 0000000..6487855 --- /dev/null +++ b/client/pics/unsticky.png |