Skip to content

Commit c759668

Browse files
committed
Allow drag+drop image files on any "quick start" or "recent file" buttons
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!)
1 parent c0693ac commit c759668

File tree

5 files changed

+93
-30
lines changed

5 files changed

+93
-30
lines changed

Controls/pdButton.ctl

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ Attribute VB_Exposed = False
3232
'PhotoDemon Generic Button control
3333
'Copyright 2014-2024 by Tanner Helland
3434
'Created: 19/October/14
35-
'Last updated: 03/May/20
36-
'Last update: switch to pd2D for UI rendering
35+
'Last updated: 01/April/24
36+
'Last update: raise custom drag/drop events (that the owner can respond to as they wish)
3737
'
3838
'In a surprise to precisely no one, PhotoDemon has some unique needs when it comes to user controls - needs that
3939
' the intrinsic VB controls can't handle. These range from the obnoxious (lack of an "autosize" property for
@@ -71,6 +71,13 @@ Public Event SetCustomTabTarget(ByVal shiftTabWasPressed As Boolean, ByRef newTa
7171
' panel on the main window, as the settings button is too short to support text display.
7272
Public Event DrawButton(ByVal bufferDC As Long, ByVal buttonIsHovered As Boolean, ByVal ptrToRectF As Long)
7373

74+
'In April 2024, I added DragDrop relays (to enable custom drag/drop behavior on individual buttons).
75+
' (Despite the name, these relays are for the underlying OLE-prefixed events, which are the only drag/drop
76+
' events PD uses.)
77+
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)
78+
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)
79+
Private m_CustomDragDropEnabled As Boolean
80+
7481
Public Enum PDButton_RenderMode
7582
BRM_Normal = 0
7683
BRM_OwnerDrawn = 1
@@ -160,6 +167,15 @@ Public Property Let BackColor(ByVal newBackColor As OLE_COLOR)
160167
End If
161168
End Property
162169

170+
Public Property Get CustomDragDropEnabled() As Boolean
171+
CustomDragDropEnabled = m_CustomDragDropEnabled
172+
End Property
173+
174+
Public Property Let CustomDragDropEnabled(ByVal newValue As Boolean)
175+
m_CustomDragDropEnabled = newValue
176+
If newValue Then UserControl.OLEDropMode = 1 Else UserControl.OLEDropMode = 0
177+
End Property
178+
163179
Public Property Get RenderMode() As PDButton_RenderMode
164180
RenderMode = m_RenderMode
165181
End Property
@@ -503,13 +519,22 @@ Private Sub UserControl_InitProperties()
503519
BackColor = vbWhite
504520
BackgroundColor = vbWhite
505521
Caption = vbNullString
522+
CustomDragDropEnabled = False
506523
Enabled = True
507524
FontSize = 10
508525
RenderMode = BRM_Normal
509526
UseCustomBackColor = False
510527
UseCustomBackgroundColor = False
511528
End Sub
512529

530+
Private Sub UserControl_OLEDragDrop(Data As DataObject, Effect As Long, Button As Integer, Shift As Integer, x As Single, y As Single)
531+
RaiseEvent CustomDragDrop(Data, Effect, Button, Shift, x, y)
532+
End Sub
533+
534+
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)
535+
RaiseEvent CustomDragOver(Data, Effect, Button, Shift, x, y, State)
536+
End Sub
537+
513538
'At run-time, painting is handled by PD's pdWindowPainter class. In the IDE, however, we must rely on VB's internal paint event.
514539
Private Sub UserControl_Paint()
515540
If (Not PDMain.IsProgramRunning()) Then ucSupport.RequestIDERepaint UserControl.hDC
@@ -520,6 +545,7 @@ Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
520545
m_BackColor = .ReadProperty("BackColor", vbWhite)
521546
m_BackgroundColor = .ReadProperty("BackgroundColor", vbWhite)
522547
Caption = .ReadProperty("Caption", vbNullString)
548+
CustomDragDropEnabled = .ReadProperty("CustomDragDropEnabled", False)
523549
Enabled = .ReadProperty("Enabled", True)
524550
FontSize = .ReadProperty("FontSize", 10)
525551
RenderMode = .ReadProperty("RenderMode", 0)
@@ -537,6 +563,7 @@ Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
537563
.WriteProperty "BackColor", m_BackColor, vbWhite
538564
.WriteProperty "BackgroundColor", m_BackgroundColor, vbWhite
539565
.WriteProperty "Caption", ucSupport.GetCaptionText, vbNullString
566+
.WriteProperty "CustomDragDropEnabled", Me.CustomDragDropEnabled, False
540567
.WriteProperty "Enabled", Me.Enabled, True
541568
.WriteProperty "FontSize", ucSupport.GetCaptionFontSize, 10
542569
.WriteProperty "RenderMode", Me.RenderMode, 0

