Developer forums (C::B DEVELOPMENT STRICTLY!) > Development

Improvement in TabSwitcher

<< < (6/10) > >>

Feneck91:
Ok, tested ! It's work perfectly.
This patch contains :
- "Use stacked based tab-switching" added option into Setting/Environment/Notebooks appearance
- Depending of option "Use stacked based tab-switching", the CTRL+TAB has old comportment if unchecked, if checked it has the stacked  tab switching comportment.
- Bug fix : When window selection opened (when pressing CTRL+TAB), it doesn't select the item under the mouse cursor automatically, only if the user move the mouse cursor more that 3 pixels width/height.
- Bug fix : When window selection is open (when pressing CTRL+TAB), when selecting an item with the mouse (just move, without pressing button), if the user select another window by pressing CTRL+TAB again, release CTRL now select the highlight item not the item under the mouse cursor.
Patch :

--- Code: ---Index: src/include/editormanager.h
===================================================================
--- src/include/editormanager.h (revision 6080)
+++ src/include/editormanager.h (working copy)
@@ -45,6 +45,20 @@
 struct cbFindReplaceData;
 
 /*
+ * Struct for store tabs stack info
+ */
+struct cbNotebookStack
+{
+    cbNotebookStack(wxWindow* a_pWindow = NULL)
+        : m_pWindow (a_pWindow),
+          m_pNextNotebookStack (NULL)
+    {}
+
+    wxWindow*           m_pWindow;
+    cbNotebookStack*    m_pNextNotebookStack;
+};
+
+/*
  * No description
  */
 class DLLIMPORT EditorManager : public Mgr<EditorManager>, public wxEvtHandler
@@ -59,6 +73,7 @@
         virtual void operator=(const EditorManager& rhs){ cbThrow(_T("Can't assign an EditorManager* !!!")); }
 
         wxAuiNotebook* GetNotebook(){ return m_pNotebook; }
+        cbNotebookStack* GetNotebookStack();
         void CreateMenu(wxMenuBar* menuBar);
         void ReleaseMenu(wxMenuBar* menuBar);
         void Configure();
@@ -174,6 +189,9 @@
         wxFileName FindHeaderSource(const wxArrayString& candidateFilesArray, const wxFileName& activeFile, bool& isCandidate);
 
         wxAuiNotebook* m_pNotebook;
+        cbNotebookStack* m_pNotebookStackHead;
+        cbNotebookStack* m_pNotebookStackTail;
+        size_t m_nNotebookStackSize;
         cbFindReplaceData* m_LastFindReplaceData;
         EditorColourSet* m_Theme;
         ListCtrlLogger* m_pSearchLog;
Index: src/sdk/editormanager.cpp
===================================================================
--- src/sdk/editormanager.cpp (revision 6080)
+++ src/sdk/editormanager.cpp (working copy)
@@ -156,6 +156,9 @@
 
 EditorManager::EditorManager()
         : m_pNotebook(0L),
+        m_pNotebookStackHead(new cbNotebookStack),
+        m_pNotebookStackTail(m_pNotebookStackHead),
+        m_nNotebookStackSize(0),
         m_LastFindReplaceData(0L),
         m_pSearchLog(0),
         m_SearchLogIndex(-1),
@@ -192,6 +195,55 @@
     Manager::Get()->GetConfigManager(_T("editor"))->Write(_T("/zoom"), m_zoom);
 }
 
