void wxAuiGenericTabArt::DrawTab(wxDC& dc, wxWindow* wnd, const wxAuiNotebookPage& page, const wxRect& in_rect, int close_button_state, wxRect* out_tab_rect, wxRect* out_button_rect, int* x_extent) { wxCoord normal_textx, normal_texty; wxCoord selected_textx, selected_texty; wxCoord texty; // if the caption is empty, measure some temporary text wxString caption = page.caption; if (caption.empty()) caption = wxT("Xj"); dc.SetFont(m_selectedFont); dc.GetTextExtent(caption, &selected_textx, &selected_texty); dc.SetFont(m_normalFont); dc.GetTextExtent(caption, &normal_textx, &normal_texty); // figure out the size of the tab wxSize tab_size = GetTabSize(dc, wnd, page.caption, page.bitmap, page.active, close_button_state, x_extent); wxCoord tab_height = m_tabCtrlHeight - 3; wxCoord tab_width = tab_size.x; wxCoord tab_x = in_rect.x; wxCoord tab_y = in_rect.y + in_rect.height - tab_height; caption = page.caption; // select pen, brush and font for the tab to be drawn if (page.active) { dc.SetFont(m_selectedFont); texty = selected_texty; } else { dc.SetFont(m_normalFont); texty = normal_texty; } // create points that will make the tab outline int clip_width = tab_width; if (tab_x + clip_width > in_rect.x + in_rect.width) clip_width = (in_rect.x + in_rect.width) - tab_x; /* wxPoint clip_points[6]; clip_points[0] = wxPoint(tab_x, tab_y+tab_height-3); clip_points[1] = wxPoint(tab_x, tab_y+2); clip_points[2] = wxPoint(tab_x+2, tab_y); clip_points[3] = wxPoint(tab_x+clip_width-1, tab_y); clip_points[4] = wxPoint(tab_x+clip_width+1, tab_y+2); clip_points[5] = wxPoint(tab_x+clip_width+1, tab_y+tab_height-3); // FIXME: these ports don't provide wxRegion ctor from array of points #if !defined(__WXDFB__) && !defined(__WXCOCOA__) // set the clipping region for the tab -- wxRegion clipping_region(WXSIZEOF(clip_points), clip_points); dc.SetClippingRegion(clipping_region); #endif // !wxDFB && !wxCocoa */ // since the above code above doesn't play well with WXDFB or WXCOCOA, // we'll just use a rectangle for the clipping region for now -- dc.SetClippingRegion(tab_x, tab_y, clip_width+1, tab_height-3); wxPoint border_points[6]; if (m_flags &wxAUI_NB_BOTTOM) { border_points[0] = wxPoint(tab_x, tab_y); border_points[1] = wxPoint(tab_x, tab_y+tab_height-6); border_points[2] = wxPoint(tab_x+2, tab_y+tab_height-4); border_points[3] = wxPoint(tab_x+tab_width-2, tab_y+tab_height-4); border_points[4] = wxPoint(tab_x+tab_width, tab_y+tab_height-6); border_points[5] = wxPoint(tab_x+tab_width, tab_y); } else //if (m_flags & wxAUI_NB_TOP) {} { border_points[0] = wxPoint(tab_x, tab_y+tab_height-4); border_points[1] = wxPoint(tab_x, tab_y+2); border_points[2] = wxPoint(tab_x+2, tab_y); border_points[3] = wxPoint(tab_x+tab_width-2, tab_y); border_points[4] = wxPoint(tab_x+tab_width, tab_y+2); border_points[5] = wxPoint(tab_x+tab_width, tab_y+tab_height-4); } // TODO: else if (m_flags &wxAUI_NB_LEFT) {} // TODO: else if (m_flags &wxAUI_NB_RIGHT) {} int drawn_tab_yoff = border_points[1].y; int drawn_tab_height = border_points[0].y - border_points[1].y; if (page.active) { // draw active tab // draw base background color wxRect r(tab_x, tab_y, tab_width, tab_height); dc.SetPen(wxPen(m_activeColour)); dc.SetBrush(wxBrush(m_activeColour)); dc.DrawRectangle(r.x+1, r.y+1, r.width-1, r.height-4); // this white helps fill out the gradient at the top of the tab dc.SetPen(*wxWHITE_PEN); dc.SetBrush(*wxWHITE_BRUSH); dc.DrawRectangle(r.x+2, r.y+1, r.width-3, r.height-4); // these two points help the rounded corners appear more antialiased dc.SetPen(wxPen(m_activeColour)); dc.DrawPoint(r.x+2, r.y+1); dc.DrawPoint(r.x+r.width-2, r.y+1); // set rectangle down a bit for gradient drawing r.SetHeight(r.GetHeight()/2); r.x += 2; r.width -= 3; r.y += r.height; r.y -= 2; // draw gradient background wxColor top_color = *wxWHITE; wxColor bottom_color = m_activeColour; dc.GradientFillLinear(r, bottom_color, top_color, wxNORTH); } else { // draw inactive tab wxRect r(tab_x, tab_y+1, tab_width, tab_height-3); // start the gradent up a bit and leave the inside border inset // by a pixel for a 3D look. Only the top half of the inactive // tab will have a slight gradient r.x += 3; r.y++; r.width -= 4; r.height /= 2; r.height--; // -- draw top gradient fill for glossy look wxColor top_color = m_baseColour; wxColor bottom_color = top_color.ChangeLightness(160); dc.GradientFillLinear(r, bottom_color, top_color, wxNORTH); r.y += r.height; r.y--; // -- draw bottom fill for glossy look top_color = m_baseColour; bottom_color = m_baseColour; dc.GradientFillLinear(r, top_color, bottom_color, wxSOUTH); } // draw tab outline dc.SetPen(m_borderPen); dc.SetBrush(*wxTRANSPARENT_BRUSH); dc.DrawPolygon(WXSIZEOF(border_points), border_points); // there are two horizontal grey lines at the bottom of the tab control, // this gets rid of the top one of those lines in the tab control if (page.active) { if (m_flags &wxAUI_NB_BOTTOM) dc.SetPen(wxPen(m_baseColour.ChangeLightness(170))); // TODO: else if (m_flags &wxAUI_NB_LEFT) {} // TODO: else if (m_flags &wxAUI_NB_RIGHT) {} else //for wxAUI_NB_TOP dc.SetPen(m_baseColourPen); dc.DrawLine(border_points[0].x+1, border_points[0].y, border_points[5].x, border_points[5].y); } int text_offset = tab_x + 8; int close_button_width = 0; if (close_button_state != wxAUI_BUTTON_STATE_HIDDEN) { close_button_width = m_activeCloseBmp.GetWidth(); } int bitmap_offset = 0; if (page.bitmap.IsOk()) { bitmap_offset = tab_x + 8; // draw bitmap dc.DrawBitmap(page.bitmap, bitmap_offset, drawn_tab_yoff + (drawn_tab_height/2) - (page.bitmap.GetHeight()/2), true); text_offset = bitmap_offset + page.bitmap.GetWidth(); text_offset += 3; // bitmap padding } else { text_offset = tab_x + 8; } wxString draw_text = wxAuiChopText(dc, caption, tab_width - (text_offset-tab_x) - close_button_width); // draw tab text dc.DrawText(draw_text, text_offset, drawn_tab_yoff + (drawn_tab_height)/2 - (texty/2) - 1); // draw focus rectangle if (page.active && (wnd->FindFocus() == wnd)) { wxRect focusRectText(text_offset, (drawn_tab_yoff + (drawn_tab_height)/2 - (texty/2) - 1), selected_textx, selected_texty); wxRect focusRect; wxRect focusRectBitmap; if (page.bitmap.IsOk()) focusRectBitmap = wxRect(bitmap_offset, drawn_tab_yoff + (drawn_tab_height/2) - (page.bitmap.GetHeight()/2), page.bitmap.GetWidth(), page.bitmap.GetHeight()); if (page.bitmap.IsOk() && draw_text.IsEmpty()) focusRect = focusRectBitmap; else if (!page.bitmap.IsOk() && !draw_text.IsEmpty()) focusRect = focusRectText; else if (page.bitmap.IsOk() && !draw_text.IsEmpty()) focusRect = focusRectText.Union(focusRectBitmap); focusRect.Inflate(2, 2); wxRendererNative::Get().DrawFocusRect(wnd, dc, focusRect, 0); } // draw close button if necessary if (close_button_state != wxAUI_BUTTON_STATE_HIDDEN) { wxBitmap bmp = m_disabledCloseBmp; if (close_button_state == wxAUI_BUTTON_STATE_HOVER || close_button_state == wxAUI_BUTTON_STATE_PRESSED) { bmp = m_activeCloseBmp; } int offsetY = tab_y-1; if (m_flags & wxAUI_NB_BOTTOM) offsetY = 1; wxRect rect(tab_x + tab_width - close_button_width - 1, offsetY + (tab_height/2) - (bmp.GetHeight()/2), close_button_width, tab_height); IndentPressedBitmap(&rect, close_button_state); dc.DrawBitmap(bmp, rect.x, rect.y, true); *out_button_rect = rect; } *out_tab_rect = wxRect(tab_x, tab_y, tab_width, tab_height); dc.DestroyClippingRegion(); }
void SAuiTabArt::DrawTab(wxDC& dc, wxWindow* wnd, const wxAuiNotebookPage& page, const wxRect& in_rect, int close_button_state, wxRect* out_tab_rect, wxRect* out_button_rect, int* x_extent) { wxCoord normal_textx, normal_texty; wxCoord selected_textx, selected_texty; wxCoord texty; // if the caption is empty, measure some temporary text wxString caption = page.caption; if (caption.empty()) caption = wxT("Xj"); dc.SetFont(m_selectedFont); dc.GetTextExtent(caption, &selected_textx, &selected_texty); dc.SetFont(m_normalFont); dc.GetTextExtent(caption, &normal_textx, &normal_texty); bool bluetab = false; if (page.window->GetName() == "startpage") bluetab = true; // figure out the size of the tab wxSize tab_size = GetTabSize(dc, wnd, page.caption, page.bitmap, page.active, close_button_state, x_extent); wxCoord tab_height = m_tabCtrlHeight + 2;// -1;// -3; wxCoord tab_width = tab_size.x; wxCoord tab_x = in_rect.x; wxCoord tab_y = in_rect.y + in_rect.height - tab_height + 3; if (!page.active) { tab_height -= 2; tab_y += 2; } caption = page.caption; // select pen, brush and font for the tab to be drawn if (page.active) { dc.SetFont(m_selectedFont); texty = selected_texty; } else { dc.SetFont(m_normalFont); texty = normal_texty; } // create points that will make the tab outline int clip_width = tab_width; if (tab_x + clip_width > in_rect.x + in_rect.width) clip_width = (in_rect.x + in_rect.width) - tab_x; dc.SetClippingRegion(tab_x, tab_y, clip_width + 1, tab_height - 3); wxPoint border_points[6]; if (m_flags &wxAUI_NB_BOTTOM) { border_points[0] = wxPoint(tab_x, tab_y); border_points[1] = wxPoint(tab_x, tab_y + tab_height - 4); border_points[2] = wxPoint(tab_x, tab_y + tab_height - 4); border_points[3] = wxPoint(tab_x + tab_width, tab_y + tab_height - 4); border_points[4] = wxPoint(tab_x + tab_width, tab_y + tab_height - 4); border_points[5] = wxPoint(tab_x + tab_width, tab_y); } else { border_points[0] = wxPoint(tab_x, tab_y + tab_height - 4); border_points[1] = wxPoint(tab_x, tab_y); border_points[2] = wxPoint(tab_x + 2, tab_y); border_points[3] = wxPoint(tab_x + tab_width - 2, tab_y); border_points[4] = wxPoint(tab_x + tab_width, tab_y); border_points[5] = wxPoint(tab_x + tab_width, tab_y + tab_height - 4); } int drawn_tab_yoff = border_points[1].y + 1; int drawn_tab_height = border_points[0].y - border_points[1].y; wxColour bgcol; if (page.active) { // draw active tab bgcol = m_activeColour; // draw base background color wxRect r(tab_x, tab_y, tab_width, tab_height); dc.SetPen(wxPen(bluetab ? wxColor(224, 238, 255) : m_activeColour)); dc.SetBrush(wxBrush(bluetab ? wxColor(224, 238, 255) : m_activeColour)); dc.DrawRectangle(r.x + 1, r.y + 1, r.width - 1, r.height - 5); // highlight top of tab wxColour col_hilight = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT); dc.SetPen(*wxTRANSPARENT_PEN);// *wxWHITE_PEN); dc.SetBrush(wxBrush(col_hilight));// *wxWHITE_BRUSH); dc.DrawRectangle(r.x + 1, r.y + 1, r.width - 1, 1); } else { bgcol = m_inactiveTabColour; wxRect r(tab_x, tab_y, tab_width, tab_height); wxPoint mouse = wnd->ScreenToClient(wxGetMousePosition()); /*if (r.Contains(mouse)) { dc.SetPen(wxPen(m_activeColour)); dc.SetBrush(wxBrush(m_activeColour)); } else {*/ dc.SetPen(wxPen(m_inactiveTabColour)); dc.SetBrush(wxBrush(m_inactiveTabColour)); //} dc.DrawRectangle(r.x + 1, r.y + 1, r.width - 1, r.height - 4); } // draw tab outline dc.SetPen(m_borderPen); dc.SetBrush(*wxTRANSPARENT_BRUSH); dc.DrawPolygon(WXSIZEOF(border_points), border_points); // there are two horizontal grey lines at the bottom of the tab control, // this gets rid of the top one of those lines in the tab control if (page.active) { if (m_flags &wxAUI_NB_BOTTOM) dc.SetPen(wxPen(m_baseColour.ChangeLightness(170))); else dc.SetPen(wxPen(bluetab ? wxColor(224, 238, 255) : m_activeColour)); dc.DrawLine(border_points[0].x + 1, border_points[0].y, border_points[5].x, border_points[5].y); } int text_offset = tab_x + 8; int close_button_width = 0; if (close_button_state != wxAUI_BUTTON_STATE_HIDDEN) { close_button_width = m_activeCloseBmp.GetWidth(); } int bitmap_offset = 0; if (page.bitmap.IsOk()) { bitmap_offset = tab_x + 8; // draw bitmap dc.DrawBitmap(page.bitmap, bitmap_offset, drawn_tab_yoff + (drawn_tab_height / 2) - (page.bitmap.GetHeight() / 2), true); text_offset = bitmap_offset + page.bitmap.GetWidth(); text_offset += 4; // bitmap padding } else { text_offset = tab_x + 8; } dc.SetTextForeground((page.active && bluetab) ? wxColor(0,0,0) : wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); wxString draw_text = wxAuiChopText(dc, caption, tab_width - (text_offset - tab_x) - close_button_width); // draw tab text dc.DrawText(draw_text, text_offset, drawn_tab_yoff + (drawn_tab_height) / 2 - (texty / 2) - 0); // draw focus rectangle if (page.active && (wnd->FindFocus() == wnd)) { wxRect focusRectText(text_offset, (drawn_tab_yoff + (drawn_tab_height) / 2 - (texty / 2) - 1), selected_textx, selected_texty); wxRect focusRect; wxRect focusRectBitmap; if (page.bitmap.IsOk()) focusRectBitmap = wxRect(bitmap_offset, drawn_tab_yoff + (drawn_tab_height / 2) - (page.bitmap.GetHeight() / 2), page.bitmap.GetWidth(), page.bitmap.GetHeight()); if (page.bitmap.IsOk() && draw_text.IsEmpty()) focusRect = focusRectBitmap; else if (!page.bitmap.IsOk() && !draw_text.IsEmpty()) focusRect = focusRectText; else if (page.bitmap.IsOk() && !draw_text.IsEmpty()) focusRect = focusRectText.Union(focusRectBitmap); focusRect.Inflate(2, 2); wxRendererNative::Get().DrawFocusRect(wnd, dc, focusRect, 0); } // draw close button if necessary if (close_button_state != wxAUI_BUTTON_STATE_HIDDEN) { wxBitmap bmp = m_disabledCloseBmp; int offsetY = tab_y; if (m_flags & wxAUI_NB_BOTTOM) offsetY = 1; wxRect rect(tab_x + tab_width - close_button_width - 3, offsetY + (tab_height / 2) - (bmp.GetHeight() / 2), close_button_width, tab_height); IndentPressedBitmap(&rect, close_button_state); if (close_button_state == wxAUI_BUTTON_STATE_HOVER || close_button_state == wxAUI_BUTTON_STATE_PRESSED) { /*wxColour bcol = m_borderPen.GetColour(); float r = ((float)bcol.Red() * 0.2f) + ((float)m_activeColour.Red() * 0.8f); float g = ((float)bcol.Green() * 0.2f) + ((float)m_activeColour.Green() * 0.8f); float b = ((float)bcol.Blue() * 0.2f) + ((float)m_activeColour.Blue() * 0.8f);*/ //captionAccentColour = wxColor(r, g, b); //dc.SetPen(*wxTRANSPARENT_PEN); dc.SetPen(wxPen(Drawing::darkColour(bgcol, 2.0f))); dc.SetBrush(wxBrush(Drawing::lightColour(bgcol, 1.0f))); dc.DrawRectangle(rect.x, rect.y + 1, rect.width - 1, rect.width - 2); bmp = m_activeCloseBmp; //dc.DrawBitmap(bmp, rect.x + 1, rect.y, true); //dc.DrawBitmap(bmp, rect.x - 1, rect.y, true); dc.DrawBitmap(bmp, rect.x, rect.y, true); } else { bmp = m_disabledCloseBmp; dc.DrawBitmap(bmp, rect.x, rect.y, true); } *out_button_rect = rect; } *out_tab_rect = wxRect(tab_x, tab_y, tab_width, tab_height); dc.DestroyClippingRegion(); }