I have created a custom panel that renders like a canvas renders it's children. I would like that 2 elements that hit each other (ie. touch each other somewhere) get replaced by another control that allows custom rendering of these elements near each other and for example puts them in a context menu.
I have code that can correctly detect these hits, however, I cannot seem to replace the elements by other elements, as the panel is always drawing the items in InternalChildren array.
I cannot do this hit testing before they get to the panel. As they come from a view that can be grouped and due to zooming in and out (which effects the positions/sizes of the children), won't know which elements collide until measuring of the panel happens.
Is there any way to let the panel render other elements than those that are in the InternalChildren array?
EDIT: image
http://www.imagedump.nl/img827/2849/12unled.png
Note that I do not care if block C get's replaced by another component or not, so if replacing it with a merged block is easier (which I think it will be), do so.
Related
I hope make text that always visible in screen, see my gif
I hope text in FloatingTextCanvs visible but it's covered by button, I find the later create ui object will cover previous objects, can i change text object's index to make text always visible?
To display one canvas in front of the other, you want to change the Sort Order property on the Canvas component to be higher than the other canvas.
If you are dealing with two separate canvases then you can set their sort order to determine which one appears on top.
If you are dealing with two UI elements that are children of the same canvas, then their physical arrangement within the hierarchy determines which one appears on top. The child at the top of the hierarchy will appear underneath the other elements. For example, in the following MainMenuCanvas, the Background image will appear behind the Text.
I'm using unity 5.3 and I'm trying to change the Rendering Order of two overlayed cross platform controls which each reside in their own canvas.
In previous versions you could bring the window into focus using
GUI.FocusWindow(0);
However this does not work with the new system.
I've also tried modifying the order in the editor window which has done nothing.
Does anyone know how I can move a control to be on top of the other?
After doing some research I found the proper way to change the Canvas Rendering Order. There is a property in the Canvas for the Sort Order, which is really the render order.
.
Just as a note remember the controls you want to be on top should have a larger order than the control on bottom.
Order in the editor window should work here. Are you sure you're changing the order of elements inside one canvas element?
Note that the order of elements in the Canvas game object is the order everything is rendered in - so the last thing you have in canvas will be the last thing drawn, so it will be on top of everything.
Here's how it works:
This is demonstrated with Unity 5.3.4, with much older Unity it can be different (there was a change of the way how children were enumerated somewhere in 5.0 or 5.1 AFAIK).
I currently have a form with a scrollable panel that potentially contains over 100 child controls (only about 10 are viewable on screen at any time)
This causes a lot of flickering when scrolling.
I have been looking at some double-buffering techniques, but they won't work in my case since I am using several child controls (Buttons, Labels, Checkboxes) and they all get painted independently. I can't do anything in the panel's OnPaint method that affect the children.
And several answers I have read state that adding existing controls take more resources rather than, say, instead of a Label, just painting a colored square with text over top.
I have 2 main questions:
If I were to no longer us child controls, and instead just draw everything in OnPaint of the panel, how can I paint only what is currently visible (considering that the user can scroll)
How would I implement things like check boxes?
1) you would get scroll_position*one_stepscroll .you would find begining item index with scroll_position*one_stepscroll/item.height -1 and last item index with adding
constant item sizes (panel.height/item.height+1 ) .
then u would draw items to backbuffer (as u see from calculations its height will be greater than panel.height of course ) . then show that buffer on panel graphics .so this is how double buffering works .`(if your controls will contain big images to draw then you can use some lazy loading techniques. proxy pattern to speed up scrolling , check this : proxy pattern
1A)if your item.heights differ then you have find first item different way. i would
suggest you for performance to store each items begining position too . this way u will
reduce calculation instead of finding looping throw items and adding heights each time
2)you will get its state and show state . for example u can do . filled rectangle as for checked hollow rectangle for unchecked .(think it will be your own object with additional boolean state property ,or just boolean variable and with its x,y,width,height ) .on panel click you will check click position with visible checkbox items areas . then you would change its state = !state . then again you will redraw whole panel again for visible items .
3)3rd way just change contents when scrolling and use controls . and scrolling step will be one object movement . Trust me on long run user prefer easy workng over fance shamancy things. .just use 10 controls items . and 100 objects storing values for it . on scrolling you would just change those 10 items display properties (text ,state or image or whatever) from 100 objects . this way you will use controls itself .easy solution for performance and memory too.
How can I create a control container where every item (control) behaves like a Floating DIV (in HTML), like this video (considering that each folder is a control)?
Take a look at the WrapPanel class. MSDN
It has the functionality you are looking for.
Positions child elements in sequential position from left to right, breaking content to the next line at the edge of the containing box. Subsequent ordering happens sequentially from top to bottom or from right to left, depending on the value of the Orientation property.
I've only been working with WPF for a few months, but I have an extensive WinForm, ASP.NET, and Flex background. I am attempting to draw a user control which looks like the following IMAGE.
We are using the MVVM pattern. When the user control first loads, everything draws correctly. The control consists of a canvas. Within the canvas exists a radial panel which will geometrically place UIElements which are added. The circular nodes are drawn into the radial panel. The PolyLines shown are drawn in the canvas. I get the end points of the PolyLine by using a GeneralTransform and a call to UIElement.TransformToVisual. Where the UIElement in the call is the blue node in the radial panel and it is transforming with the radial panel. When the control is loaded the first time, everything does draw correctly. Where it fails is when the MVVM pattern informs there is an update to the drawing.
When I attempt to refresh based off the system update, I have confirmed all of my collections contain the proper data. So the MVVM pattern is behaving like it should. However, when I attempt to draw the lines, my call to TransformToVisual is returning a point of 0,0 instead of the value it does during the load. This causes my polylines to draw at the top left of the control instead of connecting the two nodes.
Here is the order of operations:
1) User Control load will build my collections used to draw the control. These collections are built local to the User Control and the data comes from a master collection of info which resides in the view model. The user control registers a refresh method in itself to a UI refresh broadcast message.
2) The user attempts to connect two blue nodes through a wizard. The connector is saved and the refresh UI message is broadcast.
3) The User Control invokes the Refresh method. Here I am looping the children of the canvas and removing the PolyLines. I am also calling radialPanel.Children.Clear. I then perform the same code which built my collections at load. I then invalidate my user control to invoke the OnRender. The OnRender will then attempt to draw the Polylines to connect the nodes. The nodes are always placed properly in the radial panel.
4) The line connecting action is called from the OnRender. Within it I am using the GeneralTransform gt = node.TransformToVisual(radialPanel). This call always returns 0,0 when the user control is "refreshed" but always works the first load for the control.
I'm fairly positive the issue lies with how I refresh the user control based on the network notification. I've tried to clear the controls, then re-do the same load operations, but still no luck. I've executed InvalidateVisual against the user control and tried to do everything in my overriden OnRender still no luck; 0,0 is still returned.
Does anyone have any ideas on what could be happening to the GeneralTransform? I'm at a dead end and any new path would help.
I figured it out. So I'm posting the answer in case anyone else deals with this issue.
The problem was I wasn't forcing MeasureOverride and ArrangeOverride of the radial panel before attempting to draw the lines. Without these two called, the nodes are at position 0,0 at the time I connect my lines. By forcing them to call before drawing the lines, the TransformToVisual works properly.