scaled-table-layout.c 22.8 KB
Newer Older
1
/*
Stephan Haller's avatar
Stephan Haller committed
2
 * scaled-table-layout: Layouts children in a dynamic table grid
3
4
5
6
7
 *                      (rows and columns are inserted and deleted
 *                      automatically depending on the number of
 *                      child actors) and scaled to fit the allocation
 *                      of the actor holding all child actors.
 * 
8
 * Copyright 2012-2020 Stephan Haller <nomad@froevel.de>
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 * 
 * 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.
 * 
 * 
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

32
#include <libxfdashboard/scaled-table-layout.h>
33
34
35
36
37

#include <glib/gi18n-lib.h>
#include <clutter/clutter.h>
#include <math.h>

38
39
#include <libxfdashboard/actor.h>
#include <libxfdashboard/animation.h>
40
41
42
#include <libxfdashboard/compat.h>


43
44
45
46
47
48
49
/* Define this class in GObject system */
struct _XfdashboardScaledTableLayoutPrivate
{
	/* Properties related */
	gfloat		rowSpacing;
	gfloat		columnSpacing;
	gboolean	relativeScale;
50
	gboolean	preventUpscaling;
51
52
53
54

	/* Instance related */
	gint		rows;
	gint		columns;
55
	gint		numberChildren;
56
57
58

	gboolean	reentrantDetermineWidth;
	gboolean	reentrantDetermineHeight;
59
60
};

61
62
63
64
G_DEFINE_TYPE_WITH_PRIVATE(XfdashboardScaledTableLayout,
							xfdashboard_scaled_table_layout,
							CLUTTER_TYPE_LAYOUT_MANAGER)

65
66
67
68
69
70
71
72
/* Properties */
enum
{
	PROP_0,

	PROP_ROW_SPACING,
	PROP_COLUMN_SPACING,
	PROP_RELATIVE_SCALE,
73
	PROP_PREVENT_UPSCALING,
74

75
76
77
78
	PROP_NUMBER_CHILDREN,
	PROP_ROWS,
	PROP_COLUMNS,

79
80
81
	PROP_LAST
};

82
static GParamSpec* XfdashboardScaledTableLayoutProperties[PROP_LAST]={ 0, };
83

84

85
86
87
/* IMPLEMENTATION: Private variables and methods */

/* Updates the minimum number of rows and columns needed for layout */
88
89
static void _xfdashboard_scaled_table_layout_update_rows_and_columns(XfdashboardScaledTableLayout *self,
																		ClutterContainer *inContainer)
90
{
91
	XfdashboardScaledTableLayoutPrivate		*priv;
92
	ClutterRequestMode						requestMode;
93
94
	ClutterActorIter						iter;
	ClutterActor							*child;
95
96
97
	gint									numberChildren;
	gint									rows;
	gint									columns;
98

99
100
101
102
103
104
	g_return_if_fail(XFDASHBOARD_IS_SCALED_TABLE_LAYOUT(self));
	g_return_if_fail(CLUTTER_IS_CONTAINER(inContainer));
	g_return_if_fail(CLUTTER_IS_ACTOR(inContainer));

	priv=self->priv;

105
106
107
	/* Freeze notification */
	g_object_freeze_notify(G_OBJECT(self));

108
	/* Get number of visible child actors */
109
	numberChildren=0;
110
111
112
	clutter_actor_iter_init(&iter, CLUTTER_ACTOR(inContainer));
	while(clutter_actor_iter_next(&iter, &child))
	{
113
		if(clutter_actor_is_visible(child)) numberChildren++;
114
115
116
117
118
119
	}

	if(numberChildren!=priv->numberChildren)
	{
		priv->numberChildren=numberChildren;
		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardScaledTableLayoutProperties[PROP_NUMBER_CHILDREN]);
120
121
	}

Stephan Haller's avatar
Stephan Haller committed
122
	/* Get request mode to determine if more rows than columns are needed
123
124
125
126
127
128
129
	 * or the opposite
	 */
	requestMode=clutter_actor_get_request_mode(CLUTTER_ACTOR(inContainer));

	/* Calculate and update number of rows and columns */
	if(requestMode==CLUTTER_REQUEST_HEIGHT_FOR_WIDTH)
	{
130
131
		rows=ceil(sqrt((double)priv->numberChildren));
		columns=ceil((double)priv->numberChildren / (double)priv->rows);
132
133
134
	}
		else
		{
135
136
			columns=ceil(sqrt((double)priv->numberChildren));
			rows=ceil((double)priv->numberChildren / (double)priv->columns);
137
		}
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152

	if(rows!=priv->rows)
	{
		priv->rows=rows;
		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardScaledTableLayoutProperties[PROP_ROWS]);
	}

	if(columns!=priv->columns)
	{
		priv->columns=columns;
		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardScaledTableLayoutProperties[PROP_COLUMNS]);
	}

	/* Thaw notification */
	g_object_thaw_notify(G_OBJECT(self));
153
154
155
156
157
}

/* IMPLEMENTATION: ClutterLayoutManager */

/* Get preferred width/height */
158
159
160
161
162
static void _xfdashboard_scaled_table_layout_get_preferred_width(ClutterLayoutManager *self,
																	ClutterContainer *inContainer,
																	gfloat inForHeight,
																	gfloat *outMinWidth,
																	gfloat *outNaturalWidth)
163
{
164
165
166
167
	XfdashboardScaledTableLayoutPrivate		*priv;
	gfloat									maxMinWidth, maxNaturalWidth;
	ClutterActor							*parent;

168
169
170
	g_return_if_fail(XFDASHBOARD_IS_SCALED_TABLE_LAYOUT(self));
	g_return_if_fail(CLUTTER_IS_CONTAINER(inContainer));

171
	priv=XFDASHBOARD_SCALED_TABLE_LAYOUT(self)->priv;
172
173
174
175
176
177
178
179

	/* Set up default values */
	maxMinWidth=0.0f;
	maxNaturalWidth=0.0f;

	/* Update number of rows and columns needed for layout */
	_xfdashboard_scaled_table_layout_update_rows_and_columns(XFDASHBOARD_SCALED_TABLE_LAYOUT(self), inContainer);

180
	/* Get size of parent if this child is parented and if it is not reentrant */
181
	parent=clutter_actor_get_parent(CLUTTER_ACTOR(inContainer));
182
183
184
185
186
187
188
189
190
191
192
	if(parent && !priv->reentrantDetermineWidth)
	{
		/* Prevent getting size of parent (reentrance) */
		priv->reentrantDetermineWidth=TRUE;

		/* Get size of parent */
		clutter_actor_get_size(CLUTTER_ACTOR(parent), &maxNaturalWidth, NULL);

		/* Allow getting size of parent again */
		priv->reentrantDetermineWidth=FALSE;
	}
193

194
195
196
	/* Calculate width */
	if(priv->columns>0)
	{
197
198
		maxMinWidth=(priv->columns-1)*priv->columnSpacing;
		if(maxNaturalWidth==0.0f) maxNaturalWidth=(priv->columns-1)*priv->columnSpacing;
199
200
201
202
203
204
205
	}

	/* Set return values */
	if(outMinWidth) *outMinWidth=maxMinWidth;
	if(outNaturalWidth) *outNaturalWidth=maxNaturalWidth;
}

206
207
208
209
210
static void _xfdashboard_scaled_table_layout_get_preferred_height(ClutterLayoutManager *self,
																	ClutterContainer *inContainer,
																	gfloat inForWidth,
																	gfloat *outMinHeight,
																	gfloat *outNaturalHeight)
211
{
212
213
214
215
	XfdashboardScaledTableLayoutPrivate		*priv;
	gfloat									maxMinHeight, maxNaturalHeight;
	ClutterActor							*parent;

216
217
218
	g_return_if_fail(XFDASHBOARD_IS_SCALED_TABLE_LAYOUT(self));
	g_return_if_fail(CLUTTER_IS_CONTAINER(inContainer));

219
	priv=XFDASHBOARD_SCALED_TABLE_LAYOUT(self)->priv;
220
221
222
223
224
225
226
227

	/* Set up default values */
	maxMinHeight=0.0f;
	maxNaturalHeight=0.0f;

	/* Update number of rows and columns needed for layout */
	_xfdashboard_scaled_table_layout_update_rows_and_columns(XFDASHBOARD_SCALED_TABLE_LAYOUT(self), inContainer);

228
	/* Get size of parent if this child is parented and if it is not reentrant */
229
	parent=clutter_actor_get_parent(CLUTTER_ACTOR(inContainer));
230
231
232
233
234
235
236
237
238
239
240
	if(parent && !priv->reentrantDetermineHeight)
	{
		/* Prevent getting size of parent (reentrance) */
		priv->reentrantDetermineHeight=TRUE;

		/* Get size of parent */
		clutter_actor_get_size(CLUTTER_ACTOR(parent), NULL, &maxNaturalHeight);

		/* Allow getting size of parent again */
		priv->reentrantDetermineHeight=FALSE;
	}
241

242
243
244
	/* Calculate height */
	if(priv->rows>0)
	{
245
246
		maxMinHeight=(priv->rows-1)*priv->rowSpacing;
		if(maxNaturalHeight==0.0f) maxNaturalHeight=(priv->rows-1)*priv->rowSpacing;
247
248
249
250
251
252
253
254
	}

	/* Set return values */
	if(outMinHeight) *outMinHeight=maxMinHeight;
	if(outNaturalHeight) *outNaturalHeight=maxNaturalHeight;
}

