tabg.cpp

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

CPP
1,295
字号
            dc.DrawLine(
                    tabRight + 1,
                    bottom + 1,
                    tabRight + 1,
                    tabTop + 2
                    );
            dc.DrawLine(
                    tabRight + 1,
                    bottom + 1,
                    (tabRight - m_view->GetHorizontalTabOffset()),
                    bottom + 1
                    );
        }
        else
        {
            // draw right hand edge of TAB
            if (tabBelowRight && tabBelowRight->IsSelected())
            {
                dc.DrawLine(
                        tabRight + 1,
                        (long)(raisedTop - 1),
                        tabRight + 1,
                        tabTop + 2
                        );
            }
            else
            {
                dc.DrawLine(
                        tabRight + 1,
                        top - 1,
                        tabRight + 1,
                        tabTop + 2
                        );
            }
        }
    }

    // Draw centered text
    dc.SetPen(*wxBLACK_PEN);
    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);

    float textX = (tabLeft + tabRight - textWidth) / 2;
    float textY = (tabInc + tabTop + m_view->GetVerticalTabTextSpacing());

    dc.DrawText(GetLabel(), (long)textX, (long)textY);
#endif
}

bool wxTabControl::HitTest(int x, int y) const
{
  // Top-left of tab control
  int tabX1 = GetX() + m_view->GetViewRect().x;
  int tabY1 = GetY() + m_view->GetViewRect().y;

  // Bottom-right
  int tabX2 = tabX1 + GetWidth();
  int tabY2 = tabY1 + GetHeight();

  if (x >= tabX1 && y >= tabY1 && x <= tabX2 && y <= tabY2)
    return true;
  else
    return false;
}

IMPLEMENT_DYNAMIC_CLASS(wxTabView, wxObject)

wxTabView::wxTabView(long style)
{
  m_noTabs = 0;
  m_tabStyle = style;
  m_tabSelection = -1;
  m_tabHeight = 20;
  m_tabSelectionHeight = m_tabHeight + 2;
  m_tabWidth = 80;
  m_tabHorizontalOffset = 10;
  m_tabHorizontalSpacing = 2;
  m_tabVerticalTextSpacing = 3;
  m_topMargin = 5;
  m_tabViewRect.x = 20;
  m_tabViewRect.y = 20;
  m_tabViewRect.width = 300;
  m_tabViewRect.x = 300;
  m_highlightColour = *wxWHITE;
  m_shadowColour = wxColour(128, 128, 128);
  m_backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE);
  m_textColour = *wxBLACK;
  m_highlightPen = wxWHITE_PEN;
  m_shadowPen = wxGREY_PEN;
  SetBackgroundColour(m_backgroundColour);
  m_tabFont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
  m_tabSelectedFont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
  m_window = (wxWindow *) NULL;
}

wxTabView::~wxTabView()
{
  ClearTabs(true);
}

// Automatically positions tabs
// TODO: this should just add the tab to a list, and then
// a layout function (e.g. Realize) should be called when all tabs have been added.
// The view rect could easily change as the view window is resized.
wxTabControl *wxTabView::AddTab(int id, const wxString& label, wxTabControl *existingTab)
{
  // First, find which layer we should be adding to.
  wxTabLayerList::compatibility_iterator node = m_layers.GetLast();
  if (!node)
  {
    wxTabLayer *newLayer = new wxTabLayer;
    node = m_layers.Append(newLayer);
  }
  // Check if adding another tab control would go off the
  // right-hand edge of the layer.
  wxTabLayer *tabLayer = (wxTabLayer *)node->GetData();
  wxList::compatibility_iterator lastTabNode = tabLayer->GetLast();
  if (lastTabNode)
  {
    wxTabControl *lastTab = (wxTabControl *)lastTabNode->GetData();
    // Start another layer (row).
    // Tricky choice: can't just check if will be overlapping the edge, because
    // this happens anyway for 2nd and subsequent rows.
    // Should check this for 1st row, and then subsequent rows should not exceed 1st
    // in length.
    if (((tabLayer == m_layers.GetFirst()->GetData()) && ((lastTab->GetX() + 2*lastTab->GetWidth() + GetHorizontalTabSpacing())
              > GetViewRect().width)) ||
        ((tabLayer != m_layers.GetFirst()->GetData()) && (tabLayer->GetCount() == ((wxTabLayer *)m_layers.GetFirst()->GetData())->GetCount())))
    {
      tabLayer = new wxTabLayer;
      m_layers.Append(tabLayer);
      lastTabNode = wxList::compatibility_iterator();
    }
  }
  int layer = m_layers.GetCount() - 1;

  wxTabControl *tabControl = existingTab;
  if (!existingTab)
    tabControl = OnCreateTabControl();
  tabControl->SetRowPosition(tabLayer->GetCount());
  tabControl->SetColPosition(layer);

  wxTabControl *lastTab = (wxTabControl *) NULL;
  if (lastTabNode)
    lastTab = (wxTabControl *)lastTabNode->GetData();

  // Top of new tab
  int verticalOffset = (- GetTopMargin()) - ((layer+1)*GetTabHeight());
  // Offset from view top-left
  int horizontalOffset = 0;
  if (!lastTab)
    horizontalOffset = layer*GetHorizontalTabOffset();
  else
    horizontalOffset = lastTab->GetX() + GetTabWidth() + GetHorizontalTabSpacing();

  tabControl->SetPosition(horizontalOffset, verticalOffset);
  tabControl->SetSize(GetTabWidth(), GetTabHeight());
  tabControl->SetId(id);
  tabControl->SetLabel(label);
  tabControl->SetFont(* GetTabFont());

  tabLayer->Append(tabControl);
  m_noTabs ++;

  return tabControl;
}

