From faa9eddbc4c6e35615aae52c20ca96e39bb58768 Mon Sep 17 00:00:00 2001 From: Tanner Date: Tue, 19 Jun 2018 14:11:29 -0600 Subject: [PATCH] Implement basic UI for "Create macro from session history" tool --- Classes/pdPNG.cls | 20 +-- Forms/Edit_UndoHistory.frm | 7 +- Forms/MainWindow.frm | 59 ++++--- Forms/Tools_MacroSession.frm | 307 +++++++++++++++++++++++++++++++++++ Modules/BatchProcessor.bas | 8 +- Modules/Interface.bas | 4 +- Modules/Menus.bas | 8 +- PhotoDemon.vbp | 3 +- 8 files changed, 369 insertions(+), 47 deletions(-) create mode 100644 Forms/Tools_MacroSession.frm diff --git a/Classes/pdPNG.cls b/Classes/pdPNG.cls index ad01c8d2d5..99468a5b2b 100644 --- a/Classes/pdPNG.cls +++ b/Classes/pdPNG.cls @@ -67,20 +67,21 @@ End Enum Private m_Header As PD_PNGHeader 'If warnings are encountered during processing, we push their messages onto a string stack. (We may -' decide to report these to the user... I haven't decided yet. Either way, it'll be helpful for debugging.) +' decide to report these to the user... I haven't decided yet. Either way, it's helpful for debugging.) Private m_Warnings As pdStringStack -'pdStream makes our life much easier! +'pdStream handles actual byte traversal; it also makes our life much easier! Private m_Stream As pdStream 'At present, we require the caller to pass an identical source file path to every load function. -' (This is a cheap and easy way to ensure no funny business is afoot!) +' (This is a cheap and easy way to ensure no funny business.) Private m_SourceFilename As String 'In interlaced images, the number of pixels-per-reduced image is non-obvious. We calculate these ' line lengths as part of the decompression pass, and rather than re-calculate them on subsequent passes, ' we simply cache the results and re-use them later. (Note that there is no "y" byte count, because it -' is the same as the pixel count.) +' is the same as the pixel count; x requires a separate value, due to potential multi-byte-per-pixel +' color depths.) Private m_XPixelCount() As Long, m_YPixelCount() As Long Private m_XByteCount() As Long @@ -1825,14 +1826,9 @@ Private Sub ConstructGrayPalette(ByRef srcPalette() As RGBQuad, ByRef srcPalette End Sub -'TODO! We can now assemble the image's underlying pixel data. Note that -' the way we do this varies by color-mode and bit-depth. If the image has an ICC profile, we want to leave data -' in its original format in some circumstances (e.g. 16-bit-per-channel images must remain high-bit-depth prior -' to ICC conversion), while in others (e.g. 1-bit images) there is no advantage to leaving pixels in their -' original state. (In fact, we *must* convert them to another color-depth in order to ICC-correct them.) - -'NOTE: this function only works if m_Header has been populated! We need access to color-mode and bit-depth data -' in order to calculate interlacing pixel counts. +'Interlaced sub-images have varying sizes depending on the iteration pass. This function returns the +' width and height of a given interlaced sub-image; m_Header *must* be populated for this to work, since it +' relies on color-mode and bit-depth data. Private Function GetSizeInterlaced(ByRef dstX As Long, ByRef dstY As Long, ByVal intPass As Long) 'Per the spec, each interlacing pass encodes the following pixels from each 8x8 block in the image: diff --git a/Forms/Edit_UndoHistory.frm b/Forms/Edit_UndoHistory.frm index b4b6136858..fbd2fb9a5d 100644 --- a/Forms/Edit_UndoHistory.frm +++ b/Forms/Edit_UndoHistory.frm @@ -3,7 +3,7 @@ Begin VB.Form FormUndoHistory BackColor = &H80000005& BorderStyle = 4 'Fixed ToolWindow Caption = " Undo history" - ClientHeight = 6420 + ClientHeight = 6390 ClientLeft = 45 ClientTop = 285 ClientWidth = 9615 @@ -19,12 +19,13 @@ Begin VB.Form FormUndoHistory LinkTopic = "Form1" MaxButton = 0 'False MinButton = 0 'False - ScaleHeight = 428 + ScaleHeight = 426 ScaleMode = 3 'Pixel ScaleWidth = 641 ShowInTaskbar = 0 'False Begin PhotoDemon.pdLabel lblTitle Height = 255 + Index = 0 Left = 480 Top = 5280 Width = 8895 @@ -48,7 +49,7 @@ Begin VB.Form FormUndoHistory Height = 735 Left = 0 TabIndex = 0 - Top = 5685 + Top = 5655 Width = 9615 _ExtentX = 16960 _ExtentY = 1296 diff --git a/Forms/MainWindow.frm b/Forms/MainWindow.frm index e6f4294a1e..51a1b37538 100644 --- a/Forms/MainWindow.frm +++ b/Forms/MainWindow.frm @@ -1300,16 +1300,24 @@ Begin VB.Form FormMain Index = 4 End Begin VB.Menu MnuTool - Caption = "Record macro" + Caption = "Create macro" Index = 5 - Begin VB.Menu MnuRecordMacro - Caption = "Start recording" + Begin VB.Menu MnuMacroCreate + Caption = "From session history..." Index = 0 End - Begin VB.Menu MnuRecordMacro + Begin VB.Menu MnuMacroCreate + Caption = "-" + Index = 1 + End + Begin VB.Menu MnuMacroCreate + Caption = "Start recording" + Index = 2 + End + Begin VB.Menu MnuMacroCreate Caption = "Stop recording..." Enabled = 0 'False - Index = 1 + Index = 3 End End Begin VB.Menu MnuTool @@ -1624,6 +1632,29 @@ Attribute m_MetadataTimer.VB_VarHelpID = -1 Private m_AllowedToReflowInterface As Boolean +Private Sub MnuMacroCreate_Click(Index As Integer) + + Select Case Index + + 'Create from session history + Case 0 + ShowPDDialog vbModal, FormMacroSession + + '(separator) + Case 1 + + 'Start recording + Case 2 + Process "Start macro recording", , , UNDO_Nothing + + 'Stop recording + Case 3 + Process "Stop macro recording", True + + End Select + +End Sub + Private Sub MnuTest_Click() 'Filters_Scientific.InternalFFTTest @@ -2374,22 +2405,6 @@ Private Sub mnuRecentMacros_Click(Index As Integer) End Sub -Private Sub MnuRecordMacro_Click(Index As Integer) - - Select Case Index - - 'Start recording - Case 0 - Process "Start macro recording", , , UNDO_Nothing - - 'Stop recording - Case 1 - Process "Stop macro recording", True - - End Select - -End Sub - Private Sub MnuView_Click(Index As Integer) Select Case Index @@ -4137,7 +4152,7 @@ Private Sub mnuTool_Click(Index As Integer) '(separator) Case 4 - 'Record macro (top-level) + 'Create macro (top-level) Case 5 'Play saved macro diff --git a/Forms/Tools_MacroSession.frm b/Forms/Tools_MacroSession.frm new file mode 100644 index 0000000000..981732dfec --- /dev/null +++ b/Forms/Tools_MacroSession.frm @@ -0,0 +1,307 @@ +VERSION 5.00 +Begin VB.Form FormMacroSession + BackColor = &H80000005& + BorderStyle = 4 'Fixed ToolWindow + Caption = " Create macro from session history" + ClientHeight = 8475 + ClientLeft = 45 + ClientTop = 285 + ClientWidth = 11790 + BeginProperty Font + Name = "Tahoma" + Size = 8.25 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + LinkTopic = "Form1" + MaxButton = 0 'False + MinButton = 0 'False + ScaleHeight = 565 + ScaleMode = 3 'Pixel + ScaleWidth = 786 + ShowInTaskbar = 0 'False + Begin PhotoDemon.pdListBoxOD lstStart + Height = 5055 + Left = 240 + TabIndex = 1 + Top = 240 + Width = 5415 + _ExtentX = 9551 + _ExtentY = 8916 + Caption = "first macro action" + End + Begin PhotoDemon.pdCommandBarMini cmdBar + Align = 2 'Align Bottom + Height = 735 + Left = 0 + TabIndex = 0 + Top = 7740 + Width = 11790 + _ExtentX = 20796 + _ExtentY = 1296 + DontAutoUnloadParent= -1 'True + End + Begin PhotoDemon.pdListBoxOD lstEnd + Height = 5055 + Left = 6120 + TabIndex = 2 + Top = 240 + Width = 5415 + _ExtentX = 9551 + _ExtentY = 8916 + Caption = "final macro action" + End +End +Attribute VB_Name = "FormMacroSession" +Attribute VB_GlobalNameSpace = False +Attribute VB_Creatable = False +Attribute VB_PredeclaredId = True +Attribute VB_Exposed = False +'*************************************************************************** +'Undo History dialog +'Copyright 2014-2018 by Tanner Helland +'Created: 14/July/14 +'Last updated: 22/May/16 +'Last update: overhaul UI to use new owner-drawn pdListBox +' +'This is a first draft of a functional Undo History browser for PD. Most applications provide this as a floating +' toolbar, but because that would require some complicated UI work (including integration into PD's window manager), +' I'm postponing such an implementation until after we've gotten the browser working first. +' +'All previous image states, including selections, are available for restoration. +' +'Obviously, this dialog interacts heavily with the pdUndo class, as only the undo manager has access to the full +' Undo/Redo stack, including detailed information like process IDs, Undo file types, etc. +' +'When the user selects a point for restoration, the Undo/Redo manager handles the actual work of restoring the image +' to that point. This dialog simply presents the list to the user, and returns a clicked index position to pdUndo. +' +'All source code in this file is licensed under a modified BSD license. This means you may use the code in your own +' projects IF you provide attribution. For more information, please visit https://photodemon.org/license/ +' +'*************************************************************************** + +Option Explicit + +'This array contains the contents of the current Undo stack, as copied from the pdUndo class +Private m_undoEntries() As PD_UndoEntry + +'Total number of Undo entries, and index of the current Undo entry (e.g. the current image state in the undo/redo chain). +Private m_numOfUndos As Long, m_curUndoIndex As Long + +'Height of each Undo content block +Private Const BLOCKHEIGHT As Long = 58 + +'Two font objects; one for names and one for descriptions. (Two are needed because they have different sizes and colors, +' and it is faster to cache these values rather than constantly recreating them on a single pdFont object.) +Private m_TitleFont As pdFont, m_DescriptionFont As pdFont + +'The size at which we render the thumbnail images +Private Const UNDO_THUMB_SMALL As Long = 48 + +Private Function GetStringForUndoType(ByVal typeOfUndo As PD_UndoType, Optional ByVal layerID As Long = 0) As String + + Dim newText As String + + Select Case typeOfUndo + + Case UNDO_Everything + newText = vbNullString + + Case UNDO_Image, UNDO_Image_VectorSafe, UNDO_ImageHeader + newText = vbNullString + + Case UNDO_Layer, UNDO_Layer_VectorSafe, UNDO_LayerHeader + If Not (pdImages(g_CurrentImage).GetLayerByID(layerID) Is Nothing) Then + newText = g_Language.TranslateMessage("layer: %1", pdImages(g_CurrentImage).GetLayerByID(layerID).GetLayerName()) + Else + newText = vbNullString + End If + + Case UNDO_Selection + newText = g_Language.TranslateMessage("selection shape shown") + + End Select + + GetStringForUndoType = newText + +End Function + +Private Sub cmdBar_OKClick() + + 'TODO! + +End Sub + +Private Sub Form_Load() + + 'Initialize a custom font object for undo action names + Set m_TitleFont = New pdFont + m_TitleFont.SetFontBold True + m_TitleFont.SetFontSize 12 + m_TitleFont.CreateFontObject + m_TitleFont.SetTextAlignment vbLeftJustify + + '...and a second custom font object for undo descriptions + Set m_DescriptionFont = New pdFont + m_DescriptionFont.SetFontBold False + m_DescriptionFont.SetFontSize 10 + m_DescriptionFont.CreateFontObject + m_DescriptionFont.SetTextAlignment vbLeftJustify + + 'Retrieve a copy of all Undo data from the current image's undo manager + pdImages(g_CurrentImage).UndoManager.CopyUndoStack m_numOfUndos, m_curUndoIndex, m_undoEntries + + 'Populate the owner-drawn listboxes with copies of the retrieved Undo data (including thumbnails) + Dim i As Long + + lstStart.ListItemHeight = Interface.FixDPI(BLOCKHEIGHT) + lstStart.SetAutomaticRedraws False + For i = 0 To m_numOfUndos - 1 + lstStart.AddItem , i + Next i + lstStart.SetAutomaticRedraws True, True + If (lstStart.ListCount > 1) Then lstStart.ListIndex = 1 Else lstStart.ListIndex = 0 + + lstEnd.ListItemHeight = Interface.FixDPI(BLOCKHEIGHT) + lstEnd.SetAutomaticRedraws False + For i = 0 To m_numOfUndos - 1 + lstEnd.AddItem , i + Next i + lstEnd.SetAutomaticRedraws True, True + lstEnd.ListIndex = m_curUndoIndex - 1 + + 'Apply translations and visual themes + ApplyThemeAndTranslations Me + +End Sub + +Private Sub Form_Unload(Cancel As Integer) + ReleaseFormTheming Me +End Sub + +Private Sub lstEnd_DrawListEntry(ByVal bufferDC As Long, ByVal itemIndex As Long, itemTextEn As String, ByVal itemIsSelected As Boolean, ByVal itemIsHovered As Boolean, ByVal ptrToRectF As Long) + + If (bufferDC = 0) Then Exit Sub + + 'Retrieve the boundary region for this list entry + Dim tmpRectF As RectF + CopyMemory ByVal VarPtr(tmpRectF), ByVal ptrToRectF, 16& + + Dim offsetY As Single, offsetX As Single + offsetX = tmpRectF.Left + offsetY = tmpRectF.Top + Interface.FixDPI(2) + + Dim linePadding As Long + linePadding = Interface.FixDPI(2) + + Dim mHeight As Single + + 'If this filter has been selected, draw the background with the system's current selection color + If itemIsSelected Then + m_TitleFont.SetFontColor g_Themer.GetGenericUIColor(UI_TextClickableSelected) + m_DescriptionFont.SetFontColor g_Themer.GetGenericUIColor(UI_TextClickableSelected) + Else + m_TitleFont.SetFontColor g_Themer.GetGenericUIColor(UI_TextClickableUnselected, , , itemIsHovered) + m_DescriptionFont.SetFontColor g_Themer.GetGenericUIColor(UI_TextClickableUnselected, , , itemIsHovered) + End If + + 'Prepare a title string (with an asterisk added to the "current" image state title) + Dim drawString As String + If (itemIndex + 1) = m_curUndoIndex Then drawString = "* " + drawString = drawString & CStr(itemIndex + 1) & " - " & g_Language.TranslateMessage(m_undoEntries(itemIndex).srcProcCall.pcID) + + 'Render the thumbnail for this entry, and note that the thumbnail is *not* guaranteed to be square. + + Dim thumbNewWidth As Long, thumbNewHeight As Long, thumbMax As Long + thumbMax = Interface.FixDPI(UNDO_THUMB_SMALL) + PDMath.ConvertAspectRatio m_undoEntries(itemIndex).thumbnailLarge.GetDIBWidth, m_undoEntries(itemIndex).thumbnailLarge.GetDIBHeight, thumbMax, thumbMax, thumbNewWidth, thumbNewHeight + GDI_Plus.GDIPlus_StretchBlt Nothing, offsetX + Interface.FixDPI(4) + (thumbMax - thumbNewWidth) \ 2, offsetY + (Interface.FixDPI(BLOCKHEIGHT) - thumbMax) \ 2 + (thumbMax - thumbNewHeight) \ 2, thumbNewWidth, thumbNewHeight, m_undoEntries(itemIndex).thumbnailLarge, 0, 0, m_undoEntries(itemIndex).thumbnailLarge.GetDIBWidth, m_undoEntries(itemIndex).thumbnailLarge.GetDIBHeight, , , bufferDC + + 'Figure out how much space the thumbnail has taken; we'll shift text to the left of this + Dim thumbWidth As Long + thumbWidth = offsetX + Interface.FixDPI(4) + Interface.FixDPI(UNDO_THUMB_SMALL) + + 'Render the title text + If (LenB(drawString) <> 0) Then + m_TitleFont.AttachToDC bufferDC + m_TitleFont.FastRenderText thumbWidth + Interface.FixDPI(16) + offsetX, offsetY + Interface.FixDPI(4), drawString + m_TitleFont.ReleaseFromDC + End If + + 'Below that, add the description text (if any) + drawString = GetStringForUndoType(m_undoEntries(itemIndex).srcProcCall.pcUndoType, m_undoEntries(itemIndex).undoLayerID) + + If (LenB(drawString) <> 0) Then + mHeight = m_TitleFont.GetHeightOfString(drawString) + linePadding + m_DescriptionFont.AttachToDC bufferDC + m_DescriptionFont.FastRenderText thumbWidth + Interface.FixDPI(16) + offsetX, offsetY + Interface.FixDPI(4) + mHeight, drawString + m_DescriptionFont.ReleaseFromDC + End If + +End Sub + +Private Sub lstStart_DrawListEntry(ByVal bufferDC As Long, ByVal itemIndex As Long, itemTextEn As String, ByVal itemIsSelected As Boolean, ByVal itemIsHovered As Boolean, ByVal ptrToRectF As Long) + + If (bufferDC = 0) Then Exit Sub + + 'Retrieve the boundary region for this list entry + Dim tmpRectF As RectF + CopyMemory ByVal VarPtr(tmpRectF), ByVal ptrToRectF, 16& + + Dim offsetY As Single, offsetX As Single + offsetX = tmpRectF.Left + offsetY = tmpRectF.Top + Interface.FixDPI(2) + + Dim linePadding As Long + linePadding = Interface.FixDPI(2) + + Dim mHeight As Single + + 'If this filter has been selected, draw the background with the system's current selection color + If itemIsSelected Then + m_TitleFont.SetFontColor g_Themer.GetGenericUIColor(UI_TextClickableSelected) + m_DescriptionFont.SetFontColor g_Themer.GetGenericUIColor(UI_TextClickableSelected) + Else + m_TitleFont.SetFontColor g_Themer.GetGenericUIColor(UI_TextClickableUnselected, , , itemIsHovered) + m_DescriptionFont.SetFontColor g_Themer.GetGenericUIColor(UI_TextClickableUnselected, , , itemIsHovered) + End If + + 'Prepare a title string (with an asterisk added to the "current" image state title) + Dim drawString As String + If (itemIndex + 1) = m_curUndoIndex Then drawString = "* " + drawString = drawString & CStr(itemIndex + 1) & " - " & g_Language.TranslateMessage(m_undoEntries(itemIndex).srcProcCall.pcID) + + 'Render the thumbnail for this entry, and note that the thumbnail is *not* guaranteed to be square. + + Dim thumbNewWidth As Long, thumbNewHeight As Long, thumbMax As Long + thumbMax = Interface.FixDPI(UNDO_THUMB_SMALL) + PDMath.ConvertAspectRatio m_undoEntries(itemIndex).thumbnailLarge.GetDIBWidth, m_undoEntries(itemIndex).thumbnailLarge.GetDIBHeight, thumbMax, thumbMax, thumbNewWidth, thumbNewHeight + GDI_Plus.GDIPlus_StretchBlt Nothing, offsetX + Interface.FixDPI(4) + (thumbMax - thumbNewWidth) \ 2, offsetY + (Interface.FixDPI(BLOCKHEIGHT) - thumbMax) \ 2 + (thumbMax - thumbNewHeight) \ 2, thumbNewWidth, thumbNewHeight, m_undoEntries(itemIndex).thumbnailLarge, 0, 0, m_undoEntries(itemIndex).thumbnailLarge.GetDIBWidth, m_undoEntries(itemIndex).thumbnailLarge.GetDIBHeight, , , bufferDC + + 'Figure out how much space the thumbnail has taken; we'll shift text to the left of this + Dim thumbWidth As Long + thumbWidth = offsetX + Interface.FixDPI(4) + Interface.FixDPI(UNDO_THUMB_SMALL) + + 'Render the title text + If (LenB(drawString) <> 0) Then + m_TitleFont.AttachToDC bufferDC + m_TitleFont.FastRenderText thumbWidth + Interface.FixDPI(16) + offsetX, offsetY + Interface.FixDPI(4), drawString + m_TitleFont.ReleaseFromDC + End If + + 'Below that, add the description text (if any) + drawString = GetStringForUndoType(m_undoEntries(itemIndex).srcProcCall.pcUndoType, m_undoEntries(itemIndex).undoLayerID) + + If (LenB(drawString) <> 0) Then + mHeight = m_TitleFont.GetHeightOfString(drawString) + linePadding + m_DescriptionFont.AttachToDC bufferDC + m_DescriptionFont.FastRenderText thumbWidth + Interface.FixDPI(16) + offsetX, offsetY + Interface.FixDPI(4) + mHeight, drawString + m_DescriptionFont.ReleaseFromDC + End If + +End Sub + diff --git a/Modules/BatchProcessor.bas b/Modules/BatchProcessor.bas index 07bb87d9fc..9946fde70d 100644 --- a/Modules/BatchProcessor.bas +++ b/Modules/BatchProcessor.bas @@ -223,14 +223,14 @@ Private Sub UpdateMacroUI(ByVal recordingIsActive As Boolean) toolbar_Toolbox.lblRecording.Visible = True 'Disable "start recording", and enable "stop recording" - FormMain.MnuRecordMacro(0).Enabled = False - FormMain.MnuRecordMacro(1).Enabled = True + FormMain.MnuMacroCreate(2).Enabled = False + FormMain.MnuMacroCreate(3).Enabled = True Else Message "Macro recording stopped." toolbar_Toolbox.lblRecording.Visible = False - FormMain.MnuRecordMacro(0).Enabled = True - FormMain.MnuRecordMacro(1).Enabled = False + FormMain.MnuMacroCreate(2).Enabled = True + FormMain.MnuMacroCreate(3).Enabled = False End If End Sub diff --git a/Modules/Interface.bas b/Modules/Interface.bas index c07e4d81ae..9f6148847c 100644 --- a/Modules/Interface.bas +++ b/Modules/Interface.bas @@ -20,7 +20,7 @@ Attribute VB_Name = "Interface" Option Explicit -Private Declare Function GetCursorPos Lib "user32" (ByRef lpPoint As POINTAPI) As Long +Private Declare Function GetCursorPos Lib "user32" (ByRef lpPoint As PointAPI) As Long Private Declare Function GetWindowRect Lib "user32" (ByVal hWnd As Long, ByRef lpRect As winRect) As Long Private Declare Function MoveWindow Lib "user32" (ByVal hWnd As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal bRepaint As Long) As Long @@ -1586,7 +1586,7 @@ Public Sub EnableUserInput() ' still lies over the canvas. (The likelihood of movement, especially between paint ops, is high, ' and if we don't do this, the mouse cursor won't reflect any position updates that have occurred since ' the last action was started.) - Dim tmpPoint As POINTAPI, mouseMustBeFaked As Boolean + Dim tmpPoint As PointAPI, mouseMustBeFaked As Boolean If (GetCursorPos(tmpPoint) <> 0) Then mouseMustBeFaked = FormMain.MainCanvas(0).IsScreenCoordInsideCanvasView(tmpPoint.x, tmpPoint.y) '*WHILE THE MAIN FORM IS STILL DISABLED*, flush the keyboard/mouse queue. (This prevents any stray diff --git a/Modules/Menus.bas b/Modules/Menus.bas index cd6235468d..358a626fc9 100644 --- a/Modules/Menus.bas +++ b/Modules/Menus.bas @@ -469,9 +469,11 @@ Public Sub InitializeMenus() AddMenuItem "-", "-", 7, 2 AddMenuItem "Theme...", "tools_theme", 7, 3 AddMenuItem "-", "-", 7, 4 - AddMenuItem "Record macro", "tools_macrotop", 7, 5, , "macro_record" - AddMenuItem "Start recording", "tools_recordmacro", 7, 5, 0, "macro_record" - AddMenuItem "Stop recording...", "tools_stopmacro", 7, 5, 1, "macro_stop" + AddMenuItem "Create macro", "tools_macrocreatetop", 7, 5 + AddMenuItem "From history...", "tools_macrofromhistory", 7, 5, 0, "edit_history" + AddMenuItem "-", "-", 7, 5, 1 + AddMenuItem "Start recording", "tools_recordmacro", 7, 5, 2, "macro_record" + AddMenuItem "Stop recording...", "tools_stopmacro", 7, 5, 3, "macro_stop" AddMenuItem "Play macro...", "tools_playmacro", 7, 6, , "macro_play" AddMenuItem "Recent macros", "tools_recentmacros", 7, 7 AddMenuItem "-", "-", 7, 8 diff --git a/PhotoDemon.vbp b/PhotoDemon.vbp index 5089efb374..47cb0387d7 100644 --- a/PhotoDemon.vbp +++ b/PhotoDemon.vbp @@ -394,6 +394,7 @@ Form=Forms\Tools_PluginManager.frm Form=Forms\Tools_ThemeEditor.frm Form=Forms\File_Export_Palette.frm ResFile32="Resources\PD_icons.RES" +Form=Forms\Tools_MacroSession.frm IconForm="FormMain" Startup="Sub Main" HelpFile="" @@ -407,7 +408,7 @@ Description="PhotoDemon Photo Editor" CompatibleMode="0" MajorVer=7 MinorVer=1 -RevisionVer=595 +RevisionVer=598 AutoIncrementVer=1 ServerSupportFiles=0 VersionComments="Copyright 2000-2018 Tanner Helland - photodemon.org"