/* Re-layout and allocate children of container we manage */
255
256
257
258
static void _xfdashboard_scaled_table_layout_allocate(ClutterLayoutManager *self,
														ClutterContainer *inContainer,
														const ClutterActorBox *inAllocation,
														ClutterAllocationFlags inFlags)
259
{
260
	XfdashboardScaledTableLayoutPrivate		*priv;
261
262
263
	gint									row, col;
	ClutterActor							*child;
	ClutterActorIter						iter;
264
	gfloat									cellWidth, cellHeight, cellPadding;
265
	gfloat									childWidth, childHeight;
266
	gfloat									scaledChildWidth, scaledChildHeight;
267
268
269
270
	gfloat									largestWidth, largestHeight;
	gfloat									scaleWidth, scaleHeight;
	gfloat									aspectRatio;
	gfloat									x, y;
271
272
	gint									adjuster, adjustRowBegin, filledCols;
	gfloat									unfilledPadding;
273
274
	ClutterActorBox							childAllocation;

275
276
277
278
279
	g_return_if_fail(XFDASHBOARD_IS_SCALED_TABLE_LAYOUT(self));
	g_return_if_fail(CLUTTER_IS_CONTAINER(inContainer));

	priv=XFDASHBOARD_SCALED_TABLE_LAYOUT(self)->priv;

280
281
282
283
284
285
286
287
288
289
290
291
292
293
	/* Get size of container holding children to layout and
	 * determine size of a cell
	 */
	clutter_actor_get_size(CLUTTER_ACTOR(inContainer), &childWidth, &childHeight);

	cellWidth=childWidth-((priv->columns-1)*priv->columnSpacing);
	cellWidth=floor(cellWidth/priv->columns);

	cellHeight=childHeight-((priv->rows-1)*priv->rowSpacing);
	cellHeight=floor(cellHeight/priv->rows);

	/* Iterate through children and find largest one
	 * if relative scale was set
	 */
294
	largestWidth=largestHeight=0.0f;
295
296
297
298
299
300
301
	if(priv->relativeScale==TRUE)
	{
		gfloat								w, h;

		clutter_actor_iter_init(&iter, CLUTTER_ACTOR(inContainer));
		while(clutter_actor_iter_next(&iter, &child))
		{
302
			if(!clutter_actor_is_visible(child)) continue;
303
304
305
306
307
308
309

			clutter_actor_get_preferred_size(child, NULL, NULL, &w, &h);
			if(w>largestWidth) largestWidth=w;
			if(h>largestHeight) largestHeight=h;
		}
	}

310
311
312
313
314
315
316
	/* Determine how many columns in last row would not be filled, spread them
	 * over the last rows and calculate padding for each row.
	 */
	filledCols=priv->numberChildren % priv->columns;
	adjustRowBegin=(filledCols==0 ? 0 : priv->rows-priv->columns+filledCols);
	unfilledPadding=cellWidth/2.0f;

317
	/* Iterate through child actors and set their new allocation */
318
319
	row=col=adjuster=0;
	x=y=cellPadding=0.0f;
320
321
322
	clutter_actor_iter_init(&iter, CLUTTER_ACTOR(inContainer));
	while(clutter_actor_iter_next(&iter, &child))
	{
323
324
325
		gboolean							fixedPosition;
		gfloat								fixedX, fixedY;

326
		if(!clutter_actor_is_visible(child)) continue;
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352

		/* Get natural size of actor */
		clutter_actor_get_preferred_size(child, NULL, NULL, &childWidth, &childHeight);

		/* If either width or height is 0 then it is visually hidden and we
		 * skip expensive calculation. This also has the nice effect that
		 * do not perform invalid divisions by zero ;)
		 */
		if(childWidth>0.0f && childHeight>0.0f)
		{
			/* Get scale factor needed to apply to width and height.
			 * If no relative scaling should be performed the scale is always 1.0
			 * otherwise it is the scale factor for this actor to the largest one.
			 */
			if(priv->relativeScale==TRUE)
			{
				/* Get scale factors */
				scaleWidth=childWidth/largestWidth;
				scaleHeight=childHeight/largestHeight;
			}
				else scaleWidth=scaleHeight=1.0f;

			/* Get aspect ratio factor */
			aspectRatio=childHeight/childWidth;

			/* Calculate new size of child */
353
354
355
			scaledChildWidth=cellWidth*scaleWidth;
			scaledChildHeight=scaledChildWidth*aspectRatio;
			if(scaledChildHeight>cellHeight)
356
			{
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
				scaledChildHeight=cellHeight*scaleHeight;
				scaledChildWidth=scaledChildHeight/aspectRatio;
			}

			/* If upscaling should be prevent check if we are upscaling now */
			if(priv->preventUpscaling)
			{
				if(scaledChildWidth>childWidth)
				{
					scaledChildWidth=childWidth;
					scaledChildHeight=childWidth*aspectRatio;
				}

				if(scaledChildHeight>childHeight)
				{
					scaledChildHeight=childHeight;
					scaledChildWidth=childHeight/aspectRatio;
				}
375
376
377
378
379
			}
		}
			else
			{
				/* Visually hidden so do not allocate any space */
380
381
				scaledChildWidth=0.0f;
				scaledChildHeight=0.0f;
382
383
			}

384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
		/* Set new allocation of child but respect fixed position of actor */
		g_object_get(child,
						"fixed-position-set", &fixedPosition,
						"fixed-x", &fixedX,
						"fixed-y", &fixedY,
						NULL);

		if(fixedPosition)
		{
			childAllocation.x1=ceil(fixedX);
			childAllocation.y1=ceil(fixedY);
		}
			else
			{
				childAllocation.x1=ceil(x+((cellWidth-scaledChildWidth)/2.0f));
				childAllocation.y1=ceil(y+((cellHeight-scaledChildHeight)/2.0f));
			}

402
403
		childAllocation.x2=ceil(childAllocation.x1+scaledChildWidth);
		childAllocation.y2=ceil(childAllocation.y1+scaledChildHeight);
404

405
406
407
		clutter_actor_allocate(child, &childAllocation, inFlags);

		/* Set up for next child */
408
409
410
411
412
413
414
415
416
417
418
		col=(col+1) % (priv->columns-adjuster);
		if(col==0)
		{
			row++;
			if(adjuster==0 && row==adjustRowBegin)
			{
				adjuster=1;
			}
		}

		x=(col*(cellWidth+priv->columnSpacing))+(adjuster*unfilledPadding);
419
420
421
422
423
424
425
		y=row*(cellHeight+priv->rowSpacing);
	}
}

