Re: RFC: Model-View-Controller

2011-11-20 Thread Kristian Rietveld
On Nov 16, 2011, at 9:22 PM, Benjamin Otte wrote:
 On Wed, Nov 16, 2011 at 9:37 AM, Kristian Rietveld k...@loopnest.org wrote:
 If there are multiple views, which are changed by which controller?  What 
 complicates thinking about this for me is that in MVC as I know it, there is 
 1 Model, 1 View and 1 Controller for each thing.
 
 I  think this is where the misunderstanding is. I probably shouldn't
 have mentioned MVC in the email and named it actions and actors and
 just used the clutter terminology.

That is very likely ;)  I now also understand that all these objects would be 
allowed to do drawing for the widget they are connected to, etc.

Still it is a very good idea to get some prototyping going to get a feel for 
this and to see how much code it would save in the end.  I like the examples 
put forward by Federico: GtkButton/GtkScrollbar and text selection.

 you'd write a GtkTreeViewView object that'd draw a treeview. That's
 indeed kinda very useless.

If one would do *real* MVC, then something like a GtkButtonView does make sense 
and is definitely not useless.  The point is then that you have different 
implementations of GtkButtonView for e.g. normal displays, small displays, 
touch screen/tablet.  You would also have different implementations of a 
GtkButtonController according to the input method used (mouse vs. touchscreen 
is a good example).


regards,

-kris.
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: RFC: Model-View-Controller

2011-11-17 Thread Federico Mena Quintero
On Fri, 2011-11-11 at 15:55 +0100, Benjamin Otte wrote:
[Talking about GtkButton]
 And it'd have those Controllers:
 (- Hover)
 - Click
 - Activate
 (- Focus)
 - KeyPress/Release

I just took a quick look at ClutterClickAction and ClutterDragAction.
They are certainly interesting.  I wonder how things would look once you
have widgets with complex behavior.

Let me reintroduce something I talked about during the Desktop Summit -
form languages and pattern languages.  The way I see things, you want to
encapsulate common actions as controllers, and common drawing idioms as
views, so we can compose them into final widgets.  I.e. you want to make
the form language finer-grained and richer, so it will allow us to
implement patterns more easily.

Think of an app that lets you select graphical objects and move them by
dragging.  How would you implement something that needs both clicks
(quick press/release with no movement) and drags (long
press-move-release)?  Do you need to somehow tie together a
ClickController and a DragController, or do you have a generic
PressMoveReleaseController, on top of which you implement the other two?

As you said, for GTK+ it probably makes sense to start by abstracting
out simple views and controllers.  Exercise: do that in a branch for
buttons and clicks, and refactor GtkButton and GtkScrollbar's arrow
buttons to use that.  See how the code looks.  Then you may want to
tackle GtkEntry's clickable icons in terms of the click controller as
well.

A much harder view/controller would be for selectable text.  GtkEntry
picks out the first PangoLayoutLine from the PangoLayout, and runs
pango_layout_line_x_to_index() on it.  However, GtkLabel does a direct
pango_layout_xy_to_index().  No idea why GtkEntry does it like that;
maybe it wants to explicitly ignore everything but the first line in
the text.  GtkEntry has scrolling offsets, but GtkLabel doesn't... etc.
No idea how a SelectableTextController would look :)

  Federico

___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: RFC: Model-View-Controller

2011-11-17 Thread Emmanuele Bassi
hi Federico;

On 17 November 2011 18:50, Federico Mena Quintero feder...@gnome.org wrote:
 On Fri, 2011-11-11 at 15:55 +0100, Benjamin Otte wrote:
 [Talking about GtkButton]
 And it'd have those Controllers:
 (- Hover)
 - Click
 - Activate
 (- Focus)
 - KeyPress/Release
 Think of an app that lets you select graphical objects and move them by
 dragging.  How would you implement something that needs both clicks
 (quick press/release with no movement) and drags (long
 press-move-release)?  Do you need to somehow tie together a
 ClickController and a DragController, or do you have a generic
 PressMoveReleaseController, on top of which you implement the other two?

no, there's no base class, and there's no need for one.

ClickAction and DragAction (and basically all event-related code in
Clutter) do not use grabs: they use the capture phase of the event
delivery cycle, and they will not stop the event propagation, so you
can assign them both. the capture phase is far less destructive of
event handling in complex scenarios than a X11 grab; gtk+ should get a
::captured-event signal as well in the near future.

DragAction also uses the drag-threshold setting, so it will be able to
detect a drag after a certain amount of space has been covered by the
pointer with the BUTTON1 mask set.

