tabg.cpp

来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 1,295 行 · 第 1/3 页

CPP
1,295
字号
/////////////////////////////////////////////////////////////////////////////
// Name:        tabg.cpp
// Purpose:     Generic tabbed dialogs
// Author:      Julian Smart
// Modified by:
// Created:     01/02/97
// RCS-ID:      $Id: tabg.cpp,v 1.26 2005/08/25 21:58:22 CE Exp $
// Copyright:   (c)
// Licence:     wxWindows licence
/////////////////////////////////////////////////////////////////////////////

#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
#pragma implementation "tabg.h"
#endif

// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"

#ifdef __BORLANDC__
#pragma hdrstop
#endif

#if wxUSE_TAB_DIALOG

#ifndef WX_PRECOMP
    #include "wx/settings.h"
    #include "wx/intl.h"
    #include "wx/dcclient.h"
#endif

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

#include "wx/math.h"
#include "wx/tab.h"
#include "wx/listimpl.cpp"

WX_DEFINE_LIST(wxTabLayerList);

// not defined: use old, square tab implementation (fills in tabs)
// defined: use new, rounded tab implementation (doesn't colour in tabs)
// #define wxUSE_NEW_METHOD

IMPLEMENT_DYNAMIC_CLASS(wxTabControl, wxObject)

// IMPLEMENT_DYNAMIC_CLASS(wxTabLayer, wxList)

wxTabControl::wxTabControl(wxTabView *v)
{
  m_view = v;
  m_isSelected = false;
  m_offsetX = 0;
  m_offsetY = 0;
  m_width = 0;
  m_height = 0;
  m_id = 0;
  m_rowPosition = 0;
  m_colPosition = 0;
}

wxTabControl::~wxTabControl(void)
{
}