// Remove the tab without deleting the window
bool wxTabView::RemoveTab(int id)
{
  wxTabLayerList::compatibility_iterator layerNode = m_layers.GetFirst();
  while (layerNode)
  {
    wxTabLayer *layer = (wxTabLayer *)layerNode->GetData();
    wxList::compatibility_iterator tabNode = layer->GetFirst();
    while (tabNode)
    {
      wxTabControl *tab = (wxTabControl *)tabNode->GetData();
      if (tab->GetId() == id)
      {
        if (id == m_tabSelection)
          m_tabSelection = -1;
        delete tab;
        layer->Erase(tabNode);
        m_noTabs --;

        // The layout has changed
        LayoutTabs();
        return true;
      }
      tabNode = tabNode->GetNext();
    }
    layerNode = layerNode->GetNext();
  }
  return false;
}

bool wxTabView::SetTabText(int id, const wxString& label)
{
    wxTabControl* control = FindTabControlForId(id);
    if (!control)
      return false;
    control->SetLabel(label);
    return true;
}

wxString wxTabView::GetTabText(int id) const
{
    wxTabControl* control = FindTabControlForId(id);
    if (!control)
      return wxEmptyString;
    else
      return control->GetLabel();
}

// Returns the total height of the tabs component -- this may be several
// times the height of a tab, if there are several tab layers (rows).
int wxTabView::GetTotalTabHeight()
{
  int minY = 0;

  wxTabLayerList::compatibility_iterator layerNode = m_layers.GetFirst();
  while (layerNode)
  {
    wxTabLayer *layer = (wxTabLayer *)layerNode->GetData();
    wxList::compatibility_iterator tabNode = layer->GetFirst();
    while (tabNode)
    {
      wxTabControl *tab = (wxTabControl *)tabNode->GetData();

      if (tab->GetY() < minY)
        minY = tab->GetY();

      tabNode = tabNode->GetNext();
    }
    layerNode = layerNode->GetNext();
  }

  return - minY;
}

void wxTabView::ClearTabs(bool deleteTabs)
{
  wxTabLayerList::compatibility_iterator layerNode = m_layers.GetFirst();
  while (layerNode)
  {
    wxTabLayer *layer = (wxTabLayer *)layerNode->GetData();
    wxList::compatibility_iterator tabNode = layer->GetFirst();
    while (tabNode)
    {
      wxTabControl *tab = (wxTabControl *)tabNode->GetData();
      if (deleteTabs)
        delete tab;
      wxList::compatibility_iterator next = tabNode->GetNext();
      layer->Erase(tabNode);
      tabNode = next;
    }
    wxTabLayerList::compatibility_iterator nextLayerNode = layerNode->GetNext();
    delete layer;
    m_layers.Erase(layerNode);
    layerNode = nextLayerNode;
  }
  m_noTabs = 0;
  m_tabSelection = -1;
}