Lucas used ClickAction and DragAction inside his Board project, to be
able to interact with the items on the board, as well as repositioning
them around.

aside from ClickAction and DragAction, Clutter also has a
GestureAction that allows you to implement gesture recognisers, and
cancel gestures in progress to pass the control flow to the next
action; these gestures will be used more as soon as the multi-touch
support in X11 lands, so we can have a common implementation across
OSX, X11, and Wayland.

ciao,
 Emmanuele.

-- 
W: http://www.emmanuelebassi.name
B: http://blogs.gnome.org/ebassi/
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: RFC: Model-View-Controller

2011-11-16 Thread Kristian Rietveld
Hi,

I share the concerns Mitch has raised.  It is obvious that a redesign would 
help the organization of widget code and several people have thought about ways 
this can be done (e.g. Rapicorn and I also vaguely recall somebody trying to do 
pure MVC with GTK+).  Some more comments and thoughts below.


On Nov 9, 2011, at 7:12 PM, Benjamin Otte wrote:
 - widget complexity
 Our widgets - even the simple ones - are hellishly complex objects.
 Without reorganization of the code they'll get unwieldable. Here's the
 5-digit source files in the gtk sources:
 10464 gtkfilechooserdefault.c
 10482 gtkentry.c
 (10947 gdkwindow.c)
 13857 gtkwidget.c
 16439 gtktreeview.c

Of the widgets you list I don't think GtkFileChooserDefault belongs there, 
because it is a composite widget where the others are not.

 We need a way to make that code readable again. Also, those files
 generally have lots of interactions and a high cyclomatic
 complexity[1], which makes it hard to understand what they do. This in
 turn leads to people being afraid of touching them. And that starts a
 vicious cycle.

About the interactions, does the MVC approach proposed really solve this and 
doesn't it lead to people being afraid to touch the class hierarchies and 
interactions between the different views and controllers?  In the simple 
examples in your other e-mail, there are already quite some connections between 
objects involved.

 I'm proposing a Model-View-Controller split for widgets.[2]
 
 I want to split the source code for widgets into three parts. This is
 mostly an internal cleanup and should not affect applications that use
 widgets. It would however change the way widgets are coded. So this is
 mostly relevant for our own gtk/ directory, but would also be
 interesting for other widgets ike the evo calendar, EMap, the
 WebKitWebView, GtkSourceView, you name it.

So if I understand correctly, you want to re-do the implementation of widgets 
without changing the outside interface?  But you also want to expose the MVC 
objects to the outside to be used in third-party widget implementations.  I am 
wondering whether this won't get very confusing/messy.


The reasons why objects are currently so large are:

  1) View and Controller are combined in the same class, as has already been 
pointed out.
  2) Objects are often too specific to allow re-use; granularity is wrong.

If I would apply pure MVC to GtkTreeView, then we will still end up with a huge 
view and a huge controller class.  We already have the model class.  To achieve 
the desired simplification GtkTreeView will have to be split up into pieces, 
pieces which can be better re-used.  I see this transformation as a separate 
one from the transition to MVC.

So what you are actually proposing is both introducing MVC and splitting up the 
objects (albeit in an API compatible fashion).  I would argue that with just 
introducing the splitting and not doing MVC, we can already gain the majority 
of the code clean up.  I explicitly say majority, not all, because your 
approach, if feasible, would further increase code re-use. You might indeed 
want to split out rubberbanding into a separate class to not have to 
re-implement it in both an item container and somewhere else.  Whether we 
should then call this a rubberbanding Controller is something I am unsure 
about.

For GtkTreeView a start was made by pushing code into GtkCellArea, but much 
more is necessary.  In an earlier thread, I have once sketched plans to have a 
generic item container which would implement click handling, rubberbanding, 
drag and drop, keyboard handling, etc, etc.  Subclasses can then plug in 
specific layouting algorithms which make them a GtkTreeView or GtkIconView.

The other point to make here is that the above sketch for GtkTreeView is one 
possible way to do it.  The main problem with point 2) is picking the right 
granularity, there are multiple thoughts about this (e.g. the micro widget 
approach from Rapicorn) and making this decision can turn out to not be that 
easy.

 Sounds like a plan?

My feeling is that in order to come up with a solid plan, prototyping has to be 
done to figure out whether this is feasible and how things will look like.

regards,

-kris.
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: RFC: Model-View-Controller

2011-11-16 Thread Benjamin Otte
On Wed, Nov 16, 2011 at 9:37 AM, Kristian Rietveld k...@loopnest.org wrote:
 If there are multiple views, which are changed by which controller?  What 
 complicates thinking about this for me is that in MVC as I know it, there is 
 1 Model, 1 View and 1 Controller for each thing.