Controls/pdCanvas.ctl

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ Begin VB.UserControl pdCanvas
8787
_ExtentX = 1085
8888
_ExtentY = 873
8989
Caption = "New image..."
90+
CustomDragDropEnabled= -1 'True
9091
FontSize = 12
9192
End
9293
Begin PhotoDemon.pdButton cmdStart
@@ -99,6 +100,7 @@ Begin VB.UserControl pdCanvas
99100
_ExtentX = 1085
100101
_ExtentY = 873
101102
Caption = "Open image..."
103+
CustomDragDropEnabled= -1 'True
102104
FontSize = 12
103105
End
104106
Begin PhotoDemon.pdButton cmdStart
@@ -111,6 +113,7 @@ Begin VB.UserControl pdCanvas
111113
_ExtentX = 1085
112114
_ExtentY = 873
113115
Caption = "Import from clipboard..."
116+
CustomDragDropEnabled= -1 'True
114117
FontSize = 12
115118
End
116119
Begin PhotoDemon.pdButton cmdStart
@@ -123,6 +126,7 @@ Begin VB.UserControl pdCanvas
123126
_ExtentX = 1085
124127
_ExtentY = 873
125128
Caption = "Batch process..."
129+
CustomDragDropEnabled= -1 'True
126130
FontSize = 12
127131
End
128132
Begin PhotoDemon.pdButton cmdRecent
@@ -134,6 +138,7 @@ Begin VB.UserControl pdCanvas
134138
Width = 615
135139
_ExtentX = 1085
136140
_ExtentY = 873
141+
CustomDragDropEnabled= -1 'True
137142
End
138143
End
139144
Begin PhotoDemon.pdProgressBar mainProgBar
@@ -242,8 +247,8 @@ Attribute VB_Exposed = False
242247
'PhotoDemon Canvas User Control (previously a standalone form)
243248
'Copyright 2002-2024 by Tanner Helland
244249
'Created: 29/November/02
245-
'Last updated: 08/April/22
246-
'Last update: fix tab order of start screen (vertical columns are not handled correctly by PD's auto-tab-key algorithm)
250+
'Last updated: 01/April/24
251+
'Last update: allow drag+dropping image files on the command buttons on an empty canvas view
247252
'
248253
'In 2013, PD's canvas was rebuilt as a dedicated user control, and instead of each image maintaining its own canvas inside
249254
' separate, dedicated windows (which required a *ton* of code to keep in sync with the main PD window), a single canvas was
@@ -733,6 +738,14 @@ Private Sub cmdRecent_Click(Index As Integer)
733738
End If
734739
End Sub
735740

741+
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)
742+
Loading.LoadFromDragDrop Data, Effect, Button, Shift, x, y
743+
End Sub
744+
745+
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)
746+
Loading.HelperForDragOver Data, Effect, Button, Shift, x, y, State
747+
End Sub
748+
736749
Private Sub cmdRecent_SetCustomTabTarget(Index As Integer, ByVal shiftTabWasPressed As Boolean, newTargetHwnd As Long)
737750

738751
If shiftTabWasPressed Then
@@ -772,6 +785,14 @@ Private Sub cmdStart_Click(Index As Integer)
772785

773786
End Sub
774787

788+
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)
789+
Loading.LoadFromDragDrop Data, Effect, Button, Shift, x, y
790+
End Sub
791+
792+
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)
793+
Loading.HelperForDragOver Data, Effect, Button, Shift, x, y, State
794+
End Sub
795+
775796
Private Sub cmdStart_SetCustomTabTarget(Index As Integer, ByVal shiftTabWasPressed As Boolean, newTargetHwnd As Long)
776797

777798
If shiftTabWasPressed Then