/* IMPLEMENTATION: GObject */

/* Set/get properties */
426
427
428
429
static void _xfdashboard_scaled_table_layout_set_property(GObject *inObject,
															guint inPropID,
															const GValue *inValue,
															GParamSpec *inSpec)
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
{
	XfdashboardScaledTableLayout			*self=XFDASHBOARD_SCALED_TABLE_LAYOUT(inObject);
	
	switch(inPropID)
	{
		case PROP_ROW_SPACING:
			xfdashboard_scaled_table_layout_set_row_spacing(self, g_value_get_float(inValue));
			break;

		case PROP_COLUMN_SPACING:
			xfdashboard_scaled_table_layout_set_column_spacing(self, g_value_get_float(inValue));
			break;

		case PROP_RELATIVE_SCALE:
			xfdashboard_scaled_table_layout_set_relative_scale(self, g_value_get_boolean(inValue));
			break;

447
448
449
450
		case PROP_PREVENT_UPSCALING:
			xfdashboard_scaled_table_layout_set_prevent_upscaling(self, g_value_get_boolean(inValue));
			break;

451
452
453
454
455
456
		default:
			G_OBJECT_WARN_INVALID_PROPERTY_ID(inObject, inPropID, inSpec);
			break;
	}
}

457
458
459
460
static void _xfdashboard_scaled_table_layout_get_property(GObject *inObject,
															guint inPropID,
															GValue *outValue,
															GParamSpec *inSpec)
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
{
	XfdashboardScaledTableLayout	*self=XFDASHBOARD_SCALED_TABLE_LAYOUT(inObject);

	switch(inPropID)
	{
		case PROP_ROW_SPACING:
			g_value_set_float(outValue, self->priv->rowSpacing);
			break;

		case PROP_COLUMN_SPACING:
			g_value_set_float(outValue, self->priv->columnSpacing);
			break;

		case PROP_RELATIVE_SCALE:
			g_value_set_boolean(outValue, self->priv->relativeScale);
			break;

478
479
480
481
		case PROP_PREVENT_UPSCALING:
			g_value_set_boolean(outValue, self->priv->preventUpscaling);
			break;

482
483
484
485
486
487
488
489
490
491
492
493
		case PROP_NUMBER_CHILDREN:
			g_value_set_int(outValue, self->priv->numberChildren);
			break;

		case PROP_ROWS:
			g_value_set_int(outValue, self->priv->rows);
			break;

		case PROP_COLUMNS:
			g_value_set_int(outValue, self->priv->columns);
			break;

494
495
496
497
498
499
500
501
502
503
		default:
			G_OBJECT_WARN_INVALID_PROPERTY_ID(inObject, inPropID, inSpec);
			break;
	}
}