I  think this is where the misunderstanding is. I probably shouldn't
have mentioned MVC in the email and named it actions and actors and
just used the clutter terminology.
The whole idea has nothing to do with classical MVC.

It's all about splitting common interactions into separate objects -
like click, drag or rubberband - that you can then the
controller would probably emit events that you can hook into if you
want or let it do its default thing (draw a blue selection rectangle)
if you don't want to. Of course, you want to connect to the finished
signal for events to update the widget.

The same thing for the view thing, it's more about making drawing
operations stateful and giving them objects. So instead of
gtk_render_background(), you'd instantiate a GtkBackground object and
it'd do whatever needs doing to get it onto the screen. It's not like
you'd write a GtkTreeViewView object that'd draw a treeview. That's
indeed kinda very useless.

Benjamin
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: RFC: Model-View-Controller

2011-11-11 Thread Michael Natterer
Hi Benjamin,

I am sorry but this sounds like a lot of things, but not like
a plan.

- are our widgets a more-or-less huge mess? yes.
- do we need to do something about it? yes
- is MVC a well tested way to improve things? yes
- does it always work? NO

Sorry, but you are actually stating the obvious here, but fail
to provide *any* example, outline, not even a simple diagram.

Without any small example-ish thing to see what you mean
here, this is pretty much hot air :( But I surely don't
want to sound discouraging, please give a small example.

Regards,
--Mitch

On Wed, 2011-11-09 at 19:12 +0100, Benjamin Otte wrote:
 Hey,
 
 so I've been thinking about this for a bit, and I think it's a good
 idea, but I wanted to see if other people have an opinion about it.
 And I wanted to get it into people's minds before we sit down for a
 hackfest.
 
 So this idea is a result of the mainly the following things:
 - Clutter integration
 Clutter has the concepts in some form or another. It doesn't use the
 definitions I'm about to use, but it has the objects I want.
 - widget complexity
 Our widgets - even the simple ones - are hellishly complex objects.
 Without reorganization of the code they'll get unwieldable. Here's the
 5-digit source files in the gtk sources:
 10464 gtkfilechooserdefault.c
 10482 gtkentry.c
 (10947 gdkwindow.c)
 13857 gtkwidget.c
 16439 gtktreeview.c
 We need a way to make that code readable again. Also, those files
 generally have lots of interactions and a high cyclomatic
 complexity[1], which makes it hard to understand what they do. This in
 turn leads to people being afraid of touching them. And that starts a
 vicious cycle.
 - functionality duplication
 A lot of widgets duplicate functionality. Treeview and iconview have
 rubberbanding. Entries have progress bars and icons. Notebooks,
 treeviews, expanders and whatnot have buttons. We do not only
 duplicate the code here, but also behavior and policies. So if we
 decide to change the states on buttons or the way rubberbanding does
 autoscroll, we need to fix all of the widgets individually. And as we
 are currently in a process of reinventing large parts of the toolkit -
 both for UI design and for form factor reasons, we need to be able to
 change these things quickly. And currently we can't even get rid of
 underallocations.
 
 So what am I actually talking about?
 
 I'm proposing a Model-View-Controller split for widgets.[2]
 
 I want to split the source code for widgets into three parts. This is
 mostly an internal cleanup and should not affect applications that use
 widgets. It would however change the way widgets are coded. So this is
 mostly relevant for our own gtk/ directory, but would also be
 interesting for other widgets ike the evo calendar, EMap, the
 WebKitWebView, GtkSourceView, you name it.
 
 The first thing I want to do is to create View objects. So instead
 of having a huge draw() function, the widget would create a bunch of
 View objects. We would provide a few common ones (probably one per
 gtk_render_foo() function we currently have) and widgets would put
 them where they belong in the size_allocate() function. After that,
 they would take care of drawing themselves and all the stuff
 associated with looking cool based on CSS and their surroundings. In
 Clutter terms this is what ClutterActor is. Of course, they would
 probably provide other information, too, like sizing or the actual
 layout of text.
 And once we have that, we can attach additional information to these
 objects, like animation state, effects, caches and so on without the
 widgets having to care.
 
 The second thing I want to is create Controller objects. So instead
 of having input events handled on the widget, we add a bunch of
 controllers to the widget that take care of handling events and
 emitting signals for when the user did interact with the widget. These
 would go from very simple things like click, doubleclick or scroll
 controllers to more complex things like rubberband or dnd controllers.
 The Clutter equivalent here is ClutterAction. Of course, the actions
 will probably require a bunch of properties and will also emit quite
 some signals that widgets will use, but they can do things like
 keeping track of the device they're interacting with and things like
 that.
 And once we have that, we can attach lots of new controllers, like
 gesture controllers, or even switch controllers based on input method
 used. And of course, we have less place where we can control things
 like dnd threshold, double-click time, rubberband and dnd scrolling
 speed and gesture definitions.
 
 That leaves the widget itself as the Model (I think the correct term
 would be Application in the MVC context here, but bear with me, this
 makes it sound cooler). So the widget's job moves further away from
 GDK (or Cairo, Clutter or whatever the backend is) and more into the
 realm of being the manager between the application and the person in
 front of the screen. It 

Re: RFC: Model-View-Controller

2011-11-11 Thread Benjamin Otte
On Fri, Nov 11, 2011 at 2:47 PM, Michael Natterer mi...@gimp.org wrote:
 Hi Benjamin,

 [snip typical German ecouragement talk]

 please give a small example.

(disclaimer: just to illustrate the idea, might change a lot)

So, a GtkButton is kinda complex from the input perspective, but
simple for drawing. It would have these Views:
- Background
- Child
It would inherit those from GtkBin, so it wouldn't have any drawing code at all.
And it'd have those Controllers:
(- Hover)
- Click
- Activate
(- Focus)
- KeyPress/Release
Not sure if hover and focus should be default or separate controllers.
What they'd do is toggle the :focus and :hover state on the widget and
nothing else. The click controller would capture mouse presses, take a
grab, and on release it'd make the button emit clicked. Same as the
KeyPress/Release controller (which would only capture space, return
and whatever else activates a button). And the Activate controller
would respond to gtk_widget_activate().

A GtkLabel would have these Views:
- Background (or not - it'd have it in GTK4, maybe not in GTK3, where
labels have no background)
- Text
and it'd have probably these Controllers:
- Rubberband
- Click
- DoubleClick
- Drag
- KeyPress/Release
I wanted to call Rubberband Drag, but that'd confuse people with
DND. What I mean is pressing the mouse, holding it and releasing it
elsewhere. Consider the name a work in process.
All of them would only be active if the label was selectable.
Rubberband would be used to do a selection, drag would allow DND'ing
the selected text. The KeyPress/Release controller(s) would be used
for the general selection handling in text, as would the Click and
DoubleClick ones. (I suppose we would have one that'd be shared
between all the text-handling widgets that ensured all our keybindings
were identical and the selection behavior consistent - try
double-clicking between words in different widgets for some fun.)

Now for some fun widget, the notebook. We'd have these views:
- Background
- Child (for the active widget)
- per action and arrow button:
  - Background
  - Icon
per tab:
  - Background
  - Child

And these actions:
- Drop (for tabs maybe?)
- per action and arrow button:
  - Click
  - Focus
  - Hover
  - KeyPress/Release
- per tab:
  - Click
  - Focus
  - Hover
  - KeyPress/Release
  - Drag (to drag tabs elsewhere)
  - Drop (for tabs)
  - Activate (for keybindings)
  - per close button on the tab:
- Click
- Focus
- Hover
- KeyPress/Release
You would probably be able to limit actions to certain areas/views of
the widget, so the hover/focus actions would be setup to only apply to
the ones they are about. It'd at least solve all our bugs with focus,
hover and whatnot not working properly on notebooks that get filed and
fixed regularly. Or we would make the notebook have real buttons, at
which point the actions would be setup by the button. Then we'd just
have to solve attaching the DND actions to the button.
But with such an approach, the notebook code would look less scary
(apart from the setup code...). We'd just move some views around in
size_allocate and connect some signals and that'd be that.

I'm not even going to try to imagine the setup for the treeview here...

That said, you can see that the number of different views and
controllers is quite small. It's just that we duplicate their
functionality over and over and over again. And you can maybe start to
imagine what would happen when people started adding gestures etc to
the notebook code...

Benjamin
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: RFC: Model-View-Controller

2011-11-10 Thread Andrew Cowie
On Wed, 2011-11-09 at 19:12 +0100, Benjamin Otte wrote:
 The first thing I want to do is to create View objects. ... In
 Clutter terms this is what ClutterActor is.
...
 The second thing I want to is create Controller objects. ...
 The Clutter equivalent here is ClutterAction. 

How about just using Clutter's Actor / Action terminology in GTK?

Might make things a bit simpler. The three terms in MVC brings a bit of
its own conceptual baggage and meanwhile we already have TextView and
TreeModel going on; the overload on view and model might get
annoying.

{shrug}

AfC
Vancouver


___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


RFC: Model-View-Controller

2011-11-09 Thread Benjamin Otte
Hey,

so I've been thinking about this for a bit, and I think it's a good
idea, but I wanted to see if other people have an opinion about it.
And I wanted to get it into people's minds before we sit down for a
hackfest.

So this idea is a result of the mainly the following things:
- Clutter integration
Clutter has the concepts in some form or another. It doesn't use the
definitions I'm about to use, but it has the objects I want.
- widget complexity
Our widgets - even the simple ones - are hellishly complex objects.
Without reorganization of the code they'll get unwieldable. Here's the
5-digit source files in the gtk sources:
10464 gtkfilechooserdefault.c
10482 gtkentry.c
(10947 gdkwindow.c)
13857 gtkwidget.c
16439 gtktreeview.c
We need a way to make that code readable again. Also, those files
generally have lots of interactions and a high cyclomatic
complexity[1], which makes it hard to understand what they do. This in
turn leads to people being afraid of touching them. And that starts a
vicious cycle.
- functionality duplication
A lot of widgets duplicate functionality. Treeview and iconview have
rubberbanding. Entries have progress bars and icons. Notebooks,
treeviews, expanders and whatnot have buttons. We do not only
duplicate the code here, but also behavior and policies. So if we
decide to change the states on buttons or the way rubberbanding does
autoscroll, we need to fix all of the widgets individually. And as we
are currently in a process of reinventing large parts of the toolkit -
both for UI design and for form factor reasons, we need to be able to
change these things quickly. And currently we can't even get rid of
underallocations.

So what am I actually talking about?

I'm proposing a Model-View-Controller split for widgets.[2]

I want to split the source code for widgets into three parts. This is
mostly an internal cleanup and should not affect applications that use
widgets. It would however change the way widgets are coded. So this is
mostly relevant for our own gtk/ directory, but would also be
interesting for other widgets ike the evo calendar, EMap, the
WebKitWebView, GtkSourceView, you name it.

The first thing I want to do is to create View objects. So instead
of having a huge draw() function, the widget would create a bunch of
View objects. We would provide a few common ones (probably one per
gtk_render_foo() function we currently have) and widgets would put
them where they belong in the size_allocate() function. After that,
they would take care of drawing themselves and all the stuff
associated with looking cool based on CSS and their surroundings. In
Clutter terms this is what ClutterActor is. Of course, they would
probably provide other information, too, like sizing or the actual
layout of text.
And once we have that, we can attach additional information to these
objects, like animation state, effects, caches and so on without the
widgets having to care.

The second thing I want to is create Controller objects. So instead
of having input events handled on the widget, we add a bunch of
controllers to the widget that take care of handling events and
emitting signals for when the user did interact with the widget. These
would go from very simple things like click, doubleclick or scroll
controllers to more complex things like rubberband or dnd controllers.
The Clutter equivalent here is ClutterAction. Of course, the actions
will probably require a bunch of properties and will also emit quite
some signals that widgets will use, but they can do things like
keeping track of the device they're interacting with and things like
that.
And once we have that, we can attach lots of new controllers, like
gesture controllers, or even switch controllers based on input method
used. And of course, we have less place where we can control things
like dnd threshold, double-click time, rubberband and dnd scrolling
speed and gesture definitions.

That leaves the widget itself as the Model (I think the correct term
would be Application in the MVC context here, but bear with me, this
makes it sound cooler). So the widget's job moves further away from
GDK (or Cairo, Clutter or whatever the backend is) and more into the
realm of being the manager between the application and the person in
front of the screen. It has an often simple model (for GtkEntry or
GtkLabel this is a string), some additional information about the
model (word-wrap, editability, etc) and manages how people in front of
the screen, developers and possibly IPC interact with it.

Sounds like a plan?

Benjamin


1: http://en.wikipedia.org/wiki/Cyclomatic_complexity
2: http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: RFC: Model-View-Controller

2011-11-09 Thread Michael Hasselmann
On Wed, 2011-11-09 at 19:12 +0100, Benjamin Otte wrote:
 Hey,
 
 so I've been thinking about this for a bit, and I think it's a good
 idea, but I wanted to see if other people have an opinion about it.
 And I wanted to get it into people's minds before we sit down for a
 hackfest.

Please don't take Model-View-Controller paradigm too literal. It can
help when designing things; but at the same time it can be overly
complex if implemented. If you don't believe me, take a look at
libmeegotouch [LMT]. It's MVC in its purest form, and everyone hated it
in the end.

regards,
Michael

[LMT] https://meego.gitorious.org/meegotouch/libmeegotouch

___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list