X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/b6418695cadff0d160607079ea3b9876e5359112..bc119dd5069b28778899b70ceb80bbe701e6c951:/src/aui/auibook.cpp diff --git a/src/aui/auibook.cpp b/src/aui/auibook.cpp index 07cf4c0216..6de8fcede5 100644 --- a/src/aui/auibook.cpp +++ b/src/aui/auibook.cpp @@ -71,7 +71,7 @@ static wxBitmap BitmapFromBits(const unsigned char bits[], int w, int h, return wxBitmap(img); } -static void DrawButton(wxDC& dc, +static void DrawButtonS(wxDC& dc, const wxRect& _rect, const wxBitmap& bmp, const wxColour& bkcolour, @@ -123,11 +123,51 @@ wxDefaultTabArt::wxDefaultTabArt() m_normal_bkpen = wxPen(normaltab_colour); m_selected_bkbrush = wxBrush(selectedtab_colour); m_selected_bkpen = wxPen(selectedtab_colour); + + +#if defined( __WXMAC__ ) + static unsigned char close_bits[]={ + 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFE, 0x03, 0xF8, 0x01, 0xF0, 0x19, 0xF3, + 0xB8, 0xE3, 0xF0, 0xE1, 0xE0, 0xE0, 0xF0, 0xE1, 0xB8, 0xE3, 0x19, 0xF3, + 0x01, 0xF0, 0x03, 0xF8, 0x0F, 0xFE, 0xFF, 0xFF }; +#elif defined( __WXGTK__) + static unsigned char close_bits[]={ + 0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xfb, 0xef, 0xdb, 0xed, 0x8b, 0xe8, + 0x1b, 0xec, 0x3b, 0xee, 0x1b, 0xec, 0x8b, 0xe8, 0xdb, 0xed, 0xfb, 0xef, + 0x07, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; +#else + static unsigned char close_bits[]={ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xef,0xfb,0xcf,0xf9, + 0x9f,0xfc,0x3f,0xfe,0x3f,0xfe,0x9f,0xfc,0xcf,0xf9,0xef,0xfb, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; +#endif + + static unsigned char left_bits[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xfe, 0x3f, 0xfe, + 0x1f, 0xfe, 0x0f, 0xfe, 0x1f, 0xfe, 0x3f, 0xfe, 0x7f, 0xfe, 0xff, 0xfe, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + + static unsigned char right_bits[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0x9f, 0xff, 0x1f, 0xff, + 0x1f, 0xfe, 0x1f, 0xfc, 0x1f, 0xfe, 0x1f, 0xff, 0x9f, 0xff, 0xdf, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + + m_active_close_bmp = BitmapFromBits(close_bits, 16, 16, *wxBLACK); + m_disabled_close_bmp = BitmapFromBits(close_bits, 16, 16, wxColour(128,128,128)); + + m_active_left_bmp = BitmapFromBits(left_bits, 16, 16, *wxBLACK); + m_disabled_left_bmp = BitmapFromBits(left_bits, 16, 16, wxColour(128,128,128)); + + m_active_right_bmp = BitmapFromBits(right_bits, 16, 16, *wxBLACK); + m_disabled_right_bmp = BitmapFromBits(right_bits, 16, 16, wxColour(128,128,128)); +} + +wxDefaultTabArt::~wxDefaultTabArt() +{ } -void wxDefaultTabArt::DrawBackground( - wxDC* dc, - const wxRect& rect) +void wxDefaultTabArt::DrawBackground(wxDC* dc, + const wxRect& rect) { // draw background dc->SetBrush(m_bkbrush); @@ -139,6 +179,7 @@ void wxDefaultTabArt::DrawBackground( dc->DrawLine(0, rect.GetHeight()-1, rect.GetWidth(), rect.GetHeight()-1); } + // DrawTab() draws an individual tab. // // dc - output dc @@ -149,41 +190,35 @@ void wxDefaultTabArt::DrawBackground( // x_extent - the advance x; where the next tab should start void wxDefaultTabArt::DrawTab(wxDC* dc, - const wxRect& in_rect, - const wxString& caption_text, - bool active, - wxRect* out_rect, - int* x_extent) + const wxRect& in_rect, + const wxString& caption_text, + bool active, + wxRect* out_rect, + int* x_extent) { wxCoord normal_textx, normal_texty; wxCoord selected_textx, selected_texty; - wxCoord measured_textx, measured_texty; wxCoord textx, texty; - - + // if the caption is empty, measure some temporary text wxString caption = caption_text; if (caption_text.empty()) caption = wxT("Xj"); - - // measure text - dc->SetFont(m_measuring_font); - dc->GetTextExtent(caption, &measured_textx, &measured_texty); - + dc->SetFont(m_selected_font); dc->GetTextExtent(caption, &selected_textx, &selected_texty); - + dc->SetFont(m_normal_font); dc->GetTextExtent(caption, &normal_textx, &normal_texty); + + // figure out the size of the tab + wxSize tab_size = GetTabSize(dc, caption, active, x_extent); - caption = caption_text; - - wxCoord tab_height = measured_texty + 4; - wxCoord tab_width = measured_textx + tab_height + 5; + wxCoord tab_height = tab_size.y; + wxCoord tab_width = tab_size.x; wxCoord tab_x = in_rect.x; wxCoord tab_y = in_rect.y + in_rect.height - tab_height; - // select pen, brush and font for the tab to be drawn if (active) @@ -233,13 +268,108 @@ void wxDefaultTabArt::DrawTab(wxDC* dc, dc->DrawText(caption, tab_x + (tab_height/3) + (tab_width/2) - (textx/2), - tab_y + tab_height - texty - 2); + (tab_y + tab_height)/2 - (texty/2) + 1); *out_rect = wxRect(tab_x, tab_y, tab_width, tab_height); +} + + +wxSize wxDefaultTabArt::GetTabSize(wxDC* dc, + const wxString& caption, + bool WXUNUSED(active), + int* x_extent) +{ + wxCoord measured_textx, measured_texty; + + dc->SetFont(m_measuring_font); + dc->GetTextExtent(caption, &measured_textx, &measured_texty); + + wxCoord tab_height = measured_texty + 4; + wxCoord tab_width = measured_textx + tab_height + 5; + *x_extent = tab_width - (tab_height/2) - 1; + + return wxSize(tab_width, tab_height); } +void wxDefaultTabArt::DrawButton( + wxDC* dc, + const wxRect& in_rect, + int bitmap_id, + int button_state, + int orientation, + const wxBitmap& bitmap_override, + wxRect* out_rect) +{ + wxBitmap bmp; + wxRect rect; + + if (bitmap_override.IsOk()) + { + bmp = bitmap_override; + } + else + { + switch (bitmap_id) + { + case wxAUI_BUTTON_CLOSE: + if (button_state & wxAUI_BUTTON_STATE_DISABLED) + bmp = m_disabled_close_bmp; + else + bmp = m_active_close_bmp; + break; + case wxAUI_BUTTON_LEFT: + if (button_state & wxAUI_BUTTON_STATE_DISABLED) + bmp = m_disabled_left_bmp; + else + bmp = m_active_left_bmp; + break; + case wxAUI_BUTTON_RIGHT: + if (button_state & wxAUI_BUTTON_STATE_DISABLED) + bmp = m_disabled_right_bmp; + else + bmp = m_active_right_bmp; + break; + } + } + + if (!bmp.IsOk()) + return; + + rect = in_rect; + + if (orientation == wxLEFT) + { + rect.SetX(in_rect.x); + rect.SetY(((in_rect.y + in_rect.height)/2) - (bmp.GetHeight()/2)); + rect.SetWidth(bmp.GetWidth()); + rect.SetHeight(bmp.GetHeight()); + } + else + { + rect = wxRect(in_rect.x + in_rect.width - bmp.GetWidth(), + ((in_rect.y + in_rect.height)/2) - (bmp.GetHeight()/2), + bmp.GetWidth(), bmp.GetHeight()); + } + + + DrawButtonS(*dc, rect, bmp, *wxWHITE, button_state); + + *out_rect = rect; +} + + + +int wxDefaultTabArt::GetBestTabCtrlSize(wxWindow* wnd) +{ + wxClientDC dc(wnd); + dc.SetFont(m_measuring_font); + int x_ext = 0; + wxSize s = GetTabSize(&dc, wxT("ABCDEFGHIj"), true, &x_ext); + return s.y+3; +} + void wxDefaultTabArt::SetNormalFont(const wxFont& font) { m_normal_font = font; @@ -275,7 +405,12 @@ void wxDefaultTabArt::SetMeasuringFont(const wxFont& font) wxAuiTabContainer::wxAuiTabContainer() { + m_tab_offset = 0; m_art = new wxDefaultTabArt; + + AddButton(wxAUI_BUTTON_LEFT, wxLEFT); + AddButton(wxAUI_BUTTON_RIGHT, wxRIGHT); + AddButton(wxAUI_BUTTON_CLOSE, wxRIGHT); } wxAuiTabContainer::~wxAuiTabContainer() @@ -342,6 +477,25 @@ bool wxAuiTabContainer::InsertPage(wxWindow* page, return true; } +bool wxAuiTabContainer::MovePage(wxWindow* page, + size_t new_idx) +{ + int idx = GetIdxFromWindow(page); + if (idx == -1) + return false; + + // get page entry, make a copy of it + wxAuiNotebookPage p = GetPage(idx); + + // remove old page entry + RemovePage(page); + + // insert page where it should be + InsertPage(page, p, new_idx); + + return true; +} + bool wxAuiTabContainer::RemovePage(wxWindow* wnd) { size_t i, page_count = m_pages.GetCount(); @@ -448,18 +602,30 @@ size_t wxAuiTabContainer::GetPageCount() const return m_pages.GetCount(); } -void wxAuiTabContainer::AddButton(int id, int location, const wxBitmap& bmp) +void wxAuiTabContainer::AddButton(int id, + int location, + const wxBitmap& normal_bitmap, + const wxBitmap& disabled_bitmap) { wxAuiTabContainerButton button; button.id = id; - button.bitmap = bmp; + button.bitmap = normal_bitmap; + button.dis_bitmap = disabled_bitmap; button.location = location; button.cur_state = wxAUI_BUTTON_STATE_NORMAL; m_buttons.Add(button); } +size_t wxAuiTabContainer::GetTabOffset() const +{ + return m_tab_offset; +} +void wxAuiTabContainer::SetTabOffset(size_t offset) +{ + m_tab_offset = offset; +} // Render() renders the tab catalog to the specified DC // It is a virtual function and can be overridden to @@ -468,35 +634,122 @@ void wxAuiTabContainer::Render(wxDC* raw_dc) { wxMemoryDC dc; wxBitmap bmp; + size_t i; + size_t page_count = m_pages.GetCount(); + size_t button_count = m_buttons.GetCount(); + + // create off-screen bitmap bmp.Create(m_rect.GetWidth(), m_rect.GetHeight()); dc.SelectObject(bmp); + + // find out if size of tabs is larger than can be + // afforded on screen + int total_width = 0; + int visible_width = 0; + for (i = 0; i < page_count; ++i) + { + wxAuiNotebookPage& page = m_pages.Item(i); + int x_extent = 0; + wxSize size = m_art->GetTabSize(&dc, page.caption, page.active, &x_extent); + + if (i+1 < page_count) + total_width += x_extent; + else + total_width += size.x; + + if (i >= m_tab_offset) + { + if (i+1 < page_count) + visible_width += x_extent; + else + visible_width += size.x; + } + } + + if (total_width > m_rect.GetWidth() - 20 || m_tab_offset != 0) + { + // show left/right buttons + for (i = 0; i < button_count; ++i) + { + wxAuiTabContainerButton& button = m_buttons.Item(i); + if (button.id == wxAUI_BUTTON_LEFT || + button.id == wxAUI_BUTTON_RIGHT) + { + button.cur_state &= ~wxAUI_BUTTON_STATE_HIDDEN; + } + } + } + else + { + // hide left/right buttons + for (i = 0; i < button_count; ++i) + { + wxAuiTabContainerButton& button = m_buttons.Item(i); + if (button.id == wxAUI_BUTTON_LEFT || + button.id == wxAUI_BUTTON_RIGHT) + { + button.cur_state |= wxAUI_BUTTON_STATE_HIDDEN; + } + } + } + + // determine whether left button should be enabled + for (i = 0; i < button_count; ++i) + { + wxAuiTabContainerButton& button = m_buttons.Item(i); + if (button.id == wxAUI_BUTTON_LEFT) + { + if (m_tab_offset == 0) + button.cur_state |= wxAUI_BUTTON_STATE_DISABLED; + else + button.cur_state &= ~wxAUI_BUTTON_STATE_DISABLED; + } + if (button.id == wxAUI_BUTTON_RIGHT) + { + if (visible_width < m_rect.GetWidth() - ((int)button_count*16)) + button.cur_state |= wxAUI_BUTTON_STATE_DISABLED; + else + button.cur_state &= ~wxAUI_BUTTON_STATE_DISABLED; + } + } + + + + // draw background m_art->DrawBackground(&dc, m_rect); + // draw buttons + int left_buttons_width = 0; + int right_buttons_width = 0; + int offset = 0; - size_t i; // draw the buttons on the right side offset = m_rect.x + m_rect.width; - size_t button_count = m_buttons.GetCount(); for (i = 0; i < button_count; ++i) { wxAuiTabContainerButton& button = m_buttons.Item(button_count - i - 1); if (button.location != wxRIGHT) continue; - - wxRect button_rect(offset - button.bitmap.GetWidth(), 1, - button.bitmap.GetWidth(), button.bitmap.GetHeight()); - - button.rect = button_rect; - - DrawButton(dc, button.rect, button.bitmap, - //m_bkbrush.GetColour(), - *wxWHITE, - button.cur_state); - - offset -= button.bitmap.GetWidth(); + if (button.cur_state & wxAUI_BUTTON_STATE_HIDDEN) + continue; + + wxRect button_rect = m_rect; + button_rect.SetY(1); + button_rect.SetWidth(offset); + + m_art->DrawButton(&dc, + button_rect, + button.id, + button.cur_state, + wxRIGHT, + wxNullBitmap, + &button.rect); + + offset -= button.rect.GetWidth(); + right_buttons_width += button.rect.GetWidth(); } @@ -511,24 +764,31 @@ void wxAuiTabContainer::Render(wxDC* raw_dc) if (button.location != wxLEFT) continue; - - wxRect button_rect(offset, 1, - button.bitmap.GetWidth(), - button.bitmap.GetHeight()); - - button.rect = button_rect; - - DrawButton(dc, button.rect, button.bitmap, - //m_bkbrush.GetColour(), - *wxWHITE, - button.cur_state); - - offset += button.bitmap.GetWidth(); + if (button.cur_state & wxAUI_BUTTON_STATE_HIDDEN) + continue; + + wxRect button_rect(offset, 1, 1000, m_rect.height); + + m_art->DrawButton(&dc, + button_rect, + button.id, + button.cur_state, + wxLEFT, + wxNullBitmap, + &button.rect); + + offset += button.rect.GetWidth(); + left_buttons_width += button.rect.GetWidth(); } + offset = left_buttons_width; + + dc.SetClippingRegion(left_buttons_width, 0, + m_rect.GetWidth() - right_buttons_width - left_buttons_width - 2, + m_rect.GetHeight()); + // draw the tabs - size_t page_count = m_pages.GetCount(); size_t active = 999; int active_offset = 0; @@ -539,7 +799,7 @@ void wxAuiTabContainer::Render(wxDC* raw_dc) rect.width = 1000; rect.height = m_rect.height; - for (i = 0; i < page_count; ++i) + for (i = m_tab_offset; i < page_count; ++i) { wxAuiNotebookPage& page = m_pages.Item(i); @@ -562,7 +822,7 @@ void wxAuiTabContainer::Render(wxDC* raw_dc) } // draw the active tab again so it stands in the foreground - if (active < m_pages.GetCount()) + if (active >= m_tab_offset && active < m_pages.GetCount()) { wxAuiNotebookPage& page = m_pages.Item(active); @@ -575,8 +835,11 @@ void wxAuiTabContainer::Render(wxDC* raw_dc) &x_extent); } - - raw_dc->Blit(m_rect.x, m_rect.y, m_rect.GetWidth(), m_rect.GetHeight(), &dc, 0, 0); + dc.DestroyClippingRegion(); + + raw_dc->Blit(m_rect.x, m_rect.y, + m_rect.GetWidth(), m_rect.GetHeight(), + &dc, 0, 0); } @@ -587,15 +850,19 @@ bool wxAuiTabContainer::TabHitTest(int x, int y, wxWindow** hit) const { if (!m_rect.Contains(x,y)) return false; + + if (ButtonHitTest(x, y, NULL)) + return false; size_t i, page_count = m_pages.GetCount(); - for (i = 0; i < page_count; ++i) + for (i = m_tab_offset; i < page_count; ++i) { wxAuiNotebookPage& page = m_pages.Item(i); if (page.rect.Contains(x,y)) { - *hit = page.window; + if (hit) + *hit = page.window; return true; } } @@ -618,7 +885,8 @@ bool wxAuiTabContainer::ButtonHitTest(int x, int y, wxAuiTabContainerButton& button = m_buttons.Item(i); if (button.rect.Contains(x,y)) { - *hit = &button; + if (hit) + *hit = &button; return true; } } @@ -679,7 +947,6 @@ void wxAuiTabContainer::DoShowHide() // -- wxAuiTabCtrl class implementation -- -const int wxAuiButtonClose = 101; BEGIN_EVENT_TABLE(wxAuiTabCtrl, wxControl) EVT_PAINT(wxAuiTabCtrl::OnPaint) @@ -689,6 +956,7 @@ BEGIN_EVENT_TABLE(wxAuiTabCtrl, wxControl) EVT_LEFT_UP(wxAuiTabCtrl::OnLeftUp) EVT_MOTION(wxAuiTabCtrl::OnMotion) EVT_LEAVE_WINDOW(wxAuiTabCtrl::OnLeaveWindow) + EVT_AUINOTEBOOK_BUTTON(-1, wxAuiTabCtrl::OnButton) END_EVENT_TABLE() @@ -701,28 +969,11 @@ wxAuiTabCtrl::wxAuiTabCtrl(wxWindow* parent, m_click_pt = wxDefaultPosition; m_is_dragging = false; m_hover_button = NULL; - - // FIXME: copied from dockart-- needs to put in a common place -#if defined( __WXMAC__ ) - static unsigned char close_bits[]={ - 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFE, 0x03, 0xF8, 0x01, 0xF0, 0x19, 0xF3, - 0xB8, 0xE3, 0xF0, 0xE1, 0xE0, 0xE0, 0xF0, 0xE1, 0xB8, 0xE3, 0x19, 0xF3, - 0x01, 0xF0, 0x03, 0xF8, 0x0F, 0xFE, 0xFF, 0xFF }; -#elif defined( __WXGTK__) - static unsigned char close_bits[]={ - 0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xfb, 0xef, 0xdb, 0xed, 0x8b, 0xe8, - 0x1b, 0xec, 0x3b, 0xee, 0x1b, 0xec, 0x8b, 0xe8, 0xdb, 0xed, 0xfb, 0xef, - 0x07, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; -#else - static unsigned char close_bits[]={ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xef,0xfb,0xcf,0xf9, - 0x9f,0xfc,0x3f,0xfe,0x3f,0xfe,0x9f,0xfc,0xcf,0xf9,0xef,0xfb, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; -#endif - - AddButton(101, wxRIGHT, BitmapFromBits(close_bits, 16, 16, *wxBLACK)); } +wxAuiTabCtrl::~wxAuiTabCtrl() +{ +} void wxAuiTabCtrl::OnPaint(wxPaintEvent&) { @@ -750,7 +1001,7 @@ void wxAuiTabCtrl::OnLeftDown(wxMouseEvent& evt) CaptureMouse(); m_click_pt = wxDefaultPosition; m_is_dragging = false; - m_click_tab = -1; + m_click_tab = NULL; wxWindow* wnd; if (TabHitTest(evt.m_x, evt.m_y, &wnd)) @@ -763,7 +1014,7 @@ void wxAuiTabCtrl::OnLeftDown(wxMouseEvent& evt) m_click_pt.x = evt.m_x; m_click_pt.y = evt.m_y; - m_click_tab = e.GetSelection(); + m_click_tab = wnd; } if (m_hover_button) @@ -782,8 +1033,8 @@ void wxAuiTabCtrl::OnLeftUp(wxMouseEvent&) if (m_is_dragging) { wxAuiNotebookEvent evt(wxEVT_COMMAND_AUINOTEBOOK_END_DRAG, m_windowId); - evt.SetSelection(m_click_tab); - evt.SetOldSelection(m_click_tab); + evt.SetSelection(GetIdxFromWindow(m_click_tab)); + evt.SetOldSelection(evt.GetSelection()); evt.SetEventObject(this); GetEventHandler()->ProcessEvent(evt); return; @@ -795,15 +1046,18 @@ void wxAuiTabCtrl::OnLeftUp(wxMouseEvent&) Refresh(); Update(); - wxAuiNotebookEvent evt(wxEVT_COMMAND_AUINOTEBOOK_BUTTON, m_windowId); - evt.SetInt(m_hover_button->id); - evt.SetEventObject(this); - GetEventHandler()->ProcessEvent(evt); + if (!(m_hover_button->cur_state & wxAUI_BUTTON_STATE_DISABLED)) + { + wxAuiNotebookEvent evt(wxEVT_COMMAND_AUINOTEBOOK_BUTTON, m_windowId); + evt.SetInt(m_hover_button->id); + evt.SetEventObject(this); + GetEventHandler()->ProcessEvent(evt); + } } m_click_pt = wxDefaultPosition; m_is_dragging = false; - m_click_tab = -1; + m_click_tab = NULL; } void wxAuiTabCtrl::OnMotion(wxMouseEvent& evt) @@ -849,8 +1103,8 @@ void wxAuiTabCtrl::OnMotion(wxMouseEvent& evt) if (m_is_dragging) { wxAuiNotebookEvent evt(wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION, m_windowId); - evt.SetSelection(m_click_tab); - evt.SetOldSelection(m_click_tab); + evt.SetSelection(GetIdxFromWindow(m_click_tab)); + evt.SetOldSelection(evt.GetSelection()); evt.SetEventObject(this); GetEventHandler()->ProcessEvent(evt); return; @@ -864,8 +1118,8 @@ void wxAuiTabCtrl::OnMotion(wxMouseEvent& evt) abs(pos.y - m_click_pt.y) > drag_y_threshold) { wxAuiNotebookEvent evt(wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG, m_windowId); - evt.SetSelection(m_click_tab); - evt.SetOldSelection(m_click_tab); + evt.SetSelection(GetIdxFromWindow(m_click_tab)); + evt.SetOldSelection(evt.GetSelection()); evt.SetEventObject(this); GetEventHandler()->ProcessEvent(evt); @@ -884,6 +1138,33 @@ void wxAuiTabCtrl::OnLeaveWindow(wxMouseEvent& WXUNUSED(event)) } } +void wxAuiTabCtrl::OnButton(wxAuiNotebookEvent& event) +{ + int button = event.GetInt(); + + if (button == wxAUI_BUTTON_LEFT || button == wxAUI_BUTTON_RIGHT) + { + if (button == wxAUI_BUTTON_LEFT) + { + if (GetTabOffset() > 0) + { + SetTabOffset(GetTabOffset()-1); + Refresh(); + Update(); + } + } + else + { + SetTabOffset(GetTabOffset()+1); + Refresh(); + Update(); + } + } + else + { + event.Skip(); + } +} // wxTabFrame is an interesting case. It's important that all child pages // of the multi-notebook control are all actually children of that control @@ -1047,11 +1328,7 @@ void wxAuiMultiNotebook::InitNotebook() m_selected_font.SetWeight(wxBOLD); // choose a default for the tab height - wxClientDC dc(this); - int tx, ty; - dc.SetFont(m_selected_font); - dc.GetTextExtent(wxT("ABCDEFGHhijklm"), &tx, &ty); - m_tab_ctrl_height = (ty*150)/100; + m_tab_ctrl_height = m_tabs.GetArtProvider()->GetBestTabCtrlSize(this); m_dummy_wnd = new wxWindow(this, wxID_ANY, wxPoint(0,0), wxSize(0,0)); m_dummy_wnd->SetSize(200, 200); @@ -1438,6 +1715,7 @@ void wxAuiMultiNotebook::OnTabClicked(wxCommandEvent& command_evt) void wxAuiMultiNotebook::OnTabBeginDrag(wxCommandEvent&) { + m_last_drag_x = 0; } void wxAuiMultiNotebook::OnTabDragMotion(wxCommandEvent& evt) @@ -1448,17 +1726,46 @@ void wxAuiMultiNotebook::OnTabDragMotion(wxCommandEvent& evt) wxAuiTabCtrl* src_tabs = (wxAuiTabCtrl*)evt.GetEventObject(); - wxAuiTabCtrl* tab_ctrl = GetTabCtrlFromPoint(client_pt); - if (tab_ctrl == src_tabs) + wxAuiTabCtrl* dest_tabs = GetTabCtrlFromPoint(client_pt); + if (dest_tabs == src_tabs) { - // inner-tabctrl dragging is not yet implemented + // always hide the hint for inner-tabctrl drag m_mgr.HideHint(); + + wxPoint pt = dest_tabs->ScreenToClient(screen_pt); + wxWindow* dest_location_tab; + + // this is an inner-tab drag/reposition + if (dest_tabs->TabHitTest(pt.x, pt.y, &dest_location_tab)) + { + int src_idx = evt.GetSelection(); + int dest_idx = dest_tabs->GetIdxFromWindow(dest_location_tab); + + // prevent jumpy drag + if ((src_idx == dest_idx) || dest_idx == -1 || + (src_idx > dest_idx && m_last_drag_x <= pt.x) || + (src_idx < dest_idx && m_last_drag_x >= pt.x)) + { + m_last_drag_x = pt.x; + return; + } + + + wxWindow* src_tab = dest_tabs->GetWindowFromIdx(src_idx); + dest_tabs->MovePage(src_tab, dest_idx); + dest_tabs->SetActivePage((size_t)dest_idx); + dest_tabs->DoShowHide(); + dest_tabs->Refresh(); + m_last_drag_x = pt.x; + + } + return; } - if (tab_ctrl) + if (dest_tabs) { - wxRect hint_rect = tab_ctrl->GetRect(); + wxRect hint_rect = dest_tabs->GetRect(); ClientToScreen(&hint_rect.x, &hint_rect.y); m_mgr.ShowHint(hint_rect); } @@ -1490,12 +1797,22 @@ void wxAuiMultiNotebook::OnTabEndDrag(wxCommandEvent& command_evt) // If the pointer is in an existing tab frame, do a tab insert wxWindow* hit_wnd = ::wxFindWindowAtPoint(mouse_screen_pt); wxTabFrame* tab_frame = (wxTabFrame*)GetTabFrameFromTabCtrl(hit_wnd); + int insert_idx = -1; if (tab_frame) { dest_tabs = tab_frame->m_tabs; if (dest_tabs == src_tabs) return; + + + wxPoint pt = dest_tabs->ScreenToClient(mouse_screen_pt); + wxWindow* target = NULL; + dest_tabs->TabHitTest(pt.x, pt.y, &target); + if (target) + { + insert_idx = dest_tabs->GetIdxFromWindow(target); + } } else { @@ -1530,7 +1847,9 @@ void wxAuiMultiNotebook::OnTabEndDrag(wxCommandEvent& command_evt) // add the page to the destination tabs - dest_tabs->AddPage(page_info.window, page_info); + if (insert_idx == -1) + insert_idx = dest_tabs->GetPageCount(); + dest_tabs->InsertPage(page_info.window, page_info, insert_idx); if (src_tabs->GetPageCount() == 0) { @@ -1586,8 +1905,6 @@ wxWindow* wxAuiMultiNotebook::GetTabFrameFromTabCtrl(wxWindow* tab_ctrl) void wxAuiMultiNotebook::RemoveEmptyTabFrames() { - bool must_update = false; - // if we've just removed the last tab from the source // tab set, the remove the tab control completely wxPaneInfoArray all_panes = m_mgr.GetAllPanes(); @@ -1609,7 +1926,6 @@ void wxAuiMultiNotebook::RemoveEmptyTabFrames() //tab_frame->m_tabs->Destroy(); delete tab_frame; - must_update = true; } } @@ -1633,7 +1949,6 @@ void wxAuiMultiNotebook::RemoveEmptyTabFrames() if (!center_found && first_good) { m_mgr.GetPane(first_good).Centre(); - must_update = true; } m_mgr.Update(); @@ -1656,7 +1971,7 @@ void wxAuiMultiNotebook::OnTabButton(wxCommandEvent& command_evt) int button_id = evt.GetInt(); - if (button_id == wxAuiButtonClose) + if (button_id == wxAUI_BUTTON_CLOSE) { int selection = tabs->GetActivePage();