Re: Proposal of a Bonobo::Zoomable interface



Maciej Stachowiak <mjs eazel com> writes:

> One other thing to look out for: right now, the Nautilus::Zoomable
> interface depends on being add_interface'd to a Bonobo::Cotrol to work
> well, since the implementation gets at the ZoomableFrame by doing a
> query_interface on the Control's ControlFrame. While this keeps things
> relatively simple and convenient for Nautilus, where we know Controls
> are the only thing we care about, the concept of zooming is actually
> more general than that, and could in theory apply to things that don't
> even have a GUI. So perhaps it would make more sense to add an
> explicit set_zoomable_frame call (and perhaps rebame ZoomableFrame to
> ZoomableListener or something).

Well, in my latest API draft we have:

====[bonobo-zoomable.idl]====
module Bonobo {

typedef float ZoomLevel;
typedef sequence<ZoomLevel> ZoomLevelList;
	
/* A zoomable has the responsibility to look for this
 * interface on its Bonobo control frame and call
 * zoom_level_changed whenever it changes the zoom level (on
 * its own or due to calls from the zoomable interface).
*/
interface ZoomableFrame : ::Bonobo::Unknown {
	oneway void report_zoom_level_changed (in float zoom_level);
	oneway void report_zoom_parameters_changed ();
};

interface Zoomable : Bonobo::Unknown {
	/* Current zoom level. */
	readonly attribute float zoom_level;

	/* Information about the type of zooming that's supported. */
	readonly attribute float min_zoom_level;
	readonly attribute float max_zoom_level;
	readonly attribute boolean has_min_zoom_level;
	readonly attribute boolean has_max_zoom_level;
	readonly attribute boolean is_continuous;
	readonly attribute ZoomLevelList preferred_zoom_levels;
		
	/* High level operations.
	 * These can cause a change in the zoom level.
	 * The zoomable itself must decide what the concepts
	 * "one level in", "one level out", and "to fit" mean.
	 */
	oneway void zoom_in ();
	oneway void zoom_out ();
	oneway void zoom_to_fit ();
	oneway void zoom_to_default ();

	/**
	 *
	 * set_zoom_level:
	 * @zoom_level: The new zoom level.
	 *
	 * Tells the component to zoom to @zoom_level.
	 */
	void set_zoom_level (in float zoom_level);

	/**
	 * set_frame:
	 * @zoomable_frame: A Bonobo_ZoomableFrame.
	 *
	 * Gives the Zoomable a handle to its ZoomableFrame.
	 */
	void set_frame (in ZoomableFrame zoomable_frame);
};
};
=====

Note that I made the "zoom_level" attribute read-only as well:

1.) The component may not be able to zoom to exactly the requested zoom
    level but may need to change it.

2.) Changing the zoom level is an async operation and may take a while
    to complete.

So there's now a `set_zoom_level' method; when it is invoked, the component
will zoom to the requested zoom level, set the "zoom_level" attribute to
its actual current zoom level and then invokes the `report_zoom_level_changed'
method on the Bonobo::ZoomableFrame.

When any of the other parameters is changed, the `report_zoom_parameters_changed'
method will be used to inform the container about it.

