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

Go to the SVN repository for this file.

1 /* $Id: desktop_item.cpp 46376 2021-04-01 18:30:04Z asztalos $
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: Andrea Asztalos
27  *
28  * File Description:
29  *
30  */
31 
32 #include <ncbi_pch.hpp>
33 #include <serial/typeinfo.hpp>
36 
37 #include <wx/dcmemory.h>
38 
40 
41 namespace {
42  const wxFont s_DesktopFont(10, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxT("Consolas"));
43 }
44 
46  : m_Pos(wxPoint(0, 0)), m_TextHeight(0), m_Origin(wxPoint(20, 20)),
47  m_Item(item), m_Show(false), m_ExpandLevel(0), m_Indent(33), m_Selected(false)
48 {
49  if (!m_Item) return;
50  Init();
51 }
52 
54 {
59 }
60 
61 void CDesktopItem::Draw(wxDC& dc, bool highlight) const
62 {
63  dc.SetPen(m_FrameCol);
64  dc.SetBrush(m_BkgdBrush);
65 
66  int height = (m_Item->ShouldBeReduced()) ? m_Size.GetHeight() - 1 : m_Size.GetHeight();
67  wxRect rect(m_Pos, wxSize(m_Size.GetWidth(), height));
68 
69  dc.DrawRectangle(rect);
70  dc.SetTextForeground(m_TextCol);
71  dc.DrawLabel(m_CurrentText, rect, wxALIGN_TOP | wxALIGN_LEFT);
72 
73  if (highlight) {
74  dc.SetPen(*wxWHITE_PEN);
75  dc.SetBrush(*wxTRANSPARENT_BRUSH);
76  dc.DrawRectangle(GetRect());
77  }
78  if (m_Selected) {
79  dc.SetPen(wxPen(*wxBLACK, 2));
80  dc.SetBrush(*wxTRANSPARENT_BRUSH);
81  if (m_Item->ShouldBeReduced()) {
82  dc.DrawRectangle(GetRect());
83  }
84  else {
85  wxRect rect(GetRect());
86  dc.DrawRectangle(
87  wxRect(rect.GetPosition(),
88  wxSize(rect.GetSize().GetWidth(), rect.GetSize().GetHeight() + 1)));
89  }
90  }
91 }
92 
93 const string& CDesktopItem::GetType() const
94 {
95  _ASSERT(m_Item);
96  return m_Item->GetType();
97 }
98 
100 {
101  return ConstRef(m_Item->GetObject());
102 }
103 
104 bool CDesktopItem::FindSearchItem(const string& search, bool case_sensitive) const
105 {
106  for (auto& it : m_Text) {
107  SIZE_TYPE pos = NStr::Find(it, search, (case_sensitive) ? NStr::eCase : NStr::eNocase);
108  if (pos != NPOS) {
109  return true;
110  }
111  }
112  return false;
113 }
114 
116 {
117  wxMemoryDC dc;
118  // the size of the text determines the size of the rectangle
119  wxSize textSize = x_GetVisibleTextSize(dc);
120  m_Size = textSize + wxSize(20, 5);
121 }
122 
123 static wxSize s_GetMultiLineSize(wxDC& dc, const wxString& text)
124 {
125  wxCoord width, height;
126  dc.GetMultiLineTextExtent(text, &width, &height, NULL, &s_DesktopFont);
127  return wxSize(width, height);
128 }
129 
130 // CSimpleDesktopItem
131 
133  : CDesktopItem(item)
134 {
136 }
137 
139 {
140  m_ExpandLevel++;
142 }
143 
145 {
146  if (m_ExpandLevel <= 0) return;
147 
148  m_ExpandLevel--;
150 }
151 
153 {
154 }
155 
156 
158 {
159  if (GetRect().Contains(pt.x, pt.y)) {
160  return (IDesktopItem*)this;
161  }
162  return nullptr;
163 }
164 
166 {
167  string text;
168  if (m_ExpandLevel >= (int)m_Text.size()) {
169  // draw all lines
170  for (const auto& it : m_Text) {
171  text.append(it);
172  text.append("\n");
173  }
174  }
175  else {
176  for (auto i = 0; i < m_ExpandLevel + 1; ++i) {
177  text.append(m_Text[i]);
178  text.append("\n");
179  }
180  }
181 
182  text.pop_back();
184  wxSize size = s_GetMultiLineSize(dc, m_CurrentText);
185  m_TextHeight = size.y + 2; // 2 - to have vertical white space around the text
186  return size;
187 }
188 
190 {
191  m_Pos.x = depth*m_Indent + m_Origin.x;
192  m_Pos.y = *cumY;
193  *cumY += GetRelevantHeight();
194 }
195 
196 // CCompositeDesktopItem
197 
199  : CDesktopItem(item)
200 {
202 }
203 
205 {
206  m_ItemList.push_back(CIRef<IDesktopItem>(&item));
207 }
208 
210 {
211  m_ExpandLevel++;
212  if (m_ExpandLevel == 1) {
213  for (auto& it : m_ItemList) {
214  it->Show(true);
215  if (it->GetType() == objects::CBioseq::GetTypeInfo()->GetName()
216  || it->GetType() == objects::CBioseq_set::GetTypeInfo()->GetName()) {
217  it->Expand();
218  }
219  }
220  }
221  else {
222  for (auto& it : m_ItemList) {
223  it->Expand();
224  }
225  }
227 }
228 
230 {
231  if (m_ExpandLevel <= 0) return;
232 
233  m_ExpandLevel--;
234  if (m_ExpandLevel == 0) {
235  for (auto& it : m_ItemList) {
236  if (it->GetType() == objects::CBioseq::GetTypeInfo()->GetName()
237  || it->GetType() == objects::CBioseq_set::GetTypeInfo()->GetName()) {
238  it->Collapse();
239  }
240  else {
241  it->Show(false);
242  }
243  }
244  }
245  else {
246  for (auto& it : m_ItemList) {
247  it->Collapse();
248  }
249  }
251 }
252 
254 {
255  m_Size.y = 0;
256  // contribution from children items
257 
258  // flag to signal whether the last child of this composite item has a white frame color
259  //bool last_child_white_frame = false;
260  for (auto& it : m_ItemList) {
261  if (it->IsShown()) {
262  it->UpdateSize();
263  m_Size.y += it->GetSize().GetHeight();
264  int new_width = it->GetSize().GetWidth() + (it->GetPosition().x - m_Pos.x);
265  if (new_width >= m_Size.x) {
266  new_width = new_width + 2; // for making the outline visible
267  }
268  m_Size.x = max(new_width, m_Size.x);
269  //last_child_white_frame = (it->GetFrameColor() == *wxWHITE) ? true : false;
270  }
271  }
272 
273  // contribution of the actual item
274  m_Size.y += m_TextHeight;
275 }
276 
278 {
279  CDesktopItem::Traverse(traverser);
280  for (auto& it : m_ItemList) {
281  if (!it->Traverse(traverser))
282  return false;
283  }
284  return true;
285 }
286 
288 {
289  for (auto& it : m_ItemList) {
290  if (it->IsShown()) {
291  IDesktopItem* hit = it->FindItem(pt);
292  if (hit) {
293  return hit;
294  }
295  }
296  }
297 
298  if (GetRect().Contains(pt.x, pt.y)) {
299  return (IDesktopItem*)this;
300  }
301  return nullptr;
302 }
303 
305 {
306  for (auto& it : m_ItemList) {
307  if (it->GetType() == objects::CBioseq::GetTypeInfo()->GetName()
308  || it->GetType() == objects::CBioseq_set::GetTypeInfo()->GetName()) {
309  it->Show(value);
310  it->ShowTillBioseq(value);
311  }
312  }
313 }
314 
316 {
317  return m_TextHeight;
318 }
319 
321 {
322  string text;
323  if (m_ExpandLevel >= (int)m_Text.size()) {
324  // draw all lines
325  for (const auto& it : m_Text) {
326  text.append(it);
327  text.append("\n");
328  }
329  }
330  else {
331  for (auto i = 0; i < m_ExpandLevel + 1; ++i) {
332  text.append(m_Text[i]);
333  text.append("\n");
334  }
335  }
336 
337  text.pop_back();
339  wxSize size = s_GetMultiLineSize(dc, m_CurrentText);
340  m_TextHeight = size.y + 2; // 2 - to have vertical white space around the text
341  return size;
342 }
343 
345 {
346  m_Pos.x = depth*m_Indent + m_Origin.x;
347  m_Pos.y = *cumY;
348  *cumY += GetRelevantHeight();
349  for (auto& it : m_ItemList) {
350  if (it->IsShown()) {
351  it->UpdatePositions(cumY, depth + 1);
352  }
353  }
354 }
355 
356 // CRootDesktopItem
357 
359  : CCompositeDesktopItem(item)
360 {
361  Init();
362 }
363 
365 {
366  m_Pos = m_Origin;
367  m_Text = m_Item->GetDescription(true);
368  m_FrameCol = *wxBLUE;
369  m_TextCol = *wxBLUE;
370  m_BkgdBrush = *wxWHITE_BRUSH;
372  m_TextHeight = m_Size.GetHeight();
373  m_OrigSize = m_Size;
374 }
375 
377 {
378  m_ExpandLevel++;
379  if (m_ExpandLevel == 1) {
380  // gather all children up till bioseq
381  for (auto& it : m_ItemList) {
382  if (it->GetType() == objects::CBioseq::GetTypeInfo()->GetName()
383  || it->GetType() == objects::CBioseq_set::GetTypeInfo()->GetName()) {
384  it->Show(true);
385  it->ShowTillBioseq(true);
386  }
387  }
388  }
389  else if (m_ExpandLevel == 2) {
390  for (auto& it : m_ItemList) {
391  it->Show(true);
392  if (it->GetType() == objects::CBioseq::GetTypeInfo()->GetName()
393  || it->GetType() == objects::CBioseq_set::GetTypeInfo()->GetName()) {
394  it->Expand();
395  }
396  }
397  }
398  else {
399  for (auto& it : m_ItemList) {
400  it->Expand();
401  }
402  }
404 }
405 
407 {
408  if (m_ExpandLevel <= 0) return;
409 
410  m_ExpandLevel--;
411  if (m_ExpandLevel == 0) {
412  // all children should not show up
413  for (auto& it : m_ItemList) {
414  it->Show(false);
415  it->ShowTillBioseq(false);
416  }
417  }
418  else if (m_ExpandLevel == 1) {
419  for (auto& it : m_ItemList) {
420  if (it->GetType() == objects::CBioseq::GetTypeInfo()->GetName()
421  || it->GetType() == objects::CBioseq_set::GetTypeInfo()->GetName()) {
422  it->Collapse();
423  }
424  else {
425  it->Show(false);
426  }
427  }
428  }
429  else {
430  for (auto& it : m_ItemList) {
431  it->Collapse();
432  }
433  }
434 
436 }
437 
439 {
440  m_Size.y = 0;
441  // contribution from children items
442  for (auto& it : m_ItemList) {
443  if (it->IsShown()) {
444  it->UpdateSize();
445  m_Size.y += it->GetSize().GetHeight();
446  m_Size.x = max(it->GetSize().GetWidth() + (it->GetPosition().x - m_Pos.x), m_Size.x);
447  }
448  }
449  // contribution of the original item
450  m_Size.y += m_OrigSize.GetHeight();
451 }
452 
454 {
455  depth = 0;
456  *cumY = m_Origin.y + m_OrigSize.GetHeight();
457  for (auto& it : m_ItemList) {
458  if (it->IsShown()) {
459  if (it->GetType() == objects::CContact_info::GetTypeInfo()->GetName()
460  || it->GetType() == objects::CCit_sub::GetTypeInfo()->GetName()) {
461  depth = 1;
462  }
463  else {
464  depth = 0;
465  }
466  it->UpdatePositions(cumY, depth);
467  }
468  }
469 }
470 
472 {
473  return CCompositeDesktopItem::Traverse(traverser);
474 }
475 
477 {
478  string text;
479  for (const auto& it : m_Text) {
480  text.append(it);
481  text.append("\n");
482  }
483 
484  text.pop_back();
486  return s_GetMultiLineSize(dc, m_CurrentText);
487 }
488 
490 
A desktop item with children.
virtual wxSize x_GetVisibleTextSize(wxDC &dc)
Determines the size of the text to be displayed corresponding to the current expansion level.
TDeskItemList m_ItemList
List of child items.
virtual void ShowTillBioseq(bool value)
CCompositeDesktopItem(CConstRef< IDesktopDataItem > item)
virtual void Add(IDesktopItem &)
virtual bool Traverse(IDesktopCompositeTraverser &traverser)
virtual int GetRelevantHeight() const
virtual void UpdatePositions(int *cumY, int depth=0)
virtual void Collapse()
virtual void Expand()
virtual void UpdateSize()
virtual IDesktopItem * FindItem(const wxPoint &pt) const
void x_SetTextToDrawAndSize()
Sets the size of the rectangle based on the height and width of the displayed text.
virtual wxSize x_GetVisibleTextSize(wxDC &dc)=0
Determines the size of the text to be displayed corresponding to the current expansion level.
vector< string > m_Text
Text that appears in the rectangle.
int m_TextHeight
Height of the text within the rectangle.
wxColour m_FrameCol
Colour of rectangle's outline.
wxPoint m_Origin
Point where the drawing starts.
CConstRef< IDesktopDataItem > m_Item
Storing actual data.
virtual bool Traverse(IDesktopCompositeTraverser &traverser)
wxPoint m_Pos
Position of the item on the canvas.
virtual const string & GetType() const
virtual void Draw(wxDC &dc, bool highlight=false) const
virtual const CConstRef< CObject > GetAssociatedObject() const
wxColour m_TextCol
Foreground colour of the text.
bool m_Selected
Flag to indicate selection of this item.
CDesktopItem(CConstRef< IDesktopDataItem > item)
int m_Indent
Text indentation.
wxString m_CurrentText
Text that appears on the screen corresponding to the current level of expansion.
wxBrush m_BkgdBrush
Background colour of the rectangle.
int m_ExpandLevel
State(level) of expansion.
virtual void Init()
virtual bool FindSearchItem(const string &search, bool case_sensitive) const
wxSize m_Size
Size of the rectangle.
virtual bool Traverse(IDesktopCompositeTraverser &traverser)
virtual void Collapse()
wxSize m_OrigSize
Original size corresponding to 0 expansion level.
CRootDesktopItem(CConstRef< IDesktopDataItem > item)
virtual void UpdateSize()
virtual wxSize x_GetVisibleTextSize(wxDC &dc)
Determines the size of the text to be displayed corresponding to the current expansion level.
virtual void Init()
virtual void Expand()
virtual void UpdatePositions(int *cumY, int depth=0)
virtual wxSize x_GetVisibleTextSize(wxDC &dc)
Determines the size of the text to be displayed corresponding to the current expansion level.
virtual IDesktopItem * FindItem(const wxPoint &pt) const
virtual void UpdateSize()
virtual int GetRelevantHeight() const
virtual void Collapse()
virtual void Expand()
virtual void UpdatePositions(int *cumY, int depth=0)
CSimpleDesktopItem(CConstRef< IDesktopDataItem > item)
virtual const CObject * GetObject(void) const =0
virtual wxColour GetTextColor() const =0
virtual const wxBrush & GetBackgroundBrush() const =0
virtual const string & GetType() const
virtual TLines GetDescription(bool root=false) const =0
virtual wxColour GetFrameColor() const =0
virtual bool ShouldBeReduced() const
virtual IDesktopItem * FindItem(const wxPoint &pt) const =0
virtual wxRect GetRect() const
static unsigned char depth[2 *(256+1+29)+1]
static wxSize s_GetMultiLineSize(wxDC &dc, const wxString &text)
#define false
Definition: bool.h:36
#define NULL
Definition: ncbistd.hpp:225
CConstRef< C > ConstRef(const C *object)
Template function for conversion of const object pointer to CConstRef.
Definition: ncbiobj.hpp:2024
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
NCBI_NS_STD::string::size_type SIZE_TYPE
Definition: ncbistr.hpp:132
#define NPOS
Definition: ncbistr.hpp:133
static SIZE_TYPE Find(const CTempString str, const CTempString pattern, ECase use_case=eCase, EDirection direction=eForwardSearch, SIZE_TYPE occurrence=0)
Find the pattern in the string.
Definition: ncbistr.cpp:2891
@ eNocase
Case insensitive compare.
Definition: ncbistr.hpp:1206
@ eCase
Case sensitive compare.
Definition: ncbistr.hpp:1205
int i
static void text(MDB_val *v)
Definition: mdb_dump.c:62
#define wxT(x)
Definition: muParser.cpp:41
const struct ncbi::grid::netcache::search::fields::SIZE size
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1227
static bool Contains(const CSeq_loc &a, const CSeq_loc &b, CScope *scope)
T max(T x_, T y_)
#define _ASSERT
wxString ToWxString(const string &s)
Definition: wx_utils.hpp:173
Modified on Wed Jun 12 11:15:38 2024 by modify_doxy.py rev. 669887