Controls/pdCanvasView.ctl

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -406,36 +406,13 @@ End Sub
406406
'(This code is copied from FormMain's OLEDragDrop event - please mirror any changes there, or even better, stop being lazy
407407
' and write a universal drag/drop handler!)
408408
Private Sub UserControl_OLEDragDrop(Data As DataObject, Effect As Long, Button As Integer, Shift As Integer, x As Single, y As Single)
409-
410-
'Make sure the form is available (e.g. a modal form hasn't stolen focus)
411-
If (Not g_AllowDragAndDrop) Then Exit Sub
412-
413-
'Use the external function (in the clipboard handler, as the code is roughly identical to clipboard pasting)
414-
' to load the OLE source.
415-
Dim dropAsNewLayer As VbMsgBoxResult
416-
dropAsNewLayer = Dialogs.PromptDropAsNewLayer()
417-
If (dropAsNewLayer <> vbCancel) Then
418-
If (dropAsNewLayer = vbNo) Then
419-
g_Clipboard.LoadImageFromDragDrop Data, Effect, (dropAsNewLayer = vbNo), Int(x + 0.5!), Int(y + 0.5!)
420-
Else
421-
g_Clipboard.LoadImageFromDragDrop Data, Effect, (dropAsNewLayer = vbNo)
422-
End If
423-
End If
424-
409+
Loading.LoadFromDragDrop Data, Effect, Button, Shift, x, y
425410
End Sub
426411

427412
'(This code is copied from FormMain's OLEDragOver event - please mirror any changes there, or even better, stop being lazy
428413
' and write a universal drag/drop handler!)
429414
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)
430-
431-
'PD supports a lot of potential drop sources these days. These values are defined and addressed by the main
432-
' clipboard handler, as Drag/Drop and clipboard actions share a ton of similar code.
433-
If g_Clipboard.IsObjectDragDroppable(Data) And g_AllowDragAndDrop Then
434-
Effect = vbDropEffectCopy And Effect
435-
Else
436-
Effect = vbDropEffectNone
437-
End If
438-
415+
Loading.HelperForDragOver Data, Effect, Button, Shift, x, y, State
439416
End Sub
440417

441418
'Primary rendering function. Note that ucSupport handles a number of rendering duties (like maintaining a back buffer for us).

Modules/Loading.bas

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -946,6 +946,44 @@ Public Function LoadMultipleImageFiles(ByRef srcList As pdStringStack, Optional
946946

947947
End Function
948948

949+
'Load an image via drag/drop on an individual control.
950+
' Optionally, a target x/y can be passed (this is really only useful for dropping on an existing canvas;
951+
' the values will be ignored otherwise).
952+
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
953+
954+
'Make sure the main window is available (e.g. a modal dialog hasn't stolen focus)
955+
If (Not g_AllowDragAndDrop) Then Exit Function
956+
957+
'Use the external function (in the clipboard handler, as the code is roughly identical to clipboard pasting)
958+
' to load the OLE source.
959+
Dim dropAsNewLayer As VbMsgBoxResult
960+
dropAsNewLayer = Dialogs.PromptDropAsNewLayer()
961+
962+
If (dropAsNewLayer <> vbCancel) Then
963+
If (dropAsNewLayer = vbNo) And ((x <> 0!) Or (y <> 0!)) Then
964+
LoadFromDragDrop = g_Clipboard.LoadImageFromDragDrop(Data, Effect, (dropAsNewLayer = vbNo), Int(x + 0.5!), Int(y + 0.5!))
965+
Else
966+
LoadFromDragDrop = g_Clipboard.LoadImageFromDragDrop(Data, Effect, (dropAsNewLayer = vbNo))
967+
End If
968+
End If
969+
970+
End Function
971+
972+
'I don't know if it makes sense here, but because this module handles loading via drag+drop,
973+
' I've also placed a helper function here for handling cursor update on a drag/over event.
974+
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
975+
976+
'PD supports a lot of potential drop sources these days.
977+
' These values are defined and addressed by the main clipboard handler, because Drag/Drop and clipboard actions
978+
' share a lot of code.
979+
If g_Clipboard.IsObjectDragDroppable(Data) And g_AllowDragAndDrop Then
980+
Effect = vbDropEffectCopy And Effect
981+
Else
982+
Effect = vbDropEffectNone
983+
End If
984+
985+
End Function
986+
949987
'This routine sets the message on the splash screen (used only when the program is first started)
950988
Public Sub LogStartupEvent(ByRef sMsg As String)
951989

PhotoDemon.vbp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ Description="PhotoDemon Photo Editor"
526526
CompatibleMode="0"
527527
MajorVer=9
528528
MinorVer=1
529-
RevisionVer=341
529+
RevisionVer=344
530530
AutoIncrementVer=1
531531
ServerSupportFiles=0
532532
VersionComments="Copyright 2000-2024 Tanner Helland - photodemon.org"

0 commit comments

Comments
 (0)