-
Notifications
You must be signed in to change notification settings - Fork 696
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add mouse/keyboard resizing of views #2537
Comments
This needs to fix #2536 too |
@BDisp this is another Issue related to |
If one of the goals of this feature is to support TGD resizing use cases then I think that the solution needs to be decoupled from Borders. It must be possible to drag and resize any view (regardless of whether it has a Border). For example: It also needs to be possible to drag multiple views at once e.g. |
The relevant code in TGD is in: |
I'll start thinking about this... I can't see anything really challenging, but it will require some thought... Are you interested in collaborating with me on it? |
Definetly! lets see what we can do. |
DragDrag Phases (i.e. State)In order to support Undo and other stuff (like cancelling an ongoing drag) I think we should keep state in the same way TGD does with
So the process is: // Establishes the origin from which all vectors are measured
StartDrag (x,y)
// Updates positions of Views, each vector replaces the last (i.e. they are not additive)
ContinueDrag(new Vector(2,5))
ContinueDrag(new Vector(3,5))
ContinueDrag(new Vector(4,5))
// View is moved to x+4 y+5 and drag state is cleared
EndDrag() Drag Multiple At OnceTGD lets you select multiple views with a selection box. I think this can be left in TGD. But we do need the ability to drag multiple views at once. For sanity sake probably we should require that all views in a multiple drag should be in the same parent View. Drag BoundaryWhen a drag results in some/all of a view spilling out of it's parent: /// <summary>
/// True to allow dragging a view such that part/all of it is
/// outside of its parent View's viewport
/// </summary>
bool AllowDragOffscreen; Drag InitiationThere are 3 options for a View when it comes to initiating a drag enum Dragability
{
/// <summary>
/// View cannot be dragged
/// </summary>
NotDraggable,
/// <summary>
/// View can be dragged by clicking and dragging at row 0 of
/// the view.
/// </summary>
DragFromTop,
/// <summary>
/// The view can be dragged by clicking and dragging anywhere
/// in the view
/// </summary>
DragFromAnywhere
} Pos TypesWhen dragging we need to decide which For example:
Dragging a view with another that is PosView connected to it (e.g. Left of) needs considered also. Especially if dragging to another view. Drag into another ViewThis is an opt in feature. It could be a global value or View specific. But if it is tied to Views then it makes multiple view drags more complicated. bool AllowDragToOtherViews; To support dragging a view into another view we must think:
So we need some kind of confirmation probably an event EventHandler<DragEventArgs> StartDrag;
event EventHandler<DragEventArgs> EndDrag; class DragEventArgs
{
/// <summary>
/// Describes the views being moved and where they are being moved to.
/// Note that you can use set to change which views are dragged e.g. to drag multiple
/// </summary>
public DragOperation DragOperation { get; set; }
/// <summary>
/// Set to true to abandon the <see cref="DragOperation"/> and return
/// all views to original positions
/// </summary>
public bool Cancel { get; set; }
} Composite viewsSome views have sub views that complicate click and drag. For example /// <summary>
/// <para>
/// Sometimes <see cref="View.FindDeepestView"/> returns what the library considers
/// the clicked View rather than what the user would expect. For example clicking in
/// the <see cref="Border"/> area of a <see cref="TabView"/>.
/// </para>
/// <para>This works out what the real view is.</para>
/// </summary>
/// <param name="hit"></param>
/// <returns></returns>
public static View? UnpackHitView(this View? hit)
{
if (hit != null && hit.GetType().Name.Equals("TabRowView"))
{
hit = hit.SuperView;
}
// Translate clicks in the border as the real View being clicked
if (hit is Border b)
{
hit = b.Parent;
}
// TabView nesting of 'fake' views goes:
// TabView
// - TabViewRow
// - View (pane)
// - Border (note you need Parent not SuperView to find Border parent)
if (hit?.SuperView is TabView tv)
{
hit = tv;
}
return hit;
} |
A few years ago I was interested in implementing mouse/keyboard drag and drop and resizing. Then I lost the will to continue. |
Good stuff. Not a lot of thoughts so far. But one... Add a flag to Arrangement:
When set, effectively hides the Viewport from the mouse hit test code. Thus press and drag anywhere from Border-in works. Even if Border thickness is 0. |
Also, look at Highlight/HighlightMode. Can be extended to be combined with Arrangement.DesignMode to enable the whole view to be highlighted. |
But it would be useful if |
Why would we not want someone else to build a design-time tool like TGD? |
I thought you wanted TGD exclusivity that belongs to gui-cs. If that's not the case then I take back what I said. |
It sucks so much for us that every platform and use tha forces us to have to have a "driver" to jump through different hoops to make this all happen. 😤 It's things like this that make libraries like TG so damn nice to use - abstracting away all the BS so the consumer can have a more consistent experience without worrying about it. /gripe 😆 |
In #3705 we now have Keyboard moving and sizing of views per the design above for
|
Right now, dragging is handled w/in TopLevel. This needs to change to be handled within Border (or in Application, but via an interface with Border).
ViewArrangement.Movable
- if set and view has a top Border, it can be dragged with mouse. Always with keyboard (although no visual indicator if no border).ViewArrangement.Sizable
- if set and a view has left/right/bottom Border it can be resized with mouse. Always with keyboard (although no visual indicator if no border).Application.cs
:Related:
Application.Top
) #2502.My proposal:
Tiled Mode:
Mouse:
Border
top or bottom resizes the view verticallyBorder
left or right resizes the view horizontallyKeyboard:
Ctrl+F5
to enable Arrange Mode 1◊
indicating it's active for resizing. Left/Right/Up/Down will size.Ctrl+F5
orEsc
to exit Arrange ModeOverlapped mode:
Mouse:
Border
top moves the viewBorder
bottom resizes the view verticallyBorder
left or right resizes the view horizontallyKeyboard:
Ctrl+F5
to enable Arrange Mode 1◊
appears in top left corner of Border indicating Arrange ModeViewArrangement.Movable
is setLeft/Right/Up/Down
will move the viewTab
andShift+Tab
will cycle through any sides that can be sized and "Move"ViewArrangement.Resizable
(all side-flags) is set. Then◊
appears in bottom right corner of Border.◊
centered indicating it's active for resizing.Left/Right/Up/Down
will size as appropriateCtrl+F5
to exit Arrange ModeFootnotes
On Windows
Alt-Space, M
enables move-with-keyboard. On MacCtrl-F5
"Move focus to the window toolbar". No standard on Linux.Ctrl-F5
isn't used by Windows Terminal. Happy for a better suggestion. ↩ ↩2The text was updated successfully, but these errors were encountered: