Skip to content

Commit

Permalink
Allow drag+drop image files on any "quick start" or "recent file" but…
Browse files Browse the repository at this point in the history
…tons

Relates to #549 .  Thank you to @manfromarce  for suggesting.

Because this requires manually updating any control instance that can receive dropped files, I can't add this to every UI element right away (and I'm not sure I want to, honestly!)
  • Loading branch information
tannerhelland committed Apr 1, 2024
1 parent c0693ac commit c759668
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 30 deletions.
31 changes: 29 additions & 2 deletions Controls/pdButton.ctl
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ Attribute VB_Exposed = False
'PhotoDemon Generic Button control
'Copyright 2014-2024 by Tanner Helland
'Created: 19/October/14
'Last updated: 03/May/20
'Last update: switch to pd2D for UI rendering
'Last updated: 01/April/24
'Last update: raise custom drag/drop events (that the owner can respond to as they wish)
'
'In a surprise to precisely no one, PhotoDemon has some unique needs when it comes to user controls - needs that
' the intrinsic VB controls can't handle. These range from the obnoxious (lack of an "autosize" property for
Expand Down Expand Up @@ -71,6 +71,13 @@ Public Event SetCustomTabTarget(ByVal shiftTabWasPressed As Boolean, ByRef newTa
' panel on the main window, as the settings button is too short to support text display.
Public Event DrawButton(ByVal bufferDC As Long, ByVal buttonIsHovered As Boolean, ByVal ptrToRectF As Long)

'In April 2024, I added DragDrop relays (to enable custom drag/drop behavior on individual buttons).
' (Despite the name, these relays are for the underlying OLE-prefixed events, which are the only drag/drop
' events PD uses.)
Public Event CustomDragDrop(ByRef Data As DataObject, ByRef Effect As Long, ByRef Button As Integer, ByRef Shift As Integer, ByRef x As Single, ByRef y As Single)
Public Event CustomDragOver(ByRef Data As DataObject, ByRef Effect As Long, ByRef Button As Integer, ByRef Shift As Integer, ByRef x As Single, ByRef y As Single, ByRef State As Integer)
Private m_CustomDragDropEnabled As Boolean

Public Enum PDButton_RenderMode
BRM_Normal = 0
BRM_OwnerDrawn = 1
Expand Down Expand Up @@ -160,6 +167,15 @@ Public Property Let BackColor(ByVal newBackColor As OLE_COLOR)
End If
End Property

Public Property Get CustomDragDropEnabled() As Boolean
CustomDragDropEnabled = m_CustomDragDropEnabled
End Property

Public Property Let CustomDragDropEnabled(ByVal newValue As Boolean)
m_CustomDragDropEnabled = newValue
If newValue Then UserControl.OLEDropMode = 1 Else UserControl.OLEDropMode = 0
End Property

Public Property Get RenderMode() As PDButton_RenderMode
RenderMode = m_RenderMode
End Property
Expand Down Expand Up @@ -503,13 +519,22 @@ Private Sub UserControl_InitProperties()
BackColor = vbWhite
BackgroundColor = vbWhite
Caption = vbNullString
CustomDragDropEnabled = False
Enabled = True
FontSize = 10
RenderMode = BRM_Normal
UseCustomBackColor = False
UseCustomBackgroundColor = False
End Sub

Private Sub UserControl_OLEDragDrop(Data As DataObject, Effect As Long, Button As Integer, Shift As Integer, x As Single, y As Single)
RaiseEvent CustomDragDrop(Data, Effect, Button, Shift, x, y)
End Sub

Private Sub UserControl_OLEDragOver(Data As DataObject, Effect As Long, Button As Integer, Shift As Integer, x As Single, y As Single, State As Integer)
RaiseEvent CustomDragOver(Data, Effect, Button, Shift, x, y, State)
End Sub

'At run-time, painting is handled by PD's pdWindowPainter class. In the IDE, however, we must rely on VB's internal paint event.
Private Sub UserControl_Paint()
If (Not PDMain.IsProgramRunning()) Then ucSupport.RequestIDERepaint UserControl.hDC
Expand All @@ -520,6 +545,7 @@ Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
m_BackColor = .ReadProperty("BackColor", vbWhite)
m_BackgroundColor = .ReadProperty("BackgroundColor", vbWhite)
Caption = .ReadProperty("Caption", vbNullString)
CustomDragDropEnabled = .ReadProperty("CustomDragDropEnabled", False)
Enabled = .ReadProperty("Enabled", True)
FontSize = .ReadProperty("FontSize", 10)
RenderMode = .ReadProperty("RenderMode", 0)
Expand All @@ -537,6 +563,7 @@ Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
.WriteProperty "BackColor", m_BackColor, vbWhite
.WriteProperty "BackgroundColor", m_BackgroundColor, vbWhite
.WriteProperty "Caption", ucSupport.GetCaptionText, vbNullString
.WriteProperty "CustomDragDropEnabled", Me.CustomDragDropEnabled, False
.WriteProperty "Enabled", Me.Enabled, True
.WriteProperty "FontSize", ucSupport.GetCaptionFontSize, 10
.WriteProperty "RenderMode", Me.RenderMode, 0
Expand Down
25 changes: 23 additions & 2 deletions Controls/pdCanvas.ctl
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ Begin VB.UserControl pdCanvas
_ExtentX = 1085
_ExtentY = 873
Caption = "New image..."
CustomDragDropEnabled= -1 'True
FontSize = 12
End
Begin PhotoDemon.pdButton cmdStart
Expand All @@ -99,6 +100,7 @@ Begin VB.UserControl pdCanvas
_ExtentX = 1085
_ExtentY = 873
Caption = "Open image..."
CustomDragDropEnabled= -1 'True
FontSize = 12
End
Begin PhotoDemon.pdButton cmdStart
Expand All @@ -111,6 +113,7 @@ Begin VB.UserControl pdCanvas
_ExtentX = 1085
_ExtentY = 873
Caption = "Import from clipboard..."
CustomDragDropEnabled= -1 'True
FontSize = 12
End
Begin PhotoDemon.pdButton cmdStart
Expand All @@ -123,6 +126,7 @@ Begin VB.UserControl pdCanvas
_ExtentX = 1085
_ExtentY = 873
Caption = "Batch process..."
CustomDragDropEnabled= -1 'True
FontSize = 12
End
Begin PhotoDemon.pdButton cmdRecent
Expand All @@ -134,6 +138,7 @@ Begin VB.UserControl pdCanvas
Width = 615
_ExtentX = 1085
_ExtentY = 873
CustomDragDropEnabled= -1 'True
End
End
Begin PhotoDemon.pdProgressBar mainProgBar
Expand Down Expand Up @@ -242,8 +247,8 @@ Attribute VB_Exposed = False
'PhotoDemon Canvas User Control (previously a standalone form)
'Copyright 2002-2024 by Tanner Helland
'Created: 29/November/02
'Last updated: 08/April/22
'Last update: fix tab order of start screen (vertical columns are not handled correctly by PD's auto-tab-key algorithm)
'Last updated: 01/April/24
'Last update: allow drag+dropping image files on the command buttons on an empty canvas view
'
'In 2013, PD's canvas was rebuilt as a dedicated user control, and instead of each image maintaining its own canvas inside
' separate, dedicated windows (which required a *ton* of code to keep in sync with the main PD window), a single canvas was
Expand Down Expand Up @@ -733,6 +738,14 @@ Private Sub cmdRecent_Click(Index As Integer)
End If
End Sub

Private Sub cmdRecent_CustomDragDrop(Index As Integer, Data As DataObject, Effect As Long, Button As Integer, Shift As Integer, x As Single, y As Single)
Loading.LoadFromDragDrop Data, Effect, Button, Shift, x, y
End Sub

Private Sub cmdRecent_CustomDragOver(Index As Integer, Data As DataObject, Effect As Long, Button As Integer, Shift As Integer, x As Single, y As Single, State As Integer)
Loading.HelperForDragOver Data, Effect, Button, Shift, x, y, State
End Sub

Private Sub cmdRecent_SetCustomTabTarget(Index As Integer, ByVal shiftTabWasPressed As Boolean, newTargetHwnd As Long)

If shiftTabWasPressed Then
Expand Down Expand Up @@ -772,6 +785,14 @@ Private Sub cmdStart_Click(Index As Integer)

End Sub

Private Sub cmdStart_CustomDragDrop(Index As Integer, Data As DataObject, Effect As Long, Button As Integer, Shift As Integer, x As Single, y As Single)
Loading.LoadFromDragDrop Data, Effect, Button, Shift, x, y
End Sub

Private Sub cmdStart_CustomDragOver(Index As Integer, Data As DataObject, Effect As Long, Button As Integer, Shift As Integer, x As Single, y As Single, State As Integer)
Loading.HelperForDragOver Data, Effect, Button, Shift, x, y, State
End Sub

Private Sub cmdStart_SetCustomTabTarget(Index As Integer, ByVal shiftTabWasPressed As Boolean, newTargetHwnd As Long)

If shiftTabWasPressed Then
Expand Down
27 changes: 2 additions & 25 deletions Controls/pdCanvasView.ctl
Original file line number Diff line number Diff line change
Expand Up @@ -406,36 +406,13 @@ End Sub
'(This code is copied from FormMain's OLEDragDrop event - please mirror any changes there, or even better, stop being lazy
' and write a universal drag/drop handler!)
Private Sub UserControl_OLEDragDrop(Data As DataObject, Effect As Long, Button As Integer, Shift As Integer, x As Single, y As Single)

'Make sure the form is available (e.g. a modal form hasn't stolen focus)
If (Not g_AllowDragAndDrop) Then Exit Sub

'Use the external function (in the clipboard handler, as the code is roughly identical to clipboard pasting)
' to load the OLE source.
Dim dropAsNewLayer As VbMsgBoxResult
dropAsNewLayer = Dialogs.PromptDropAsNewLayer()
If (dropAsNewLayer <> vbCancel) Then
If (dropAsNewLayer = vbNo) Then
g_Clipboard.LoadImageFromDragDrop Data, Effect, (dropAsNewLayer = vbNo), Int(x + 0.5!), Int(y + 0.5!)
Else
g_Clipboard.LoadImageFromDragDrop Data, Effect, (dropAsNewLayer = vbNo)
End If
End If

Loading.LoadFromDragDrop Data, Effect, Button, Shift, x, y
End Sub

'(This code is copied from FormMain's OLEDragOver event - please mirror any changes there, or even better, stop being lazy
' and write a universal drag/drop handler!)
Private Sub UserControl_OLEDragOver(Data As DataObject, Effect As Long, Button As Integer, Shift As Integer, x As Single, y As Single, State As Integer)

'PD supports a lot of potential drop sources these days. These values are defined and addressed by the main
' clipboard handler, as Drag/Drop and clipboard actions share a ton of similar code.
If g_Clipboard.IsObjectDragDroppable(Data) And g_AllowDragAndDrop Then
Effect = vbDropEffectCopy And Effect
Else
Effect = vbDropEffectNone
End If

