Browse Source

initial commit after porting

Signed-off-by: Emanoil Kotsev <deloptes@gmail.com>
master
Emanoil Kotsev 1 year ago
parent
commit
8dbd9ba3a6
Signed by: deloptes
GPG Key ID: F1EEB8CD9FB16A50
  1. 7
      AUTHORS
  2. 73
      CMakeLists.txt
  3. 29
      ConfigureChecks.cmake
  4. 94
      INSTALL
  5. 20
      Makefile.am
  6. 7
      Makefile.cvs
  7. 14
      README.md
  8. 32
      client/CMakeLists.txt
  9. 23
      client/Makefile.am
  10. 30
      client/config/CMakeLists.txt
  11. 18
      client/config/Makefile.am
  12. 99
      client/config/configdialog.ui
  13. 118
      client/config/exampleconfig.cc
  14. 58
      client/config/exampleconfig.h
  15. 5
      client/example.desktop
  16. 890
      client/exampleclient.cc
  17. 165
      client/exampleclient.h
  18. 3
      configure.in.in
  19. BIN
      docs/images/menu.png
  20. BIN
      docs/images/minimize.png
  21. BIN
      docs/images/motiflayout.png
  22. BIN
      docs/images/nextlayout.png
  23. BIN
      docs/images/screenshot.png
  24. BIN
      docs/images/titlebar.png
  25. 1101
      docs/kwintheme.html

7
AUTHORS

@ -0,0 +1,7 @@
Authors
-------
David Johnson <david@usermode.org>
Contributors
------------
Lubos Lunak <l.lunak@suse.cz>

73
CMakeLists.txt

