I'm trying to use a custom cursor in order to use for drag and drop (in my application, the adorner method has significant lag behind the cursor)
Everything is working well using https://wpf.2000things.com/2012/12/17/713-setting-the-cursor-to-an-image-of-an-uielement-while-dragging/ but, when I display my cursor, it's much smaller than my original.
How do I adjust the cursor size in order to allow the cursor to be a similar size to the element I'm copying?
Related
I wrote a project that's creating a hierarchy diagram using nested controls.
When run on a complex data source, having WPF paint the diagram comprising approx. 2,000 nested controls takes quite a while.
A property change, like border stroke width, may trigger the whole render cycle, incl. Measure, Arrange etc.
I'd like to show a wait cursor for the whole render cycle, including Measure, Arrange and everything else happening before WPF presents the final result on screen. Is there a set of events I can register with to set the mouse cursor appropriately?
What is the best way to manage a very large amount of images (10,000+) in WPF? This is for a 2d tile map editor similar to this : http://www.mapeditor.org/ .
At the moment i have a canvas with all tiles as an image and a list box which contains the different images to choose from. Each tile is added to the canvas as children and then stored in a list for later access. You paint into the canvas by setting the Source property of a tile to the one selected in the listbox. It works well with around 50x50 tile maps but anything above that causes loading delays, in general slow application.
Any suggestions on this? Would QT maybe be more suited instead of wpf?
Thanks in advance
Check out Implementing virtualized panel series of articles.
Virtualized panels are efficient, because:
Only the displayed elements (and a few extra around the borders to enable smooth scrolling) are in the memory (and rendered).
Elements are reused, instead of being repeatedly created and discarded - an old cell is simply filled with new content (supplied with new DataContext) and used in new location.
You might also try to use WPF's DataGrid for this, it supports virtualization out of the box and is essentially what are you trying to do.
WPF is certainly able to do this, if implemented properly (if you can do that in JavaScript, you can certainly do it in WPF as well).
I'm sort-of just nit picking here, but maybe there's a simple solution which will save me some time.
When I'm drawing my Winforms GUI in the designer, controls snap to certain points. I can align the baseline of the text of one control to that of another, I can align the left and/or top of one control to another, etc. This is all great.
What's great too, is that the controls snap to other controls spaced with their margins. This means that if I'm making a vertical array of TextBoxes, then I can have them equidistant in my GUI - it looks less messy.
However not everything snaps correctly, or at all. Say I have put in my TextBoxes and now I wish to reduce the width of my form so that there is no white space between the edges of the TextBoxes and the edge of the form. Additionally, I want the distance between the edge of the TextBoxes and the edge of the Form to be the same on the left as it is on the right. If I drag the right edge of the form to the left, towards the TextBoxes it will not snap. I'm left with either calculations to work out what the width should be, or a juggling act to gradually reduce the width until the TextBox is snapping to both the left of the right.
I'm not saying this process is particularly difficult or time consuming. It's just that if it were to snap, the whole process would be infinitely easier.
Is there a built-in option in VS2010, or perhaps an extension? Or maybe I'm just doing it wrong in the first place?
The snap lines in the designer work perfectly when moving or resizing any of the built-in controls. The only time that they don't work is when you are resizing the form itself.
I agree that it would be extremely convenient to have snap lines here, as well. I wish I knew of a way to enable this. But unfortunately, I don't believe that there is one.
The workarounds are either to calculate the proper size mathematically, or guess at resizing the form then check your work by dragging one of the controls (and using the snap lines that appear). I go through the same "juggling act" that you describe on an unfortunately regular basis.
Whenever a control needs to be positioned so that it "snaps" to a form edge I usually move (or resize) the controls to the correct size first, and then change the controls "Anchor" property of those controls to be anchored to the corresponding form edge (even if the form itself won't be allowed to resize).
That way whenever I resize the form, the controls position relative to that form remains the same, simply resizing or moving the control as required (depending on the Anchor property chosen).
I completely agree that the ability to "snap" the form to controls when resizing the form would be extremely useful, but its normally possible to work-around using the anchor property in this way - the times when its doesn't work (such as when a form consists entirely of a column of text-boxes is a fixed height), I'm afraid you need to resort to calculations, but I find that most of my dialogs are resizable.
Using gdk_screen_get_monitor_geometry, I can get the total area in pixels and the relative position of each monitor, even when there are two or more used as a single screen.
However, I want to get the usable area (that is, excluding panels) of each monitor. The only thing I have found is _NET_WORKAREA, but that is one giant area stretching across all monitors. Depending on the resolution and arrangement, there may be panels inside this area.
How can I get the actual usable area of each monitor? Ideally, using only Gtk/Gdk, nothing X11-specific.
The following approach is a bit convoluted, but it is what I'd use. It should be robust even when there is complex interaction between the window manager and GTK+ when a window is mapped -- for example, when some of the panels are automatically hidden.
The basic idea is to create a transparent decorationless maximized window for each screen, obtain its geometry (size and position) when it gets mapped (for example, using a map-event callback), and immediately destroy them. That gets you the usable area within each screen. You can then use your existing gdk_screen_get_monitor_geometry() approach to determine how the usable area is split between monitors, if any.
In detail:
Use gdk_display_get_default() to get the default display, then gdk_display_get_n_screens() to find out how many screens it has.
Create a new window for each screen using gtk_window_new(), moving the windows to their respective screens using gtk_window_set_screen(). Undecorate the windows using gtk_window_set_decorated(,FALSE), maximuze them using gtk_window_maximize(,TRUE), and make them transparent using gtk_window_set_opacity(,0.0). Connect the map-event signal to a callback handler (using g_signal_connect()). Show the window using gtk_widget_show().
The signal handler needs to call gtk_window_get_position() and/or gtk_window_get_size() to get the position and/or size of the newly-mapped window, and then destroy the window using gtk_widget_destroy().
Note that in practice, you only need one window. I would personally use a simple loop. I suspect that due to window manager oddities/bugs, it is much more robust to create a new window for each screen, rather than just move the same window between screens. It turns out it is easier, too, as you can use a single simple callback function to obtain the usable area for each screen.
Like I said, this is quite convoluted. On the other hand, a standard application should not care about the screen sizes; it should simply do what the user or window manager asks. Because of that, I would not be surprised if there are no better facilities to find out this information. Screen size may change at any point, for example if the user rotates their display, or changes the display resolution.
in the end I ended up using xlib directly, various "tricks" like the one suggested above ended up eventually failing in the long run often with odd corner cases and never followed the KISS principle.
The solution I used is in the X-Tile code base.
I'm having amazing difficulties with a high-precision pixel-oriented image program in WPF and starting to suspect that the Cursors.Cross cursor hotspot is not at its centre, as you would expect.
I'm debugging using Magnifier at 16x and mouse set to the lowest acceleration. The code is based on DrawTools from CodeProject.
Is this the same cursor as you get in Winforms? If so, I can look at that cursor's hotspot - the Cursor class in System.Windows.Input doesn't have the HotSpot property.
UPDATE
In case anyone is looking for a workaround, in my case I already have a delegate being invoked to filter the points so I can implement snap-to-grid behaviour. It was trivial to offset the point by 1 to compensate. This was a lot easier than creating a custom cursor and has the advantage that I'm still using the stock cursor if its appearance should change.
I have an empirical answer that yes, the hotspot is offset.
I modified the program to be able to trigger graphics modes by pressing keys, so you don't need to move the mouse.
Using the same Magnifier view as the snapshot above, just pressing a key to change the mode toggles the cursor between arrow and cross.
When I switch it draws the cursor so the black lines centre on the top-left point of the normal arrow cursor.
The arrow cursor hotspot is at the pixel it points to (not a black pixel) so yes, the cross cursor hotspot is NOT at the centre of the crosshairs!
sigh