disable default move behaviour

Discuss the use and design of the MicroDesigner custom designer framework, or the creation of custom designers and editors in general.

Moderators: Frank Hileman, Anne Szyjan

disable default move behaviour

Postby bartdeman » Tue Feb 17, 2009 1:44 am

Hi,

I am experimenting with adornments.
I created a custom adorner class and a custom adornement class. I got it to work fine: I can rotate the objects when dragging a specific point in my custom adornment.

Now, I would like to restrict the possibility to move objects only if the user drags a specific child object of my custom adornment.

Right now I get a mouse cursor indicating i can move the object if i hover over it (even if not selected) and i can drag&drop it. How can I disable this behaviour?

Thanks,
Bart
bartdeman
 
Posts: 5
Joined: Mon Nov 05, 2007 8:10 am

Postby Frank Hileman » Tue Feb 17, 2009 1:08 pm

Hello Bart,

In the MicroDesigner template project, created when you create a new MicroDesigner project, there is a class called SectorAdornment. This is a good example of what you are trying to accomplish.

The cursor is set via the MouseOverCursor property in the constructor. The StateActivated property selects your custom State (you must have a custom State):
Code: Select all
      public SectorAdornment()
      {
         InitializeComponent();   // required by the designer

         // set the name of the State activated by a mouse down and drag on this
         // SectorAdornment
         StateActivated = "ChangingAngle";

         // set the Cursor used on a mouse over
         MouseOverCursor = System.Windows.Forms.Cursors.Cross;

         SetBoundsCore(new FRectangle(0, 0, 100, 100), BoundsChanges.All);
      }

Please see ChangingAngleState for a custom state example.

The problem may be that you are doing too much with a single Adornment. In general, for your situation, you want to have an additional adornment, that is, in addition to what is already there, not a change to any selection adornment.

If your adornment can only trigger your custom State, there is no way it can move objects, unless your State does that.

To control which adornments are created, see the CustomAdorner class as an example. It adds an additional adornment for one type of object.

Regards,
User avatar
Frank Hileman
Site Admin
 
Posts: 1291
Joined: Sun Jul 25, 2004 8:16 pm
Location: California

Postby bartdeman » Thu Feb 19, 2009 1:49 am

Hi Frank,

Yes, I looked at that example specifically, and already added a customadorner class as well

it looks like this:

Code: Select all
public class CustomAdorner : Adorner
    {
        public CustomAdorner()
        {
        }

        protected override Adornment CreateSelectionAdornment(Element element)
        {
            // This method is only called when a single Element is selected.
            // Before making the SelectionAdornment, we make a SectorAdornment,
            // if the selected Element is the correct type.

            if (element is BlockOfSeats)
            {
                RotationAdornment a = new RotationAdornment();
                Adornments.Add(a);
                a.ContentElement = element;
                return a;
            }
            else
            {
                return base.CreateSelectionAdornment(element);
            }
        }

    }


Also I created a custom state 'ChangingRotation' to handle my custom work.

But I don't think that is the problem. The thing is that there seem to be 2 kinds of dragging possible.
When i drag on the 'hotspots' in my adornement, i get correctly in my custom created state 'ChangingRotation'.

But when i drag another part of the object, I seem to get into state 'Moving' (that I did not define) (i see this in the Console output).

This is what I get:
Code: Select all
1 State: Moving
1 Input: DragEnter
1 Input: ClientDragOver
1 Input: MouseLeave
1 Input: ClientIdleDragOver
1 Input: ClientDragOver
1 Input: ClientDragOver
1 Input: ClientIdleDragOver
1 Input: ClientDragOver
1 Input: ClientDragOver
1 Input: ClientDragOver
1 Input: ClientDragOver
1 Input: ClientDragOver
1 Input: ClientDragOver
1 Input: ClientDragOver
1 Input: ClientIdleDragOver
1 Input: ClientDragOver
1 Input: ClientDragOver
1 Input: ClientDragOver
1 Input: ClientDragOver
1 Input: ClientDragOver
1 Input: ClientDragOver
1 Input: ClientDragOver
1 Input: ClientDragOver
1 Input: ClientDragOver
1 Input: ClientDragOver
1 Input: ClientDragOver
1 Input: ClientDragOver
1 Input: ClientDragOver
1 Input: ClientDragOver
1 Input: ClientDragOver
1 Input: ClientDragOver
1 Input: ClientDragOver
1 Input: ClientIdleDragOver
1 Input: ClientDragOver
1 Input: ClientDragOver
1 Input: ClientDragOver
1 Input: ClientDragOver
1 Input: ClientDragOver
1 Input: ClientDragOver
1 Input: ClientDragOver
1 Input: ClientDragDrop
1 CreateTransaction: Move
1 PopTransaction: Move
1 SavedTransaction 12: Move
1 State: ObjectsSelected