/* Class initialization
 * Override functions in parent classes and define properties
 * and signals
 */
504
static void xfdashboard_scaled_table_layout_class_init(XfdashboardScaledTableLayoutClass *klass)
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
{
	ClutterLayoutManagerClass	*layoutClass=CLUTTER_LAYOUT_MANAGER_CLASS(klass);
	GObjectClass				*gobjectClass=G_OBJECT_CLASS(klass);

	/* Override functions */
	layoutClass->get_preferred_width=_xfdashboard_scaled_table_layout_get_preferred_width;
	layoutClass->get_preferred_height=_xfdashboard_scaled_table_layout_get_preferred_height;
	layoutClass->allocate=_xfdashboard_scaled_table_layout_allocate;

	gobjectClass->set_property=_xfdashboard_scaled_table_layout_set_property;
	gobjectClass->get_property=_xfdashboard_scaled_table_layout_get_property;

	/* Define properties */
	XfdashboardScaledTableLayoutProperties[PROP_ROW_SPACING]=
		g_param_spec_float("row-spacing",
520
521
								"Row spacing",
								"The spacing between rows in table",
522
523
524
								0.0f,
								G_MAXFLOAT,
								0.0f,
525
								G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
526
527
528

	XfdashboardScaledTableLayoutProperties[PROP_COLUMN_SPACING]=
		g_param_spec_float("column-spacing",
529
530
								"Column spacing",
								"The spacing between columns in table",
531
532
533
								0.0f,
								G_MAXFLOAT,
								0.0f,
534
								G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
535
536
537

	XfdashboardScaledTableLayoutProperties[PROP_RELATIVE_SCALE]=
		g_param_spec_boolean("relative-scale",
538
539
								"Relative scale",
								"Whether all children should be scaled relatively to largest child",
540
								FALSE,
541
								G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
542

543
544
	XfdashboardScaledTableLayoutProperties[PROP_PREVENT_UPSCALING]=
		g_param_spec_boolean("prevent-upscaling",
545
546
								"Prevent upscaling",
								"Whether this layout manager should prevent upsclaing any child beyond its real size",
547
548
549
								FALSE,
								G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);

550
	XfdashboardScaledTableLayoutProperties[PROP_NUMBER_CHILDREN]=
Gaël Bonithon's avatar
Gaël Bonithon committed
551
		g_param_spec_int("number-children",
552
553
								"Number children",
								"Current number of child actors in this layout",
554
555
556
557
558
559
								0,
								G_MAXINT,
								0,
								G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);

	XfdashboardScaledTableLayoutProperties[PROP_ROWS]=
Gaël Bonithon's avatar
Gaël Bonithon committed
560
		g_param_spec_int("rows",
561
562
								"Rows",
								"Current number of rows in this layout",
563
564
565
566
567
568
								0,
								G_MAXINT,
								0,
								G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);

	XfdashboardScaledTableLayoutProperties[PROP_COLUMNS]=
Gaël Bonithon's avatar
Gaël Bonithon committed
569
		g_param_spec_int("columns",
570
571
								"Columns",
								"Current number of columns in this layout",
572
573
574
575
576
								0,
								G_MAXINT,
								0,
								G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
	
577
578
579
580
581
582
	g_object_class_install_properties(gobjectClass, PROP_LAST, XfdashboardScaledTableLayoutProperties);
}

/* Object initialization
 * Create private structure and set up default values
 */
583
static void xfdashboard_scaled_table_layout_init(XfdashboardScaledTableLayout *self)
584
585
586
{
	XfdashboardScaledTableLayoutPrivate	*priv;

587
	priv=self->priv=xfdashboard_scaled_table_layout_get_instance_private(self);
588
589
590
591
592

	/* Set default values */
	priv->rowSpacing=0.0f;
	priv->columnSpacing=0.0f;
	priv->relativeScale=FALSE;
593
	priv->preventUpscaling=FALSE;
594
595
596

	priv->rows=0;
	priv->columns=0;
597
	priv->numberChildren=0;
598
599
600

	priv->reentrantDetermineWidth=FALSE;
	priv->reentrantDetermineHeight=FALSE;
601
602
}

Stephan Haller's avatar
Stephan Haller committed
603
/* IMPLEMENTATION: Public API */
604

605
606
/* Create new instance */
ClutterLayoutManager* xfdashboard_scaled_table_layout_new(void)
607
{
608
	return(CLUTTER_LAYOUT_MANAGER(g_object_new(XFDASHBOARD_TYPE_SCALED_TABLE_LAYOUT, NULL)));
609
610
}

611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
/* Get number of (visible) children which will be layouted */
gint xfdashboard_scaled_table_layout_get_number_children(XfdashboardScaledTableLayout *self)
{
	g_return_val_if_fail(XFDASHBOARD_IS_SCALED_TABLE_LAYOUT(self), 0);

	return(self->priv->numberChildren);
}

/* Get number of rows */
gint xfdashboard_scaled_table_layout_get_rows(XfdashboardScaledTableLayout *self)
{
	g_return_val_if_fail(XFDASHBOARD_IS_SCALED_TABLE_LAYOUT(self), 0);

	return(self->priv->rows);
}

/* Get number of columns */
gint xfdashboard_scaled_table_layout_get_columns(XfdashboardScaledTableLayout *self)
{
	g_return_val_if_fail(XFDASHBOARD_IS_SCALED_TABLE_LAYOUT(self), 0);

	return(self->priv->columns);
}

635
636
637
638
639
640
641
642
643
644
/* Get/set relative scaling of all children to largest one */
gboolean xfdashboard_scaled_table_layout_get_relative_scale(XfdashboardScaledTableLayout *self)
{
	g_return_val_if_fail(XFDASHBOARD_IS_SCALED_TABLE_LAYOUT(self), FALSE);

	return(self->priv->relativeScale);
}

void xfdashboard_scaled_table_layout_set_relative_scale(XfdashboardScaledTableLayout *self, gboolean inScaling)
{
645
646
	XfdashboardScaledTableLayoutPrivate		*priv;

647
648
	g_return_if_fail(XFDASHBOARD_IS_SCALED_TABLE_LAYOUT(self));

649
	priv=self->priv;
650
651
652
653
654
655
656
657
658
659
660
661
662

	/* Set new value if changed */
	if(priv->relativeScale!=inScaling)
	{
		/* Set new value and notify about property change */
		priv->relativeScale=inScaling;
		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardScaledTableLayoutProperties[PROP_RELATIVE_SCALE]);

		/* Notify for upcoming layout changes */
		clutter_layout_manager_layout_changed(CLUTTER_LAYOUT_MANAGER(self));
	}
}

663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
/* Get/set if layout manager should prevent to size any child larger than its real size */
gboolean xfdashboard_scaled_table_layout_get_prevent_upscaling(XfdashboardScaledTableLayout *self)
{
	g_return_val_if_fail(XFDASHBOARD_IS_SCALED_TABLE_LAYOUT(self), FALSE);

	return(self->priv->preventUpscaling);
}

void xfdashboard_scaled_table_layout_set_prevent_upscaling(XfdashboardScaledTableLayout *self, gboolean inPreventUpscaling)
{
	XfdashboardScaledTableLayoutPrivate		*priv;

	g_return_if_fail(XFDASHBOARD_IS_SCALED_TABLE_LAYOUT(self));

	priv=self->priv;

	/* Set new value if changed */
	if(priv->preventUpscaling!=inPreventUpscaling)
	{
		/* Set new value and notify about property change */
		priv->preventUpscaling=inPreventUpscaling;
		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardScaledTableLayoutProperties[PROP_PREVENT_UPSCALING]);

		/* Notify for upcoming layout changes */
		clutter_layout_manager_layout_changed(CLUTTER_LAYOUT_MANAGER(self));
	}
}

691
692
693
/* Set relative row and column spacing to same value at once */
void xfdashboard_scaled_table_layout_set_spacing(XfdashboardScaledTableLayout *self, gfloat inSpacing)
{
694
695
	XfdashboardScaledTableLayoutPrivate		*priv;

696
697
698
	g_return_if_fail(XFDASHBOARD_IS_SCALED_TABLE_LAYOUT(self));
	g_return_if_fail(inSpacing>=0.0f);

699
	priv=self->priv;
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725

	/* Set new values if changed */
	if(priv->rowSpacing!=inSpacing || priv->columnSpacing!=inSpacing)
	{
		/* Set new values and notify about properties changes */
		priv->rowSpacing=inSpacing;
		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardScaledTableLayoutProperties[PROP_ROW_SPACING]);

		priv->columnSpacing=inSpacing;
		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardScaledTableLayoutProperties[PROP_COLUMN_SPACING]);

		/* Notify for upcoming layout changes */
		clutter_layout_manager_layout_changed(CLUTTER_LAYOUT_MANAGER(self));
	}
}