IMO using PropertyBags and listeners doesn't work quite well here since if one
of the parameters (`min_zoom_level', `max_zoom_level' etc.) changes, normally
all of them or at least more than one of them changes.

For instance, if a component wants to change its `max_zoom_level', it'll
also set `has_max_zoom_level' and if a components wants to change its preferred
zoom levels, it'll normally also change `is_continuous'.

But even if not, I think it's much easier for a component to make up its mind
about all the new parameters after an update (for instance loading a new image)
and then calling one notification method than it is for the container to deal
with several notification callbacks when really more than one parameter is
changed.

Also, I think the parameters will only change when the component loads a new
file or something like this and in this case all of them will change anyways.

====[bonobo-zoomable.h]====
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
#ifndef _BONOBO_ZOOMABLE_H_
#define _BONOBO_ZOOMABLE_H_

#include <bonobo/bonobo-object.h>

BEGIN_GNOME_DECLS

#define BONOBO_ZOOMABLE_TYPE		(bonobo_zoomable_get_type ())
#define BONOBO_ZOOMABLE(o)		(GTK_CHECK_CAST ((o), BONOBO_ZOOMABLE_TYPE, BonoboZoomable))
#define BONOBO_ZOOMABLE_CLASS(k)	(GTK_CHECK_CLASS_CAST((k), BONOBO_ZOOMABLE_TYPE, BonoboZoomableClass))
#define BONOBO_IS_ZOOMABLE(o)		(GTK_CHECK_TYPE ((o), BONOBO_ZOOMABLE_TYPE))
#define BONOBO_IS_ZOOMABLE_CLASS(k)	(GTK_CHECK_CLASS_TYPE ((k), BONOBO_ZOOMABLE_TYPE))

typedef struct _BonoboZoomable		BonoboZoomable;
typedef struct _BonoboZoomablePrivate	BonoboZoomablePrivate;
typedef struct _BonoboZoomableClass	BonoboZoomableClass;

struct _BonoboZoomable {
        BonoboObject		object;

	BonoboZoomablePrivate	*priv;
};

struct _BonoboZoomableClass {
	BonoboObjectClass	parent;

	void (*set_zoom_level)	(BonoboZoomable *zoomable,
				 float zoom_level);

	void (*zoom_in)		(BonoboZoomable *zoomable);
	void (*zoom_out)	(BonoboZoomable *zoomable);
	void (*zoom_to_fit)	(BonoboZoomable *zoomable);
	void (*zoom_to_default)	(BonoboZoomable *zoomable);
};

POA_Bonobo_Zoomable__epv *bonobo_zoomable_get_epv  (void);

GtkType			 bonobo_zoomable_get_type (void);
Bonobo_Zoomable		 bonobo_zoomable_corba_object_create	(BonoboObject   *object);

BonoboZoomable		*bonobo_zoomable_new			(float		 min_zoom_level,
								 float		 max_zoom_level,
								 gboolean	 has_min_zoom_level,
								 gboolean	 has_max_zoom_level,
								 gboolean	 is_continuous,
								 float		*preferred_zoom_levels,
								 int		 num_preferred_zoom_levels);

BonoboZoomable		*bonobo_zoomable_construct		(BonoboZoomable	*zoomable,
								 Bonobo_Zoomable corba_zoomable,
								 float		 min_zoom_level,
								 float		 max_zoom_level,
								 gboolean	 has_min_zoom_level,
								 gboolean	 has_max_zoom_level,
								 gboolean	 is_continuous,
								 float		*preferred_zoom_levels,
								 int		 num_preferred_zoom_levels);

void		 bonobo_zoomable_set_parameters			(BonoboZoomable	*zoomable,
								 float		 min_zoom_level,
								 float		 max_zoom_level,
								 gboolean	 has_min_zoom_level,
								 gboolean	 has_max_zoom_level,
								 gboolean	 is_continuous,
								 float		*preferred_zoom_levels,
								 int		 num_preferred_zoom_levels);

void		 bonobo_zoomable_report_zoom_level_changed	(BonoboZoomable	*zoomable,
								 float		 new_zoom_level);

void		 bonobo_zoomable_report_zoom_parameters_changed	(BonoboZoomable	*zoomable);


END_GNOME_DECLS

#endif /* _BONOBO_ZOOMABLE_H_ */
=====

====[bonobo-zoomable-frame.h]====
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
#ifndef _BONOBO_ZOOMABLE_FRAME_H_
#define _BONOBO_ZOOMABLE_FRAME_H_

#include <bonobo/bonobo-object.h>

BEGIN_GNOME_DECLS

#define BONOBO_ZOOMABLE_FRAME_TYPE		(bonobo_zoomable_frame_get_type ())
#define BONOBO_ZOOMABLE_FRAME(o)		(GTK_CHECK_CAST ((o), BONOBO_ZOOMABLE_FRAME_TYPE, BonoboZoomableFrame))
#define BONOBO_ZOOMABLE_FRAME_CLASS(k)		(GTK_CHECK_CLASS_CAST((k), BONOBO_ZOOMABLE_FRAME_TYPE, BonoboZoomableFrameClass))
#define BONOBO_IS_ZOOMABLE_FRAME(o)		(GTK_CHECK_TYPE ((o), BONOBO_ZOOMABLE_FRAME_TYPE))
#define BONOBO_IS_ZOOMABLE_FRAME_CLASS(k)	(GTK_CHECK_CLASS_TYPE ((k), BONOBO_ZOOMABLE_FRAME_TYPE))

typedef struct _BonoboZoomableFrame		BonoboZoomableFrame;
typedef struct _BonoboZoomableFramePrivate	BonoboZoomableFramePrivate;
typedef struct _BonoboZoomableFrameClass	BonoboZoomableFrameClass;

struct _BonoboZoomableFrame {
        BonoboObject			object;

	BonoboZoomableFramePrivate	*priv;
};

struct _BonoboZoomableFrameClass {
	BonoboObjectClass		parent;

	void (*zoom_level_changed)	(BonoboZoomableFrame *zframe,
					 float zoom_level);
	void (*zoom_parameters_changed)	(BonoboZoomableFrame *zframe);
};

POA_Bonobo_ZoomableFrame__epv *bonobo_zoomable_frame_get_epv  (void);

GtkType			 bonobo_zoomable_frame_get_type			(void);
Bonobo_ZoomableFrame	 bonobo_zoomable_frame_corba_object_create	(BonoboObject		*object);

BonoboZoomableFrame	*bonobo_zoomable_frame_new			(void);

BonoboZoomableFrame	*bonobo_zoomable_frame_construct		(BonoboZoomableFrame	*zframe,
									 Bonobo_ZoomableFrame	 corba_zframe);

float		 bonobo_zoomable_frame_get_zoom_level			(BonoboZoomableFrame	*zframe);

float		 bonobo_zoomable_frame_get_min_zoom_level		(BonoboZoomableFrame	*zframe);
float		 bonobo_zoomable_frame_get_max_zoom_level		(BonoboZoomableFrame	*zframe);
gboolean	 bonobo_zoomable_frame_has_min_zoom_level		(BonoboZoomableFrame	*zframe);
gboolean	 bonobo_zoomable_frame_has_max_zoom_level		(BonoboZoomableFrame	*zframe);
gboolean	 bonobo_zoomable_frame_is_continuous			(BonoboZoomableFrame	*zframe);

float		*bonobo_zoomable_frame_get_preferred_zoom_levels	(BonoboZoomableFrame	*zframe,
									 int			*pnum_ret);

void		 bonobo_zoomable_frame_set_zoom_level			(BonoboZoomableFrame	*zframe,
									 float			 zoom_level);

void		 bonobo_zoomable_frame_zoom_in				(BonoboZoomableFrame	*zframe);
void		 bonobo_zoomable_frame_zoom_out				(BonoboZoomableFrame	*zframe);
void		 bonobo_zoomable_frame_zoom_to_fit			(BonoboZoomableFrame	*zframe);
void		 bonobo_zoomable_frame_zoom_to_default			(BonoboZoomableFrame	*zframe);

/* Connecting to the remote object */
void		 bonobo_zoomable_frame_bind_to_zoomable			(BonoboZoomableFrame	*zframe,
									 Bonobo_Zoomable	 zoomable);

Bonobo_Zoomable	 bonobo_zoomable_frame_get_zoomable			(BonoboZoomableFrame	*zframe);


END_GNOME_DECLS

#endif /* _BONOBO_ZOOMABLE_FRAME_H_ */
=====

-- 
Martin Baulig
martin gnome org (private)
baulig suse de (work)




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]