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

Go to the SVN repository for this file.

1 /* $Id: min_panel_container.cpp 46060 2021-01-21 18:38:06Z grichenk $
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: Andrey Yazhuk
27  *
28  * File Description:
29  *
30  */
31 
32 
33 #include <ncbi_pch.hpp>
34 
36 
38 
42 
43 
44 #include <wx/dc.h>
45 #include <wx/dcbuffer.h>
46 #include <wx/settings.h>
47 #include <wx/menu.h>
48 
49 
52 
53 
54 ////////////////////////////////////////////////////////////////////////////////
55 /// CMinPanelContainer
56 
57 static const int kRestoreWindowFirst = 15000;
58 static const int kRestoreWindowLast = 15100;
59 
64  EVT_CONTEXT_MENU(CMinPanelContainer::OnContextMenu)
66  CMinPanelContainer::OnDockPanelCommand)
68  CMinPanelContainer::OnRestoreWindow)
70  CMinPanelContainer::OnUpdateWindowCommand)
71 
74 
75 
76 CMinPanelContainer::CMinPanelContainer(wxWindow* parent, CDockManager& manager)
77 : TParent(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, _("min_panel_container")),
78  m_DockManager(manager),
79  m_PrefSize(0, 0),
80  m_MenuPanel(NULL)
81 {
82  SetBackgroundStyle(wxBG_STYLE_CUSTOM);
83 
84  m_Font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
85 }
86 
87 
89 {
90 }
91 
92 
94 {
95  SItem* item = new SItem;
96  item->m_DockPanel = &panel;
97  m_Items.push_back(item);
98 
99  m_MenuPanel = &panel;
100 
101  panel.Hide();
102  panel.Reparent(this);
103 
104  InvalidateBestSize();
105 
106  Layout();
107  GetParent()->Layout();
108  Refresh();
109 }
110 
111 
113 {
115  SItem& item = **it;
116  if(item.m_DockPanel == &panel) {
117  // delete this item
118  panel.Hide();
119  m_Items.erase(it);
120 
121  if (m_MenuPanel != NULL && m_MenuPanel == &panel) {
122  m_MenuPanel = NULL;
123 
124  if (!m_Items.empty()) {
125  m_MenuPanel = m_Items.back()->m_DockPanel;
126  }
127  }
128 
129  InvalidateBestSize();
130 
131  Layout();
132  GetParent()->Layout();
133  Refresh();
134  return;
135  }
136  }
137 
138  _ASSERT(false); // cannot find the panel !
139 }
140 
141 
143 {
144  const SItem* item = x_FindItemByPanel(&panel);
145  return item != NULL;
146 }
147 
148 
149 void CMinPanelContainer::OnSize(wxSizeEvent& event)
150 {
151  Layout();
152  Refresh();
153 }
154 
155 
158 {
159  ITERATE(TItems, it, m_Items) {
160  const SItem* item = *it;
161  if(item->m_DockPanel == panel)
162  return item;
163  }
164  return NULL;
165 }
166 
167 
169 {
171  SItem* item = *it;
172  if(item->m_Rect.Contains(pt))
173  return item;
174  }
175  return NULL;
176 }
177 
178 
179 static const int kOffsetX = 2;
180 static const int kOffsetY = 2;
181 static const int kMinW = 50;
182 static const int kMaxW = 200;
183 static const int kMinH = 20;
184 static const int kLabelOffsetX = 4;
185 static const int kLabelOffsetY = 3;
186 static const int kIconOffX = 3;
187 static const int kIconOffY = 3;
188 
189 
191 {
192  m_PrefSize = wxSize(0, 0);
193 
194  wxRect bounds = GetRect();
195  bounds.x = bounds.y = 0;
196  bounds.Deflate(kOffsetX, kOffsetY);
197 
198  bool new_row = true;
199  int x = bounds.x, y = bounds.y;
200 
201  wxClientDC dc(this);
202  dc.SetFont(m_Font);
203 
204  // iterate by items
205  for( size_t i = 0; i < m_Items.size(); i++ ) {
206  SItem& item = *m_Items[i];
207 
208  wxSize size = x_MeasureItem(dc, item);
209 
210  int right = x + size.x + kOffsetX;
211  if(right > bounds.GetRight() && ! new_row) {
212  // start a new row
213  x = bounds.x;
214  y += kMinH + kOffsetY;
215  new_row = true;
216  }
217 
218  // set rectangle
219  item.m_Rect = wxRect(x, y, size.x, size.y);
220  x = item.m_Rect.GetRight() + kOffsetX;
221 
222  m_PrefSize.x = std::max(m_PrefSize.x, x);
223  m_PrefSize.y = std::max(m_PrefSize.y, item.m_Rect.GetBottom());
224 
225  new_row = false;
226  }
227  m_PrefSize.x += kOffsetX * 2;
228  if(m_PrefSize.y > 0) {
229  m_PrefSize.y += kOffsetY * 2;
230  }
231  return true;
232 }
233 
234 
235 wxSize CMinPanelContainer::x_MeasureItem(wxDC& dc, const SItem& item)
236 {
237  wxSize size;
238 
239  const IWMClient* client = item.m_DockPanel->GetClient();
240 
241  string alias = client->GetIconAlias();
242  wxBitmap bmp = wxArtProvider::GetBitmap(ToWxString(alias));
243  if(bmp.IsOk()) {
244  size.x += bmp.GetWidth() + kIconOffX * 2;
245  size.y += bmp.GetHeight() + kIconOffY * 2;
246  }
247 
248  /// measure item text
249  wxString label = ToWxString(client->GetClientLabel());
250  int w = 0, h = 0;
251  dc.GetTextExtent(label, &w, &h);
252  // add extra spacing around the text
253  w += kLabelOffsetX * 2;
254  h += kLabelOffsetY * 2;
255  size.x = max(size.x, w);
256  size.y = max(size.y, h);
257 
258  // apply min / max constraints
259  size.x = max(kMinW, size.x);
260  size.x = min(kMaxW, size.x);
261  size.y = min(kMinH, size.y);
262  return size;
263 }
264 
265 
267 {
268  return m_PrefSize;
269 }
270 
271 
272 void CMinPanelContainer::OnPaint(wxPaintEvent& event)
273 {
274  wxRect rc = GetRect();
275 
276  wxAutoBufferedPaintDC dc(this);
277 
278  // fill background
279  wxColour back_cl = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
280  wxBrush brush(back_cl);
281  dc.SetBrush(brush);
282  dc.SetPen(*wxTRANSPARENT_PEN);
283  dc.DrawRectangle(0, 0, rc.width, rc.height);
284 
285  // draw items
286  for( size_t i = 0; i < m_Items.size(); i++ ) {
287  SItem& item = *m_Items[i];
288  x_DrawItem(dc, item);
289  }
290 }
291 
292 
294 {
295  const IWMClient* client = item.m_DockPanel->GetClient();
296  wxRect& rc = item.m_Rect;
297 
298  wxColor cl_text = wxSystemSettings::GetColour(wxSYS_COLOUR_3DDKSHADOW);
299  wxColor cl_line = wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW);
300  wxColour back_cl = wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT);
301 
302  wxBrush brush(back_cl);
303  wxPen pen(cl_line);
304  dc.SetBrush(brush);
305  dc.SetPen(pen);
306 
307  dc.DrawRoundedRectangle(rc.x, rc.y, rc.width, rc.height, 3);
308 
309  int pos_x = rc.x;
310 
311  // draw Client icon
312  string alias = client->GetIconAlias();
313  wxBitmap bmp = wxArtProvider::GetBitmap(ToWxString(alias));
314  if(bmp.IsOk()) {
315  pos_x += kIconOffX;
316  int pos_y = rc.y + (rc.height - bmp.GetHeight()) / 2;
317  dc.DrawBitmap(bmp, pos_x, pos_y);
318  pos_x += bmp.GetWidth() + kIconOffX;
319  }
320 
321  dc.SetFont(m_Font);
322 
323  // truncate label if needed
324  pos_x += kLabelOffsetX;
325  int av_w = rc.x + rc.width - pos_x - kLabelOffsetX;
326  wxString label = ToWxString(client->GetClientLabel());
327  wxString s = TruncateText(dc, label, av_w);
328 
329  int w = 0, h = 0;
330  dc.GetTextExtent(s, &w, &h);
331  int pos_y = rc.y + (rc.height - h) / 2;
332 
333  dc.SetTextForeground(cl_text);
334  dc.DrawText(s, pos_x, pos_y);
335 }
336 
337 
338 void CMinPanelContainer::OnLeftClick(wxMouseEvent& event)
339 {
340  wxPoint pt = event.GetPosition();
341  SItem* item = x_FindItemByPos(pt);
342 
343  if(item) {
344  // restore the window associated with the item
346  }
347 }
348 
349 
350 void CMinPanelContainer::OnContextMenu(wxContextMenuEvent& event)
351 {
352  static const size_t kMaxLabelChars = 40;
353 
354  m_MenuPanel = NULL;
355  unique_ptr<wxMenu> menu;
357 
358  // hit testing
359  wxPoint sc_pt = event.GetPosition();
360  wxPoint pt = ScreenToClient(sc_pt);
361  SItem* item = x_FindItemByPos(pt);
362 
363  if(item) {
364  // clicked on an item
365  m_MenuPanel = item->m_DockPanel;
367 
368  } else {
369  // show generic menu
370  menu.reset(new wxMenu());
371 
372  int cmd = kRestoreWindowFirst;
373 
375  SItem& item = **it;
376  const IWMClient* client = item.m_DockPanel->GetClient();
377 
378  string label = client->GetClientLabel();
379  if(label.size() > kMaxLabelChars) {
380  label.resize(40);
381  label += "...";
382  }
383 
384  wxString wxs = ToWxString(label);
385  menu->Append(cmd, wxs);
386  m_CmdToPanel[cmd] = item.m_DockPanel;
387 
388  cmd++;
389  }
390 
391  menu->AppendSeparator();
392 
394  cmd_reg.AppendMenuItem(*menu, eCmdShowWindowsDlg);
395  }
396 
397  // show context menu
398  PopupMenu(menu.get());
399 }
400 
401 
402 void CMinPanelContainer::OnDockPanelCommand(wxCommandEvent& event)
403 {
405 
407  m_MenuPanel = NULL;
408 }
409 
410 
411 void CMinPanelContainer::OnRestoreWindow(wxCommandEvent& event)
412 {
413  int cmd = event.GetId();
415 
416  if(it != m_CmdToPanel.end()) {
417  CDockPanel* panel = it->second;
419  SItem& item = **it;
420  if(item.m_DockPanel == panel) {
422  return;
423  }
424  }
425  }
426  _ASSERT(false); // invalid command or panel is not found
427 }
428 
429 
430 void CMinPanelContainer::OnUpdateWindowCommand(wxUpdateUIEvent& event)
431 {
432  if (m_MenuPanel != NULL) {
435  }
436 }
437 
438 
439 void CMinPanelContainer::OnShowWindowsDlg(wxCommandEvent& event)
440 {
442 }
443 
CDockManager CDockManager sends requests to Window Manager, Window Manager makes decisions about dele...
bool OnDockPanelCommand(CDockPanel &panel, TCmdID cmd)
CWindowManager & GetWindowManager()
wxMenu * GetDockPanelMenu(CDockPanel &panel)
CDockPanel - a container with a title bar (caption) hosting a single client window (IWMClient).
Definition: dock_panel.hpp:73
IWMClient * GetClient()
Definition: dock_panel.hpp:93
CMinPanelContainer.
void OnSize(wxSizeEvent &event)
void RemoveClient(CDockPanel &panel)
bool HasClient(CDockPanel &panel) const
void OnLeftClick(wxMouseEvent &event)
CDockManager & m_DockManager
void AddClient(CDockPanel &panel)
void OnContextMenu(wxContextMenuEvent &event)
SItem * x_FindItemByPos(const wxPoint &pt)
void OnDockPanelCommand(wxCommandEvent &event)
void OnPaint(wxPaintEvent &event)
const SItem * x_FindItemByPanel(CDockPanel *panel) const
void OnRestoreWindow(wxCommandEvent &event)
wxSize x_MeasureItem(wxDC &dc, const SItem &descr)
void OnShowWindowsDlg(wxCommandEvent &event)
void OnUpdateWindowCommand(wxUpdateUIEvent &event)
virtual wxSize DoGetBestSize() const
map< int, CDockPanel * > m_CmdToPanel
panel for which context menu is shown
vector< SItem * > TItems
void x_DrawItem(wxDC &dc, SItem &descr)
CUICommandRegistry is a centralized registry where all application commands should be registered.
Definition: ui_command.hpp:146
static CUICommandRegistry & GetInstance()
the main instance associated with the application
Definition: ui_command.cpp:176
wxMenuItem * AppendMenuItem(wxMenu &menu, TCmdID cmd_id) const
Definition: ui_command.cpp:300
void OnShowWindowsDlg(wxCommandEvent &event)
void OnUpdateWindowCommand_Client(wxUpdateUIEvent &event, IWMClient *client)
IWClient - abstract Window Manager client.
Definition: wm_client.hpp:50
const_iterator end() const
Definition: map.hpp:152
void clear()
Definition: map.hpp:169
const_iterator find(const key_type &key) const
Definition: map.hpp:153
Definition: map.hpp:338
static const char * bounds[]
#define _(proto)
Definition: ct_nlmzip_i.h:78
@ eCmdCloseDockPanel
Definition: dock_panel.hpp:54
@ eCmdWindowRestore
Definition: dock_panel.hpp:58
thread_local unique_ptr< FtaMsgPost > bmp
Definition: ftaerr.cpp:120
static CS_COMMAND * cmd
Definition: ct_dynamic.c:26
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
#define NON_CONST_ITERATE(Type, Var, Cont)
Non constant version of ITERATE macro.
Definition: ncbimisc.hpp:822
#define NULL
Definition: ncbistd.hpp:225
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
static const char label[]
@ eCmdShowWindowsDlg
END_EVENT_TABLE()
int i
USING_SCOPE(objects)
static const int kMaxW
static const int kLabelOffsetY
static const int kRestoreWindowFirst
CMinPanelContainer.
EVT_MENU_RANGE(eCmdCloseDockPanel, eCmdWindowRestore, CMinPanelContainer::OnDockPanelCommand) EVT_MENU_RANGE(kRestoreWindowFirst
CMinPanelContainer::OnRestoreWindow EVT_UPDATE_UI_RANGE(eCmdCloseDockPanel, eCmdWindowRestore, CMinPanelContainer::OnUpdateWindowCommand) CMinPanelContainer
static const int kRestoreWindowLast
static const int kMinW
static const int kOffsetX
static const int kMinH
static const int kLabelOffsetX
static const int kIconOffX
static const int kOffsetY
static const int kIconOffY
const struct ncbi::grid::netcache::search::fields::SIZE size
T max(T x_, T y_)
T min(T x_, T y_)
static static static wxID_ANY
ViewerWindowBase::OnEditMenu ViewerWindowBase::OnJustification EVT_MENU(MID_SHOW_GEOM_VLTNS, ViewerWindowBase::OnShowGeomVltns) EVT_MENU(MID_FIND_PATTERN
static CNamedPipeClient * client
#define _ASSERT
wxString ToWxString(const string &s)
Definition: wx_utils.hpp:173
wxString TruncateText(wxDC &dc, const wxString &s, int w, Ewx_Truncate trunc=ewxTruncate_Ellipsis)
truncates given string so that its length is less or equal "w" "trunc" controls truncation,...
Definition: wx_utils.cpp:878
Modified on Wed Apr 17 13:09:14 2024 by modify_doxy.py rev. 669887