+cbNotebookStack* EditorManager::GetNotebookStack()
+{
+    bool bFounded = false;
+    wxWindow* pWindow;
+    cbNotebookStack* pNotebookStack;
+    cbNotebookStack* pPrevNotebookStack;
+
+    while(m_nNotebookStackSize != m_pNotebook->GetPageCount()) //Sync stack with Notebook
+    {
+        if(m_nNotebookStackSize < m_pNotebook->GetPageCount())
+        {
+            for(size_t i = 0; i<m_pNotebook->GetPageCount(); ++i)
+            {
+                pWindow = m_pNotebook->GetPage(i);
+                bFounded = false;
+                for (pNotebookStack = m_pNotebookStackHead->m_pNextNotebookStack; pNotebookStack != NULL; pNotebookStack = pNotebookStack->m_pNextNotebookStack)
+                {
+                    if(pWindow == pNotebookStack->m_pWindow)
+                    {
+                        bFounded = true;
+                        break;
+                    }
+                }
+                if(!bFounded)
+                {
+                    m_pNotebookStackTail->m_pNextNotebookStack = new cbNotebookStack(pWindow);
+                    m_pNotebookStackTail = m_pNotebookStackTail->m_pNextNotebookStack;
+                    ++m_nNotebookStackSize;
+                }
+            }
+        }
+        if(m_nNotebookStackSize > m_pNotebook->GetPageCount())
+        {
+            for (pPrevNotebookStack = m_pNotebookStackHead, pNotebookStack = pPrevNotebookStack->m_pNextNotebookStack; pNotebookStack != NULL; pPrevNotebookStack = pNotebookStack, pNotebookStack = pNotebookStack->m_pNextNotebookStack)
+            {
+                if(m_pNotebook->GetPageIndex(pNotebookStack->m_pWindow) == wxNOT_FOUND)
+                {
+                    pPrevNotebookStack->m_pNextNotebookStack = pNotebookStack->m_pNextNotebookStack;
+                    delete pNotebookStack;
+                    --m_nNotebookStackSize;
+                    pNotebookStack = pPrevNotebookStack;
+                }
+            }
+        }
+    }
+
+    return m_pNotebookStackHead->m_pNextNotebookStack;
+}
+
 void EditorManager::CreateMenu(wxMenuBar* menuBar)
 {
 }
@@ -2510,6 +2562,32 @@
     CodeBlocksEvent evt(cbEVT_EDITOR_ACTIVATED, -1, 0, eb);
     Manager::Get()->GetPluginManager()->NotifyPlugins(evt);
 
+    wxWindow* pWindow;
+    cbNotebookStack* pNotebookStack;
+    cbNotebookStack* pPrevNotebookStack;
+    pWindow = m_pNotebook->GetPage(event.GetSelection());
+    for (pPrevNotebookStack = m_pNotebookStackHead, pNotebookStack = pPrevNotebookStack->m_pNextNotebookStack; pNotebookStack != NULL; pPrevNotebookStack = pNotebookStack, pNotebookStack = pNotebookStack->m_pNextNotebookStack)
+    {
+        if(pWindow == pNotebookStack->m_pWindow)
+        {
+            if(m_pNotebookStackTail == pNotebookStack)
+            {
+                m_pNotebookStackTail = pPrevNotebookStack;
+            }
+            pPrevNotebookStack->m_pNextNotebookStack = pNotebookStack->m_pNextNotebookStack;
+            pNotebookStack->m_pNextNotebookStack = m_pNotebookStackHead->m_pNextNotebookStack;
+            m_pNotebookStackHead->m_pNextNotebookStack = pNotebookStack;
+            break;
+        }
+    }
+    if((m_pNotebookStackHead->m_pNextNotebookStack == NULL)||(pWindow != m_pNotebookStackHead->m_pNextNotebookStack->m_pWindow))
+    {
+        pNotebookStack = new cbNotebookStack(pWindow);
+        pNotebookStack->m_pNextNotebookStack = m_pNotebookStackHead->m_pNextNotebookStack;
+        m_pNotebookStackHead->m_pNextNotebookStack = pNotebookStack;
+        ++m_nNotebookStackSize;
+    }
+
     // focus editor on next update event
     m_pData->m_SetFocusFlag = true;
 
@@ -2539,6 +2617,21 @@
         if (!QueryClose(eb))
             event.Veto();
     }