// Layout tabs (optional, e.g. if resizing window)
void wxTabView::LayoutTabs(void)
{
  // Make a list of the tab controls, deleting the wxTabLayers.
  wxList controls;

  wxTabLayerList::compatibility_iterator layerNode = m_layers.GetFirst();
  while (layerNode)
  {
    wxTabLayer *layer = (wxTabLayer *)layerNode->GetData();
    wxList::compatibility_iterator tabNode = layer->GetFirst();
    while (tabNode)
    {
      wxTabControl *tab = (wxTabControl *)tabNode->GetData();
      controls.Append(tab);
      wxList::compatibility_iterator next = tabNode->GetNext();
      layer->Erase(tabNode);
      tabNode = next;
    }
    wxTabLayerList::compatibility_iterator nextLayerNode = layerNode->GetNext();
    delete layer;
    m_layers.Erase(layerNode);
    layerNode = nextLayerNode;
  }

  wxTabControl *lastTab = (wxTabControl *) NULL;

  wxTabLayer *currentLayer = new wxTabLayer;
  m_layers.Append(currentLayer);

  wxList::compatibility_iterator node = controls.GetFirst();
  while (node)
  {
    wxTabControl *tabControl = (wxTabControl *)node->GetData();
    if (lastTab)
    {
      // Start another layer (row).
      // Tricky choice: can't just check if will be overlapping the edge, because
      // this happens anyway for 2nd and subsequent rows.
      // Should check this for 1st row, and then subsequent rows should not exceed 1st
      // in length.
      if (((currentLayer == m_layers.GetFirst()->GetData()) && ((lastTab->GetX() + 2*lastTab->GetWidth() + GetHorizontalTabSpacing())
                > GetViewRect().width)) ||
          ((currentLayer != m_layers.GetFirst()->GetData()) && (currentLayer->GetCount() == ((wxTabLayer *)m_layers.GetFirst()->GetData())->GetCount())))
     {
       currentLayer = new wxTabLayer;
       m_layers.Append(currentLayer);
       lastTab = (wxTabControl *) NULL;
     }
    }

    int layer = m_layers.GetCount() - 1;

    tabControl->SetRowPosition(currentLayer->GetCount());
    tabControl->SetColPosition(layer);

    // Top of new tab
    int verticalOffset = (- GetTopMargin()) - ((layer+1)*GetTabHeight());
    // Offset from view top-left
    int horizontalOffset = 0;
    if (!lastTab)
      horizontalOffset = layer*GetHorizontalTabOffset();
    else
      horizontalOffset = lastTab->GetX() + GetTabWidth() + GetHorizontalTabSpacing();

    tabControl->SetPosition(horizontalOffset, verticalOffset);
    tabControl->SetSize(GetTabWidth(), GetTabHeight());

    currentLayer->Append(tabControl);
    lastTab = tabControl;

    node = node->GetNext();
  }

  // Move the selected tab to the bottom
  wxTabControl *control = FindTabControlForId(m_tabSelection);
  if (control)
    MoveSelectionTab(control);

}

// Draw all tabs
void wxTabView::Draw(wxDC& dc)
{
        // Don't draw anything if there are no tabs.
        if (GetNumberOfTabs() == 0)
          return;

    // Draw top margin area (beneath tabs and above view area)
    if (GetTabStyle() & wxTAB_STYLE_COLOUR_INTERIOR)
    {
        dc.SetPen(*wxTRANSPARENT_PEN);
        dc.SetBrush(*GetBackgroundBrush());

        // Add 1 because the pen is transparent. Under Motif, may be different.
        dc.DrawRectangle(
                m_tabViewRect.x,
                (m_tabViewRect.y - m_topMargin),
                (m_tabViewRect.width + 1),
                (m_topMargin + 1)
                );
    }

    // Draw layers in reverse order
    wxTabLayerList::compatibility_iterator node = m_layers.GetLast();
    while (node)
    {
        wxTabLayer *layer = (wxTabLayer *)node->GetData();
        wxList::compatibility_iterator node2 = layer->GetFirst();
        while (node2)
        {
            wxTabControl *control = (wxTabControl *)node2->GetData();
            control->OnDraw(dc, (!node2->GetNext()));
            node2 = node2->GetNext();
        }

        node = node->GetPrevious();
    }


#ifndef wxUSE_NEW_METHOD
    if (GetTabStyle() & wxTAB_STYLE_DRAW_BOX)
    {
        dc.SetPen(* GetShadowPen());

        // Draw bottom line
        dc.DrawLine(
                (GetViewRect().x + 1),
                (GetViewRect().y + GetViewRect().height),
                (GetViewRect().x + GetViewRect().width + 1),
                (GetViewRect().y + GetViewRect().height)
                );

        // Draw right line
        dc.DrawLine(
                (GetViewRect().x + GetViewRect().width),
                (GetViewRect().y - GetTopMargin() + 1),
                (GetViewRect().x + GetViewRect().width),
                (GetViewRect().y + GetViewRect().height)
                );

        dc.SetPen(* wxBLACK_PEN);

        // Draw bottom line
        dc.DrawLine(
                (GetViewRect().x),
                (GetViewRect().y + GetViewRect().height + 1),
#if defined(__WXMOTIF__)
                (GetViewRect().x + GetViewRect().width + 1),
#else
                (GetViewRect().x + GetViewRect().width + 2),
#endif

⌨️ 快捷键说明

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