void wxTabControl::OnDraw(wxDC& dc, bool lastInRow)
{
    // Old, but in some ways better (drawing opaque tabs)
#ifndef wxUSE_NEW_METHOD
  if (!m_view)
    return;

  // Top-left of tab view area
  int viewX = m_view->GetViewRect().x;
  int viewY = m_view->GetViewRect().y;

  // Top-left of tab control
  int tabX = GetX() + viewX;
  int tabY = GetY() + viewY;
  int tabHeightInc = 0;
  if (m_isSelected)
  {
    tabHeightInc = (m_view->GetTabSelectionHeight() - m_view->GetTabHeight());
    tabY -= tabHeightInc;
  }

  dc.SetPen(*wxTRANSPARENT_PEN);

  // Draw grey background
  if (m_view->GetTabStyle() & wxTAB_STYLE_COLOUR_INTERIOR)
  {
    dc.SetBrush(*m_view->GetBackgroundBrush());

    // Add 1 because the pen is transparent. Under Motif, may be different.
#ifdef __WXMOTIF__
    dc.DrawRectangle(tabX, tabY, (GetWidth()+1), (GetHeight() + tabHeightInc));
#else
    dc.DrawRectangle(tabX, tabY, (GetWidth()+1), (GetHeight() + 1 + tabHeightInc));
#endif
  }

  // Draw highlight and shadow
  dc.SetPen(*m_view->GetHighlightPen());

  // Calculate the top of the tab beneath. It's the height of the tab, MINUS
  // a bit if the tab below happens to be selected. Check.
  wxTabControl *tabBeneath = NULL;
  int subtractThis = 0;
  if (GetColPosition() > 0)
    tabBeneath = m_view->FindTabControlForPosition(GetColPosition() - 1, GetRowPosition());
  if (tabBeneath && tabBeneath->IsSelected())
    subtractThis = (m_view->GetTabSelectionHeight() - m_view->GetTabHeight());

  // Vertical highlight: if first tab, draw to bottom of view
  if (tabX == m_view->GetViewRect().x && (m_view->GetTabStyle() & wxTAB_STYLE_DRAW_BOX))
    dc.DrawLine(tabX, tabY, tabX, (m_view->GetViewRect().y + m_view->GetViewRect().height));
  else if (tabX == m_view->GetViewRect().x)
    // Not box drawing, just to top of view.
    dc.DrawLine(tabX, tabY, tabX, (m_view->GetViewRect().y));
  else
    dc.DrawLine(tabX, tabY, tabX, (tabY + GetHeight() + tabHeightInc - subtractThis));

  dc.DrawLine(tabX, tabY, (tabX + GetWidth()), tabY);
  dc.SetPen(*m_view->GetShadowPen());

  // Test if we're outside the right-hand edge of the view area
  if (((tabX + GetWidth()) >= m_view->GetViewRect().x + m_view->GetViewRect().width) && (m_view->GetTabStyle() & wxTAB_STYLE_DRAW_BOX))
  {
    int bottomY = m_view->GetViewRect().y + m_view->GetViewRect().height + GetY() + m_view->GetTabHeight() + m_view->GetTopMargin();
    // Add a tab height since we wish to draw to the bottom of the view.
    dc.DrawLine((tabX + GetWidth()), tabY,
      (tabX + GetWidth()), bottomY);

    // Calculate the far-right of the view, since we don't wish to
    // draw inside that
    int rightOfView = m_view->GetViewRect().x + m_view->GetViewRect().width + 1;

    // Draw the horizontal bit to connect to the view rectangle
    dc.DrawLine((wxMax((tabX + GetWidth() - m_view->GetHorizontalTabOffset()), rightOfView)), (bottomY-1),
      (tabX + GetWidth()), (bottomY-1));

    // Draw black line to emphasize shadow
    dc.SetPen(*wxBLACK_PEN);
    dc.DrawLine((tabX + GetWidth() + 1), (tabY+1),
      (tabX + GetWidth() + 1), bottomY);

    // Draw the horizontal bit to connect to the view rectangle
    dc.DrawLine((wxMax((tabX + GetWidth() - m_view->GetHorizontalTabOffset()), rightOfView)), (bottomY),
      (tabX + GetWidth() + 1), (bottomY));
  }
  else
  {
    if (lastInRow)
    {
      // 25/5/97 UNLESS it's less than the max number of positions in this row

      int topY = m_view->GetViewRect().y - m_view->GetTopMargin();

      int maxPositions = ((wxTabLayer *)m_view->GetLayers().Item(0)->GetData())->GetCount();

      // Only down to the bottom of the tab, not to the top of the view
      if ( GetRowPosition() < (maxPositions - 1) )
        topY = tabY + GetHeight() + tabHeightInc;

#ifdef __WXMOTIF__
      topY -= 1;
#endif

      // Shadow
      dc.DrawLine((tabX + GetWidth()), tabY, (tabX + GetWidth()), topY);
      // Draw black line to emphasize shadow
      dc.SetPen(*wxBLACK_PEN);
      dc.DrawLine((tabX + GetWidth() + 1), (tabY+1), (tabX + GetWidth() + 1),
         topY);
    }
    else
    {
      // Calculate the top of the tab beneath. It's the height of the tab, MINUS
      // a bit if the tab below (and next col along) happens to be selected. Check.
      wxTabControl *tabBeneath = NULL;
      int subtractThis = 0;
      if (GetColPosition() > 0)
        tabBeneath = m_view->FindTabControlForPosition(GetColPosition() - 1, GetRowPosition() + 1);
      if (tabBeneath && tabBeneath->IsSelected())
        subtractThis = (m_view->GetTabSelectionHeight() - m_view->GetTabHeight());

#ifdef __WXMOTIF__
      subtractThis += 1;
#endif

      // Draw only to next tab down.
      dc.DrawLine((tabX + GetWidth()), tabY,
         (tabX + GetWidth()), (tabY + GetHeight() + tabHeightInc - subtractThis));

      // Draw black line to emphasize shadow
      dc.SetPen(*wxBLACK_PEN);
      dc.DrawLine((tabX + GetWidth() + 1), (tabY+1), (tabX + GetWidth() + 1),
         (tabY + GetHeight() + tabHeightInc - subtractThis));
    }
  }

  // Draw centered text
  int textY = tabY + m_view->GetVerticalTabTextSpacing() + tabHeightInc;

  if (m_isSelected)
    dc.SetFont(* m_view->GetSelectedTabFont());
  else
    dc.SetFont(* GetFont());

  wxColour col(m_view->GetTextColour());
  dc.SetTextForeground(col);
  dc.SetBackgroundMode(wxTRANSPARENT);
  long textWidth, textHeight;
  dc.GetTextExtent(GetLabel(), &textWidth, &textHeight);

  int textX = (int)(tabX + (GetWidth() - textWidth)/2.0);
  if (textX < (tabX + 2))
    textX = (tabX + 2);

  dc.SetClippingRegion(tabX, tabY, GetWidth(), GetHeight());
  dc.DrawText(GetLabel(), textX, textY);
  dc.DestroyClippingRegion();

  if (m_isSelected)
  {
    dc.SetPen(*m_view->GetHighlightPen());

    // Draw white highlight from the tab's left side to the left hand edge of the view
    dc.DrawLine(m_view->GetViewRect().x, (tabY + GetHeight() + tabHeightInc),
     tabX, (tabY + GetHeight() + tabHeightInc));

    // Draw white highlight from the tab's right side to the right hand edge of the view
    dc.DrawLine((tabX + GetWidth()), (tabY + GetHeight() + tabHeightInc),
     m_view->GetViewRect().x + m_view->GetViewRect().width, (tabY + GetHeight() + tabHeightInc));
  }
#else
    // New HEL version with rounder tabs

    if (!m_view) return;

    int tabInc   = 0;
    if (m_isSelected)
    {
        tabInc = m_view->GetTabSelectionHeight() - m_view->GetTabHeight();
    }
    int tabLeft  = GetX() + m_view->GetViewRect().x;
    int tabTop   = GetY() + m_view->GetViewRect().y - tabInc;
    int tabRight = tabLeft + m_view->GetTabWidth();
    int left     = m_view->GetViewRect().x;
    int top      = tabTop + m_view->GetTabHeight() + tabInc;
    int right    = left + m_view->GetViewRect().width;
    int bottom   = top + m_view->GetViewRect().height;

    if (m_isSelected)
    {
        // TAB is selected - draw TAB and the View's full outline

        dc.SetPen(*(m_view->GetHighlightPen()));
        wxPoint pnts[10];
        int n = 0;
        pnts[n].x = left;            pnts[n++].y = bottom;
        pnts[n].x = left;             pnts[n++].y = top;
        pnts[n].x = tabLeft;         pnts[n++].y = top;
        pnts[n].x = tabLeft;            pnts[n++].y = tabTop + 2;
        pnts[n].x = tabLeft + 2;        pnts[n++].y = tabTop;
        pnts[n].x = tabRight - 1;    pnts[n++].y = tabTop;
        dc.DrawLines(n, pnts);
        if (!lastInRow)
        {
            dc.DrawLine(
                    (tabRight + 2),
                    top,
                    right,
                    top
                    );
        }

        dc.SetPen(*(m_view->GetShadowPen()));
        dc.DrawLine(
                tabRight,
                tabTop + 2,
                tabRight,
                top
                );
        dc.DrawLine(
                right,
                top,
                right,
                bottom
                );
        dc.DrawLine(
                right,
                bottom,
                left,
                bottom
                );

        dc.SetPen(*wxBLACK_PEN);
        dc.DrawPoint(
                tabRight,
                tabTop + 1
                );
        dc.DrawPoint(
                tabRight + 1,
                tabTop + 2
                );
        if (lastInRow)
        {
            dc.DrawLine(
                tabRight + 1,
                bottom,
                tabRight + 1,
                tabTop + 1
                );
        }
        else
        {
            dc.DrawLine(
                tabRight + 1,
                tabTop + 2,
                tabRight + 1,
                top
                );
            dc.DrawLine(
                right + 1,
                top,
                right + 1,
                bottom + 1
                );
        }
        dc.DrawLine(
                right + 1,
                bottom + 1,
                left + 1,
                bottom + 1
                );
    }
    else
    {
        // TAB is not selected - just draw TAB outline and RH edge
        // if the TAB is the last in the row

        int maxPositions = ((wxTabLayer*)m_view->GetLayers().Item(0)->GetData())->GetCount();
        wxTabControl* tabBelow = 0;
        wxTabControl* tabBelowRight = 0;
        if (GetColPosition() > 0)
        {
            tabBelow = m_view->FindTabControlForPosition(
                        GetColPosition() - 1,
                        GetRowPosition()
                        );
        }
        if (!lastInRow && GetColPosition() > 0)
        {
            tabBelowRight = m_view->FindTabControlForPosition(
                        GetColPosition() - 1,
                        GetRowPosition() + 1
                        );
        }

        float raisedTop = top - m_view->GetTabSelectionHeight() +
                            m_view->GetTabHeight();

        dc.SetPen(*(m_view->GetHighlightPen()));
        wxPoint pnts[10];
        int n = 0;

        pnts[n].x = tabLeft;

        if (tabBelow && tabBelow->IsSelected())
        {
            pnts[n++].y = (long)raisedTop;
        }
        else
        {
            pnts[n++].y = top;
        }
        pnts[n].x = tabLeft;            pnts[n++].y = tabTop + 2;
        pnts[n].x = tabLeft + 2;        pnts[n++].y = tabTop;
        pnts[n].x = tabRight - 1;    pnts[n++].y = tabTop;
        dc.DrawLines(n, pnts);

        dc.SetPen(*(m_view->GetShadowPen()));
        if (GetRowPosition() >= maxPositions - 1)
        {
            dc.DrawLine(
                    tabRight,
                    (tabTop + 2),
                    tabRight,
                    bottom
                    );
            dc.DrawLine(
                    tabRight,
                    bottom,
                    (tabRight - m_view->GetHorizontalTabOffset()),
                    bottom
                    );
        }
        else
        {
            if (tabBelowRight && tabBelowRight->IsSelected())
            {
                dc.DrawLine(
                        tabRight,
                        (long)raisedTop,
                        tabRight,
                        tabTop + 1
                        );
            }
            else
            {
                dc.DrawLine(
                        tabRight,
                        top - 1,
                        tabRight,
                        tabTop + 1
                        );
            }
        }

        dc.SetPen(*wxBLACK_PEN);
        dc.DrawPoint(
                tabRight,
                tabTop + 1
                );
        dc.DrawPoint(
                tabRight + 1,
                tabTop + 2
                );
        if (GetRowPosition() >= maxPositions - 1)
        {
            // draw right hand edge to bottom of view

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?