+
+    wxWindow* pWindow;
+    cbNotebookStack* pNotebookStack;
+    cbNotebookStack* pPrevNotebookStack;
+    pWindow = m_pNotebook->GetPage(event.GetSelection());
+    for (pPrevNotebookStack = m_pNotebookStackHead, pNotebookStack = pPrevNotebookStack->m_pNextNotebookStack; pNotebookStack != NULL; pPrevNotebookStack = pNotebookStack, pNotebookStack = pNotebookStack->m_pNextNotebookStack)
+    {
+        if(pWindow == pNotebookStack->m_pWindow)
+        {
+            pPrevNotebookStack->m_pNextNotebookStack = pNotebookStack->m_pNextNotebookStack;
+            delete pNotebookStack;
+            --m_nNotebookStackSize;
+            break;
+        }
+    }
     event.Skip(); // allow others to process it too
 }
 
Index: src/src/environmentsettingsdlg.cpp
===================================================================
--- src/src/environmentsettingsdlg.cpp (revision 6080)
+++ src/src/environmentsettingsdlg.cpp (working copy)
@@ -170,6 +170,7 @@
     // tab "Notebook"
     XRCCTRL(*this, "cmbEditorTabs", wxComboBox)->SetSelection(cfg->ReadInt(_T("/environment/tabs_style"), 0));
     XRCCTRL(*this, "chkListTabs", wxCheckBox)->SetValue(cfg->ReadBool(_T("/environment/tabs_list"), 0));
+    XRCCTRL(*this, "chkStackedBasedTabSwitching", wxCheckBox)->SetValue(cfg->ReadBool(_T("/environment/stacked_based_tab_switching"), 0));
 
     // tab "Docking"
     XRCCTRL(*this, "spnAuiBorder", wxSpinCtrl)->SetValue(cfg->ReadInt(_T("/environment/aui/border_size"), m_pArt->GetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE)));
@@ -409,6 +410,7 @@
         // tab "Appearence"
         cfg->Write(_T("/environment/tabs_style"),           (int)XRCCTRL(*this, "cmbEditorTabs", wxComboBox)->GetSelection());
         cfg->Write(_T("/environment/tabs_list"),           (bool)XRCCTRL(*this, "chkListTabs", wxCheckBox)->GetValue());
+        cfg->Write(_T("/environment/stacked_based_tab_switching"),(bool)XRCCTRL(*this, "chkStackedBasedTabSwitching", wxCheckBox)->GetValue());
         cfg->Write(_T("/environment/aui/border_size"),          (int)XRCCTRL(*this, "spnAuiBorder", wxSpinCtrl)->GetValue());
         cfg->Write(_T("/environment/aui/sash_size"),            (int)XRCCTRL(*this, "spnAuiSash", wxSpinCtrl)->GetValue());
         cfg->Write(_T("/environment/aui/caption_size"),         (int)XRCCTRL(*this, "spnAuiCaption", wxSpinCtrl)->GetValue());
Index: src/src/main.cpp
===================================================================
--- src/src/main.cpp (revision 6080)
+++ src/src/main.cpp (working copy)
@@ -4010,27 +4010,64 @@
     // Create container and add all open editors:
     wxSwitcherItems items;
     items.AddGroup(_("Open files"), wxT("editors"));