and when I drag a hotspot, I get correctly:
Code: Select all
1 Input: MouseDownLeft
1 State: ChangingRotation
1 Input: MouseUpLeft
1 State: ObjectsSelected


Do you have an idea what might be happening here?

Thanks,
Bart
bartdeman
 
Posts: 5
Joined: Mon Nov 05, 2007 8:10 am

Postby Frank Hileman » Thu Feb 19, 2009 7:38 am

Hello Bart,

Currently the Adornment has no control over the entry to the MovingState, caused when the user drags the content Element.

The entry to the MovingState is controlled by ObjectSelectedState.MouseMoveLeft. You could disable the transition by creating a derived class that overrides that method, and avoids the base class method call if the wrong object is selected. This is not the best solution.

Could you please provide more information about when this object can be moved, and when it cannot be moved? Can it never be moved?

We have a structure called AllowedOperations, that determines which operations are allowed per Element. If we make the computation of AllowedOperations a virtual method in ObejctSelectedState, you could control which operations are allowed per Element, by providing a class derived from ObjectSelectedState. This is probably the best solution. I can make this change if you wish, and send a new build after some testing.

How does the user move the BlockOfSeats? BlockOfSeats can prevent all movement, at design-time or run-time, by overriding SetBoundsCore and doing nothing, or doing nothing in certain conditions.

Thanks,
User avatar
Frank Hileman
Site Admin
 
Posts: 1291
Joined: Sun Jul 25, 2004 8:16 pm
Location: California

Postby Frank Hileman » Thu Feb 19, 2009 7:55 am

Hello Bart,

After further thought, the best solution is a new Service called Limiter. It would be responsible for computing AllowedOperations on any selected Element.

This is a better way to solve the problem because we need AllowedOperations in other places as well. For example, you can move an Element by dragging a selection adornment. The selection adornment also needs to know if an Element can be resized, etc. All this information should be computed in one place.

We would need to make this change for you.

Regards,
User avatar
Frank Hileman
Site Admin
 
Posts: 1291
Joined: Sun Jul 25, 2004 8:16 pm
Location: California

Postby bartdeman » Thu Feb 19, 2009 11:17 am

Hi Frank,

Actually it is no problem that the object can be moved. Only i need to be able to store this 'move' in the db. I just tried to subclass the MovingState, and i replaced the default movingstate class with mine in the designercreated event.

In CustomMovingState.ClientDragDrop i can then place code to store the new coordinates in my db.

So working this way seems to be ok for me.

The other thing is that the objects may not be resized. I can do this by not showing the default selection adornment with the resize handles, but instead show my custom adornment.

Your idea of working with the AllowedOperations would be good i think: if you could define for an object what the allowedoperations are, and the standard selectionadornment would only allow these, there would be no need to make custom adornments for the standard moving/resizing/rotation operations. (provided the standard selection adornment supports rotation)

And thanks for the good support!

Regards,
Bart
bartdeman
 
Posts: 5
Joined: Mon Nov 05, 2007 8:10 am

Postby Frank Hileman » Thu Feb 19, 2009 9:57 pm

Hello Bart,

Unfortunately I believe simply changing MovingState is only good for changing behavior. For database saves it is not reliable.

There are many ways properties can be modified. The only thing they have in common is the use of the Recorder and the creation of Transactions, to record each permanent property change. For example, properties are modified by undo and redo.

I see two ways to sync reliably with a database:
  • With a timer, periodically save the entire content Picture. Or wait for explicit user save operations. The Serializer is the Service to modify.
  • Override the behavior of each Change object stored in Transactions and SavedTransactions. This will probably require changes to the MicroDesigner SDK. Each database transaction corresponds to a set of Changes applied or reversed by a Transaction (on initial apply) or a SavedTransaction (on undo or redo). I must review this more thoroughly and discuss this with you in detail, if you choose this approach.

With either approach, to keep the UI responsive you may want to use asynchronous database calls.

Regards,
User avatar
Frank Hileman
Site Admin
 
Posts: 1291
Joined: Sun Jul 25, 2004 8:16 pm
Location: California

Can i get hold of a copy

Postby Mikeclx » Mon Mar 30, 2009 7:17 pm

Hi Frank,
can i get hold of a copy of your designer component?
I would like to try it out.

My project is comming along nicely..

Thanks for a great product.

Mike
Mikeclx
 
Posts: 4
Joined: Mon Mar 30, 2009 6:56 pm

Postby Frank Hileman » Tue Mar 31, 2009 11:58 am

Hi Mike,

Thanks for the nice comment. :) I send you the download information.

Regards,
User avatar
Frank Hileman
Site Admin
 
Posts: 1291
Joined: Sun Jul 25, 2004 8:16 pm
Location: California


Return to MicroDesigner and Custom Editors

Who is online

Users browsing this forum: No registered users and 1 guest

cron