ElementFlow Mouse Events (12372)

Jun 12, 2008 at 9:50 PM

How would you suggest we resolve which ModelUIElement3D is returned now in Mouse Events with ElementFlow? 

The SelectedIndex is fine for some applications, but I also want to know what model got Right Clicked and/or DoubleClicked.  I haven't been able to find a clean way to resolve this without changing ElementFlow.  Currently for testing... I've made the _modelContainer public.  This works, but I just don't like modifying the base code to get the functionality.

Any issues with giving us access to the model container...  or more item types... [ Your guess is as good as mine as to what to name them. ;-) ]

Thanks!

Jun 13, 2008 at 2:35 AM


rralston4 wrote:

Currently for testing... I've made the _modelContainer public. 

 

 

 

Ok... now for testing... I added the following property to ElementFlow.cs
public
Visual3DCollection Visual3DCollection
{
        get { return _modelContainer.Children; }
}

This allows me to locate the item clicked on within a client...

 

 

void _elementFlow_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
        ModelUIElement3D model = e.Source as ModelUIElement3D;
        if (model != null)
        {
                MessageBox.Show(_elementFlow.Visual3DCollection.IndexOf(model).ToString());
        }
}

 

 



Coordinator
Jun 13, 2008 at 10:35 AM
Hi Ricky,
       I totally agree that you should not have to change the base code for the mouse events. I will be exposing a bunch of them that would make sense for most applications. I had planned on adding this in the next update. Do vote for it and you will have it ;-). For now you can use your solution. I won't keep you waiting for too long.

Thanks for sharing!
Jun 13, 2008 at 10:57 PM


pavanpodila wrote:
I had planned on adding this in the next update. Do vote for it and you will have it ;
Thanks!

Another thing that would be very nice would be an actual or approx count of humanly visible items. ;-)  This may not make sense in some views, but in others it does.  Some nice hint would allow people to create some lazy loading of items.

Thanks again!
Coordinator
Jun 14, 2008 at 4:57 AM
Sure thing...I plan to add real virtualization soon !
Jun 14, 2008 at 5:22 PM
Very nice... :-)  I look forward to it.

The ability to extend to have some simple mouse gestures would also be really nice.  (ie. for scrolling thru items and item specific tasks)  I don't know much about gestures, but I would think something like start/stop pos, elapsed time, and maybe a cheap hint of if starting over a specific item vs the panel as a whole. 

Anyway... thanks for your hard work.
Jul 1, 2008 at 8:01 AM
Caveat: I am a relative newbie to WPF.

I was puzzling as to why if I add, say, a button, above the image that the button does not get any mouse events. 

And also that I don't seem to be able to get any events telling me that the item was clicked.

This thread would seem to indicate that the later would be facilitated in due course - great.  But what about the former - I can't see anything setting the event.Handled property to true in the source code - makes me think that everything I've read so far on event routing might not be quite true.  Forgive me if this is not an appropriate forum for this issue but you guys obviously know a lot more than I do and you seem helpful!

BTW - The ElementFlow is a really excellent visual control - keep up the good work.


Jul 15, 2008 at 12:03 AM


mahpet wrote:
Caveat: I am a relative newbie to WPF.

I was puzzling as to why if I add, say, a button, above the image that the button does not get any mouse events. 

I'm in the same boat as you Mahpet. I need to add some controls, buttons, or toolbar above the image. I can't for the life of me figure out how to get mouse click events routed to those buttons. The OnContainerLeftButtonDown in ElementFlow.cs gets gets them and then never the buttons.

Any guidance in this would be greatly appreciated.
Coordinator
Jul 15, 2008 at 1:24 PM
Hey mahpet and shares,
      The ElementFlow control so far only does a visual mapping of the DataTemplate to the 3D models without any interaction. That is the reason why your Buttons are not responding. Actually they are not even buttons but just texture-mapped visuals, done using the VisualBrush. In the forthcoming version we should have support for Interactive visuals on 3D models. I know it sucks to not have interactivity with those great looking buttons ;-).

If you guys can elaborate on exactly what kind of interactivity you need, I can rig up some temporary solution. Let me know.
Jul 15, 2008 at 4:45 PM



If you guys can elaborate on exactly what kind of interactivity you need, I can rig up some temporary solution. Let me know.


I add a button inside the TestDataTemplate_Reflection DataTemplate. So each 'element' has a button included with it. Now, if someone presses the button, I need the buttons handler to be called, and as a newb to WPF I just don't know how to do it. I may be making it more difficult than it needs to be, but either way, a little hand holding would be greatly appreciated.

Thanks
Coordinator
Jul 16, 2008 at 1:34 PM
Shares,
         Do you want the button to be interactive on all 3D elements or only the one that is selected ?
Jul 16, 2008 at 3:16 PM


pavanpodila wrote:
Shares,
         Do you want the button to be interactive on all 3D elements or only the one that is selected ?


