NCBI C++ ToolKit
composite_text_item.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: composite_text_item.cpp 47479 2023-05-02 13:24:02Z ucko $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Authors: Roman Katargin
27  *
28  * File Description:
29  *
30  */
31 
32 #include <ncbi_pch.hpp>
33 
38 
39 #include <wx/dcclient.h>
40 
42 
44 {
45  if (m_DeleteChildren) {
46  vector<ITextItem*>::iterator it;
47  for (it = m_Items.begin(); it != m_Items.end(); ++it)
48  delete *it;
49  }
50 }
51 
53 {
54  for (vector<ITextItem*>::iterator it = m_Items.begin(); it != m_Items.end(); ++it) {
55  ITextItem* item = m_Items[it - m_Items.begin()];
56  if (!item->Traverse(traverser))
57  return false;
58  }
59  return true;
60 }
61 
63 {
64  for (auto i : m_Items) {
65  if (context->IsCanceled())
66  return;
67  if (i) i->CalcSize(dc, context);
68  }
69 
71 }
72 
73 ITextItem* CCompositeTextItem::GetItemByLine(int lineNum, bool expanded)
74 {
75  if (lineNum < 0 || lineNum >= GetLineCount() || m_Items.empty())
76  return 0;
77 
78  vector<int>::iterator it = upper_bound(m_AccumLines.begin(), m_AccumLines.end(), lineNum);
79  if (it == m_AccumLines.end())
80  return 0;
81  size_t index = it - m_AccumLines.begin();
82  if (index > 0)
83  lineNum -= m_AccumLines[index - 1];
84 
85  return m_Items[index]->GetItemByLine(lineNum, expanded);
86 }
87 
88 wxPoint CCompositeTextItem::GetItemPosition(int index) const
89 {
90  wxPoint pos = GetPosition();
91 
92  if (index > 0 && (size_t)index < m_AccumHeight.size())
93  return pos + wxPoint(0, m_AccumHeight[index - 1]);
94  return pos;
95 }
96 
98 {
99  int startLine = GetStartLine();
100 
101  if (index > 0 && (size_t)index < m_AccumLines.size())
102  return startLine + m_AccumLines[index - 1];
103  return startLine;
104 }
105 
107 {
108  UpdatePositions();
109 
110  if (m_Container)
112 }
113 
114 void CCompositeTextItem::Draw(wxDC& dc, const wxRect& updateRect, CTextPanelContext* context)
115 {
116  wxPoint dcOrigin = context->GetDeviceOrigin();
117 
118  vector<int>::iterator posIt = upper_bound(m_AccumHeight.begin(), m_AccumHeight.end(), updateRect.GetTop());
119 
120  for (size_t index = posIt - m_AccumHeight.begin(); index < m_Items.size(); ++index) {
121  ITextItem* item = m_Items[index];
122  int top = (index > 0) ? m_AccumHeight[index - 1] : 0;
123  if (top > updateRect.GetBottom())
124  break;
125 
126  wxRect rect(updateRect);
127  rect.Offset(0, -top);
128  context->SetDeviceOrigin(wxPoint(dcOrigin.x, dcOrigin.y + top));
129  item->Draw(dc, rect, context);
130  }
131 
132  context->SetDeviceOrigin(dcOrigin);
133 }
134 
136 {
137 // This is only container, it should only distribute events
138 // TParent::MouseEvent(event, context);
139 // if (!event.GetSkipped())
140 // return;
141 
142  if (event.Moving()) {
143  context.MouseMoveInContainer(this);
144  }
145 
146  CTextItemPanel* panel = static_cast<CTextItemPanel*>(event.GetEventObject());
147 
148  if (m_Items.empty()) return;
149 
150  int x = event.m_x, y = event.m_y;
151 
152  vector<int>::iterator posIt = upper_bound(m_AccumHeight.begin(), m_AccumHeight.end(), y);
153  if (posIt == m_AccumHeight.end()) --posIt;
154  size_t index = posIt - m_AccumHeight.begin();
155 
156  ITextItem* item = m_Items[index];
157 
158  if (index > 0)
159  y -= m_AccumHeight[index - 1];
160 
161  wxSize size = item->GetSize();
162  if (panel->Selecting() || (0 <= y && y < size.GetHeight())) {
163  wxMouseEvent ev(event);
164  ev.m_x = x;
165  ev.m_y = y;
166  item->MouseEvent(ev, context);
167  }
168  else
169  panel->SetCursor(wxCursor(wxCURSOR_ARROW));
170 }
171 
172 void CCompositeTextItem::AddItem (ITextItem* item, bool updatePositions)
173 {
174  InsertItems (m_Items.size(), &item, 1, updatePositions);
175 }
176 
178 {
179  return (index < m_Items.size()) ? m_Items[index] : 0;
180 }
181 
182 void CCompositeTextItem::GetText(wxTextOutputStream& os,
183  const CTextBlock& block,
185 {
186  for (size_t i = 0; i < m_Items.size(); ++i) {
187  CTextBlock itemBlock = m_Items[i]->GetItemBlock();
188 
189  if (itemBlock.GetEnd().GetRow() <= block.GetStart().GetRow())
190  continue;
191  if (itemBlock.GetStart().GetRow() > block.GetEnd().GetRow())
192  break;
193 
194  m_Items[i]->GetText(os, block, context);
195  }
196 }
197 
198 void CCompositeTextItem::InsertItems (size_t index, ITextItem* const * items, size_t count, bool updatePositions)
199 {
200  if (index > m_Items.size()) index = m_Items.size();
201  m_Items.insert(m_Items.begin() + index, items, items + count);
202 
203  m_AccumLines.resize(m_AccumLines.size() + count);
204  m_AccumHeight.resize(m_AccumHeight.size() + count);
205 
206  if (updatePositions) {
207  UpdatePositions();
208  if (m_Container)
210  }
211 }
212 
214 {
215  if (index >= m_Items.size()) return;
216  if (m_DeleteChildren) {
217  delete m_Items[index];
218  }
219  m_Items.erase(m_Items.begin() + index);
220  m_AccumLines.erase(m_AccumLines.begin() + index);
221  m_AccumHeight.erase(m_AccumHeight.begin() + index);
222  UpdatePositions();
223 
224  if (m_Container)
226 }
227 
229 {
230  m_LineCount = 0;
231  m_Size = wxSize(0,0);
232 
233  for (size_t i = 0; i < m_AccumLines.size(); ++i) {
234  ITextItem* item = m_Items[i];
235  if (!item) continue;
236  item->SetContainer(this, static_cast<int>(i));
237  IContainer* container = dynamic_cast<IContainer*>(item);
238  if (container) {
239  container->UpdatePositions();
240  }
241  m_LineCount += item->GetLineCount();
242  m_AccumLines[i] = static_cast<int>(m_LineCount);
243 
244  wxSize childSize = item->GetSize();
245  m_Size.SetWidth(max(m_Size.GetWidth(), childSize.GetWidth()));
246  m_Size.IncBy(0, childSize.GetHeight());
247 
248  m_AccumHeight[i] = m_Size.GetHeight();
249  }
250 }
251 
virtual void ItemSizeChanged(int index)
ITextItem * GetItem(size_t index)
virtual wxPoint GetItemPosition(int index) const
virtual void MouseEvent(wxMouseEvent &event, CTextPanelContext &context)
void RemoveItem(size_t index)
virtual void UpdatePositions()
vector< ITextItem * > m_Items
virtual bool Traverse(ICompositeTraverser &traverser)
virtual void Draw(wxDC &dc, const wxRect &updateRect, CTextPanelContext *context)
virtual int GetItemStartLine(int index) const
virtual void CalcSize(wxDC &dc, CTextPanelContext *context)
virtual ITextItem * GetItemByLine(int lineNum, bool expanded)
void InsertItems(size_t index, ITextItem *const *items, size_t count, bool updatePositions=true)
virtual void GetText(wxTextOutputStream &os, const CTextBlock &block, CTextPanelContext *context)
void AddItem(ITextItem *item, bool updatePositions=true)
CTextPosition GetEnd() const
CTextPosition GetStart() const
bool Selecting() const
size_t m_LineCount
Definition: text_item.hpp:171
virtual wxPoint GetPosition() const
Definition: text_item.hpp:137
virtual int GetStartLine() const
Definition: text_item.hpp:145
virtual size_t GetLineCount() const
Definition: text_item.hpp:148
IContainer * m_Container
Definition: text_item.hpp:174
wxSize m_Size
Definition: text_item.hpp:172
int GetRow() const
virtual void ItemSizeChanged(int index)=0
virtual void UpdatePositions()=0
virtual wxSize GetSize() const =0
virtual void Draw(wxDC &dc, const wxRect &updateRect, CTextPanelContext *context)=0
virtual void MouseEvent(wxMouseEvent &, CTextPanelContext &)
Definition: text_item.hpp:86
virtual bool Traverse(ICompositeTraverser &)=0
virtual size_t GetLineCount() const =0
virtual void SetContainer(IContainer *container, int index)=0
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
int i
const struct ncbi::grid::netcache::search::fields::SIZE size
T max(T x_, T y_)
static CS_CONTEXT * context
Definition: will_convert.c:21
Modified on Sun Jul 14 05:02:11 2024 by modify_doxy.py rev. 669887