Loading.HelperForDragOver Data, Effect, Button, Shift, x, y, State
End Sub

'Primary rendering function. Note that ucSupport handles a number of rendering duties (like maintaining a back buffer for us).
Expand Down
38 changes: 38 additions & 0 deletions Modules/Loading.bas
Original file line number Diff line number Diff line change
Expand Up @@ -946,6 +946,44 @@ Public Function LoadMultipleImageFiles(ByRef srcList As pdStringStack, Optional

End Function

'Load an image via drag/drop on an individual control.
' Optionally, a target x/y can be passed (this is really only useful for dropping on an existing canvas;
' the values will be ignored otherwise).
Public Function LoadFromDragDrop(ByRef Data As DataObject, ByRef Effect As Long, ByRef Button As Integer, ByRef Shift As Integer, Optional ByRef x As Single = 0!, Optional ByRef y As Single = 0!) As Boolean

'Make sure the main window is available (e.g. a modal dialog hasn't stolen focus)
If (Not g_AllowDragAndDrop) Then Exit Function

'Use the external function (in the clipboard handler, as the code is roughly identical to clipboard pasting)
' to load the OLE source.
Dim dropAsNewLayer As VbMsgBoxResult
dropAsNewLayer = Dialogs.PromptDropAsNewLayer()

If (dropAsNewLayer <> vbCancel) Then
If (dropAsNewLayer = vbNo) And ((x <> 0!) Or (y <> 0!)) Then
LoadFromDragDrop = g_Clipboard.LoadImageFromDragDrop(Data, Effect, (dropAsNewLayer = vbNo), Int(x + 0.5!), Int(y + 0.5!))
Else
LoadFromDragDrop = g_Clipboard.LoadImageFromDragDrop(Data, Effect, (dropAsNewLayer = vbNo))
End If
End If

End Function

'I don't know if it makes sense here, but because this module handles loading via drag+drop,
' I've also placed a helper function here for handling cursor update on a drag/over event.
Public Function HelperForDragOver(ByRef Data As DataObject, ByRef Effect As Long, ByRef Button As Integer, ByRef Shift As Integer, ByRef x As Single, ByRef y As Single, ByRef State As Integer) As Boolean

'PD supports a lot of potential drop sources these days.
' These values are defined and addressed by the main clipboard handler, because Drag/Drop and clipboard actions
' share a lot of code.
If g_Clipboard.IsObjectDragDroppable(Data) And g_AllowDragAndDrop Then
Effect = vbDropEffectCopy And Effect
Else
Effect = vbDropEffectNone
End If

End Function

'This routine sets the message on the splash screen (used only when the program is first started)
Public Sub LogStartupEvent(ByRef sMsg As String)

Expand Down
2 changes: 1 addition & 1 deletion PhotoDemon.vbp
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ Description="PhotoDemon Photo Editor"
CompatibleMode="0"
MajorVer=9
MinorVer=1
RevisionVer=341
RevisionVer=344
AutoIncrementVer=1
ServerSupportFiles=0
VersionComments="Copyright 2000-2024 Tanner Helland - photodemon.org"
Expand Down

0 comments on commit c759668

Please sign in to comment.