I don't need 3D elements, but I do need click notifications to get to my app. I will have more than one one button on each element, so I'll need to know which of the three was clicked. And I need some way of getting to the button object so I can change is appearance - it's image.

Hope that's doable, I really appreciate it. Looks like others will too.
Thanks
Jul 17, 2008 at 12:45 AM
Pavan,

Sounds like to me that a quick hack isn't the answer.  I think what folks really need is the next release of the ElementFlow.  If I personally had to vote... I would vote for a new updated release and not any short term work arounds.  I'd rather see you focus on the next release and not potentially get off track. (IMHO)

Take care
Coordinator
Jul 17, 2008 at 10:26 AM
Thanks rralston4,
      I would have to agree with you. Off late I have been busy at work so you can see the lag in my replies and the updates. Plus if you have read my blog you would know that I am also writing a book! That said, I'd love to get working on this soon.
Jul 17, 2008 at 12:08 PM
Thanks for the update.  I guess in the future I'll be adding a 2nd book to my WPF collection. ;-)  I fully understand about being busy and overloaded in my younger years I was a 16+ hour a day guy.  Don't forget about Work/Life Balance man.  I'd hate to hear that you got burned out or worse got ill due to overwork. 

Coordinator
Jul 17, 2008 at 10:13 PM
Thanks Ricky,
          I'll keep your advice in mind. Glad to take it.

Cheers!
Jul 18, 2008 at 4:29 PM


pavanpodila wrote:
Thanks Ricky,
          I'll keep your advice in mind. Glad to take it.

Cheers!


Looks like I'm on my own. Thanks rralston4
Jul 19, 2008 at 3:27 AM
shares... you are only on your own if you can't wait for the next release of ElementFlow.  I'm in the queue waiting also.  I read your requests and Pavan questions.  I believe I had an idea as to where Pavan might have been going with his questioning for a possible hack.  I don't think it would resolve your final request and if it did... as a hack... it would not be the go forward solution.  Just something that's one-off.  Much like some of the solutions that I've provided to folks using ElementFlow.  I spent 22 years in the business before I retired, and I have a pretty good understanding of the evils of one-off solutions.  I can't say that I'm sorry because I think you were getting Pavan off track, but I can definitely say that I feel your pain and hope to see a release soon so that I too can continue on my project.
Aug 29, 2008 at 8:55 PM
Edited Aug 29, 2008 at 10:00 PM
Good afternoon,

   Shares, if you can't wait for the release it should be fairly straightforward to accomplish.  Essentially you'll need to replace the ModelUIElement3D objects with Viewport2DVisual3D objects which support interactive controls mapped to 3D elements.  There will be some other slight modifications required as currently ModelUIElement3D is used all over but a simple Replace should handle that.  Another area of concern is that you can't just simply plugin the GeometryModel3D from Viewport.xaml into the Viewport2DVisual3D object so you'll need to make sure your generated Viewport2DVisual3D contains the transforms etc.  I simply just extracted the values from the GeometryModel3D and put them in my Viewport2DVisual3D for testing and it works.  Anyway, I haven't done all of this yet but I have accomplished the main goal which is to allow interactive content in the ElementFlow models using the above steps.  I just quickly threw a sample together to make sure it would work before I responded here and it looks promising as it does render my button and the button does respond to it's events as expected.  Just a thought in case you couldn't wait for the official release. 

PS: Ok, after some further work I've got this completed for the most part.  The only thing that is broken is the OnContainerLeftButtonDown because now the Source is whatever UIElement was clicked on rather than the Viewport2DVisual3D so there is some work that needs to be done there.  One area I left out was the BuildPropertyPath function that will need to be modified since we can now exclude the ModelUIElement3D.Model step since the transforms are now part of the root object (Viewport2DVisual3D).  And now voila! you have interactive content on your 3D element flow panels.  I wanted to post a screenshot on here to prove it works but this forum doesn't allow that I don't believe.

Good luck!


Coordinator
Aug 30, 2008 at 8:16 PM
Sounds exciting eVolve. Do you have a blog where you can demo this ?
Sep 1, 2008 at 10:37 PM
Edited Sep 1, 2008 at 10:47 PM
unfortunately I do not but I'll clean up the code and throw together a sample and send it over to you so you can look at it and maybe get some ideas from it to incorporate into fluidkit.  I just threw it together to see if I could do it in order to help Shares so it could use some tune-up as ElementFlow does take a slight performance hit while using it.  I'll package it up tomorrow (Tues. 9/2) and send it over.  Ultimately I wanted to have support for this as well as interactive content on the back of the panel but I haven't figured out a quick way to accomplish this yet.  Using the ModelUIElement3D approach I was able to have content on the front and back so when selected the panel would flip around so you could see the back however it was just a rendered visual so no interaction.  In order to have interactive content I switched to use Viewport2DVisual3D but in doing so lost the ability to have content on the back since it doesn't have a BackMaterial.  And that is where it stands for now but hopefully this could be a starting point.
Coordinator
Sep 2, 2008 at 2:18 AM
Sounds good eVolve
Sep 9, 2008 at 3:25 PM
Hi pavan, I sent the code for the interactive elementflow support last week but haven't received confirmation that you got it.  I've been having issues with my email so it may have never made it to you and that is why I'm posting here.  Let me know whether or not you've received it please.
Coordinator
Sep 9, 2008 at 5:37 PM
Hi eVolve,
        Sorry for not responding earlier. I was on vacation and just got back. I did receive your email but haven't tested yet. I should be able to do it today. Will reply back.


Sep 18, 2008 at 7:54 AM
Is there a known ETA for this functionality?

Thanks in advance!
Aug 17, 2011 at 1:49 PM

Could I get it as well please?  It looks like this never made it in to the main trunk

Mar 27, 2014 at 8:44 PM
Hi @eVolve, do you have the example for the Viewport2DVisual3D replacement?...

I'm having trouble making the ElementFlow items interactive.

Thanks in advance!
Mar 4, 2015 at 5:04 PM
Has anyone managed to modify the code as is to get interactivity? I've tried the modifications described by @eVolve some years back, but I know nothing about 3D, and simply switching ModelUIElement3d for Viewport2dVisual3d (and moving the geometry into the corresponding object as opposed to having it as a child f the ModelUIElement3d) hasn't made a difference.

I'm currently trawling through the selection code to see if I can work out how the ElementFlow control identifies what it needs to transform, but haven't managed to find the right line as yet. If anyone knows how to go about this (or more specifically: how to get commands on buttons contained in an ElementFlow to fire correctly), I'd very much appreciate some insight.
Mar 5, 2015 at 12:56 PM
Right, got this working. I think it's probably something that's not crazy difficult if you know what you're doing, but I didn't, which made it a challenge. Thanks to eVolve for the pointers towards Viewport2dVisual3d. Steps I took were:
  1. Replace all ModelUIElement3d occurrences with Viewport2dVisual3d ones (just using find and replace)
  2. In InternalResources, attach Geometry and Material to Viewport2DVisual3D instead of having them hosted in some other object.
  3. Using the approach found here, replace the CreateMeshModel method with one based on Josh's Build3dInteractiveModel. See below for the code.
  4. Tweak Josh's CreateContentPresenter method so that it just uses the DataTemplate on ElementFlow rather than trying to find some itemscontrol that owns the element.
It's worth noting that my approach breaks the Samples project for ElementFlow, so it's likely there's something I should be accounting for but am not. However, it does work for displaying buttons etc.

It probably also breaks the click to focus functionality that eVolve mentioned there were issues with, but for me, that's no an issue.

Methods Changed in ElementFlow.Internal.cs

// Added

private ContentPresenter CreateContentPresenter(FrameworkElement content)

{

var presenter = new ContentPresenter()

{

Content = content.DataContext,

Width=ElementWidth,

Height=ElementHeight

};

if (this.ItemTemplate != null)

presenter.ContentTemplate = this.ItemTemplate;

else if (this.ItemTemplateSelector != null)

presenter.ContentTemplate = this.ItemTemplateSelector.SelectTemplate(content.DataContext, presenter);

else

{

// This is the equivalent of the useTypedTemplate conditions

presenter.SetResourceReference(ContentPresenter.ContentTemplateProperty, new DataTemplateKey(content.DataContext.GetType()));

}

return presenter;

}

private int _registeredNameCounter;

private string GetNextName() { return "name" + _registeredNameCounter++; }

// Replaced

private Viewport2DVisual3D CreateMeshModel(FrameworkElement element)

{

var presenter = this.CreateContentPresenter(element);

presenter.Name = this.GetNextName();

this.Viewport.RegisterName(presenter.Name, presenter);

// Opacity set in original code here. Don't think it's needed in this case.

var model = InternalResources["ElementModel"] as Viewport2DVisual3D;

model.Visual = presenter;

Viewport2DVisual3D.SetIsVisualHostMaterial(model.Material, true);

return model;

}

Mar 6, 2015 at 3:31 AM
If you just want clicking, I have hit-testing in ElementFlow. By default it brings the clicked item to the front but you can override this behavior easily. I have not been using it to do any more significant interactive stuff, so I don't know how far it'll go.

And I remember the changes were like a few lines of code, not the major surgery you described. If you are interested, I can dig through my code to find the changes.
Mar 6, 2015 at 3:34 AM
Come to think of it, I remember how I did it. I built in links between the models and geometries via attached properties and used them to relate the two. This has the benefit of changing very little code, as well as enabling other features that I added to FluidKit -- for example, reusing models and virtualization to enable loading thousands of items into ElementFlow, having near/far clipping planes, culling out-of-view items etc.