Basic Handle configuration in CupDraw

Handles are the small white and black objects that you see when you select a Figure (see next figure). They allow you to manipulate the figure by moving them around. In this tutorial, we will show you how to configure a Handle to alter the size of a Figure. We will as a base the diagram editor we were building in the previous part of the tutorial.

Handle configuration

Configuring a Handle is quite simple, basically in the initialization method of your Figure, you have to add the Handle to the handles collection it’s inherited from the Figure class. Let’s modify our SimpleRectangleFigure figure:

In this case we have added 4 handles that will look to the topLeft, topRight, bottomLeft and bottomRight properties of the Figure. If we reload the editor you can see that the Figure has the 4 handles and that if you move them around the SimpleRectangleFigure resizes itself.

Understanding how handles work

When we instantiate a Handle we pass the Figure which the Handle has to observe and a selector as a String. The Handle registers itself as an observer of the Figure so that when:

– The Figure the Handle observes is moved
It moves to a new position that is computed by sending the message to the Figure. In our first case Figure>>topLeft will be evaluated and a Point will be return. That point is used to set the new Frame of the Handle.

– The Handle is moved
The Handle sends Figure>>topLeft: aPoint to the observing Figure so that the Figure updates its Frame. One thing we have to recall is how we implement the – (void) drawRect:(CGRect) rect on: (id) context of our SimpleRectangleFigure:

Because we used the bounds of the SimpleRectangleFigure to draw, we are safe that the Handle will work when we move it around.

You can try it yourself here.
Also, the sources of the project are available here.

In the next episode we will show you how to create a more advance Handle to change the color of the Figure based on the distance to its center!

Creating a Figure in CupDraw

In this series of tutorials we will show how to create diagram editors using CupDraw. In this first tutorial we will code a Rectangle figure and a Tool to create it.

Creating a BASIC Figure in Cupdraw consists in 2 basic steps:

  1. Define the visual aspects of the figure.
  2. Define the tool that creates the figure.

Before we start, copy the empty project to start a new one.

Define the visual aspects of the figure

To create a figure simply subclass the Figure class and implement the method (void) drawRect: (CGRect) rect on: (id) context

In our case we are going to create a SimpleRectangleFigure, so we will need to draw the background of the rectangle and the border. This can be done simply as follows:

All figures come with 2 predefined instance variables for the foreground and background colors that can be configured to paint it. We will define them as black and white in the initialization method as follows:

Great! so we have our figure coded, now let’s define the tool that creates the figure.

Define the tool that creates the figure

A Tool is responsible for interpreting events/gestures and instantiating the Figure. CupDraw comes with some abstract classes that can help you create some basic tools quickly. In our example we will extend AbstractCreateFigureTool and implement a simple method for creating the rectangle with a default width and height when the user clicks in the Drawing. We implement the – (void) createFigureAt: (id) aPoint on: (id) aDrawing method as follows:

The first line creates a default frame for the given point and then we instantiate our SimpleRectangleFigure. Then we add the rectangle to the given Drawing and we active the Selection tool so that the next click is handle by the Selection tool. If you want to stick to this tool so that multiple clicks create multiple rectangles, you can remove the last line.

The last thing is to add the Tool to the toolbox in the AppController, we can do that by simply:

That’s it, you can find the source code of the project here.
Check the working diagram here.
Stay tuned, in the next part we will add handles to the rectangle so that we can manipulate it.

CupDraw 0.1 released

I’m pleased to announced the release of CupDraw 0.1.


CupDraw is a Objective-J framework for creating graphical editors that is based on the concepts of the famous Smalltalk Hotdraw. So far, this version contains the main concepts of that Hotdraw with a few utility classes that can help you build a basic editor.

We were users of Hotdraw for desktop applications and we want to provide a port for Objective-J (as it is quite similar to Smalltalk). We are using this version to migrate most of the features of an Eclipse based editor for the WebSpec requirement language (you can see some videos of the eclipse version here). We plan to open this editor soon so that you can also be aware of the things you can do with CupDraw.

Features of this release:

  • Drawing
  • Basic Figures with Models and connections
  • Selection Tool with marquee selection
  • Common Tool classes for 1 click figure creation and figure connections
  • Magnets and handles
  • Grid, Snap to grid
  • Alignment commands
  • Grouping commands
  • Lock commands
  • Z-Index commands

More info

Why I give up using SmartGWT

I guess that most of you agree with me that UI is one of the most painful aspects of building Web applications (at least if you compare it with backend development). Well if you are building a Web application using GWT you may be tempted to use SmartGWT as it provides really cool widgets. Well, that’s true, their widgets are really cool and the themes are great. However, I would like to explain my experience using SmartGWT for a personal project (a first version of the app is shown below).

First version using SmartGWT

My application is pretty basic, just a couple of forms, windows, tabs and toolbars; nothing more crazy than that. The main intent of the application is to allow people to take personal notes. The development went pretty well the first 2 weeks while I was working with the basic stuff; then I realize that I need to use a simple autocomplete field and though SmartGWT doesn’t provide an Autocomplete field OOTB I tried to use a custom solution using the ComboBoxItem; a really bad idea…

First, ComboBoxItem doesn’t work as a field in Calendars so big problem; lucky I found a workaround to fix the issue. Then I tried to make the ComboBoxItem’s datasource work with a remote GWT call though SmartGWT doesn’t provide a OOTB datasource that works with the GWT paradigm. Again, a big mess digging into the javascript code where SmartGWT is implemented

Ok, so let’s try to fix the autocomplete problem using the SuggestBox that GWT provides OOTB. Well, another bad idea as SmartGWT randomly works with GWT and they clearly mentioned in their docs that it is not recommended to mix both.

Finally let’s try to extend the framework to make it work in either case. Well, here is the main issue I found with SmartGwt: the GWT UI classes that they provide delegate most of their behavior to plain javascript that is inside the JAR file. Oh my God, how do you expect developers to extend your framework?

The answer may be: either open the jar and do it yourself or move to Smart GWT Pro (license based). Open the jar or extending at the javascript level lowers the level of abstraction and that’s something I don’t want and the main reason I’m using GWT and not jQuery.

I’m my case it is ridiculous paying for a license and I must say that I’m used to the business model that other open source products have (e.g. Mule, Spring, Hibernate) that you pay for support though you are able to extend the framework easily.

A small suggestion from a disappointed engineer: you have one of the best GWT UI libraries in the market that look perfect and your widgets are really cool, don’t screw it up with this mix which is NOT easy to extend.

At the end, I tried for a couple of days to implement a workaround, the solution was not stable enough to be used in a real application. I end up implementing a basic window and toolbar in plain GWT using GWT Drag and Drop and reuse some of the SmartGWT styling. The results are shown below; now I have an extensible solution that I can fix in case of problems 🙂 but with the overhead of having to fix it myself :(.

Custom solution with Gwt drag and drop