summaryrefslogtreecommitdiffstats
path: root/kdm/kfrontend/themer/kdmitem.h
blob: 1a87692acc7a3194a25d9fdfc9d0773a3abf4553 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
/*
 *  Copyright (C) 2003 by Unai Garro <ugarro@users.sourceforge.net>
 *  Copyright (C) 2004 by Enrico Ros <rosenric@dei.unipd.it>
 *  Copyright (C) 2004 by Stephan Kulow <coolo@kde.org>
 *  Copyright (C) 2004 by Oswald Buddenhagen <ossi@kde.org>
 *
 *  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 this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#ifndef KDMITEM_H
#define KDMITEM_H

#include <tqobject.h>
#include <tqvaluelist.h>
#include <tqrect.h>
#include <tqdom.h>

class KdmItem;
class KdmLayoutBox;
class KdmLayoutFixed;

class TQPainter;
class TQLayoutItem;

/** class KdmItem
 * @short Base class for every kdmthemes' element.
 *
 * This class provides methods for arranging it and its children to the
 * screen (see note below), painting the whole area or a sub-region using
 * an opened painter, handling mouse events or events in general dispatching
 * them to children and sending some signals to the root (for example on
 * mouse click).
 *
 * KdmItem sits in a hierarchical top to bottom tree with signals that
 * traverse the tree back from leafs (or inner nodes) to the root.
 *
 * To implement a KdmItem only a few virtual protected methods must be
 * reimplemented, other virtual functions are there for convenience only -
 * the default implementation should satisfy your needs.
 */

/**
 * A note on layouting - how does it work?
 *  - setgeometry is called by parent (passing the new geometry)
 *    - item changes its geometry
 *    - if item embeds a widget, reposition it too
 *    - call children's box manager. box->update( my geom )
 *      - sum up the whole space taken by children (via *hint calls) if
 *        needed for box width / height computation. note that the computed
 *        geometry should be equal or similar to parent's geometry.
 *      - pad the rectangle bounding box' contents
 *      - for every child
 *        - if vertical
 *          ( use a top-to-bottom insertion, spacing insertion lines by
 *            children's individual height )
 *          - set up a zero height Parent (placed at the insertion line's
 *            position) and get Geom = child->placementHint( p )
 *          - set up child's Size using Parent's width and Geom's height.
 *          - call to child->setGeometry( Parent.topLeft, Size )
 *        - if horizontal
 *          - flows like the vertical one but uses a left-to-right insertion
 *            and insertion entry points are vertical lines
 *    - call to children's fix manager. fixed->update( my geom )
 *      - for every child
 *          - S = get child's geometry hint (and we'll give item the whole
 *            space it needs, without constraints)
 *          - call to child->setGeometry( S )
 *    - TODO: send a selective redraw signal also merging children's areas
 */

class KdmItem : public TQObject {
	Q_OBJECT

	friend class KdmThemer;

public:
	/**
	 * Item constructor and destructor
	 */
	KdmItem( KdmItem *parent, const TQDomNode &node = TQDomNode(), const char *name = 0 );
	KdmItem( TQWidget *parent, const TQDomNode &node = TQDomNode(), const char *name = 0 ); // for the root

	virtual ~KdmItem();

	/**
	 * Fixup the geometry of an item and its children (even if fixed
	 * or boxed ones). Note that this will generate tqrepaint signals
	 * when needed. The default implementation should fit all needs.
	 */
	virtual void setGeometry( const TQRect &newGeometry, bool force );

	/**
	 * Paint the item and its children using the given painter.
	 * This is the compositing core function. It buffers paint operations
	 * to speed up rendering of dynamic objects.
	 */
	void paint( TQPainter *painter, const TQRect &boundaries );

	/**
	 * Update representation of contents and tqrepaint.
	 */
	virtual void update();

	/**
	 * Handle mouse motion and dispatch events to children. This
	 * leads to items prelighting, activation() on click and more..
	 */
	void mouseEvent( int x, int y, bool pressed = false, bool released = false );

	/**
	 * Similar to tqsizeHint(..), this returns the area of the item
	 * given the @p parentGeometry. The default implementation
	 * takes into account geometric constraints and layoutings.
	 * @param parentGeometry the geometry of the caller item or a
	 * null rect if the geometry of the parent is not yet defined.
	 */
	virtual TQRect placementHint( const TQRect &parentGeometry );

