diff --git a/README.md b/README.md index b35c5e6..3468269 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ **[Video overview - v.2.2](https://youtu.be/30dyXAs-m1A)** -# Scxml Editor 2.5.4 +# Scxml Editor 2.5.5 Powerful tool for creating, editing and debugging SCXML charts. ![MainExample](Images/Inheritance_TV_example.gif) @@ -24,6 +24,7 @@ Powerful tool for creating, editing and debugging SCXML charts. [![Discord](Images/Discord.svg)](https://discord.gg/5XWDsbEXzn) ### Changelog +**2.5.5:** Chart design panel view presets
**2.5.4:** Nested initial state indication
**2.5.3:** Chart Draw Constraints, Select Chart Elements
**2.5.1:** [Fast Triggers](Doc/DebugScxmlStateCharts.md#transition-triggers)
@@ -52,7 +53,7 @@ Powerful tool for creating, editing and debugging SCXML charts. ## Installation You can find portable version as attached Zip in ScxmlEditor Github Release page -Latest version: **[2.5.4.1769]** +Latest version: **[2.5.5.1755]** ### Windows Installation #### First Install diff --git a/Src/CommonConsts.h b/Src/CommonConsts.h index a3696af..0043deb 100644 --- a/Src/CommonConsts.h +++ b/Src/CommonConsts.h @@ -42,6 +42,7 @@ #define WM_SCXML_DELETE_TREE_SHAPE WM_USER+106 #define WM_SCXML_ADD_OR_OPEN_EXISTING_UNIT WM_USER+107 #define WM_SCXML_UPDATE_DBG_MSG_QUEUE WM_USER+108 +#define WM_SCXML_EDIT_TREE_SHAPE WM_USER+109 #include @@ -94,4 +95,10 @@ struct INTERPROCESS_COPYDATA wchar_t wchArg3[SCXML_INTERPROCESS_BUFFER_SIZE]; }; + +#define SET_PROPERTY_MIN(X, TYPE, MIN) void __fastcall Set##X(TYPE val) { if (val>=MIN) F##X=val;} +#define SET_PROPERTY_MAX(X, TYPE, MAX) void __fastcall Set##X(TYPE val) { if (val<=MAX) F##X=val;} +#define SET_PROPERTY_RANGE(X, TYPE, MIN, MAX) void __fastcall Set##X(TYPE val) { if (val>=MIN && val<=MAX) F##X=val;} + + #endif diff --git a/Src/ScxmlEditor.cbproj b/Src/ScxmlEditor.cbproj index 47c6a73..d7ff8ba 100644 --- a/Src/ScxmlEditor.cbproj +++ b/Src/ScxmlEditor.cbproj @@ -1015,13 +1015,13 @@ alexander.zhornyak@gmail.com Scxml State Charts Editor - 2.5.4.1769 + 2.5.5.1755 alexander.zhornyak@gmail.com ScxmlEditor - 2.5.4.0 + 2.5.5 diff --git a/Src/ScxmlEditor.res b/Src/ScxmlEditor.res index 075b3b0..6643cd1 100644 Binary files a/Src/ScxmlEditor.res and b/Src/ScxmlEditor.res differ diff --git a/Src/ScxmlEditor_resources.rc b/Src/ScxmlEditor_resources.rc index e0aceaf..8878f79 100644 --- a/Src/ScxmlEditor_resources.rc +++ b/Src/ScxmlEditor_resources.rc @@ -1,40 +1,40 @@ -PngFinalize RCData "Images\\finalize_16_16.png" -PngForeach RCData "Images\\foreach_16_16.png" -CompleteBasic RCData "complete_basic.lua" -PngDatamodel RCData "Images\\datamodel_16_16.png" -PngVirtualFolder RCData "Images\\virtual_folder_16_16.png" +PngIf RCData "Images\\if_16_16.png" +CompleteCPP RCData "complete_all_CPP.txt" +PngLog RCData "Images\\log_16_16.png" +PngError RCData "Images\\error_16.png" +PngWatch RCData "Images\\watch_16_16.png" +PngData RCData "Images\\data_16_16.png" +PngAssign RCData "Images\\assign_16_16.png" +PngParam RCData "Images\\param_16_16.png" +PngSessionState RCData "Images\\statemachine_16_16.png" +PngProtocol RCData "Images\\protocol_16_16.png" +PngTransitionXML RCData "Images\\XMLText_Transition_16.png" +CompletePython RCData "complete_all_python.txt" +CompleteDebug RCData "complete_debug.lua" +PngTrigger RCData "Images\\trigger_16_16.png" +ResLogProperties RCData "ScxmlEditor.properties" +PngScript RCData "Images\\script_16_16.png" +PngCancel RCData "Images\\cancel_16_16.png" +CompleteString RCData "complete_string.lua" +PngProtocolWeak RCData "Images\\protocol_weak_16_16.png" PngSend RCData "Images\\send_16_16.png" +PngVirtualFolder RCData "Images\\virtual_folder_16_16.png" PngComment RCData "Images\\comment_16_16.png" PngRaise RCData "Images\\raise_16_16.png" -PngExtraContent RCData "Images\\extracontent_16_16.png" -CompleteTable RCData "complete_table.lua" +CompleteBasic RCData "complete_basic.lua" +PngDatamodel RCData "Images\\datamodel_16_16.png" CompleteEcmascript RCData "complete_all_js.txt" CompleteUtf8 RCData "complete_utf8.lua" -PngOnExit RCData "Images\\onexit_16_16.png" -PngDoneData RCData "Images\\donedata_16_16.png" -CompleteOs RCData "complete_os.lua" -PngInvoke RCData "Images\\invoke_16_16.png" -PngSetValue RCData "Images\\setvalue_16_16.png" +PngExtraContent RCData "Images\\extracontent_16_16.png" +CompleteTable RCData "complete_table.lua" +PngForeach RCData "Images\\foreach_16_16.png" +PngFinalize RCData "Images\\finalize_16_16.png" PngOnEntry RCData "Images\\onenter_16_16.png" -PngContent RCData "Images\\content_16_16.png" -ResCurPan Cursor "Images\\PanningCursor.cur" +PngSetValue RCData "Images\\setvalue_16_16.png" +PngInvoke RCData "Images\\invoke_16_16.png" CompleteMath RCData "complete_math.lua" -PngData RCData "Images\\data_16_16.png" -PngAssign RCData "Images\\assign_16_16.png" -PngProtocol RCData "Images\\protocol_16_16.png" -PngParam RCData "Images\\param_16_16.png" -PngSessionState RCData "Images\\statemachine_16_16.png" -CompleteCPP RCData "complete_all_CPP.txt" -PngIf RCData "Images\\if_16_16.png" -PngError RCData "Images\\error_16.png" -PngWatch RCData "Images\\watch_16_16.png" -PngLog RCData "Images\\log_16_16.png" -CompleteString RCData "complete_string.lua" -PngCancel RCData "Images\\cancel_16_16.png" -PngProtocolWeak RCData "Images\\protocol_weak_16_16.png" -ResLogProperties RCData "ScxmlEditor.properties" -PngScript RCData "Images\\script_16_16.png" -PngTrigger RCData "Images\\trigger_16_16.png" -PngTransitionXML RCData "Images\\XMLText_Transition_16.png" -CompleteDebug RCData "complete_debug.lua" -CompletePython RCData "complete_all_python.txt" +ResCurPan Cursor "Images\\PanningCursor.cur" +PngContent RCData "Images\\content_16_16.png" +PngDoneData RCData "Images\\donedata_16_16.png" +CompleteOs RCData "complete_os.lua" +PngOnExit RCData "Images\\onexit_16_16.png" diff --git a/Src/TreeEditor/TreeEditorEx.cpp b/Src/TreeEditor/TreeEditorEx.cpp index 3af84e7..e8bce6d 100644 --- a/Src/TreeEditor/TreeEditorEx.cpp +++ b/Src/TreeEditor/TreeEditorEx.cpp @@ -1261,8 +1261,6 @@ void __fastcall TTreeEditorEx::TheTreeKeyDown(System::TObject* Sender, System::W // стираем временный прямоугольник ForceResetTemporarySelected(); - bool bNeedToDeleteFullScreenForm = false; - switch(Key) { case VK_BACK: { if (Shift == Classes::TShiftState() << ssCtrl) { @@ -1480,33 +1478,53 @@ void __fastcall TTreeEditorEx::TheTreeKeyDown(System::TObject* Sender, System::W } }break; case VK_F12: { - if (!FFullScreenForm) { - FFullScreenForm = new TForm(this->Owner); - FFullScreenForm->BorderStyle = bsNone; - FFullScreenForm->WindowState = wsMaximized; - this->TheTree->Parent = FFullScreenForm; - - FFullScreenForm->OnCloseQuery = OnFullScreenFormCloseQuery; - FFullScreenForm->Show(); - } - else { - bNeedToDeleteFullScreenForm = true; - } + ToggleFullScreenMode(); }break; case VK_ESCAPE: { - bNeedToDeleteFullScreenForm = true; + ExitFullScreenMode(); }break; } +} + +// --------------------------------------------------------------------------- +void __fastcall TTreeEditorEx::EnterFullScreenMode(void) { + if (!FFullScreenForm) { + FFullScreenForm = new TForm(this->Owner); + FFullScreenForm->BorderStyle = bsNone; + FFullScreenForm->WindowState = wsMaximized; + this->TheTree->Parent = FFullScreenForm; + + FFullScreenForm->OnCloseQuery = OnFullScreenFormCloseQuery; + FFullScreenForm->Show(); + } +} - if (bNeedToDeleteFullScreenForm) { - if (FFullScreenForm) { +// --------------------------------------------------------------------------- +void __fastcall TTreeEditorEx::ExitFullScreenMode(void) { + if (FFullScreenForm) { + try { this->TheTree->Parent = PanelTree; delete FFullScreenForm; FFullScreenForm = NULL; + + this->TheTree->SetFocus(); + } + catch(Exception * E) { + LOG_ERROR(LOG_ERROR_MSG); } } } +// --------------------------------------------------------------------------- +void __fastcall TTreeEditorEx::ToggleFullScreenMode(void) { + if (!FFullScreenForm) { + EnterFullScreenMode(); + } + else { + ExitFullScreenMode(); + } +} + // --------------------------------------------------------------------------- void __fastcall TTreeEditorEx::NodeTreeKeyDown(System::TObject* Sender, System::Word &Key, Classes::TShiftState Shift) { try { @@ -1634,6 +1652,9 @@ void __fastcall TTreeEditorEx::NodeTreeKeyDown(System::TObject* Sender, System:: // --------------------------------------------------------------------------- void __fastcall TTreeEditorEx::TheTreeKeyUp(System::TObject* Sender, System::Word &Key, Classes::TShiftState Shift) { +#if 0 + WLOG_DEBUG(L"TheTreeKeyUp: Key:%d Shift:%d", Key, Shift.ToInt()); +#endif switch(Key) { case VK_DOWN: { @@ -1888,25 +1909,15 @@ void __fastcall TTreeEditorEx::TheTreeMouseUp(System::TObject* Sender, Controls: // --------------------------------------------------------------------------- void __fastcall TTreeEditorEx::OnConnectionReconnected(TTreeConnection *AConnection) { - + // XXX: } // --------------------------------------------------------------------------- void MoveShapeWithMovingLayout(Teetree::TTreeNodeShape* Sender, const int DeltaX, const int DeltaY, - std::set &AConnections) { + std::set &AConnections, bool bIsPrimary) { if (Sender && Sender->Parent) { - - /* This callback is called for every shape in the selection, so we should handle only the first one */ - int iSelIndex = -1; - int iShapeSelIndex = -1; - for (int i = 0; i < Sender->Parent->Children->Count; i++) { TTreeNodeShape *AChildShape = Sender->Parent->Children->Items[i]; - - if (AChildShape->Selected) { - iSelIndex++; - } - if (AChildShape != Sender) { if (DeltaY > 0) { if (AChildShape->Y0 > Sender->Y1 - DeltaY) { @@ -1936,12 +1947,9 @@ void MoveShapeWithMovingLayout(Teetree::TTreeNodeShape* Sender, const int DeltaX AConnections.insert(AChildShape->Connections->Items[k]); } } - else { - iShapeSelIndex = iSelIndex; - } } - if (iShapeSelIndex == 0) { + if (bIsPrimary) { if (DeltaX < 0) { const int iNewX = Sender->Parent->X0 + DeltaX; if (iNewX > 0) { @@ -1965,7 +1973,7 @@ void MoveShapeWithMovingLayout(Teetree::TTreeNodeShape* Sender, const int DeltaX AConnections.insert(Sender->Parent->Connections->Items[k]); } - MoveShapeWithMovingLayout(Sender->Parent, DeltaX, DeltaY, AConnections); + MoveShapeWithMovingLayout(Sender->Parent, DeltaX, DeltaY, AConnections, bIsPrimary); } } } @@ -1979,7 +1987,8 @@ void __fastcall TTreeEditorEx::TheTreeMovingShape(Teetree::TTreeNodeShape* Sende if (IsShiftPressed() && !IsAltPressed() && !IsControlPressed()) { std::setAConnections; - MoveShapeWithMovingLayout(Sender, DeltaX, DeltaY, AConnections); + const bool bIsPrimary = GetSafeTreeListFirst(TheTree->Selected->Shapes) == Sender; + MoveShapeWithMovingLayout(Sender, DeltaX, DeltaY, AConnections, bIsPrimary); for (std::set::iterator it = AConnections.begin(); it != AConnections.end(); ++it) { Editorutils::AdjustSidesConnection(*it); } @@ -1988,20 +1997,11 @@ void __fastcall TTreeEditorEx::TheTreeMovingShape(Teetree::TTreeNodeShape* Sende // --------------------------------------------------------------------------- void ResizeShapeWithMovingLayout(Teetree::TTreeNodeShape* Sender, const int DeltaX, const int DeltaY, - std::set &AConnections) { + std::set &AConnections, bool bIsPrimary) { if (Sender && Sender->Parent) { - /* This callback is called for every shape in the selection, so we should handle only the first one */ - int iSelIndex = -1; - int iShapeSelIndex = -1; - for (int i = 0; i < Sender->Parent->Children->Count; i++) { TTreeNodeShape *AChildShape = Sender->Parent->Children->Items[i]; - - if (AChildShape->Selected) { - iSelIndex++; - } - if (AChildShape != Sender) { if (DeltaY != 0) { if (AChildShape->Y0 > Sender->Y1 - DeltaY /* край на момент сдвига */ ) { @@ -2019,12 +2019,9 @@ void ResizeShapeWithMovingLayout(Teetree::TTreeNodeShape* Sender, const int Delt AConnections.insert(AChildShape->Connections->Items[k]); } } - else { - iShapeSelIndex = iSelIndex; - } } - if (iShapeSelIndex == 0) { + if (bIsPrimary) { Sender->Parent->X1 = Sender->Parent->X1 + DeltaX; Sender->Parent->Y1 = Sender->Parent->Y1 + DeltaY; @@ -2032,7 +2029,7 @@ void ResizeShapeWithMovingLayout(Teetree::TTreeNodeShape* Sender, const int Delt AConnections.insert(Sender->Parent->Connections->Items[k]); } - ResizeShapeWithMovingLayout(Sender->Parent, DeltaX, DeltaY, AConnections); + ResizeShapeWithMovingLayout(Sender->Parent, DeltaX, DeltaY, AConnections, bIsPrimary); } } } @@ -2049,7 +2046,8 @@ void __fastcall TTreeEditorEx::TheTreeResizingShape(Teetree::TTreeNodeShape* Sen if (IsShiftPressed() && !IsAltPressed()) { std::setAConnections; - ResizeShapeWithMovingLayout(Sender, DeltaX, DeltaY, AConnections); + const bool bIsPrimary = GetSafeTreeListFirst(TheTree->Selected->Shapes) == Sender; + ResizeShapeWithMovingLayout(Sender, DeltaX, DeltaY, AConnections, bIsPrimary); for (std::set::iterator it = AConnections.begin(); it != AConnections.end(); ++it) { Editorutils::AdjustSidesConnection(*it); } diff --git a/Src/TreeEditor/TreeEditorEx.h b/Src/TreeEditor/TreeEditorEx.h index f0e06fd..45bd682 100644 --- a/Src/TreeEditor/TreeEditorEx.h +++ b/Src/TreeEditor/TreeEditorEx.h @@ -309,6 +309,10 @@ class TTreeEditorEx : public TTreeEditorNew void __fastcall InvalidateTheTreeWithTemp(void); void __fastcall RefreshTheTreeWithTemp(void); + void __fastcall EnterFullScreenMode(void); + void __fastcall ExitFullScreenMode(void); + void __fastcall ToggleFullScreenMode(void); + __property TTreeEditWindows HideWindowsStatus = {read=GetHideWindowsStatus}; __published: diff --git a/Src/UnitScxmlBaseShape.cpp b/Src/UnitScxmlBaseShape.cpp index 73a588d..4bcfc7e 100644 --- a/Src/UnitScxmlBaseShape.cpp +++ b/Src/UnitScxmlBaseShape.cpp @@ -1728,6 +1728,51 @@ void __fastcall TVisualScxmlBaseShape::SetIsInitial(bool val) { } } +// --------------------------------------------------------------------------- +bool __fastcall TVisualScxmlBaseShape::GetIsInitialDeep(void) { + TVisualScxmlBaseShape *AVisualParent = dynamic_cast(this->Parent); + while (AVisualParent) { + const bool bIsInitial = !AVisualParent->FInitial.IsEmpty() && (AVisualParent->FInitial == this->SimpleText); + if (bIsInitial) { + return true; + } + AVisualParent = dynamic_cast(AVisualParent->Parent); + } + return false; +} + +// --------------------------------------------------------------------------- +void __fastcall TVisualScxmlBaseShape::SetIsInitialDeep(bool val) { + bool bNeedToRedraw = false; + TVisualScxmlBaseShape *AVisualParent = dynamic_cast(this->Parent); + if (AVisualParent) { + if (val) { + if (AVisualParent->FInitial != this->SimpleText) { + AVisualParent->Initial = this->SimpleText; + bNeedToRedraw = true; + } + } + else if (AVisualParent->FInitial == this->SimpleText) { + AVisualParent->Initial = L""; + bNeedToRedraw = true; + } + + AVisualParent = dynamic_cast(AVisualParent->Parent); + while (AVisualParent) { + if (AVisualParent->FInitial == this->SimpleText) { + AVisualParent->Initial = L""; + bNeedToRedraw = true; + } + AVisualParent = dynamic_cast(AVisualParent->Parent); + } + } + + // иначе будет access violation + if (!this->ComponentState.Contains(csReading) && !this->ComponentState.Contains(csLoading) && bNeedToRedraw) { + this->Draw(); + } +} + // --------------------------------------------------------------------------- void __fastcall TVisualScxmlBaseShape::SetStateId(UnicodeString sVal) { // эта нода была initial до этого @@ -2075,7 +2120,7 @@ void __fastcall TVisualScxmlBaseShape::DrawShapeCanvas(Tecanvas::TCanvas3D * ACa std::auto_ptrAInitialList(new TStringList); AInitialList->StrictDelimiter = true; AInitialList->Delimiter = L' '; - AInitialList->DelimitedText = AVisualUpperParent->FInitial; + AInitialList->DelimitedText = AVisualUpperParent->FInitial; if (AInitialList->IndexOf(this->SimpleText) != -1) { bIsNestedInitial = true; } @@ -2168,8 +2213,8 @@ void __fastcall TVisualScxmlBaseShape::SetDefaultSize() { SetNormalAppearance(); - Width = 100; - Height = 50; + Width = SettingsData->ThemeSettings->StateDefaultWidth; + Height = SettingsData->ThemeSettings->StateDefaultHeight; } // --------------------------------------------------------------------------- diff --git a/Src/UnitScxmlBaseShape.h b/Src/UnitScxmlBaseShape.h index 9d26eb4..6199127 100644 --- a/Src/UnitScxmlBaseShape.h +++ b/Src/UnitScxmlBaseShape.h @@ -448,6 +448,9 @@ class TVisualScxmlBaseShape : public TScxmlBaseShape { bool __fastcall GetIsInitial(void); void __fastcall SetIsInitial(bool val); + bool __fastcall GetIsInitialDeep(void); + void __fastcall SetIsInitialDeep(bool val); + virtual void __fastcall SetEntered(bool val); virtual void __fastcall SetExamined(bool val); virtual void __fastcall SetBreakpointSet(bool val); @@ -515,6 +518,7 @@ class TVisualScxmlBaseShape : public TScxmlBaseShape { __property bool Examined = {read=FExamined, write=SetExamined, default=false}; __property bool BreakpointSet = {read=FBreakpointSet, write=SetBreakpointSet, default=false}; __property bool IsInitial = {read=GetIsInitial,write=SetIsInitial}; + __property bool IsInitialDeep = {read=GetIsInitialDeep,write=SetIsInitialDeep}; __property UnicodeString Initial = {read=GetInitial, write=FInitial}; __property int ParentOffsetX = { read=GetParentOffsetX }; __property int ParentOffsetY = { read=GetParentOffsetY }; diff --git a/Src/UnitSettingsEditor.cpp b/Src/UnitSettingsEditor.cpp index 11a5e4b..0309dd1 100644 --- a/Src/UnitSettingsEditor.cpp +++ b/Src/UnitSettingsEditor.cpp @@ -1,34 +1,34 @@ -/*********************************************************************************** - BSD 3-Clause License - - Copyright (c) 2018, https://github.com/alexzhornyak - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - * Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -***************************************************************************************/ +/** ********************************************************************************* +BSD 3-Clause License + +Copyright (c) 2018, https://github.com/alexzhornyak +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + + * Neither the name of the copyright holder nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ************************************************************************************** */ #include #pragma hdrstop @@ -51,8 +51,8 @@ #pragma resource "*.dfm" // --------------------------------------------------------------------------- -__fastcall TFormSettingsEditor::TFormSettingsEditor(TComponent* Owner, TPersistent *APersistent) : TForm(Owner), FPersistent(APersistent), -m_b_modified(false) { +__fastcall TFormSettingsEditor::TFormSettingsEditor(TComponent* Owner, TPersistent *APersistent) : TForm(Owner), +FPersistent(APersistent), m_b_modified(false) { if (!FPersistent) throw Exception("Can not edit NULL object!"); @@ -101,7 +101,8 @@ void __fastcall TFormSettingsEditor::FormCloseQuery(TObject *Sender, bool &CanCl if (m_b_modified) { String Caption = "WARNING!"; String Text = "Settings are modified! Are you sure to quit?"; - CanClose = Application->MessageBoxA(Text.c_str(), Caption.c_str(), MB_OKCANCEL | MB_ICONWARNING | MB_DEFBUTTON2) == IDOK; + CanClose = Application->MessageBoxA(Text.c_str(), Caption.c_str(), + MB_OKCANCEL | MB_ICONWARNING | MB_DEFBUTTON2) == IDOK; } } // --------------------------------------------------------------------------- @@ -192,7 +193,7 @@ void __fastcall TFormSettingsEditor::ActionResetToDefaultExecute(TObject *Sender } } -//--------------------------------------------------------------------------- +// --------------------------------------------------------------------------- void __fastcall TFormSettingsEditor::ActionResetSelectedToDefaultExecute(TObject *Sender) { if (PropSettingsInspector->ActiveItem) { @@ -220,31 +221,32 @@ void __fastcall TFormSettingsEditor::ActionResetSelectedToDefaultExecute(TObject } } -//--------------------------------------------------------------------------- -void __fastcall TFormSettingsEditor::PropSettingsInspectorFilterProp(TObject *Sender, TPersistent *AInstance, ILMDProperty *APropInfo, - bool AIsSubProp, bool &AIncludeProp) { +// --------------------------------------------------------------------------- +void __fastcall TFormSettingsEditor::PropSettingsInspectorFilterProp(TObject *Sender, TPersistent *AInstance, + ILMDProperty *APropInfo, bool AIsSubProp, bool &AIncludeProp) { Propinspext::PropSettingsInspectorFilterProp(Sender, AInstance, APropInfo, AIsSubProp, AIncludeProp); } -//--------------------------------------------------------------------------- -void __fastcall TFormSettingsEditor::PropSettingsInspectorGetCaptionColor(TObject *Sender, TLMDPropertyInspectorItem *AItem, - TColor &AColor) { +// --------------------------------------------------------------------------- +void __fastcall TFormSettingsEditor::PropSettingsInspectorGetCaptionColor(TObject *Sender, + TLMDPropertyInspectorItem *AItem, TColor &AColor) { Propinspext::PropSettingsInspectorGetCaptionColor(Sender, AItem, AColor); } -//--------------------------------------------------------------------------- +// --------------------------------------------------------------------------- -void __fastcall TFormSettingsEditor::PropSettingsInspectorGetEditorClass(TObject *Sender, TPersistent *AInstance, ILMDProperty *APropInfo, - TLMDPropEditorClass &AEditorClass) { +void __fastcall TFormSettingsEditor::PropSettingsInspectorGetEditorClass(TObject *Sender, TPersistent *AInstance, + ILMDProperty *APropInfo, TLMDPropEditorClass &AEditorClass) { Propinspext::PropSettingsInspectorGetEditorClass(Sender, AInstance, APropInfo, AEditorClass); } -//--------------------------------------------------------------------------- -void __fastcall TFormSettingsEditor::SelectItemOrRestoreState(const UnicodeString &sItemName, TLMDPropPageStateObject *APropStateObject) { +// --------------------------------------------------------------------------- +void __fastcall TFormSettingsEditor::SelectItemOrRestoreState(const UnicodeString &sItemName, + TLMDPropPageStateObject *APropStateObject) { if (!sItemName.IsEmpty()) { std::auto_ptrAStringListPtr(new TStringList()); AStringListPtr->Delimiter = L'.'; @@ -254,9 +256,11 @@ void __fastcall TFormSettingsEditor::SelectItemOrRestoreState(const UnicodeStrin TLMDPropertyInspectorItem* AItem = NULL; for (int i = 0; i < AStringListPtr->Count; i++) { - AItem = i == 0 ? this->PropSettingsInspector->Items->Find(AStringListPtr->Strings[i]) : AItem->Find(AStringListPtr->Strings[i]); + AItem = i == 0 ? this->PropSettingsInspector->Items->Find(AStringListPtr->Strings[i]) : AItem->Find + (AStringListPtr->Strings[i]); if (!AItem) { - WLOG_WARNING(L"Can not find property item:[%s]. Full path:[%s]", AStringListPtr->Strings[i].c_str(), sItemName.c_str()); + WLOG_WARNING(L"Can not find property item:[%s]. Full path:[%s]", AStringListPtr->Strings[i].c_str(), + sItemName.c_str()); break; // надо обязательно выйти, так как вверху без проверки используется AItem } else { @@ -274,6 +278,14 @@ void __fastcall TFormSettingsEditor::SelectItemOrRestoreState(const UnicodeStrin this->PropSettingsInspector->RestoreState(APropStateObject, false); } } + + // HACK: scroll can be broken if there are no active items yet + if (!this->PropSettingsInspector->ActiveItem) { + for (int i = 0; i < this->PropSettingsInspector->Items->Count; i++) { + this->PropSettingsInspector->Items->Items[i]->Active = true; + break; + } + } } -//--------------------------------------------------------------------------- +// --------------------------------------------------------------------------- diff --git a/Src/UnitSettingsEditor.dfm b/Src/UnitSettingsEditor.dfm index b283901..d2fe8f5 100644 --- a/Src/UnitSettingsEditor.dfm +++ b/Src/UnitSettingsEditor.dfm @@ -338,7 +338,7 @@ object FormSettingsEditor: TFormSettingsEditor Left = 328 Top = 272 Bitmap = { - 494C01010C001800640010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 + 494C01010C001800680010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 0000000000003600000028000000400000004000000001002000000000000040 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 diff --git a/Src/UnitSyntaxEditorForm.dfm b/Src/UnitSyntaxEditorForm.dfm index 48b57ee..1c042f1 100644 --- a/Src/UnitSyntaxEditorForm.dfm +++ b/Src/UnitSyntaxEditorForm.dfm @@ -125,7 +125,7 @@ object FormSyntaxEditorForm: TFormSyntaxEditorForm Left = 40 Top = 152 Bitmap = { - 494C0101220040003C0110001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 + 494C010122004000440110001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 0000000000003600000028000000400000009000000001002000000000000090 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 diff --git a/Src/UnitSyntaxUtils.cpp b/Src/UnitSyntaxUtils.cpp index 793f722..309e52a 100644 --- a/Src/UnitSyntaxUtils.cpp +++ b/Src/UnitSyntaxUtils.cpp @@ -55,6 +55,7 @@ namespace Syntaxutils { AExtensionPtr->Values["ini"] = "INI"; AExtensionPtr->Values["dfm"] = "DFM"; AExtensionPtr->Values["cmd"] = "Batch"; + AExtensionPtr->Values["py"] = "Python"; if (sExt.Pos(".") == 1) { sExt = sExt.Delete(1, 1); @@ -76,6 +77,7 @@ namespace Syntaxutils { AExtensionPtr->Values["DFM"] = "dfm"; AExtensionPtr->Values["Batch"] = "cmd"; AExtensionPtr->Values["JavaScript"] = "js"; + AExtensionPtr->Values["Python"] = "py"; return AExtensionPtr->Values[sSyntaxScheme]; } @@ -94,6 +96,7 @@ namespace Syntaxutils { AStartCommentListPtr->Values[L"CPP"] = L"//"; AStartCommentListPtr->Values[L"Batch"] = L"REM"; AStartCommentListPtr->Values[L"INI"] = L";"; + AStartCommentListPtr->Values[L"Python"] = L"#"; std::auto_ptrAEndCommentListPtr(new TStringList()); AEndCommentListPtr->Values[L"XML"] = L"-->"; diff --git a/Src/UnitThemeSettings.cpp b/Src/UnitThemeSettings.cpp index 9264b47..11a588c 100644 --- a/Src/UnitThemeSettings.cpp +++ b/Src/UnitThemeSettings.cpp @@ -69,6 +69,9 @@ __fastcall TThemeSettings::TThemeSettings() { FStateNormalFontStyle = TFontStyles(); FStateSelfConnectionInsideFontStyle = g_STATE_SELF_CONNECTION_INSIDE_FONT_STYLE; + FStateDefaultWidth = 100; + FStateDefaultHeight = 50; + FScxmlNormalHeadColor = clMoneyGreen; FScxmlDatamodelFontColor = clMaroon; FScxmlVirtualFontColor = clBlue; @@ -106,6 +109,10 @@ void __fastcall TThemeSettings::Assign(Classes::TPersistent* Source) { FStateNormalBorderColor = AThemeSettings->FStateNormalBorderColor; FStateNormalBorderStyle = AThemeSettings->FStateNormalBorderStyle; FStateNormalFontStyle = AThemeSettings->FStateNormalFontStyle; + + FStateDefaultWidth = AThemeSettings->FStateDefaultWidth; + FStateDefaultHeight = AThemeSettings->FStateDefaultHeight; + FStateSelfConnectionInsideFontStyle = AThemeSettings->FStateSelfConnectionInsideFontStyle; FScxmlNormalHeadColor = AThemeSettings->FScxmlNormalHeadColor; @@ -143,20 +150,6 @@ void __fastcall TThemeSettings::OnGetPropEditorClass(TPersistent *AInstance, ILM // } } -//--------------------------------------------------------------------------- -void __fastcall TThemeSettings::SetTransitionLineWidth(int val) { - if (val > 0 && val < 20) { - FTransitionLineWidth = val; - } -} - -//--------------------------------------------------------------------------- -void __fastcall TThemeSettings::SetTransitionFromCircleSize(int val) { - if (val > 6 && val < 40) { - FTransitionFromCircleSize = val; - } -} - //--------------------------------------------------------------------------- //---------------------- TThemeSettingsPropEditor ---------------------------- //--------------------------------------------------------------------------- diff --git a/Src/UnitThemeSettings.h b/Src/UnitThemeSettings.h index 07ff283..cb892c0 100644 --- a/Src/UnitThemeSettings.h +++ b/Src/UnitThemeSettings.h @@ -36,6 +36,8 @@ #include "LMDInsPropEditors.hpp" +#include "CommonConsts.h" + static const TColor g_CHILD_NORMAL_BORDER_COLOR = TColor(RGB(32, 32, 32)); static const TColor g_STATE_NORMAL_COLOR = TColor(0x00FFD680); static const TColor g_STATE_INITIAL_BORDER_COLOR = TColor(0x000080FF); @@ -57,6 +59,11 @@ class TThemeSettings: public TPersistent { TFontStyles FStateNormalFontStyle; TFontStyles FStateSelfConnectionInsideFontStyle; + int FStateDefaultWidth; + SET_PROPERTY_MIN(StateDefaultWidth, int, 20); + int FStateDefaultHeight; + SET_PROPERTY_MIN(StateDefaultHeight, int, 10); + TColor FScxmlNormalHeadColor; TColor FVirtualNormalColor; TColor FVirtualHeadColor; @@ -71,10 +78,10 @@ class TThemeSettings: public TPersistent { TPenStyle FChildNormalBorderStyle; int FTransitionLineWidth; - void __fastcall SetTransitionLineWidth(int val); + SET_PROPERTY_RANGE(TransitionLineWidth, int, 1, 20); int FTransitionFromCircleSize; - void __fastcall SetTransitionFromCircleSize(int val); + SET_PROPERTY_RANGE(TransitionFromCircleSize, int, 7, 40); protected: @@ -94,6 +101,9 @@ class TThemeSettings: public TPersistent { __property TFontStyles StateNormalFontStyle = {read=FStateNormalFontStyle, write=FStateNormalFontStyle, default=0}; __property TFontStyles StateSelfConnectionInsideFontStyle = {read=FStateSelfConnectionInsideFontStyle, write=FStateSelfConnectionInsideFontStyle, default=g_STATE_SELF_CONNECTION_INSIDE_FONT_STYLE_INT}; + __property int StateDefaultWidth = {read=FStateDefaultWidth, write=SetStateDefaultWidth, default=100}; + __property int StateDefaultHeight = {read=FStateDefaultHeight, write=SetStateDefaultHeight, default=50}; + __property TColor ChildNormalColor = {read=FChildNormalColor, write=FChildNormalColor, default=clWhite}; __property TFontStyles ChildNormalFontStyle = {read=FChildNormalFontStyle, write=FChildNormalFontStyle, default=0}; __property TColor ChildNormalBorderColor = {read=FChildNormalBorderColor, write=FChildNormalBorderColor, default=g_CHILD_NORMAL_BORDER_COLOR}; diff --git a/Src/UnitTreeEditorStateMachine.cpp b/Src/UnitTreeEditorStateMachine.cpp index aa1fb88..1daf044 100644 --- a/Src/UnitTreeEditorStateMachine.cpp +++ b/Src/UnitTreeEditorStateMachine.cpp @@ -357,6 +357,10 @@ FPropSplitter(NULL), FFormReplaceDlg(NULL) { MenuChartStatistics->OnClick = OnMenuChartStatistics; MenuResetToDefault->OnClick = OnMenuResetViewToDefault; + MenuViewPresetsMinimal->OnClick = OnMenuViewPresetsMinimal; + MenuViewPresetsCustom->OnClick = OnMenuViewPresetsCustom; + MenuViewPresets->OnClick = OnMenuViewPresets; + MenuViewFullScreen->OnClick = OnMenuViewFullScreen; for (int i = 0; i < File1->Count; i++) { File1->Items[i]->ShortCut = 0; @@ -4043,9 +4047,13 @@ void __fastcall TStateMachineEditor::PopupNodePopup(System::TObject * Sender) { FMenuFilterSelectionByProperty->Visible = TheTree->Selected->Count() > 1; + // NOTE: IsInitialDeep is not published ! FMenuIsInitial->Visible = ASelectedShape && IsPublishedProp(ASelectedShape, "IsInitial"); if (FMenuIsInitial->Visible) { - FMenuIsInitial->Checked = GetPropValue(ASelectedShape, "IsInitial"); + TVisualScxmlBaseShape *AVisualShape = dynamic_cast(ASelectedShape); + if (AVisualShape) { + FMenuIsInitial->Checked = AVisualShape->IsInitialDeep; + } } FMenuConvertTo->Clear(); @@ -4409,11 +4417,15 @@ void __fastcall TStateMachineEditor::OnMenuIsInitialClick(TObject * Sender) { if (AMenuItem) { TVisualScxmlBaseShape *AVisualShape = dynamic_cast (GetSafeTreeListFirst(TheTree->Selected->Shapes)); + // NOTE: IsInitialDeep is not published ! if (AVisualShape && IsPublishedProp(AVisualShape, "IsInitial")) { + AVisualShape->IsInitialDeep = AMenuItem->Checked; - SetPropValue(AVisualShape, "IsInitial", AMenuItem->Checked); + if (PropSettingsInspector) { + PropSettingsInspector->UpdateContent(); + } - GetPropSettingsInspector()->UpdateContent(); + TheTree->Invalidate(); TeeModified(true, 1, "Changed initial state [" + AVisualShape->SimpleText + "]"); } @@ -5241,6 +5253,161 @@ void __fastcall TStateMachineEditor::OnMenuResetViewToDefault(TObject *Sender) { TheTree->ShowImages = true; TheTree->ShowText = true; TheTree->CrossBox->Visible = true; + + this->SaveEditorParameters(); +} + +// --------------------------------------------------------------------------- +void __fastcall TStateMachineEditor::OnMenuViewPresetsMinimal(TObject *Sender) { + TTreeEditWindows HideWindows = TTreeEditWindows() << teInspector << teNodeTree << teToolbar << teToolShapes << + teEditors << teFont << teFormat << teRulers << TTreeEditWindow::teStatus << teModeTabs << teMainMenu << + teSideToolbar; + + this->TreeHideEditorPanels(HideWindows); + + TheTree->Shapes->Visible = true; + TheTree->Connections->Visible = true; + TheTree->CrossBox->Visible = true; + TheTree->ShowImages = true; + TheTree->ShowText = true; + TheTree->CrossBox->Visible = true; + + this->SaveEditorParameters(); +} + +// --------------------------------------------------------------------------- +void __fastcall TStateMachineEditor::OnMenuViewPresetsCustom(TObject *Sender) { + std::auto_ptrAFormPtr(new TForm(this)); + AFormPtr->Caption = L"View Presets Editor"; + + TPanel *APanel = new TPanel(AFormPtr.get()); + APanel->Parent = AFormPtr.get(); + APanel->ShowCaption = false; + APanel->Height = 40; + APanel->Align = alTop; + APanel->AlignWithMargins = true; + + TButton *AButtonAdd = new TButton(AFormPtr.get()); + AButtonAdd->Parent = APanel; + AButtonAdd->Caption = L"Add"; + AButtonAdd->Align = alLeft; + AButtonAdd->AlignWithMargins = true; + AButtonAdd->ModalResult = mrYes; + + TButton *AButtonRemove = new TButton(AFormPtr.get()); + AButtonRemove->Parent = APanel; + AButtonRemove->Caption = L"Remove"; + AButtonRemove->Align = alLeft; + AButtonRemove->AlignWithMargins = true; + AButtonRemove->ModalResult = mrNo; + + TButton *AButtonCancel = new TButton(AFormPtr.get()); + AButtonCancel->Parent = APanel; + AButtonCancel->Caption = L"Cancel"; + AButtonCancel->Align = alRight; + AButtonCancel->AlignWithMargins = true; + AButtonCancel->ModalResult = mrCancel; + + TComboBox *AComboEdit = new TComboBox(AFormPtr.get()); + AComboEdit->Parent = AFormPtr.get(); + AComboEdit->Align = alTop; + AComboEdit->AlignWithMargins = true; + + // NOTE: use this to garantee Combo over Panel + AComboEdit->Top = 0; + APanel->Top = AComboEdit->Height; + + for (int k = 0; k < SettingsData->TempRegistry->Count; k++) { + const UnicodeString sPrefix = this->ClassName() + ".ViewPresets."; + if (SettingsData->TempRegistry->Names[k].Pos(sPrefix) == 1) { + AComboEdit->Items->Add(StringReplace(SettingsData->TempRegistry->Names[k], sPrefix, L"", + TReplaceFlags() << rfIgnoreCase)); + } + } + + AFormPtr->AutoSize = true; + + const int iRes = AFormPtr->ShowModal(); + + const UnicodeString sPresetName = AComboEdit->Text.Trim(); + if (!sPresetName.IsEmpty()) { + const UnicodeString sRegKey = this->ClassName() + ".ViewPresets." + sPresetName; + + switch(iRes) { + case mrYes: { + SettingsData->TempRegistry->Values[sRegKey] = UnicodeString().sprintf(L"%d;%d", + this->HideWindowsStatus.ToInt(), PanelNodes->Width); + }break; + case mrNo: { + const int iIndex = SettingsData->TempRegistry->IndexOfName(sRegKey); + if (iIndex != -1) { + SettingsData->TempRegistry->Delete(iIndex); + } + }break; + } + } + else { + LOG_WARNING_SS << "Preset name can not be empty!"; + } + +} + +// --------------------------------------------------------------------------- +void __fastcall TStateMachineEditor::OnMenuViewPresetsApply(TObject *Sender) { + try { + TMenuItem *AMenuItem = dynamic_cast(Sender); + if (AMenuItem) { + const UnicodeString sRegKey = this->ClassName() + ".ViewPresets." + StripHotkey(AMenuItem->Caption); + const int iIndex = SettingsData->TempRegistry->IndexOfName(sRegKey); + if (iIndex != -1) { + std::auto_ptrADataPtr(new TStringList); + ADataPtr->StrictDelimiter = true; + ADataPtr->Delimiter = L';'; + ADataPtr->DelimitedText = SettingsData->TempRegistry->ValueFromIndex[iIndex]; + + const TTreeEditWindows AHideWindows(ADataPtr->Strings[0].ToInt()); + TreeHideEditorPanels(AHideWindows); + + PanelNodes->Width = ADataPtr->Strings[1].ToInt(); + + this->SaveEditorParameters(); + } + } + } + catch(Exception * E) { + LOG_ERROR(LOG_ERROR_MSG); + } +} + +// --------------------------------------------------------------------------- +void __fastcall TStateMachineEditor::OnMenuViewPresets(TObject *Sender) { + + int iIndex = -1; + for (int i = MenuViewPresets->Count - 1; i > 0; i--) { + if (MenuViewPresets->Items[i]->Name == L"MenuViewPresetsMinimal") { + iIndex = i; + break; + } + else { + MenuViewPresets->Remove(MenuViewPresets->Items[i]); + } + } + + for (int k = 0; k < SettingsData->TempRegistry->Count; k++) { + const UnicodeString sPrefix = this->ClassName() + ".ViewPresets."; + if (SettingsData->TempRegistry->Names[k].Pos(sPrefix) == 1) { + TMenuItem *AMenuItem = new TMenuItem(this); + AMenuItem->Caption = StringReplace(SettingsData->TempRegistry->Names[k], sPrefix, L"", + TReplaceFlags() << rfIgnoreCase); + AMenuItem->OnClick = OnMenuViewPresetsApply; + MenuViewPresets->Insert(++iIndex, AMenuItem); + } + } +} + +// --------------------------------------------------------------------------- +void __fastcall TStateMachineEditor::OnMenuViewFullScreen(TObject *Sender) { + this->ToggleFullScreenMode(); } // --------------------------------------------------------------------------- @@ -5616,6 +5783,17 @@ void __fastcall TStateMachineEditor::TheTreeKeyDown(System::TObject* Sender, Sys FFrameTransitionTypes->Visible = false; } + switch(Key) { + case VK_RETURN: { + if (Shift == Classes::TShiftState() << ssCtrl) { + if (TScxmlBaseShape * AScxmlBaseShape = FirstSelected) { + // NOTE: we need to disable expand-collapse on press 'Ctrl+Enter' + Key = 0; + } + } + }break; + } + TTreeEditorEx::TheTreeKeyDown(Sender, Key, Shift); switch(Key) { @@ -5638,6 +5816,22 @@ void __fastcall TStateMachineEditor::TheTreeKeyDown(System::TObject* Sender, Sys } } +// --------------------------------------------------------------------------- +void __fastcall TStateMachineEditor::TheTreeKeyUp(System::TObject* Sender, System::Word &Key, + Classes::TShiftState Shift) { + switch(Key) { + case VK_RETURN: { + if (Shift == Classes::TShiftState() << ssCtrl) { + if (TScxmlBaseShape * AScxmlBaseShape = FirstSelected) { + PostMessage(this->Handle, WM_SCXML_EDIT_TREE_SHAPE, (WPARAM)this, (LPARAM)AScxmlBaseShape); + } + } + }break; + } + + TTreeEditorEx::TheTreeKeyUp(Sender, Key, Shift); +} + // --------------------------------------------------------------------------- void __fastcall TStateMachineEditor::TheTreeMouseDown(System::TObject* Sender, Controls::TMouseButton Button, Classes::TShiftState Shift, int X, int Y) { @@ -6164,6 +6358,20 @@ void __fastcall TStateMachineEditor::OnMsgDeleteTreeShape(TMessage &AMsg) { } } +// --------------------------------------------------------------------------- +void __fastcall TStateMachineEditor::OnMsgEditTreeShape(TMessage &AMsg) { + if (!AMsg.LParam) + return; + + if ((int)AMsg.WParam != (int)this) + return; + + TScxmlBaseShape *AScxmlBaseShape = reinterpret_cast(AMsg.LParam); + if (TheTree->Shapes->IndexOf(AScxmlBaseShape) != -1) { + DoEditScxmlShapes(AScxmlBaseShape); + } +} + // --------------------------------------------------------------------------- void __fastcall TStateMachineEditor::SelectConnection(TTreeConnection * AConnection, const bool bScrollInView /* = SCROLL_CHART_IN_VIEW */ ) { diff --git a/Src/UnitTreeEditorStateMachine.h b/Src/UnitTreeEditorStateMachine.h index 6f24899..d39a47c 100644 --- a/Src/UnitTreeEditorStateMachine.h +++ b/Src/UnitTreeEditorStateMachine.h @@ -476,12 +476,13 @@ class TStateMachineEditor : public TTreeEditorEx { virtual void __fastcall TheTreeMovingShape(Teetree::TTreeNodeShape* Sender, int &DeltaX, int &DeltaY); virtual void __fastcall TheTreeResizingShape(Teetree::TTreeNodeShape* Sender, Teetree::TTreeShapeHandle ACorner, int &DeltaX, int &DeltaY); virtual void __fastcall TheTreeKeyDown(System::TObject* Sender, System::Word &Key, Classes::TShiftState Shift); + virtual void __fastcall TheTreeKeyUp(System::TObject* Sender, System::Word &Key, Classes::TShiftState Shift); virtual void __fastcall TheTreeMouseDown(System::TObject* Sender, Controls::TMouseButton Button, Classes::TShiftState Shift, int X, int Y); virtual void __fastcall TheTreeMouseUp(System::TObject* Sender, Controls::TMouseButton Button, Classes::TShiftState Shift, int X, int Y); virtual void __fastcall TheTreeMouseWheelEvent(System::TObject* Sender, Classes::TShiftState Shift, int WheelDelta, const Types::TPoint &MousePos, bool &Handled); virtual void __fastcall TheTreeDragOver(TObject *Sender, TObject *Source, int X, int Y, TDragState State, bool &Accept); virtual void __fastcall TheTreeDragDrop(TObject *Sender, TObject *Source, int X, int Y); - virtual void __fastcall TheTreeDeletingConnection(Teetree::TTreeConnection* Sender, bool &AllowDelete); + virtual void __fastcall TheTreeDeletingConnection(Teetree::TTreeConnection* Sender, bool &AllowDelete); virtual void __fastcall TryPopup(Teetree::TCustomTree* ATree, int x, int y, int xScreen, int yScreen); TPopupMenu * __fastcall GetPreparedPopupMenu(Teetree::TCustomTree* ATree, @@ -496,6 +497,12 @@ class TStateMachineEditor : public TTreeEditorEx { virtual void __fastcall OnMenuClone(TObject *Sender); void __fastcall OnMenuResetViewToDefault(TObject *Sender); + void __fastcall OnMenuViewPresetsMinimal(TObject *Sender); + void __fastcall OnMenuViewPresetsCustom(TObject *Sender); + void __fastcall OnMenuViewPresets(TObject *Sender); + void __fastcall OnMenuViewPresetsApply(TObject *Sender); + + void __fastcall OnMenuViewFullScreen(TObject *Sender); void __fastcall OnMenuClearSelection(TObject *Sender); @@ -539,10 +546,12 @@ class TStateMachineEditor : public TTreeEditorEx { void __fastcall ExecuteInterprocessCommand(INTERPROCESS_COPYDATA *ACopyData); void __fastcall OnMsgDeleteTreeShape(TMessage &AMsg); + void __fastcall OnMsgEditTreeShape(TMessage &AMsg); void __fastcall OnMsgCopyData(TWMCopyData &msg); BEGIN_MESSAGE_MAP VCL_MESSAGE_HANDLER(WM_SCXML_DELETE_TREE_SHAPE, TMessage, OnMsgDeleteTreeShape) + VCL_MESSAGE_HANDLER(WM_SCXML_EDIT_TREE_SHAPE, TMessage, OnMsgEditTreeShape) VCL_MESSAGE_HANDLER(WM_COPYDATA, TWMCopyData, OnMsgCopyData) END_MESSAGE_MAP(TTreeEditorEx)