/* Get/set row spacing */
gfloat xfdashboard_scaled_table_layout_get_row_spacing(XfdashboardScaledTableLayout *self)
{
	g_return_val_if_fail(XFDASHBOARD_IS_SCALED_TABLE_LAYOUT(self), 0.0f);

	return(self->priv->rowSpacing);
}

void xfdashboard_scaled_table_layout_set_row_spacing(XfdashboardScaledTableLayout *self, gfloat inSpacing)
{
726
727
	XfdashboardScaledTableLayoutPrivate		*priv;

728
729
730
	g_return_if_fail(XFDASHBOARD_IS_SCALED_TABLE_LAYOUT(self));
	g_return_if_fail(inSpacing>=0.0f);

731
	priv=self->priv;
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754

	/* Set new value if changed */
	if(priv->rowSpacing!=inSpacing)
	{
		/* Set new value and notify about property change */
		priv->rowSpacing=inSpacing;
		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardScaledTableLayoutProperties[PROP_ROW_SPACING]);

		/* Notify for upcoming layout changes */
		clutter_layout_manager_layout_changed(CLUTTER_LAYOUT_MANAGER(self));
	}
}

/* Get/set columns spacing */
gfloat xfdashboard_scaled_table_layout_get_column_spacing(XfdashboardScaledTableLayout *self)
{
	g_return_val_if_fail(XFDASHBOARD_IS_SCALED_TABLE_LAYOUT(self), 0.0f);

	return(self->priv->columnSpacing);
}

void xfdashboard_scaled_table_layout_set_column_spacing(XfdashboardScaledTableLayout *self, gfloat inSpacing)
{
755
756
	XfdashboardScaledTableLayoutPrivate		*priv;

757
758
759
	g_return_if_fail(XFDASHBOARD_IS_SCALED_TABLE_LAYOUT(self));
	g_return_if_fail(inSpacing>=0.0f);

760
	priv=self->priv;
761
762
763
764
765
766
767
768
769
770
771
772

	/* Set new value if changed */
	if(priv->columnSpacing!=inSpacing)
	{
		/* Set new value and notify about property change */
		priv->columnSpacing=inSpacing;
		g_object_notify_by_pspec(G_OBJECT(self), XfdashboardScaledTableLayoutProperties[PROP_COLUMN_SPACING]);

		/* Notify for upcoming layout changes */
		clutter_layout_manager_layout_changed(CLUTTER_LAYOUT_MANAGER(self));
	}
}