	/**
	 * Create the box layout manager; next children will be
	 * managed by the box layouter
	 */
	void setBoxLayout( const TQDomNode &node = TQDomNode() );

	/**
	 * Create the fixed layout manager; next children will be
	 * in fixed position relative to this item
	 */
	void setFixedLayout( const TQDomNode &node = TQDomNode() );

	TQString type() const { return itemType;	}
	void setType( const TQString &t ) { itemType = t; }
	void setBaseDir( const TQString &bd ) { basedir = bd; }

	TQString baseDir() const
	{
		if (basedir.isEmpty() && parent())
			return static_cast<KdmItem *>( tqparent()->qt_cast( "KdmItem" ) )->baseDir();
		return basedir;
	}

	KdmItem *findNode( const TQString &id ) const;
	virtual void setWidget( TQWidget *widget );
	TQWidget *widget() const { return myWidget; }
	virtual void setLayoutItem( TQLayoutItem *item );

	virtual void hide( bool force = false );
	virtual void show( bool force = false );

	bool isHidden() const { return isShown != Shown; }
	bool isExplicitlyHidden() const { return isShown == ExplicitlyHidden; }
	TQRect rect() const { return area; }

	TQWidget *parentWidget() const;
	TQString getId() const { return id; }

signals:
	void needUpdate( int x, int y, int w, int h );
	void activated( const TQString &id );

protected slots:
	void widgetGone();
	void layoutItemGone();

protected:
	/**
	 * Returns the optimal/minimal size for this item.
	 * This should be reimplemented in items like label and pixmap.
	 * @return (-1,-1) if no size can be determined (so it should
	 * default to parent's size).
	 */
	virtual TQSize tqsizeHint();

	/**
	 * Low level graphical function to paint the item.
	 * All items must reimplement this function to draw themeselves
	 * (or a part of) into the @p image keeping inside the @p rect .
	 * Try to do this as fast as possible.
	 * @param painter the painter to draw the item with
	 * @param region the part of the the image to render
	 */
	virtual void drawContents( TQPainter *painter, const TQRect &region ) = 0;

	/**
	 * Called when item changes its 'state' variable. This must
	 * handle item's tqrepaint.
	 */
	virtual void statusChanged();

	/**
	 * emits needUpdate( int, int, int, int ) with the full widget area.
	 */
	void needUpdate();

	// This enum identifies in which state the item is
	enum ItemState { Snormal, Sactive, Sprelight } state;

	static KdmItem *currentActive;

	// This struct can be filled in by derived items
	struct {
		bool incrementalPaint;
	} properties;

	// This is the placement of the item
	TQRect area;

	// This struct is filled in by KdmItem base class
	enum DataType { DTnone, DTpixel, DTnpixel, DTpercent, DTbox };
	struct {
		enum DataType xType, yType, wType, hType;
		int x;
		int y;
		int width;
		int height;
		TQString anchor;
	} pos;

	/* For internal use ONLY
	 * Add a child item. This function is called automatically
	 * when constructing an @p item with this as the parent.
	 */
	void addChildItem( KdmItem *item );

	/* For internal use ONLY
	 * Parse type and value of an attribute (pos tag), a font or a
	 * color.
	 */
	void parseAttribute( const TQString &, int &, enum DataType & );
	void parseFont( const TQString &, TQFont & );
	void parseColor( const TQString &, TQColor & );

	void inheritFromButton( KdmItem *button );
	void init( const TQDomNode &node = TQDomNode(), const char *name = 0 );

	TQString itemType, id;
	TQValueList<KdmItem *> m_children;

	int m_backgroundModifier;

	// Layouting related variables
	enum { MNone = 0, MFixed = 1, MBox = 2 } currentManager;
	KdmLayoutBox *boxManager;
	KdmLayoutFixed *fixedManager;

	// Compositing related variables
	TQImage *image;

	// defines the directory the theme is in (may be present in the parent)
	TQString basedir;

	TQWidget *myWidget;
	TQLayoutItem *myLayoutItem;

	enum { InitialHidden, ExplicitlyHidden, Shown } isShown;

	KdmItem *buttonParent;
};

#endif