-    for (size_t i = 0; i < nb->GetPageCount(); ++i)
-    {
-        wxString title = nb->GetPageText(i);
-        wxWindow* window = nb->GetPage(i);
 
-        items.AddItem(title, title, i, nb->GetPageBitmap(i)).SetWindow(window);
+    ConfigManager* pCfg = Manager::Get()->GetConfigManager(_T("app"));
+    if (!pCfg->ReadBool(_T("/environment/stacked_based_tab_switching")))
+    {   // Switch tabs editor with tab order
+        for (size_t i = 0; i < nb->GetPageCount(); ++i)
+        {
+            wxString title = nb->GetPageText(i);
+            wxWindow* window = nb->GetPage(i);
+
+            items.AddItem(title, title, i, nb->GetPageBitmap(i)).SetWindow(window);
+        }
+
+        // Select the focused editor:
+        int idx = items.GetIndexForFocus();
+        if (idx != wxNOT_FOUND)
+        {
+            items.SetSelection(idx);
+        }
     }
+    else
+    {   // Switch tabs editor with last used order
+        size_t nIndex = 0;
+        cbNotebookStack* pNotebookStack;
+        for (pNotebookStack = Manager::Get()->GetEditorManager()->GetNotebookStack() ; pNotebookStack != NULL; pNotebookStack = pNotebookStack->m_pNextNotebookStack)
+        {
+            nIndex = nb->GetPageIndex(pNotebookStack->m_pWindow);
+            if (nIndex == (size_t) wxNOT_FOUND)
+            {
+                continue;
+            }
+            wxString title = nb->GetPageText(nIndex);
 
-    // Select the focused editor:
-    int idx = items.GetIndexForFocus();
-    if (idx != wxNOT_FOUND)
-        items.SetSelection(idx);
+            items.AddItem(title, title, nIndex, nb->GetPageBitmap(nIndex)).SetWindow(pNotebookStack->m_pWindow);
+        }
 
+        // Select the focused editor:
+        if(items.GetItemCount() > 2)
+        {   // CTRL + TAB directly select the last editor, not the current one
+            items.SetSelection(2);
+        }
+        else
+        {
+            items.SetSelection(items.GetItemCount()-1);
+        }
+    }
+
     // Create the switcher dialog
     wxSwitcherDialog dlg(items, wxGetApp().GetTopWindow());
 
     // Ctrl+Tab workaround for non windows platforms:
     if (platform::cocoa)
+    {
         dlg.SetModifierKey(WXK_ALT);
+    }
     else if (platform::gtk)
+    {
         dlg.SetExtraNavigationKey(wxT(','));
+    }
 
     // Finally show the dialog:
     int answer = dlg.ShowModal();
Index: src/src/resources/env_settings.xrc
===================================================================
--- src/src/resources/env_settings.xrc (revision 6080)
+++ src/src/resources/env_settings.xrc (working copy)
@@ -398,6 +398,13 @@
  <flag>wxALL|wxALIGN_LEFT|wxALIGN_TOP</flag>
  <border>8</border>
  </object>
+ <object class="sizeritem">
+ <object class="wxCheckBox" name="chkStackedBasedTabSwitching">
+ <label>Use stacked based tab-switching</label>
+ </object>
+ <flag>wxALL|wxALIGN_LEFT|wxALIGN_TOP</flag>
+ <border>8</border>
+ </object>
  </object>
  </object>
  <label>Notebooks appearance</label>
Index: src/src/switcherdlg.cpp
===================================================================
--- src/src/switcherdlg.cpp (revision 6080)
+++ src/src/switcherdlg.cpp (working copy)
@@ -509,26 +509,45 @@
 
         Refresh();
     }
