Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TGPack.cxx
Go to the documentation of this file.
1// @(#)root/eve:$Id$
2// Author: Matevz Tadel 2007
3
4/*************************************************************************
5 * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#include "TGPack.h"
13#include "TGSplitter.h"
14#include "TMath.h"
15
16
17/** \class TGPack
18 \ingroup guiwidgets
19
20Stack of frames in horizontal (default) or vertical stack.
21The splitters are placed between the neighbouring frames so that
22they can be resized by the user.
23When the whole pack is resized, frames are scaled proportionally to
24their previous size.
25
26When frames are left in pack at destruction time, they will be
27deleted via local-cleanup.
28
29*/
30
31
33
34////////////////////////////////////////////////////////////////////////////////
35/// Constructor.
36
37TGPack::TGPack(const TGWindow *p, UInt_t w, UInt_t h, UInt_t options, Pixel_t back) :
38 TGCompositeFrame(p, w, h, options, back),
39 fVertical (kTRUE),
40 fUseSplitters (kTRUE),
41 fSplitterLen (4),
42 fDragOverflow (0),
43 fWeightSum(0),
44 fNVisible(0)
45{
47}
48
49////////////////////////////////////////////////////////////////////////////////
50/// Constructor.
51
53 TGCompositeFrame(c, id, parent),
54 fVertical (kTRUE),
55 fUseSplitters (kTRUE),
56 fSplitterLen (4),
57 fDragOverflow (0),
58 fWeightSum (0.0),
59 fNVisible (0)
60{
62}
63
64////////////////////////////////////////////////////////////////////////////////
65/// Destructor.
66
68{
69}
70
71//------------------------------------------------------------------------------
72
73////////////////////////////////////////////////////////////////////////////////
74/// Return length of entire frame without splitters.
75
77{
78 Int_t len = fVertical ? GetHeight() : GetWidth();
79 len -= fSplitterLen * (fNVisible - 1);
80
81 return len;
82}
83
84////////////////////////////////////////////////////////////////////////////////
85/// Set pack-wise length of frame f.
86
88{
89 if (fVertical)
90 f->Resize(GetWidth(), len);
91 else
92 f->Resize(len, GetHeight());
93}
94
95////////////////////////////////////////////////////////////////////////////////
96/// Set pack-wise position of frame f.
97
99{
100 if (fVertical)
101 f->Move(0, pos);
102 else
103 f->Move(pos, 0);
104}
105
106////////////////////////////////////////////////////////////////////////////////
107/// Check if splitter of first visible frame is hidden.
108/// Check if the next following visible splitter is visible.
109
111{
113 TIter next(fList);
114 Int_t rvf = 0;
115 while ((el = (TGFrameElementPack*) next())) {
116 if (el->fState && el->fSplitFE) {
117 if (rvf) {
118 // unmap first slider if necessary
119 if ( el->fSplitFE->fState == 0 ) {
120 el->fSplitFE->fState = 1;
121 el->fSplitFE->fFrame->MapWindow();
122 }
123 } else {
124 // show slider in next visible frame
125 if (el->fSplitFE->fState) {
126 el->fSplitFE->fState = 0;
128 }
129 }
130 ++rvf;
131 }
132 }
133}
134
135////////////////////////////////////////////////////////////////////////////////
136/// Resize (shrink or expand) existing frames by amount in total.
137
139{
140 if (fList->IsEmpty())
141 return;
142
143 // get unitsize
144 Int_t nflen = GetAvailableLength();
145 Float_t unit = Float_t(nflen)/fWeightSum;
146
147 // set frame sizes
148 Int_t sumFrames = 0;
149 Int_t frameLength = 0;
150 {
152 TIter next(fList);
153 while ((el = (TGFrameElementPack*) next())) {
154 if (el->fState) {
155 frameLength = TMath::Nint( unit*(el->fWeight));
156 SetFrameLength(el->fFrame, frameLength);
157 sumFrames += frameLength;
158 }
159 }
160 }
161
162 // redistribute the remain
163 {
164 // printf("available %d total %d \n", nflen, sumFrames);
165 Int_t remain = nflen-sumFrames;
166 Int_t step = TMath::Sign(1, remain);
168 TIter next(fList);
169 while ((el = (TGFrameElementPack*) next()) && remain) {
170 if (el->fState) {
171 Int_t l = GetFrameLength(el->fFrame) + step;
172 if (l > 0) {
173 SetFrameLength(el->fFrame, l);
174 remain -= step;
175 }
176 }
177 }
178 }
180}
181
182////////////////////////////////////////////////////////////////////////////////
183/// Refit existing frames to pack size.
184
186{
187 TGFrameElement *el;
188 TIter next(fList);
189
190 while ((el = (TGFrameElement *) next())) {
191 if (fVertical)
192 el->fFrame->Resize(GetWidth(), el->fFrame->GetHeight());
193 else
194 el->fFrame->Resize(el->fFrame->GetWidth(), GetHeight());
195 }
196}
197
198////////////////////////////////////////////////////////////////////////////////
199/// Find frames around splitter and return them f0 (previous) and f1 (next).
200
202{
204 TIter next(fList);
205
206 while ((el = (TGFrameElementPack *) next())) {
207 if ( ! (el->fState & kIsVisible) )
208 continue;
209
210 if (el->fFrame == splitter)
211 break;
212 f0 = el;
213 }
214 f1 = (TGFrameElementPack *) next();
215}
216
217////////////////////////////////////////////////////////////////////////////////
218/// Add frame f at the end.
219/// LayoutHints are ignored in TGPack.
220
222{
223 // add splitter
224 TGFrameElementPack *sf = 0;
225 if (fUseSplitters) {
226 TGSplitter* s = 0;
227 if (fVertical)
228 s = new TGHSplitter(this, GetWidth(), fSplitterLen, kTRUE);
229 else
230 s = new TGVSplitter(this, fSplitterLen, GetHeight(), kTRUE);
231 s->Connect("Moved(Int_t)", "TGPack", this, "HandleSplitterResize(Int_t)");
232 s->Connect("DragStarted()", "TGPack", this, "HandleSplitterStart()");
233
234 sf = new TGFrameElementPack(s, l ? l : fgDefaultHints, 0);
235 fList->Add(sf);
236 // in case of recursive cleanup, propagate cleanup setting to all
237 // child composite frames
240 s->MapWindow();
241 }
242
243 // instead TGCopositeFrame::AddFrame
245 el->fSplitFE = sf;
246 fList->Add(el);
247
248 // in case of recursive cleanup, propagate cleanup setting to all
249 // child composite frames
251 f->SetCleanup(kDeepCleanup);
252 f->MapWindow();
253
254 fNVisible ++;
255 fWeightSum += weight;
256
259}
260
261////////////////////////////////////////////////////////////////////////////////
262/// Add frame f at the end with given weight.
263/// LayoutHints are ignored in TGPack.
264
266{
267 AddFrameInternal(f, l, weight);
268 Layout();
269}
270
271////////////////////////////////////////////////////////////////////////////////
272/// Add frame f at the end with default weight.
273/// LayoutHints are ignored in TGPack.
274
276{
277 AddFrameInternal(f, l, 1);
278 Layout();
279}
280
281////////////////////////////////////////////////////////////////////////////////
282/// Remove frame f.
283
285{
287
288 if (!el) return;
289
290 if (fUseSplitters) {
294 // This is needed so that splitter window gets destroyed on server.
295 splitter->ReparentWindow(fClient->GetDefaultRoot());
296 delete splitter;
297 }
298 if (el->fState & kIsVisible) {
299 f->UnmapWindow();
300 fWeightSum -= el->fWeight;
301 --fNVisible;
302 }
304
307}
308
309////////////////////////////////////////////////////////////////////////////////
310/// Remove frame f and refit existing frames to pack size.
311/// Frame is deleted.
312
314{
316 delete f;
317 Layout();
318}
319
320////////////////////////////////////////////////////////////////////////////////
321/// Remove frame f and refit existing frames to pack size.
322/// Frame is not deleted.
323
325{
327 Layout();
328}
329
330////////////////////////////////////////////////////////////////////////////////
331/// Print sub frame info.
332
333void TGPack::Dump() const
334{
335 printf("--------------------------------------------------------------\n");
336 Int_t cnt = 0;
338 TIter next(fList);
339 while ((el = (TGFrameElementPack *) next())) {
340 printf("idx[%d] visible(%d) %s \n",cnt, el->fState, el->fFrame->GetName());
341 cnt++;
342 }
343 printf("--------------------------------------------------------------\n");
344}
345
346////////////////////////////////////////////////////////////////////////////////
347/// Show sub frame.
348/// Virtual from TGCompositeFrame.
349
351{
353 if (el) {
354 //show
355 el->fState = 1;
356 el->fFrame->MapWindow();
357
358 // show splitter
359 if (fUseSplitters) {
360 el->fSplitFE->fFrame->MapWindow();
361 el->fSplitFE->fState = 1;
362 }
363
364 // Dump();
365 fNVisible++;
366 fWeightSum += el->fWeight;
367
370 Layout();
371 }
372}
373
374////////////////////////////////////////////////////////////////////////////////
375/// Hide sub frame.
376/// Virtual from TGCompositeFrame.
377
379{
381 if (el) {
382 // hide real frame
383 el->fState = 0;
384 el->fFrame->UnmapWindow();
385
386 // hide splitter
387 if (fUseSplitters) {
389 el->fSplitFE->fState = 0;
390 }
391
392 // Dump();
393 fNVisible--;
394 fWeightSum -= el->fWeight;
395
398 Layout();
399 }
400}
401
402
403////////////////////////////////////////////////////////////////////////////////
404/// Virtual method of TGcompositeFrame.
405/// Map all sub windows that are part of the composite frame.
406
408{
409 if (!fMapSubwindows) {
410 return;
411 }
412
413 if (!fList) return;
414
415 TGFrameElement *el;
416 TIter next(fList);
417
418 while ((el = (TGFrameElement *) next())) {
419 if (el->fFrame && el->fState) {
420 el->fFrame->MapWindow();
421 el->fFrame->MapSubwindows();
423 if (fe) fe->fState |= kIsVisible;
424 }
425 }
426}
427
428////////////////////////////////////////////////////////////////////////////////
429/// Resize the pack.
430/// Contents is resized proportionally.
431
433{
434 if (w == fWidth && h == fHeight) return;
435
436 fWidth = w;
437 fHeight = h;
439
441
442 Layout();
443}
444
445////////////////////////////////////////////////////////////////////////////////
446/// Move and resize the pack.
447
449{
451 Resize(w, h);
452}
453
454////////////////////////////////////////////////////////////////////////////////
455/// Reposition the frames so that they fit correctly.
456/// LayoutHints are ignored.
457
459{
460 Int_t pos = 0;
461
462 TGFrameElement *el;
463 TIter next(fList);
464
465 while ((el = (TGFrameElement *) next())) {
466 if (el->fState) {
467 SetFramePosition(el->fFrame, pos);
468 pos += GetFrameLength(el->fFrame);
469 el->fFrame->Layout();
470 }
471 }
472}
473
474////////////////////////////////////////////////////////////////////////////////
475/// Refit existing frames so that their lengths are equal.
476
478{
479 if (fList->IsEmpty())
480 return;
481
482 fWeightSum = 0;
484 TIter next(fList);
485 while ((el = (TGFrameElementPack *) next())) {
486 el->fWeight = 1;
487 if (el->fState)
488 fWeightSum ++;
489 }
490
492 Layout();
493}
494
495////////////////////////////////////////////////////////////////////////////////
496/// Called when splitter drag starts.
497
499{
500 fDragOverflow = 0;
501}
502
503////////////////////////////////////////////////////////////////////////////////
504/// Handle resize events from splitters.
505
507{
508 Int_t available = GetAvailableLength();
509 Int_t min_dec = - (available + fNVisible*2 -1);
510 if (delta < min_dec)
511 delta = min_dec;
512
513 TGSplitter *s = dynamic_cast<TGSplitter*>((TGFrame*) gTQSender);
514
515 TGFrameElementPack *f0 = nullptr, *f1 = nullptr;
516 FindFrames(s, f0, f1);
517 if (!f0 || !f1)
518 return;
519
520 if (fDragOverflow < 0) {
521 fDragOverflow += delta;
522 if (fDragOverflow > 0) {
523 delta = fDragOverflow;
524 fDragOverflow = 0;
525 } else {
526 return;
527 }
528 } else if (fDragOverflow > 0) {
529 fDragOverflow += delta;
530 if (fDragOverflow < 0) {
531 delta = fDragOverflow;
532 fDragOverflow = 0;
533 } else {
534 return;
535 }
536 }
537
538 Int_t l0 = GetFrameLength(f0->fFrame);
539 Int_t l1 = GetFrameLength(f1->fFrame);
540 if (delta < 0) {
541 if (l0 - 1 < -delta) {
542 fDragOverflow += delta + l0 - 1;
543 delta = -l0 + 1;
544 }
545 } else {
546 if (l1 - 1 < delta) {
547 fDragOverflow += delta - l1 + 1;
548 delta = l1 - 1;
549 }
550 }
551 l0 += delta;
552 l1 -= delta;
553 SetFrameLength(f0->fFrame, l0);
554 SetFrameLength(f1->fFrame, l1);
555 Float_t weightDelta = Float_t(delta)/available;
556 weightDelta *= fWeightSum;
557 f0->fWeight += weightDelta;
558 f1->fWeight -= weightDelta;
559
561 Layout();
562}
563
564
565////////////////////////////////////////////////////////////////////////////////
566/// Sets the vertical flag and reformats the back to new stacking
567/// direction.
568
570{
571 if (x == fVertical)
572 return;
573
574 TList list;
575 while ( ! fList->IsEmpty()) {
577 TGFrame *f = el->fFrame;
578 if ( ! (el->fState & kIsVisible) )
581 list.Add(f);
582 }
583 fVertical = x;
584 while ( ! list.IsEmpty()) {
585 TGFrame* f = (TGFrame*) list.First();
587 if (f->TestBit(kTempFrame)) {
588 f->ResetBit(kTempFrame);
589 HideFrame(f);
590 }
591 list.RemoveFirst();
592 }
593 Layout();
594}
@ kTempFrame
Definition GuiTypes.h:393
ULong_t Pixel_t
Pixel value.
Definition GuiTypes.h:40
Handle_t Window_t
Window handle.
Definition GuiTypes.h:29
#define f(i)
Definition RSha256.hxx:104
#define c(i)
Definition RSha256.hxx:101
#define h(i)
Definition RSha256.hxx:106
float Float_t
Definition RtypesCore.h:57
const Bool_t kTRUE
Definition RtypesCore.h:100
#define ClassImp(name)
Definition Rtypes.h:364
@ kLocalCleanup
Definition TGFrame.h:41
@ kDeepCleanup
Definition TGFrame.h:42
@ kIsVisible
Definition TGFrame.h:33
XFontStruct * id
Definition TGX11.cxx:109
R__EXTERN void * gTQSender
Definition TQObject.h:46
virtual Bool_t IsEmpty() const
Window client.
Definition TGClient.h:37
const TGWindow * GetDefaultRoot() const
Returns the root (i.e.
Definition TGClient.cxx:234
The base class for composite widgets (menu bars, list boxes, etc.).
Definition TGFrame.h:287
virtual TGFrameElement * FindFrameElement(TGFrame *f) const
Find frame-element holding frame f.
Definition TGFrame.cxx:1094
Int_t fMustCleanup
cleanup mode (see EFrameCleanup)
Definition TGFrame.h:294
virtual void SetCleanup(Int_t mode=kLocalCleanup)
Turn on automatic cleanup of child frames in dtor.
Definition TGFrame.cxx:1072
Bool_t fMapSubwindows
kTRUE - map subwindows
Definition TGFrame.h:295
TList * fList
container of frame elements
Definition TGFrame.h:292
virtual void RemoveFrame(TGFrame *f)
Remove frame from composite frame.
Definition TGFrame.cxx:1149
static TGLayoutHints * fgDefaultHints
Definition TGFrame.h:297
Float_t fWeight
relative weight
Definition TGPack.h:28
TGFrameElementPack * fSplitFE
! cached variable for optimisation
Definition TGPack.h:29
TGFrame * fFrame
Definition TGLayout.h:112
A subclasses of TGWindow, and is used as base class for some simple widgets (buttons,...
Definition TGFrame.h:80
UInt_t fHeight
frame height
Definition TGFrame.h:88
TGFrameElement * GetFrameElement() const
Definition TGFrame.h:235
virtual void Move(Int_t x, Int_t y)
Move frame.
Definition TGFrame.cxx:593
virtual void Resize(UInt_t w=0, UInt_t h=0)
Resize the frame.
Definition TGFrame.cxx:605
UInt_t fWidth
frame width
Definition TGFrame.h:87
UInt_t GetHeight() const
Definition TGFrame.h:225
virtual void SetCleanup(Int_t=kLocalCleanup)
Definition TGFrame.h:217
virtual void Layout()
Definition TGFrame.h:199
virtual void MapWindow()
map window
Definition TGFrame.h:204
UInt_t GetWidth() const
Definition TGFrame.h:224
virtual void MapSubwindows()
map sub windows
Definition TGFrame.h:200
virtual void UnmapWindow()
unmap window
Definition TGFrame.h:206
This class describes layout hints used by the layout classes.
Definition TGLayout.h:50
TGClient * fClient
Connection to display server.
Definition TGObject.h:27
Stack of frames in horizontal (default) or vertical stack.
Definition TGPack.h:40
Bool_t fVertical
Definition TGPack.h:46
virtual void RemoveFrame(TGFrame *f)
Remove frame f and refit existing frames to pack size.
Definition TGPack.cxx:324
void RemoveFrameInternal(TGFrame *f)
Remove frame f.
Definition TGPack.cxx:284
virtual ~TGPack()
Destructor.
Definition TGPack.cxx:67
void ResizeExistingFrames()
Resize (shrink or expand) existing frames by amount in total.
Definition TGPack.cxx:138
virtual void Resize(UInt_t w=0, UInt_t h=0)
Resize the pack.
Definition TGPack.cxx:432
Int_t GetAvailableLength() const
Return length of entire frame without splitters.
Definition TGPack.cxx:76
Int_t fSplitterLen
Definition TGPack.h:48
virtual void DeleteFrame(TGFrame *f)
Remove frame f and refit existing frames to pack size.
Definition TGPack.cxx:313
Int_t GetFrameLength(const TGFrame *f) const
Definition TGPack.h:55
virtual void AddFrameWithWeight(TGFrame *f, TGLayoutHints *l, Float_t w)
Add frame f at the end with given weight.
Definition TGPack.cxx:265
virtual void ShowFrame(TGFrame *f)
Show sub frame.
Definition TGPack.cxx:350
virtual void MoveResize(Int_t x, Int_t y, UInt_t w=0, UInt_t h=0)
Move and resize the pack.
Definition TGPack.cxx:448
void RefitFramesToPack()
Refit existing frames to pack size.
Definition TGPack.cxx:185
virtual void HideFrame(TGFrame *f)
Hide sub frame.
Definition TGPack.cxx:378
virtual void Layout()
Reposition the frames so that they fit correctly.
Definition TGPack.cxx:458
virtual void AddFrame(TGFrame *f, TGLayoutHints *l=0)
Add frame f at the end with default weight.
Definition TGPack.cxx:275
void EqualizeFrames()
Refit existing frames so that their lengths are equal.
Definition TGPack.cxx:477
void HandleSplitterStart()
Called when splitter drag starts.
Definition TGPack.cxx:498
Float_t fWeightSum
total sum of sub frame weights
Definition TGPack.h:52
TGPack(const TGPack &)=delete
void AddFrameInternal(TGFrame *f, TGLayoutHints *l=nullptr, Float_t weight=1)
Add frame f at the end.
Definition TGPack.cxx:221
virtual void MapSubwindows()
Virtual method of TGcompositeFrame.
Definition TGPack.cxx:407
Bool_t fUseSplitters
Definition TGPack.h:47
void SetVertical(Bool_t x)
Sets the vertical flag and reformats the back to new stacking direction.
Definition TGPack.cxx:569
void HandleSplitterResize(Int_t delta)
Handle resize events from splitters.
Definition TGPack.cxx:506
void SetFrameLength(TGFrame *f, Int_t len)
Set pack-wise length of frame f.
Definition TGPack.cxx:87
void SetFramePosition(TGFrame *f, Int_t pos)
Set pack-wise position of frame f.
Definition TGPack.cxx:98
void CheckSplitterVisibility()
Check if splitter of first visible frame is hidden.
Definition TGPack.cxx:110
Int_t fNVisible
number of visible frames
Definition TGPack.h:53
Int_t fDragOverflow
!
Definition TGPack.h:50
virtual void Dump() const
Print sub frame info.
Definition TGPack.cxx:333
void FindFrames(TGFrame *splitter, TGFrameElementPack *&f0, TGFrameElementPack *&f1) const
Find frames around splitter and return them f0 (previous) and f1 (next).
Definition TGPack.cxx:201
A splitter allows the frames left and right or above and below of it to be resized.
Definition TGSplitter.h:19
ROOT GUI Window base class.
Definition TGWindow.h:23
virtual const char * GetName() const
Return unique name, used in SavePrimitive methods.
Definition TGWindow.cxx:336
virtual void Resize(UInt_t w, UInt_t h)
Resize the window.
Definition TGWindow.cxx:279
A doubly linked list.
Definition TList.h:38
virtual void Add(TObject *obj)
Definition TList.h:81
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
Definition TList.cxx:357
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition TList.cxx:659
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:766
Bool_t Connect(const char *signal, const char *receiver_class, void *receiver, const char *slot)
Non-static method is used to connect from the signal of this object to the receiver slot.
Definition TQObject.cxx:869
virtual void RemoveFirst()
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
TF1 * f1
Definition legend1.C:11
Int_t Nint(T x)
Round to nearest integer. Rounds half integers to the nearest even integer.
Definition TMath.h:663
T1 Sign(T1 a, T2 b)
Definition TMathBase.h:161
auto * l
Definition textangle.C:4
REAL splitter
Definition triangle.c:617