@ -0,0 +1,73 @@
#################################################
#
# (C) 2021 Emanoil Kotsev
# deloptes (AT) gmail.com
#
# Improvements and feedback are welcome
#
# This file is released under GPL >= 2
#
#################################################
cmake_minimum_required( VERSION 2.8.12 )
##### general package setup #####################
project( twintheme )
set( VERSION R14.1.0 )
##### include essential cmake modules ###########
include( FindPkgConfig )
include( CheckIncludeFile )
include( CheckLibraryExists )
include( CheckSymbolExists )
include( CheckCSourceCompiles )
include( CheckCXXSourceCompiles )
##### include our cmake modules #################
set( CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules" )
include( TDEMacros )
include( TDESetupPaths )
##### setup install paths #######################
include( TDESetupPaths )
tde_setup_paths( )
##### user requested modules ####################
option( BUILD_ALL "Build all" OFF )
#option( BUILD_DOC "Build doc" ${BUILD_ALL} )
#option( BUILD_TRANSLATIONS "Build translations" ${BUILD_ALL} )
##### configure checks ##########################
include( ConfigureChecks.cmake )
###### global compiler settings #################
#add_definitions(
# -DHAVE_CONFIG_H
#)
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TQT_CXX_FLAGS}" )
set( CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined" )
set( CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--no-undefined" )
##### source directories ########################
add_subdirectory( client )
#tde_conditional_add_subdirectory( BUILD_DOC doc )
#tde_conditional_add_subdirectory( BUILD_TRANSLATIONS po )
##### write configure files #####################
#
#configure_file( config.h.cmake config.h @ONLY )

29
ConfigureChecks.cmake

@ -0,0 +1,29 @@
#################################################
#
# (C) 2010 Serghei Amelian
# serghei (DOT) amelian (AT) gmail.com
#
# Improvements and feedback are welcome
#
# This file is released under GPL >= 2
#
#################################################
# required stuff
find_package( TQt )
find_package( TDE )
tde_setup_architecture_flags( )
include(TestBigEndian)
test_big_endian(WORDS_BIGENDIAN)
tde_setup_largefiles( )
##### check for gcc visibility support
if( WITH_GCC_VISIBILITY )
tde_setup_gcc_visibility( )
endif( WITH_GCC_VISIBILITY )

94
INSTALL

@ -0,0 +1,94 @@
Example Installation
====================
The example themes requires the KDE 3.2 or greater libraries. This
can be found at <http://www.kde.org>. These are also included with
many Linux, BSD and Unix systems.
You also need GNU make, and not your standard make. On many systems,
GNU make has been installed as "gmake" If this is your situation,
substitute "gmake" for every occurance of "make" in these
instructions.
====================================================================
To save room in the distribution, the admin directory is not included
nor any of its included files. Before you can build the example, this
must be added. The simplest way is to copy one over from another KDE
package.
====================================================================
The themes use the 'configure' script to attempt a reasonable and
correct configuration for compilation on your system. It creates an
appropriate 'Makefile' for each directory in this package, along with
one or more headerfiles containing system-dependent definitions. It
also creates 'config.status','config.cache' and 'config.log' files
that are useful for recreating or debugging the configuration.
Sincerely,
David Johnson
Example Installation in a Nutshell:
====================================
1) Type './configure'
2) Type 'make'
3) Type 'make install'
Example Installation in More Detail:
=====================================
0) Make sure that the prerequisite KDE 3.2 development libraries and
headers are installed first. These can be found at
<http://www.kde.org>.
1) Unzip and untar the package into its own directory. Change into
this directory, and read the README file. (I'm assuming that
you've read this, the INSTALL file :-))
2) Type './configure --help", and peruse the configure options
available. It may be necessary to use one or more of these options
on your system.
3) Type './configure' to configure the software for your system. If
you're using `csh' on an old version of System V, you might need
to type `sh ./configure' instead.
4) Type 'make' to compile the package.
5) If you are not logged in as root, type 'su' and enter the root
password to switch over to the root account. This is not necessary
if you configured the software to install to your home directory/
6) Type 'make install' to install the software.
7) Activate the styles, decorations and color schemes through the
KDE Control Center or the Preferences menu.
8) You can uninstall the software by typing 'make uninstall'.
A Note on the KDE Library
========================
If you are having problems configuring the software, first make sure
that the required KDE 3.0 or greater libraries are installed. Several
systems have broken this into several packages. You will need both
the runtime and the development packages.
If you still have problems, set the TDEDIR environment variable and
the --prefix configure option to the location where you installed
KDE. Also makesure that you are using GNU make and not the standard
make everyone else uses.
Rebuilding the Configuration
============================
If you ever need to rebuild the configuration files, type the
following in thebase directory of the distribution:
make -f Makefile.cvs
You will need the current automake/autoconf set of programs.

20
Makefile.am

@ -0,0 +1,20 @@
SUBDIRS = $(TOPSUBDIRS)
MAINTAINERCLEANFILES = subdirs configure.in acinclude.m4 configure.files
EXTRA_DIST = Makefile.cvs admin
AUTOMAKE_OPTIONS = foreign
$(top_srcdir)/configure.in: configure.in.in $(top_srcdir)/subdirs
cd $(top_srcdir) && $(MAKE) -f admin/Makefile.common configure.in ;
$(top_srcdir)/subdirs:
cd $(top_srcdir) && $(MAKE) -f admin/Makefile.common subdirs
$(top_srcdir)/acinclude.m4: $(top_srcdir)/admin/acinclude.m4.in $(top_srcdir)/admin/libtool.m4.in
@cd $(top_srcdir) && cat admin/acinclude.m4.in admin/libtool.m4.in > acinclude.m4
dist-hook:
cd $(top_distdir) && perl admin/am_edit -padmin
cd $(top_distdir) && $(MAKE) -f admin/Makefile.common subdirs

7
Makefile.cvs

@ -0,0 +1,7 @@
all:
$(MAKE) -f admin/Makefile.common cvs
dist:
$(MAKE) -f admin/Makefile.common dist
.SILENT:

14
README.md

@ -1,3 +1,15 @@
# twintheme-example
This is an example on how to create TWin themes and was ported as such to TDE from www.usermode.org/docs/kwintheme.html
This is an example on how to create TWin themes and was ported as such to TDE from www.usermode.org/docs/kwintheme.html
Example 0.8
===========
This is an example theme for KDE for use as a tutorial. Please see
the documentation under the docs directory for more information.
As this is strictly example code, absolutely no support is available.
Bug reports are always welcome, but help in installation or
configuration will be politely ignored.
Everybody is welcome to improve and update the example code and documentation.

32
client/CMakeLists.txt

@ -0,0 +1,32 @@
#################################################
#
# (C) 2021 Emanoil Kotsev
# deloptes (AT) gmail.com
#
# Improvements and feedback are welcome
#
# This file is released under GPL >= 2
#
#################################################
add_subdirectory( config )
include_directories(
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_BINARY_DIR}
${TDE_INCLUDE_DIR}
${TQT_INCLUDE_DIRS}
)
link_directories(
${TQT_LIBRARY_DIRS}
)
##### twin_example ######################
tde_add_library( twin_example SHARED AUTOMOC
SOURCES exampleclient.cc
VERSION 1.0.0
LINK tdecore-shared -L/opt/trinity/lib -ltdecorations
DESTINATION ${LIB_INSTALL_DIR}
)

23
client/Makefile.am

@ -0,0 +1,23 @@
AUTOMAKE_OPTIONS = foreign
SUBDIRS = config
KDE_CXXFLAGS = -DQT_PLUGIN
INCLUDES = $(all_includes) -I$(kde_includes)/twin
twindir = $(kde_datadir)/twin/
twin_DATA = example.desktop
noinst_HEADERS = exampleclient.h
kde_module_LTLIBRARIES = twin3_example.la
twin3_example_la_SOURCES = exampleclient.cc
twin3_example_la_LIBADD = $(kde_libraries)/libtdecorations.la
twin3_example_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -ltdecore -module
twin3_example_la_METASOURCES = AUTO
DISTCLEANFILES = $(twin3_example_la_METASOURCES)
messages:
$(XGETTEXT) *.cpp -o $(podir)/twin_example.po

30
client/config/CMakeLists.txt

@ -0,0 +1,30 @@
#################################################
#
# (C) 2021 Emanoil Kotsev
# deloptes (AT) gmail.com
#
# Improvements and feedback are welcome
#
# This file is released under GPL >= 2
#
#################################################
include_directories(
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_BINARY_DIR}
${TDE_INCLUDE_DIR}
${TQT_INCLUDE_DIRS}
)
link_directories(
${TQT_LIBRARY_DIRS}
)
##### twin_example_config ######################
tde_add_library( twin_example_config SHARED AUTOMOC
SOURCES exampleconfig.cc configdialog.ui
VERSION 1.0.0
LINK tdeui-shared
DESTINATION ${LIB_INSTALL_DIR}
)

18
client/config/Makefile.am

@ -0,0 +1,18 @@
AUTOMAKE_OPTIONS = foreign
KDE_CXXFLAGS = -DQT_PLUGIN
INCLUDES = $(all_includes)
noinst_HEADERS = exampleconfig.h
kde_module_LTLIBRARIES = twin_example_config.la
twin_example_config_la_SOURCES = exampleconfig.cc configdialog.ui
twin_example_config_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -module
twin_example_config_la_LIBADD = $(LIB_TDEUI)
twin_example_config_la_METASOURCES = AUTO
DISTCLEANFILES = $(twin_example_config_la_METASOURCES)
messages:
$(XGETTEXT) *.cpp -o $(podir)/twin_example_config.pot

99
client/config/configdialog.ui

@ -0,0 +1,99 @@
<!DOCTYPE UI><UI version="3.1" stdsetdef="1">
<class>ConfigDialog</class>
<widget class="TQWidget">
<property name="name">
<cstring>ConfigDialog</cstring>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>235</width>
<height>108</height>
</rect>
</property>
<property name="caption">
<string>Config Dialog</string>
</property>
<hbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQGroupBox">
<property name="name">
<cstring>generalbox</cstring>
</property>
<property name="frameShape">
<enum>GroupBoxPanel</enum>
</property>
<property name="frameShadow">
<enum>Sunken</enum>
</property>
<property name="title">
<string>Decoration Settings</string>
</property>
<vbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQButtonGroup">
<property name="name">
<cstring>titlealign</cstring>
</property>
<property name="title">
<string>Title &amp;Alignment</string>
</property>
<property name="toolTip" stdset="0">
<string></string>
</property>
<property name="whatsThis" stdset="0">
<string>Use these buttons to set the alignment of the window title</string>
</property>
<hbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQRadioButton">
<property name="name">
<cstring>AlignLeft</cstring>
</property>
<property name="text">
<string>Left</string>
</property>
<property name="toolTip" stdset="0">
<string></string>
</property>
</widget>
<widget class="TQRadioButton">
<property name="name">
<cstring>AlignHCenter</cstring>
</property>
<property name="text">
<string>Center</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="toolTip" stdset="0">
<string></string>
</property>
</widget>
<widget class="TQRadioButton">
<property name="name">
<cstring>AlignRight</cstring>
</property>
<property name="text">
<string>Right</string>
</property>
<property name="toolTip" stdset="0">
<string></string>
</property>
</widget>
</hbox>
</widget>
</vbox>
</widget>
</hbox>
</widget>
<layoutdefaults spacing="6" margin="11"/>
</UI>

118
client/config/exampleconfig.cc

@ -0,0 +1,118 @@
//////////////////////////////////////////////////////////////////////////////
// exampleconfig.cc
// -------------------
// Config module for Example window decoration
// -------------------
// Copyright (c) 2003 David Johnson <david@usermode.org>
// Please see the header file for copyright and license information.
//////////////////////////////////////////////////////////////////////////////
#include <tdeconfig.h>
#include <tdelocale.h>
#include <tdeglobal.h>
#include <tqbuttongroup.h>
#include <tqgroupbox.h>
#include <tqradiobutton.h>
#include <tqwhatsthis.h>
#include "exampleconfig.h"
#include "configdialog.h"
//////////////////////////////////////////////////////////////////////////////
// ExampleConfig()
// -------------
// Constructor
ExampleConfig::ExampleConfig(TDEConfig* config, TQWidget* parent)
: TQObject(parent), config_(0), dialog_(0)
{
// create the configuration object
config_ = new TDEConfig("twinexamplerc");
TDEGlobal::locale()->insertCatalogue("twin_example_config");
// create and show the configuration dialog
dialog_ = new ConfigDialog(parent);
dialog_->show();
// load the configuration
load(config_);
// setup the connections
connect(dialog_->titlealign, SIGNAL(clicked(int)),
this, SLOT(selectionChanged(int)));
}
//////////////////////////////////////////////////////////////////////////////
// ~ExampleConfig()
// --------------
// Destructor
ExampleConfig::~ExampleConfig()
{
if (dialog_) delete dialog_;
if (config_) delete config_;
}
//////////////////////////////////////////////////////////////////////////////
// selectionChanged()
// ------------------
// Selection has changed
void ExampleConfig::selectionChanged(int)
{
emit changed();
}
//////////////////////////////////////////////////////////////////////////////
// load()
// ------
// Load configuration data
void ExampleConfig::load(TDEConfig*)
{
config_->setGroup("General");
TQString value = config_->readEntry("TitleAlignment", "AlignHCenter");
TQRadioButton *button = (TQRadioButton*)dialog_->titlealign->child(value.latin1());
if (button) button->setChecked(true);
}
//////////////////////////////////////////////////////////////////////////////
// save()
// ------
// Save configuration data
void ExampleConfig::save(TDEConfig*)
{
config_->setGroup("General");
TQRadioButton *button = (TQRadioButton*)dialog_->titlealign->selected();
if (button) config_->writeEntry("TitleAlignment", TQString(button->name()));
config_->sync();
}
//////////////////////////////////////////////////////////////////////////////
// defaults()
// ----------
// Set configuration defaults
void ExampleConfig::defaults()
{
TQRadioButton *button =
(TQRadioButton*)dialog_->titlealign->child("AlignHCenter");
if (button) button->setChecked(true);
}
//////////////////////////////////////////////////////////////////////////////
// Plugin Stuff //
//////////////////////////////////////////////////////////////////////////////
extern "C"
{
TQObject* allocate_config(TDEConfig* config, TQWidget* parent) {
return (new ExampleConfig(config, parent));
}
}
#include "exampleconfig.moc"

58
client/config/exampleconfig.h

@ -0,0 +1,58 @@
//////////////////////////////////////////////////////////////////////////////
// exampleconfig.h
// -------------------
// Config module for Example window decoration
// -------------------
// Copyright (c) 2003 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 EXAMPLECONFIG_H
#define EXAMPLECONFIG_H
#include <tqobject.h>
class TDEConfig;
class ConfigDialog;
class ExampleConfig : public TQObject
{
TQ_OBJECT
public:
ExampleConfig(TDEConfig* config, TQWidget* parent);
~ExampleConfig();
signals:
void changed();
public slots:
void load(TDEConfig*);
void save(TDEConfig*);
void defaults();
protected slots:
void selectionChanged(int);
private:
TDEConfig *config_;
ConfigDialog *dialog_;
};
#endif // EXAMPLECONFIG_H

5
client/example.desktop

@ -0,0 +1,5 @@
# KDE Desktop Entry
[Desktop Entry]
Encoding=UTF-8
Name=Example
X-TDE-Library=twin3_example

890
client/exampleclient.cc

@ -0,0 +1,890 @@
//////////////////////////////////////////////////////////////////////////////
// exampleclient.cc
// -------------------
// Example window decoration for KDE
// -------------------
// Copyright (c) 2003, 2004 David Johnson
// Please see the header file for copyright and license information.
//////////////////////////////////////////////////////////////////////////////
#include <tdeconfig.h>
#include <tdeversion.h>
#include <tdeglobal.h>
#include <tdeglobalsettings.h>
#include <tdelocale.h>
#include <tqbitmap.h>
#include <tqlabel.h>
#include <tqlayout.h>
#include <tqpainter.h>
#include <tqtooltip.h>
#include "exampleclient.h"
using namespace Example;
// global constants
static const int BUTTONSIZE = 18;
static const int DECOSIZE = 8;
static const int TITLESIZE = 18;
static const int FRAMESIZE = 4;
// window button decorations
static const unsigned char close_bits[] = {
0x00, 0x66, 0x7e, 0x3c, 0x3c, 0x7e, 0x66, 0x00};
static const unsigned char help_bits[] = {
0x7e, 0x7e, 0x60, 0x78, 0x78, 0x00, 0x18, 0x18};
static const unsigned char max_bits[] = {
0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x00, 0x00};
static const unsigned char min_bits[] = {
0x00, 0x00, 0xff, 0xff, 0x7e, 0x3c, 0x18, 0x00};
static const unsigned char minmax_bits[] = {
0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e, 0x00};
static const unsigned char stickydown_bits[] = {
0x00, 0x18, 0x18, 0x7e, 0x7e, 0x18, 0x18, 0x00};
static const unsigned char sticky_bits[] = {
0x00, 0x00, 0x00, 0x7e, 0x7e, 0x00, 0x00, 0x00};
static const unsigned char above_on_bits[] = {
0x7e, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00 };
static const unsigned char above_off_bits[] = {
0x18, 0x3c, 0x7e, 0x18, 0x7e, 0x00, 0x00, 0x00 };
static const unsigned char below_on_bits[] = {
0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x7e };
static const unsigned char below_off_bits[] = {
0x00, 0x00, 0x00, 0x7e, 0x18, 0x7e, 0x3c, 0x18 };
static const unsigned char shade_on_bits[] = {
0xff, 0xff, 0x81, 0xa5, 0x81, 0xa5, 0x81, 0xff };
static const unsigned char shade_off_bits[] = {
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
//////////////////////////////////////////////////////////////////////////////
// ExampleFactory Class //
//////////////////////////////////////////////////////////////////////////////
bool ExampleFactory::initialized_ = false;
TQt::AlignmentFlags ExampleFactory::titlealign_ = TQt::AlignHCenter;
extern "C" KDecorationFactory* create_factory()
{
return new Example::ExampleFactory();
}
//////////////////////////////////////////////////////////////////////////////
// ExampleFactory()
// ----------------
// Constructor
ExampleFactory::ExampleFactory()
{
readConfig();
initialized_ = true;
}
//////////////////////////////////////////////////////////////////////////////
// ~ExampleFactory()
// -----------------
// Destructor
ExampleFactory::~ExampleFactory() { initialized_ = false; }
//////////////////////////////////////////////////////////////////////////////
// createDecoration()
// -----------------
// Create the decoration
KDecoration* ExampleFactory::createDecoration(KDecorationBridge* b)
{
return new ExampleClient(b, this);
}
//////////////////////////////////////////////////////////////////////////////
// reset()
// -------
// Reset the handler. Returns true if decorations need to be remade, false if
// only a repaint is necessary
bool ExampleFactory::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 ExampleFactory::readConfig()
{
// create a config object
TDEConfig config("twinexamplerc");
config.setGroup("General");
// grab settings
TQt::AlignmentFlags oldalign = titlealign_;
TQString value = config.readEntry("TitleAlignment", "AlignHCenter");
if (value == "AlignLeft") titlealign_ = TQt::AlignLeft;
else if (value == "AlignHCenter") titlealign_ = TQt::AlignHCenter;
else if (value == "AlignRight") titlealign_ = TQt::AlignRight;
if (oldalign == titlealign_)
return false;
else
return true;
}
//////////////////////////////////////////////////////////////////////////////
// ExampleButton Class //
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// ExampleButton()
// ---------------
// Constructor
ExampleButton::ExampleButton(ExampleClient *parent, const char *name,
const QString& tip, ButtonType type,
const unsigned char *bitmap)
: TQButton(parent->widget(), name), client_(parent), type_(type),
deco_(0), lastmouse_(NoButton)
{
setBackgroundMode(NoBackground);
setFixedSize(BUTTONSIZE, BUTTONSIZE);
setCursor(arrowCursor);
if (bitmap) setBitmap(bitmap);
TQToolTip::add(this, tip);
}
ExampleButton::~ExampleButton()
{
if (deco_) delete deco_;
}
//////////////////////////////////////////////////////////////////////////////
// setBitmap()
// -----------
// Set the button decoration
void ExampleButton::setBitmap(const unsigned char *bitmap)
{
if (!bitmap) return; // no bitmap, probably the menu button
if (deco_) delete deco_;
deco_ = new TQBitmap(DECOSIZE, DECOSIZE, bitmap, true);
deco_->setMask(*deco_);
repaint(false);
}
//////////////////////////////////////////////////////////////////////////////
// sizeHint()
// ----------
// Return size hint
TQSize ExampleButton::sizeHint() const
{
return TQSize(BUTTONSIZE, BUTTONSIZE);
}
//////////////////////////////////////////////////////////////////////////////
// enterEvent()
// ------------
// Mouse has entered the button
void ExampleButton::enterEvent(TQEvent *e)
{
// if we wanted to do mouseovers, we would keep track of it here
TQButton::enterEvent(e);
}
//////////////////////////////////////////////////////////////////////////////
// leaveEvent()
// ------------
// Mouse has left the button
void ExampleButton::leaveEvent(TQEvent *e)
{
// if we wanted to do mouseovers, we would keep track of it here
TQButton::leaveEvent(e);
}
//////////////////////////////////////////////////////////////////////////////
// mousePressEvent()
// -----------------
// Button has been pressed
void ExampleButton::mousePressEvent(TQMouseEvent* 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
}
TQMouseEvent me(e->type(), e->pos(), e->globalPos(),
button, e->state());
TQButton::mousePressEvent(&me);
}
//////////////////////////////////////////////////////////////////////////////
// mouseReleaseEvent()
// -----------------
// Button has been released
void ExampleButton::mouseReleaseEvent(TQMouseEvent* 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
}
TQMouseEvent me(e->type(), e->pos(), e->globalPos(), button, e->state());
TQButton::mouseReleaseEvent(&me);
}
//////////////////////////////////////////////////////////////////////////////
// drawButton()
// ------------
// Draw the button
void ExampleButton::drawButton(TQPainter *painter)
{
if (!ExampleFactory::initialized()) return;
TQColorGroup group;
int dx, dy;
// paint a plain box with border
group = KDecoration::options()->
colorGroup(KDecoration::ColorButtonBg, client_->isActive());
painter->fillRect(rect(), group.button());
painter->setPen(group.dark());
painter->drawRect(rect());
if (type_ == ButtonMenu) {
// we paint the mini icon (which is 16 pixels high)
dx = (width() - 16) / 2;
dy = (height() - 16) / 2;
if (isDown()) { dx++; dy++; }
painter->drawPixmap(dx, dy, client_->icon().pixmap(TQIconSet::Small,
TQIconSet::Normal));
} else if (deco_) {
// otherwise we paint the deco
dx = (width() - DECOSIZE) / 2;
dy = (height() - DECOSIZE) / 2;
if (isDown()) { dx++; dy++; }
painter->setPen(group.dark());
painter->drawPixmap(dx, dy, *deco_);
}
}
//////////////////////////////////////////////////////////////////////////////
// ExampleClient Class //
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// ExampleClient()
// ---------------
// Constructor
ExampleClient::ExampleClient(KDecorationBridge *b, KDecorationFactory *f)
: KDecoration(b, f) { ; }
ExampleClient::~ExampleClient()
{
for (int n=0; n<ButtonTypeCount; n++) {
if (button[n]) delete button[n];
}
}
//////////////////////////////////////////////////////////////////////////////
// init()
// ------
// Actual initializer for class
void ExampleClient::init()
{
createMainWidget(WResizeNoErase | WRepaintNoErase);
widget()->installEventFilter(this);
// for flicker-free redraws
widget()->setBackgroundMode(NoBackground);
// setup layout
TQGridLayout *mainlayout = new TQGridLayout(widget(), 4, 3); // 4x3 grid
TQHBoxLayout *titlelayout = new TQHBoxLayout();
titlebar_ = new TQSpacerItem(1, TITLESIZE, TQSizePolicy::Expanding,
TQSizePolicy::Fixed);
mainlayout->setResizeMode(TQLayout::FreeResize);
mainlayout->addRowSpacing(0, FRAMESIZE);
mainlayout->addRowSpacing(3, FRAMESIZE*2);
mainlayout->addColSpacing(0, FRAMESIZE);
mainlayout->addColSpacing(2, FRAMESIZE);
mainlayout->addLayout(titlelayout, 1, 1);
if (isPreview()) {
mainlayout->addWidget(
new TQLabel(i18n("<b><center>Example preview</center></b>"),
widget()), 2, 1);
} else {
mainlayout->addItem(new TQSpacerItem(0, 0), 2, 1);
}
// the window should stretch
mainlayout->setRowStretch(2, 10);
mainlayout->setColStretch(1, 10);
// setup titlebar buttons
for (int n=0; n<ButtonTypeCount; n++) button[n] = 0;
addButtons(titlelayout, options()->titleButtonsLeft());
titlelayout->addItem(titlebar_);
addButtons(titlelayout, options()->titleButtonsRight());
// connections
connect(this, SIGNAL(keepAboveChanged(bool)), SLOT(keepAboveChange(bool)));
connect(this, SIGNAL(keepBelowChanged(bool)), SLOT(keepBelowChange(bool)));
}
//////////////////////////////////////////////////////////////////////////////
// addButtons()
// ------------
// Add buttons to title layout
void ExampleClient::addButtons(TQBoxLayout *layout, const TQString& s)
{
const unsigned char *bitmap;
TQString 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 ExampleButton(this, "menu", i18n("Menu"),
ButtonMenu, 0);
connect(button[ButtonMenu], SIGNAL(pressed()),
this, SLOT(menuButtonPressed()));
layout->addWidget(button[ButtonMenu]);
}
break;
case 'S': // Sticky button
if (!button[ButtonSticky]) {
if (isOnAllDesktops()) {
bitmap = stickydown_bits;
tip = i18n("Un-Sticky");
} else {
bitmap = sticky_bits;
tip = i18n("Sticky");
}
button[ButtonSticky] =
new ExampleButton(this, "sticky", tip,
ButtonSticky, bitmap);
connect(button[ButtonSticky], SIGNAL(clicked()),
this, SLOT(toggleOnAllDesktops()));
layout->addWidget(button[ButtonSticky]);
}
break;
case 'H': // Help button
if ((!button[ButtonHelp]) && providesContextHelp()) {
button[ButtonHelp] =
new ExampleButton(this, "help", i18n("Help"),
ButtonHelp, help_bits);
connect(button[ButtonHelp], SIGNAL(clicked()),
this, SLOT(showContextHelp()));
layout->addWidget(button[ButtonHelp]);
}
break;
case 'I': // Minimize button
if ((!button[ButtonMin]) && isMinimizable()) {
button[ButtonMin] =
new ExampleButton(this, "iconify", i18n("Minimize"),
ButtonMin, min_bits);
connect(button[ButtonMin], SIGNAL(clicked()),
this, SLOT(minimize()));
layout->addWidget(button[ButtonMin]);
}
break;
case 'A': // Maximize button
if ((!button[ButtonMax]) && isMaximizable()) {
if (maximizeMode() == MaximizeFull) {
bitmap = minmax_bits;
tip = i18n("Restore");
} else {
bitmap = max_bits;
tip = i18n("Maximize");
}
button[ButtonMax] =
new ExampleButton(this, "maximize", tip,
ButtonMax, bitmap);
connect(button[ButtonMax], SIGNAL(clicked()),
this, SLOT(maxButtonPressed()));
layout->addWidget(button[ButtonMax]);
}
break;
case 'X': // Close button
if ((!button[ButtonClose]) && isCloseable()) {
button[ButtonClose] =
new ExampleButton(this, "close", i18n("Close"),
ButtonClose, close_bits);
connect(button[ButtonClose], SIGNAL(clicked()),
this, SLOT(closeWindow()));
layout->addWidget(button[ButtonClose]);
}
break;
case 'F': // Above button
if ((!button[ButtonAbove])) {
button[ButtonAbove] =
new ExampleButton(this, "above",
i18n("Keep Above Others"), ButtonAbove,
keepAbove() ? above_on_bits : above_off_bits);
connect(button[ButtonAbove], SIGNAL(clicked()),
this, SLOT(aboveButtonPressed()));
layout->addWidget(button[ButtonAbove]);
}
break;
case 'B': // Below button
if ((!button[ButtonBelow])) {
button[ButtonBelow] =
new ExampleButton(this, "below",
i18n("Keep Below Others"), ButtonBelow,
keepBelow() ? below_on_bits : below_off_bits);
connect(button[ButtonBelow], SIGNAL(clicked()),
this, SLOT(belowButtonPressed()));
layout->addWidget(button[ButtonBelow]);
}
break;
case 'L': // Shade button
if ((!button[ButtonShade && isShadeable()])) {
if ( isSetShade()) {
bitmap = shade_on_bits;
tip = i18n("Unshade");
} else {
bitmap = shade_off_bits;
tip = i18n("Shade");
}
button[ButtonShade] =
new ExampleButton(this, "shade", tip,
ButtonShade, bitmap);
connect(button[ButtonShade], SIGNAL(clicked()),
this, SLOT(shadeButtonPressed()));
layout->addWidget(button[ButtonShade]);
}
break;
case '_': // Spacer item
layout->addSpacing(FRAMESIZE);
}
}
}
}
//////////////////////////////////////////////////////////////////////////////
// activeChange()
// --------------
// window active state has changed
void ExampleClient::activeChange()
{
for (int n=0; n<ButtonTypeCount; n++)
if (button[n]) button[n]->reset();
widget()->repaint(false);
}
//////////////////////////////////////////////////////////////////////////////
// captionChange()
// ---------------
// The title has changed
void ExampleClient::captionChange()
{
widget()->repaint(titlebar_->geometry(), false);
}
//////////////////////////////////////////////////////////////////////////////
// desktopChange()
// ---------------
// Called when desktop/sticky changes
void ExampleClient::desktopChange()
{
bool d = isOnAllDesktops();
if (button[ButtonSticky]) {
button[ButtonSticky]->setBitmap(d ? stickydown_bits : sticky_bits);
TQToolTip::remove(button[ButtonSticky]);
TQToolTip::add(button[ButtonSticky], d ? i18n("Un-Sticky") : i18n("Sticky"));
}
}
//////////////////////////////////////////////////////////////////////////////
// iconChange()
// ------------
// The title has changed
void ExampleClient::iconChange()
{
if (button[ButtonMenu]) {
button[ButtonMenu]->setBitmap(0);
button[ButtonMenu]->repaint(false);
}
}
//////////////////////////////////////////////////////////////////////////////
// maximizeChange()
// ----------------
// Maximized state has changed
void ExampleClient::maximizeChange()
{
bool m = (maximizeMode() == MaximizeFull);
if (button[ButtonMax]) {
button[ButtonMax]->setBitmap(m ? minmax_bits : max_bits);
TQToolTip::remove(button[ButtonMax]);
TQToolTip::add(button[ButtonMax], m ? i18n("Restore") : i18n("Maximize"));
}
}
//////////////////////////////////////////////////////////////////////////////
// shadeChange()
// -------------
// Called when window shading changes
void ExampleClient::shadeChange()
{
bool s = isSetShade();
if (button[ButtonShade]) {
button[ButtonShade]->setBitmap(s ? shade_on_bits : shade_off_bits);
TQToolTip::remove(button[ButtonShade]);
TQToolTip::add(button[ButtonShade], s ? i18n("Unshade") : i18n("Shade"));
}
}
//////////////////////////////////////////////////////////////////////////////
// keepAboveChange()
// ------------
// The above state has changed
void ExampleClient::keepAboveChange(bool a)
{
if (button[ButtonAbove]) {
button[ButtonAbove]->setBitmap(a ? above_on_bits : above_off_bits);
}
}
//////////////////////////////////////////////////////////////////////////////
// keepBelowChange()
// ------------
// The below state has changed
void ExampleClient::keepBelowChange(bool b)
{
if (button[ButtonBelow]) {
button[ButtonBelow]->setBitmap(b ? below_on_bits : below_off_bits);
}
}
//////////////////////////////////////////////////////////////////////////////
// borders()
// ----------
// Get the size of the borders
void ExampleClient::borders(int &l, int &r, int &t, int &b) const
{
l = r = FRAMESIZE;
t = TITLESIZE + FRAMESIZE;
b = FRAMESIZE * 2;
}
//////////////////////////////////////////////////////////////////////////////
// resize()
// --------
// Called to resize the window
void ExampleClient::resize(const TQSize &size)
{
widget()->resize(size);
}
//////////////////////////////////////////////////////////////////////////////
// minimumSize()
// -------------
// Return the minimum allowable size for this window
TQSize ExampleClient::minimumSize() const
{
return widget()->minimumSize();
}
//////////////////////////////////////////////////////////////////////////////
// mousePosition()
// ---------------
// Return logical mouse position
KDecoration::Position ExampleClient::mousePosition(const TQPoint &point) const
{
const int corner = 24;
Position pos;
if (point.y() <= FRAMESIZE) {
// inside top frame
if (point.x() <= corner) pos = PositionTopLeft;
else if (point.x() >= (width()-corner)) pos = PositionTopRight;
else pos = PositionTop;
} else if (point.y() >= (height()-FRAMESIZE*2)) {
// inside handle
if (point.x() <= corner) pos = PositionBottomLeft;
else if (point.x() >= (width()-corner)) pos = PositionBottomRight;
else pos = PositionBottom;
} else if (point.x() <= FRAMESIZE) {
// on left frame
if (point.y() <= corner) pos = PositionTopLeft;
else if (point.y() >= (height()-corner)) pos = PositionBottomLeft;
else pos = PositionLeft;
} else if (point.x() >= width()-FRAMESIZE) {
// on right frame
if (point.y() <= corner) pos = PositionTopRight;
else if (point.y() >= (height()-corner)) pos = PositionBottomRight;
else pos = PositionRight;
} else {
// inside the frame
pos = PositionCenter;
}
return pos;
}
//////////////////////////////////////////////////////////////////////////////
// eventFilter()
// -------------
// Event filter
bool ExampleClient::eventFilter(TQObject *obj, TQEvent *e)
{
if (obj != widget()) return false;
switch (e->type()) {
case TQEvent::MouseButtonDblClick: {
mouseDoubleClickEvent(static_cast<TQMouseEvent *>(e));
return true;
}
case TQEvent::MouseButtonPress: {
processMousePressEvent(static_cast<TQMouseEvent *>(e));
return true;
}
case TQEvent::Paint: {
paintEvent(static_cast<TQPaintEvent *>(e));
return true;
}
case TQEvent::Resize: {
resizeEvent(static_cast<TQResizeEvent *>(e));
return true;
}
case TQEvent::Show: {
showEvent(static_cast<TQShowEvent *>(e));
return true;
}
default: {
return false;
}
}
return false;
}
//////////////////////////////////////////////////////////////////////////////
// mouseDoubleClickEvent()
// -----------------------
// Doubleclick on title
void ExampleClient::mouseDoubleClickEvent(TQMouseEvent *e)
{
if (titlebar_->geometry().contains(e->pos())) titlebarDblClickOperation();
}
//////////////////////////////////////////////////////////////////////////////
// paintEvent()
// ------------
// Repaint the window
void ExampleClient::paintEvent(TQPaintEvent*)
{
if (!ExampleFactory::initialized()) return;
TQColorGroup group;
TQPainter painter(widget());
// draw the titlebar
TQRect title(titlebar_->geometry());
group = options()->colorGroup(KDecoration::ColorTitleBar, isActive());
painter.fillRect(title, group.background());
painter.setPen(group.dark());
painter.drawRect(title);
// draw title text
painter.setFont(options()->font(isActive(), false));
painter.setPen(options()->color(KDecoration::ColorFont, isActive()));
painter.drawText(title.x() + FRAMESIZE, title.y(),