-    else
-    {
-        int idx = m_items.HitTest(event.GetPosition());
+    else if (event.GetButton() == wxMOUSE_BTN_NONE)
+    {   // Mouse move
+        bool bCanSelectItem = true;
+        if (m_ptMouse.x != -2 && m_ptMouse.y != -2)
+        {   // If ==-2 => Don't select item on mouse pointer : used when user select the window with keyboard
+            if (m_ptMouse.x != -1 && m_ptMouse.y != -1)
+            {   // If ==-1 => The client already move the mouse, select the item under the mouse cursor
+                wxPoint ptCurrent = ClientToScreen(event.GetPosition());
+                if (abs(ptCurrent.x - m_ptMouse.x) >= 3 || abs(ptCurrent.y - m_ptMouse.y) >= 3)
+                {   // the user has moved the mouse over a 3 pixels square
+                    m_ptMouse.x = m_ptMouse.y = -1; // Accept to select an item
+                }
+                else
+                {   // Select this item is not allowed for the moment, the user must move the mouse
+                    bCanSelectItem = false;
+                }
+            }
 
-        if (idx != wxNOT_FOUND)
-        {
-            m_items.SetSelection(idx);
+            if (bCanSelectItem)
+            {
+                int idx = m_items.HitTest(event.GetPosition());
 
-            GenerateSelectionEvent();
+                if (idx != wxNOT_FOUND)
+                {
+                    m_items.SetSelection(idx);
 
-            Refresh();
-        }
+                    GenerateSelectionEvent();
 
-        if (event.LeftDown())
-        {
-            SendCloseEvent();
-
-            SetFocus();
+                    Refresh();
+                }
+            }
         }
     }
+    else if (event.LeftDown())
+    {
+        m_ptMouse.x = m_ptMouse.y = -1; // Accept to select an item
+        SendCloseEvent();
+        SetFocus();
+    }
 }
 
 void wxMultiColumnListCtrl::OnChar(wxKeyEvent& WXUNUSED(event))
@@ -541,6 +560,8 @@
     {
         if (event.GetKeyCode() == GetModifierKey())
         {
+            // The window will close, don't select the item under mouse pointer
+            m_ptMouse.x = m_ptMouse.y = -2;
             SendCloseEvent();
         }
         event.Skip();
@@ -549,6 +570,9 @@
 
     if (event.GetKeyCode() == WXK_ESCAPE || event.GetKeyCode() == WXK_RETURN)
     {
+        // The window will close, don't select the item under mouse pointer
+        m_ptMouse.x = m_ptMouse.y = -2;
+
         if (event.GetKeyCode() == WXK_ESCAPE)
             m_items.SetSelection(-1);
 
@@ -802,6 +826,7 @@
     m_overallSize = wxSize(200, 100);
     m_modifierKey = WXK_CONTROL;
     m_extraNavigationKey = 0;
+    m_ptMouse = wxGetMousePosition();
 }
 
 /*!
Index: src/src/switcherdlg.h
===================================================================
--- src/src/switcherdlg.h (revision 6080)
+++ src/src/switcherdlg.h (working copy)
@@ -233,7 +233,15 @@
     void SendCloseEvent();
 
 protected:
-
+    /**
+     * Mouse point initialized on Init function.
+     *
+     * Used because if the mouse is over the dialog when it's opened, it automatically
+     * select the item under the mouse pointer.
+     * Recording the mouse pointer position when the dialog is opened prevent this :
+     * select the item only if the user move the mouse.
+    */
+    wxPoint             m_ptMouse;
     wxSwitcherItems     m_items;
     wxSize              m_overallSize;
     int                 m_extraNavigationKey;

--- End code ---

Thanks for all to give me Feedback.
I place comments into my Codeblocks source patch. I don't see very often comments into source code (specially into .h), I don't know if it's good or not to place comments (into javadoc format).

Alatar:
Added new version of patch to tracker - http://developer.berlios.de/patch/index.php?func=detailpatch&patch_id=2902&group_id=5358

Included all changes from Feneck91`s last patch.
Some code cleanup, simplify code in functions GetNotebookStack(), OnPageChanged() and OnPageClose().
Added stack deletion and rebuild stack function.
If we not using stack based tab switching, we don`t manage stack. But I don`t know, where should I rebuild stack, when it turn on in settings. For now I place this code into EnvironmentSettingsDlg::EndModal(), but it seems wrong - there are no such code. Marting, what do you think?

Feneck91, by the way, don`t use long camel case names for local variables - this is not Code::Blocks style =) .

Feneck91:

--- Code: ---Feneck91, by the way, don`t use long camel case names for local variables
--- End code ---
I'm sorry, I didn't understand. What is camel  case name ?

Alatar:

--- Quote from: Feneck91 on January 15, 2010, 05:03:59 am ---I'm sorry, I didn't understand. What is camel  case name ?

--- End quote ---
ItIsSameAsMixedCase ;)
http://en.wikipedia.org/wiki/CamelCase

MortenMacFly:

--- Quote from: Feneck91 on January 15, 2010, 05:03:59 am ---
--- Code: ---Feneck91, by the way, don`t use [b]long[/b] camel case names for local variables
--- End code ---
I'm sorry, I didn't understand. What is camel  case name ?

--- End quote ---
I think whar he meant was the long names. As variable names that are too long make the code harder to read.

Navigation

[0] Message Index

[#] Next page

[*] Previous page

Go to full version