On Sat, 01 Mar 2003 12:46:57 +0100
Michael Natterer <[EMAIL PROTECTED]> wrote:
> Ernst Lippe <[EMAIL PROTECTED]> writes:
> > On 26 Feb 2003 17:29:37 +0100
> > Sven Neumann <[EMAIL PROTECTED]> wrote:
> > > Hi,
> > >
> > > Ernst Lippe <[EMAIL PROTECTED]> writes:
> > >
> > > > The point is the following. In the current implementation the preview
> > > > widget consists of the following components from top to bottom: the image,
> > > > the progress bar and the zoom controls. When scrollbars should be added
> > > > the horizontal scrollbar should be located between the progress bar and
> > > > the image. So it is not possible to add scrollbars by simply wrapping
> > > > the entire current preview but the preview itself must be modified.
> > > > Adding scrollbars makes the layout algorithm more complex.
> > >
> > > IMO the preview widget should only be the preview, nothing else. If
> > > possible it should expose two adjustments so that you can easily add
> > > scrollbars. Progress-bar, zoom-control and scrollbars don't belong to
> > > the preview widget itself. They can be added by a composite widget.
> > That is already in my current design. There is a bare preview widget
> > that can do scaling and scrolling but has no GUI for these operations.
> > There is another composite widget that can include a progress bar and
> > zoom buttons. Having a standard composite widget makes life easier for
> > developers and gives more uniformity among the plug-ins.
> > > > > Actually if you go for two adjustments and
> > > > > expose them in your API you don't need to deal with signals at all
> > > > > since it should be sufficient to connect to the "value_changed" and
> > > > > "changed" signals of the two adjustments.
> > > >
> > > > The reason for a separate signal is that this makes it possible to
> > > > distinguish between between modifications that are initiated by the
> > > > user via the preview GUI and modifications that were initiated
> > > > programmatically via the API. When this distinction is never
> > > > important the requirement could be dropped.
> > >
> > > Why should a widget behave differently if changed by the user or
> > > programmatically via the API? That sounds like a broken concept.
> > Why? This is simply a method to get a hook for trapping operations that
> > the user has performed on the GUI of the widget.
> > A set of previews that you want to synchronize is an example of a
> > constraint based system where you want to solve a set of constraints
> > among multiple objects. The naive implementation of such a system is
> > to let each object synchronize with all others when its value is changed.
> > In general this is not a very good architecture:
> > * It is expensive, you need at least n * (n - 1) synchronizations.
> > * It frequently leads to oscillatory behaviour.
> > As an example where you could get funny behavior, take two previews that
> > show the area around a certain point at different magnifications.
> > Assume that the user scrolls in preview A. Now A will update the
> > position of B. Because B is updated it will attempt to update
> > A's position. In all implementations that I can think of there
> > are choices for the scale factor such that the new position for
> > A is different from the position that was set by the user.
> > So A's position changes again and A will try to update B a
> > second time. Eventually, this will probably stabilize, but
> > when there are 3 previews with different magnifications there
> > are probably cases where the oscillations never stabilize.
> > The standard solution for these problems is to have some
> > central arbitrator that makes global decisions for all objects.
> > When you have a seperate signal for user operations this is
> > a nice hook for such an arbitrator.
> > It is of course possible to implement an arbitrator without these
> > signals but its implementation seems a lot messier. Probably
> > you would need some global arbitration flag and change the way
> > that "value-changed" signals are handled based on the value of
> > this flag. You would also have to be careful about subsequent
> > operations by the user before the arbitration computations
> > are finished.
> You should make yourself familiar with what's actually possible
> when using GObject signals correctly.
> The canonical way to solve the issue you mentioned is to let
> the widget itself perform it's operation in the signal's
> default handler (remember signals are just especially mighty
> virtual functions) and register the signal with G_SIGNAL_RUN_LAST.
> This way user signal connections are performed *before* the
> widget's default implementation and the user callback can choose
> to stop the signal or do whever voodoo it likes.
> All the "hooks" and "central arbitrators" your are telking about are
> already implemented in the GSignal system.
> BTW, the example of synchronizing two preview's scrolling offsets is
> rather an example of higher level logic than something the widgets
> themselves should provide. The "arbitrator" looks very much like a
> common signal handler that has some simple
> /* do stuff */
> stuff to sync the views. That's something implemented in the
> GIMP dozens of times and really nothing we have to worry about.
I believe you are proposing a similar solution as Sven. Please see my
reply to his post, for the reason why I am not really comfortable with
Gimp-developer mailing list