29#include <wx/treectrl.h>
30#include <wx/listctrl.h>
31#include <wx/stc/stc.h>
34#include <wx/dragimag.h>
37#include <wx/dcmemory.h>
38#include <wx/dcclient.h>
39#include <wx/dcbuffer.h>
52 wxSearchCtrl* search_widget =
new wxSearchCtrl( aParent, wxID_ANY );
54 search_widget->ShowSearchButton(
false );
55 search_widget->ShowCancelButton(
true );
57 search_widget->SetDescriptiveText( aDescriptiveText );
62 search_widget->SetMinSize( wxSize( -1, aParent->GetTextExtent( wxT(
"qb" ) ).y + 10 ) );
70 const wxSize& aInitialSize ) :
71 DIALOG_SHIM( aParent, wxID_ANY, aTitle, wxDefaultPosition, aInitialSize,
72 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER ),
86 wxBoxSizer* mainSizer =
new wxBoxSizer( wxVERTICAL );
87 SetSizer( mainSizer );
89 wxBoxSizer* infoBarSizer =
new wxBoxSizer( wxHORIZONTAL );
92 infoBarSizer->Add(
m_infoBar, 0, wxEXPAND, 0 );
95 m_splitter =
new wxSplitterWindow(
this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
96 wxSP_3D | wxSP_LIVE_UPDATE | wxSP_3DSASH );
101 new WX_PANEL(
m_splitter, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE | wxTAB_TRAVERSAL );
102 treeCtrlPanel->
SetBorders(
true,
true,
true,
true );
103 wxBoxSizer* treeCtrlSizer =
new wxBoxSizer( wxVERTICAL );
104 treeCtrlPanel->SetSizer( treeCtrlSizer );
111 m_ruleTreeCtrl =
new wxTreeCtrl( treeCtrlPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize,
112 wxTR_DEFAULT_STYLE | wxTR_HIDE_ROOT | wxTR_HAS_BUTTONS );
117 treeCtrlFlags = ( treeCtrlFlags & ~wxBORDER_MASK ) | wxBORDER_NONE;
124 wxBoxSizer* actionButtonsSizer =
new wxBoxSizer( wxHORIZONTAL );
129 wxDefaultPosition, wxDefaultSize, 0 );
131 wxDefaultPosition, wxDefaultSize, 0 );
134 wxDefaultPosition, wxDefaultSize, 0 );
137 wxDefaultPosition, wxDefaultSize, 0 );
140 wxDefaultPosition, wxDefaultSize, 0 );
148 actionButtonsSizer->AddStretchSpacer( 1 );
154 treeCtrlSizer->Add( actionButtonsSizer, 0, wxBOTTOM | wxEXPAND, 5 );
156 treeCtrlPanel->Layout();
164 treeCtrlPanel->Layout();
165 int minTreeWidth = treeCtrlPanel->GetBestSize().GetWidth();
168 if( minTreeWidth < 200 )
178 wxBoxSizer* m_sizerButtons =
new wxBoxSizer( wxHORIZONTAL );
180 wxStdDialogButtonSizer* m_sdbSizer =
new wxStdDialogButtonSizer();
187 m_sdbSizer->Realize();
189 m_sizerButtons->Add( m_sdbSizer, 1, wxEXPAND, 5 );
193 mainSizer->Add( infoBarSizer, 0, wxEXPAND, 0 );
194 mainSizer->Add(
m_splitter, 1, wxEXPAND | wxBOTTOM, 5 );
195 mainSizer->Add( m_sizerButtons, 0, wxALL | wxEXPAND, 5 );
196 SetSize( wxSize( 980, 680 ) );
232 wxSize curSz = GetSize();
233 wxSize minSz = GetMinSize();
238 minSz = GetMinSize();
280 if( !DIALOG_SHIM::TransferDataToWindow() )
293 if( !DIALOG_SHIM::TransferDataFromWindow() )
306 return currentDialog;
308 aParent = aParent->GetParent();
322 wxTreeItemId rootId =
m_ruleTreeCtrl->AddRoot( aNodes[0].m_nodeName );
328 std::vector<RULE_TREE_NODE> childNodes;
331 for(
const auto& child : childNodes )
350 sash_position =
m_splitter->GetSashPosition();
356 auto treeCtrlPanel =
m_splitter->GetWindow1();
365 wxTreeItemId aParent )
373 std::vector<int>& existingChildren = std::get<1>( it->second );
374 existingChildren.push_back( aNode.
m_nodeId );
411 const std::vector<RULE_TREE_NODE>& aNodes,
const RULE_TREE_NODE& aNode,
412 wxTreeItemId aParent )
416 std::vector<RULE_TREE_NODE> childNodes;
419 for(
const auto& child : childNodes )
430 wxTreeItemId item = aEvent.GetItem();
440 if( !ruleTreeItemData )
467 menu.Bind( wxEVT_COMMAND_MENU_SELECTED,
468 [&]( wxCommandEvent& aCmd )
470 switch( aCmd.GetId() )
481 default: aCmd.Skip();
491 wxTreeItemId selectedItem = aEvent.GetItem();
496 if( !selectedItemData )
555 if( !selectedItem.IsOk() )
558 wxTreeItemId parent =
m_ruleTreeCtrl->GetItemParent( selectedItem );
563 wxTreeItemIdValue cookie;
564 wxTreeItemId current =
m_ruleTreeCtrl->GetFirstChild( parent, cookie );
565 wxTreeItemId previous;
566 wxTreeItemId beforePrevious;
568 while( current.IsOk() && current != selectedItem )
570 beforePrevious = previous;
575 if( !previous.IsOk() )
580 wxTreeItemId insertPosition = beforePrevious.IsOk() ? beforePrevious : wxTreeItemId();
583 parent, insertPosition,
m_ruleTreeCtrl->GetItemText( selectedItem ) );
587 wxTreeItemData* itemData =
m_ruleTreeCtrl->GetItemData( selectedItem );
617 if( !selectedItem.IsOk() )
620 wxTreeItemId parent =
m_ruleTreeCtrl->GetItemParent( selectedItem );
621 wxTreeItemIdValue cookie;
622 wxTreeItemId current =
m_ruleTreeCtrl->GetFirstChild( parent, cookie );
624 while( current.IsOk() && current != selectedItem )
637 wxTreeItemData* itemData =
m_ruleTreeCtrl->GetItemData( selectedItem );
665 wxPoint pt = aEvent.GetPosition();
670 if( flags & wxTREE_HITTEST_ONITEMBUTTON )
683 wxBitmap bitmap( 200, 30 );
684 dc.SelectObject( bitmap );
685 dc.SetBackground( *wxWHITE_BRUSH );
687 dc.SetFont( *wxNORMAL_FONT );
688 dc.DrawText(
text, 5, 5 );
689 dc.SelectObject( wxNullBitmap );
703 wxPoint currentPos = aEvent.GetPosition();
740 wxPoint pos = aEvent.GetPosition();
744 if( !targetItem.IsOk() )
748 wxTreeItemId targetParent =
m_ruleTreeCtrl->GetItemParent( targetItem );
750 if( draggedParent != targetParent )
753 if( draggedParent == targetParent )
755 wxTreeItemId newItem;
756 wxTreeItemIdValue cookie;
758 if( flags & wxTREE_HITTEST_ONITEMLABEL
759 && targetItem ==
m_ruleTreeCtrl->GetFirstChild( targetParent, cookie ) )
767 wxTreeItemId current =
m_ruleTreeCtrl->GetFirstChild( targetParent, cookie );
768 wxTreeItemId previous;
771 while( current.IsOk() && current != targetItem )
777 if( !previous.IsOk() )
785 wxTreeItemId nextSibling =
m_ruleTreeCtrl->GetNextChild( targetParent, cookie );
787 if( nextSibling.IsOk() )
791 targetParent, previous,
836 const auto searchStr = aEvent.GetString().Lower();
853 bool matches =
m_ruleTreeCtrl->GetItemText( aItem ).Lower().Contains( aFilter );
855 wxTreeItemIdValue cookie;
856 wxTreeItemId child =
m_ruleTreeCtrl->GetFirstChild( aItem, cookie );
857 bool hasVisibleChildren =
false;
859 std::vector<wxTreeItemId> itemsToDelete;
861 while( child.IsOk() )
865 hasVisibleChildren =
true;
869 itemsToDelete.push_back( child );
875 for(
const auto&
id : itemsToDelete )
880 return matches || hasVisibleChildren;
887 std::vector<int> children;
889 wxTreeItemIdValue cookie;
890 wxTreeItemId child =
m_ruleTreeCtrl->GetFirstChild( aItem, cookie );
892 while( child.IsOk() )
896 int childId = childItemData->
GetNodeId();
898 children.push_back( childId );
916 const auto& [itemText, children, itemId] = it->second;
918 wxTreeItemId newItem;
927 wxTreeItemId& treeItemId = std::get<2>( it->second );
928 treeItemId = newItem;
934 for(
const auto& childId : children )
954 return currentTreeItemId;
960 std::vector<RULE_TREE_NODE>& aResult )
962 std::vector<RULE_TREE_NODE> filteredNodes;
964 std::copy_if( aNodes.begin(), aNodes.end(), std::back_inserter( filteredNodes ),
967 return node.m_nodeData->GetParentId() == aParentId;
970 if( filteredNodes.size() > 0 )
972 aResult.insert( aResult.end(), filteredNodes.begin(), filteredNodes.end() );
979 wxTreeItemIdValue cookie;
980 wxTreeItemId child =
m_ruleTreeCtrl->GetFirstChild( aSrc, cookie );
982 while( child.IsOk() )
984 wxTreeItemId newChild =
1009 if( !selectedItem.IsOk() )
1025 wxTreeItemId parent =
m_ruleTreeCtrl->GetItemParent( selectedItem );
1026 wxTreeItemIdValue cookie;
1027 wxTreeItemId firstChild =
m_ruleTreeCtrl->GetFirstChild( parent, cookie );
1028 wxTreeItemId lastChild = firstChild;
1030 while( lastChild.IsOk() )
1093 wxPostEvent(
this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL ) );
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
DIALOG_SHIM(wxWindow *aParent, wxWindowID id, const wxString &title, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER, const wxString &name=wxDialogNameStr)
int GetParentId()
Get the parent ID of the rule.
void populateRuleTreeCtrl(const std::vector< RULE_TREE_NODE > &aRuleTreeNodes, const RULE_TREE_NODE &aRuleTreeNode, wxTreeItemId aParentTreeItemId)
Populates the rule tree with nodes and their children.
void onRuleTreeItemSelectionChanged(wxTreeEvent &aEvent)
Updates action buttons based on the selected tree item.
void moveRuleTreeItemChildrensTooOnDrag(wxTreeItemId aSrcTreeItemId, wxTreeItemId aDestTreeItemId)
Recursively moves all child nodes of a source item to a destination during drag.
void DeleteRuleTreeItem(wxTreeItemId aItemId, const int &aNodeId)
Deletes a tree item and removes its corresponding node from history.
void onRuleTreeItemMouseMotion(wxMouseEvent &aEvent)
Handles drag motion to move the item along with the cursor.
wxTreeItemId m_draggedItem
void UpdateRuleTreeItemText(wxTreeItemId aItemId, wxString aItemText)
Updates the text of a specified rule tree item.
void onNewRuleOptionClick(wxCommandEvent &aEvent)
Creates a new rule when the "New Rule" option is clicked.
void onRuleTreeItemLeftDown(wxMouseEvent &aEvent)
Initiates drag operation for a tree item on mouse down.
void onMoveUpRuleOptionClick(wxCommandEvent &aEvent)
Moves a rule item up in the tree when "Move Up" is clicked.
virtual void RuleTreeItemSelectionChanged(RULE_TREE_ITEM_DATA *aCurrentRuleTreeItemData)=0
Pure virtual method to handle tree item selection changes.
void onClose(wxCloseEvent &aEvt)
wxBitmapButton * m_addRuleButton
void onMoveDownRuleOptionClick(wxCommandEvent &aEvent)
Moves a rule item down in the tree when "Move Down" is clicked.
void AppendNewRuleTreeItem(const RULE_TREE_NODE &aRuleTreeNode, wxTreeItemId aParentTreeItemId)
Adds a new rule tree item under the specified parent and updates the tree history.
void InitRuleTreeItems(const std::vector< RULE_TREE_NODE > &aRuleTreeNodes)
Initializes the rule tree by adding nodes, setting up the structure, and saving its state.
void saveRuleTreeState(const wxTreeItemId &aItem, const int &aNodeId=0)
Saves the state of a tree item to history.
static RULE_EDITOR_DIALOG_BASE * GetDialog(wxWindow *aWindow)
Static method to retrieve the rule editor dialog instance associated with a given window.
wxTreeItemId m_previousId
void onRuleTreeItemLeftUp(wxMouseEvent &aEvent)
Completes the drag operation on mouse release.
void onRuleTreeItemActivated(wxTreeEvent &aEvent)
Handles double-click activation of a tree item.
void SetContentPanel(wxPanel *aContentPanel)
Replaces the current content panel with a new one based on the selected constraint type.
virtual void OnSave(wxCommandEvent &aEvent)=0
wxTreeCtrl * m_ruleTreeCtrl
wxButton * m_cancelRuleButton
std::vector< RULE_TREE_NODE > m_defaultTreeItems
virtual void AddNewRule(RULE_TREE_ITEM_DATA *aRuleTreeItemData)=0
Pure virtual method to add a new rule to the tree.
wxButton * m_saveRuleButton
void onDuplicateRuleOptionClick(wxCommandEvent &aEvent)
Duplicates the selected rule when "Duplicate Rule" is clicked.
bool m_enableDuplicateRule
RULE_TREE_ITEM_DATA * m_selectedData
void restoreRuleTree(const wxTreeItemId &aParent, const int &aNodeId)
Restores a tree item from history and appends it under a parent.
bool TransferDataToWindow() override
wxBitmapButton * m_deleteRuleButton
RULE_EDITOR_DIALOG_BASE(wxWindow *aParent, const wxString &aTitle, const wxSize &aInitialSize=wxDefaultSize)
virtual void RemoveRule(int aNodeId)=0
Pure virtual method to remove a rule from the tree.
wxTreeItemId appendRuleTreeItem(const RULE_TREE_NODE &aRuleTreeNode, wxTreeItemId aParentTreeItemId)
Appends a new rule item to the tree.
std::unordered_map< int, std::tuple< wxString, std::vector< int >, wxTreeItemId > > m_treeHistoryData
void onResize(wxSizeEvent &event)
void onDeleteRuleOptionClick(wxCommandEvent &aEvent)
Deletes the selected rule when "Delete Rule" is clicked.
wxSearchCtrl * m_filterSearch
int m_defaultSashPosition
virtual void DuplicateRule(RULE_TREE_ITEM_DATA *aRuleTreeItemData)=0
Pure virtual method to duplicate an existing rule in the tree.
bool TransferDataFromWindow() override
~RULE_EDITOR_DIALOG_BASE() override
void onRuleTreeItemRightClick(wxTreeEvent &aEvent)
Handles right-click on a rule tree item to create a context menu.
void getRuleTreeChildNodes(const std::vector< RULE_TREE_NODE > &aNodes, int aParentId, std::vector< RULE_TREE_NODE > &aResult)
Retrieves child nodes of a given parent node.
wxBitmapButton * m_copyRuleButton
void onFilterSearch(wxCommandEvent &aEvent)
Applies filter to the rule tree based on the search string.
wxBitmapButton * m_moveTreeItemUpButton
wxSplitterWindow * m_splitter
virtual bool isEnabled(RULE_TREE_ITEM_DATA *aRuleTreeItemData, RULE_EDITOR_TREE_CONTEXT_OPT aOption)=0
Pure virtual method to verify if a context menu option for a rule tree item should be enabled.
void updateRuleTreeItemMoveOptionState()
Updates the state of move options (up/down) for the selected item.
wxDragImage * m_dragImage
virtual void OnCancel(wxCommandEvent &aEvent)=0
void updateRuleTreeActionButtonsState(RULE_TREE_ITEM_DATA *aRuleTreeItemData)
Updates the action buttons based on the current selection.
void finishInitialization()
void SetControlsEnabled(bool aEnable)
Enables or disables controls within the rule editor dialog.
bool filterRuleTree(const wxTreeItemId &aItem, const wxString &aFilter)
Recursively filters tree items to show only those matching the filter.
wxBitmapButton * m_moveTreeItemDownButton
A class representing additional data associated with a wxTree item.
void SetTreeItemId(wxTreeItemId aTreeItemId)
void SetParentTreeItemId(wxTreeItemId aParentTreeItemId)
A modified version of the wxInfoBar class that allows us to:
void SetBorders(bool aLeft, bool aRight, bool aTop, bool aBottom)
This file is part of the common library.
KICOMMON_API wxFont GetControlFont(wxWindow *aWindow)
KICOMMON_API wxMenuItem * AddMenuItem(wxMenu *aMenu, int aId, const wxString &aText, const wxBitmapBundle &aImage, wxItemKind aType=wxITEM_NORMAL)
Create and insert a menu item with an icon into aMenu.
static wxSearchCtrl * CreateTextFilterBox(wxWindow *aParent, const wxString &aDescriptiveText)
Helper function to add a filter box to a panel, with some sensible defaults for that purpose.
void Refresh()
Update the board display after modifying it by a python script (note: it is automatically called by a...
static wxSearchCtrl * CreateTextFilterBox(wxWindow *aParent, const wxString &aDescriptiveText)
Structure representing a node in a rule tree, collection of this used for building the rule tree.
std::shared_ptr< RULE_EDITOR_DATA_BASE > m_nodeData
Functions to provide common constants and other functions to assist in making a consistent UI.