TNB Library
TnbGroupLayout.h
[詳解]
1#pragma once
11#include "TnbSimpleVector.h"
12#include "TnbLayout.h"
13
14
15
16//TNB Library
17namespace TNB
18{
19
20
21
84{
85 DEFSUPER(CAbstractLayout);
86public:
87
101 {
102 public:
103
109 CParallelGroup(ELocation defloc = DEFAULT) : m_defaultLocation(defloc)
110 {
111 m_params = new CParamVector;
112 }
113
120 CParallelGroup& Add(const ILayout& layout, ELocation loc)
121 {
122 TParam p(loc, layout.Clone());
123 m_params->Add(p);
124 return *this;
125 }
126
133 CParallelGroup& Add(const ILayout& layout)
134 {
135 return Add(layout, m_defaultLocation);
136 }
137
142 size_t GetItemCount(void) const
143 {
144 return m_params->GetSize();
145 }
146
152 ILayout* GetItemLayout(INDEX index)
153 {
154 return m_params->At(index).pLayout;
155 }
156
162 const ILayout* GetItemLayout(INDEX index) const
163 {
164 return m_params->At(index).pLayout;
165 }
166
172 ELocation GetItemLocation(INDEX index) const
173 {
174 return m_params->At(index).locate;
175 }
176
182 SIZE GetMinimumSize(void) const
183 {
184 SIZE ret = { 0, 0 };
185 loop ( i, GetItemCount() )
186 {
187 SIZE sz;
189 ret.cx = max(ret.cx, sz.cx);
190 ret.cy = max(ret.cy, sz.cy);
191 }
192 return ret;
193 }
194
195 private:
197 struct TParam
198 {
199 ELocation locate;
200 ILayout::Ptr pLayout;
202 TParam(void) { }
204 TParam(ELocation loc, ILayout* p) : locate(loc), pLayout(p) { }
205 };
206 typedef CSimpleVectorT<TParam> CParamVector;
208 ELocation m_defaultLocation;
209 };
210
216 {
222 };
223
237 {
238 public:
239
241 CSequentialGroup(void) : m_params(new CParamVector)
242 {
243 }
244
254 {
255 TParam p(dis, val, g);
256 m_params->Add(p);
257 return *this;
258 }
259
267 {
268 size_t num = GetGroupCount();
269 size_t v = 0;
270 loop ( i, num )
271 {
272 TParam& par = m_params->At(i);
273 par.distance = Distance_Rate;
274 double a = p;
275 a /= num;
276 a *= (i + 1);
277 par.value = 1;
278 if ( a >= v )
279 {
280 par.value = static_cast<size_t>(a - v);
281 if ( par.value <= 0 )
282 {
283 par.value = 1;
284 }
285 }
286 v = static_cast<size_t>(a);
287 }
288 return *this;
289 }
290
295 size_t GetGroupCount(void) const
296 {
297 return m_params->GetSize();
298 }
299
306 {
307 return m_params->At(index).parallel;
308 }
309
315 const CParallelGroup& GetGroup(INDEX index) const
316 {
317 return m_params->At(index).parallel;
318 }
319
325 EDistance GetGroupDistance(INDEX index) const
326 {
327 return m_params->At(index).distance;
328 }
329
335 size_t GetGroupValue(INDEX index) const
336 {
337 return m_params->At(index).value;
338 }
339
345 SIZE GetMinimumSize(void) const
346 {
347 SIZE ret = { 0, 0 };
349 loop ( i, GetGroupCount() )
350 {
351 const CParallelGroup& pg = GetGroup(i);
352 SIZE sz;
353 switch ( GetGroupDistance(i) )
354 {
355 case Distance_Absolute:// 絶対値
356 {
357 size_t val = GetGroupValue(i);
358 sz.cx = LOWORD(val);
359 sz.cy = HIWORD(val);
360 }
361 break;
362 case Distance_Default:// デフォルト
363 case Distance_Rate:// 比率
364 case Distance_ItemMax:// アイテム最大
365 case Distance_Rast:// 余り
366 sz = pg.GetMinimumSize();
367 break;
368 default:
369 sz .cx = 0;
370 sz .cy = 0;
371 ASSERT( false );
372 break;
373 }
374 ret.cx += sz.cx;
375 ret.cy += sz.cy;
376 sizes[i] = sz;
377 }
378 // Rateチェック
379 SIZE adSize = { 0, 0 };
380 loop ( i, GetGroupCount() )
381 {
383 {
384 size_t val = GetGroupValue(i);
385 INT_PTR x = ret.cx * val / 100;
386 if ( sizes[i].cx > x )
387 {
388 adSize.cx = max(adSize.cx, down_cast<LONG>(sizes[i].cx * 100 / val));
389 }
390 INT_PTR y = ret.cy * val / 100;
391 if ( sizes[i].cy > y )
392 {
393 adSize.cy = max(adSize.cy, ToInt(sizes[i].cy * 100 / val));
394 }
395 }
396 }
397 if ( adSize.cx != 0 || adSize.cy != 0 )
398 {
399 ret.cx = max(ret.cx, adSize.cx);
400 ret.cy = max(ret.cy, adSize.cy);
401 }
402 return ret;
403 }
404
405 private:
407 struct TParam
408 {
409 EDistance distance;
410 size_t value;
411 CParallelGroup parallel;
413 TParam(void) { }
415 TParam(EDistance dis, int v, CParallelGroup& para) : distance(dis), value(v), parallel(para) { }
416 };
418 typedef CSimpleVectorT<TParam> CParamVector;
420 };
421
422
423 //-------------------------------------
424
425
428 {
429 }
430
436 {
437 m_hGroup = g;
438 }
439
445 {
446 m_vGroup = g;
447 }
448
454 virtual ILayout* Clone(void) const
455 {
456 CGroupLayout* P = new CGroupLayout();
457 *P = *this;
458 return P;
459 }
460
468 virtual bool GetMinimumSize(SIZE& _size) const
469 {
470 // Xを計算
471 size_t hcnt = m_hGroup.GetGroupCount();
472 _size.cx = (hcnt == 0) ? 0 :m_hGroup.GetMinimumSize().cx;
473 // Yを計算
474 size_t vcnt = m_vGroup.GetGroupCount();
475 _size.cy = (vcnt == 0) ? 0 : m_vGroup.GetMinimumSize().cy;
476 // 補正
477 AddChinkSize(_size, hcnt, vcnt);
478 return true;
479 }
480
489 virtual void Decide(int x, int y, WPARAM wParam, LPARAM lParam)
490 {
491 size_t hcnt = m_hGroup.GetGroupCount();
492 size_t vcnt = m_vGroup.GetGroupCount();
493 SIZE chinkSize = { 0, 0 };
494 AddChinkSize(chinkSize, hcnt, vcnt);
495 //======= X座標
496 if ( x >= 0 && hcnt > 0 )
497 {
498 //-- 有効幅
499 INT_PTR width = m_layoutSize.cx - chinkSize.cx;
500 INT_PTR widthOrg = width;
501 //
502 INT_PTR xx = m_margn.left;
503 CWorkMemT<INT_PTR> xpos(hcnt);
504 CWorkMemT<size_t> xlen(hcnt);
505 INDEX rastItem = INVALID_INDEX;
506 loop ( index, hcnt )
507 {
508 xpos[index] = xx;
509 const CParallelGroup& pg = m_hGroup.GetGroup(index);
510 size_t val = m_hGroup.GetGroupValue(index);
511 EDistance dis = m_hGroup.GetGroupDistance(index);
512 if ( dis == Distance_Default )
513 {
514 dis = Distance_ItemMax;
515 if ( index == hcnt - 1 && rastItem == INVALID_INDEX )
516 {
517 dis = Distance_Rast;
518 }
519 }
520 switch ( dis )
521 {
522 case Distance_Absolute:// 絶対値
523 val = LOWORD(val);
524 break;
525 case Distance_Rate:// 比率
526 val = widthOrg * val / 100;
527 break;
528 case Distance_ItemMax:// アイテム最大
529 val = pg.GetMinimumSize().cx;
530 break;
531 case Distance_Rast:// 余り(二つ指定禁止)
532 val = 0;
533 ASSERT( rastItem == INVALID_INDEX );
534 rastItem = index;
535 break;
536 default:
537 ASSERT( false );
538 break;
539 }
540 xlen[index] = val;
541 width -= val;
542 xx += val;
543 xx += m_gapSize.cx; //アイテム間のサイズ
544 }
545 if ( rastItem != INVALID_INDEX )
546 {
547 // rastアイテムあり。以降、ずらす
548 xlen[rastItem] = width;
549 for ( size_t i = rastItem + 1; i < hcnt; i++ )
550 {
551 xpos[i] += width;
552 }
553 }
554 loop ( index, hcnt )
555 {
556 CParallelGroup& pg = m_hGroup.GetGroup(index);
557 loop ( i, pg.GetItemCount() )
558 {
559 HorizontalItemDecide(pg.GetItemLayout(i), x, xpos[index], xlen[index], pg.GetItemLocation(i), wParam, lParam);
560 }
561 }
562 }
563 //======= Y座標
564 if ( y >= 0 && vcnt > 0 )
565 {
566 //-- 有効幅
567 INT_PTR height = m_layoutSize.cy - chinkSize.cy;
568 INT_PTR heightOrg = height;
569 //
570 INT_PTR yy = m_margn.top;
571 CWorkMemT<INT_PTR> ypos(vcnt);
572 CWorkMemT<size_t> ylen(vcnt);
573 INDEX rastItem = INVALID_INDEX;
574 loop ( index, vcnt )
575 {
576 ypos[index] = yy;
577 const CParallelGroup& pg = m_vGroup.GetGroup(index);
578 size_t val = m_vGroup.GetGroupValue(index);
579 EDistance dis = m_vGroup.GetGroupDistance(index);
580 if ( dis == Distance_Default )
581 {
582 dis = Distance_ItemMax;
583 if ( index == vcnt - 1 && rastItem == INVALID_INDEX )
584 {
585 dis = Distance_Rast;
586 }
587 }
588 switch ( dis )
589 {
590 case Distance_Absolute:// 絶対値
591 val = HIWORD(val);
592 break;
593 case Distance_Rate:// 比率
594 val = heightOrg * val / 100;
595 break;
596 case Distance_ItemMax:// アイテム最大
597 val = pg.GetMinimumSize().cy;
598 break;
599 case Distance_Rast:// 余り(二つ指定禁止)
600 val = 0;
601 ASSERT( rastItem == INVALID_INDEX );
602 rastItem = index;
603 break;
604 default:
605 ASSERT( false );
606 break;
607 }
608 ylen[index] = val;
609 height -= val;
610 yy += val;
611 yy += m_gapSize.cy; //アイテム間のサイズ
612 }
613 if ( rastItem != INVALID_INDEX )
614 {
615 // rastアイテムあり。以降、ずらす
616 ylen[rastItem] = height;
617 for ( size_t i = rastItem + 1; i < vcnt; i++ )
618 {
619 ypos[i] += height;
620 }
621 }
622 loop ( index, vcnt )
623 {
624 CParallelGroup& pg = m_vGroup.GetGroup(index);
625 loop ( i, pg.GetItemCount() )
626 {
627 VerticalItemDecide(pg.GetItemLayout(i), y, ypos[index], ylen[index], pg.GetItemLocation(i), wParam, lParam);
628 }
629 }
630 }
631 }
632
633
634 //------------------------
635
636
644 inline friend CParallelGroup Add(ELocation defloc)
645 {
646 return CParallelGroup(defloc);
647 }
648
655 inline friend CParallelGroup Add(const ILayout& layout)
656 {
657 return CParallelGroup().Add(layout);
658 }
659
667 inline friend CParallelGroup Add(const ILayout& layout, ELocation loc)
668 {
669 return CParallelGroup().Add(layout, loc);
670 }
671
682 {
683 return CSequentialGroup().AddGroup(g, dis, val);
684 }
685
686private:
687 CSequentialGroup m_hGroup;
688 CSequentialGroup m_vGroup;
689};
690
691
692
693}; // TNB
#define loop(VAR, CNT)
loop構文.
Definition: TnbDef.h:343
レイアウト関係のヘッダ
簡易配列型情報管理関係のヘッダ
レイアウトアイテム抽象クラス.
Definition: TnbLayout.h:194
ELocation
レイアウトアイテム配置方法.
Definition: TnbLayout.h:204
@ DEFAULT
横方向は左寄せ、縦方向は中央
Definition: TnbLayout.h:205
void HorizontalItemDecide(ILayout *pLayout, INT_PTR x, INT_PTR xx, INT_PTR width, ELocation loc, WPARAM wParam, LPARAM lParam)
[設定] 水平方向アイテム決定.
Definition: TnbLayout.h:338
SIZE m_gapSize
各アイテム間のギャップ(縦、横)
Definition: TnbLayout.h:326
SIZE m_layoutSize
レイアウト全体サイズ(縦、横)
Definition: TnbLayout.h:324
void VerticalItemDecide(ILayout *pLayout, INT_PTR y, INT_PTR yy, INT_PTR height, ELocation loc, WPARAM wParam, LPARAM lParam)
[設定] 垂直方向アイテム決定.
Definition: TnbLayout.h:379
void AddChinkSize(SIZE &_size, size_t cx, size_t cy) const
[加算] 隙間サイズ加算.
Definition: TnbLayout.h:438
RECT m_margn
外周のマージン
Definition: TnbLayout.h:325
パラレルグループ定義クラス.
CParallelGroup & Add(const ILayout &layout)
[設定] アイテム追加.
ELocation GetItemLocation(INDEX index) const
[取得] アイテムの配置種取得.
const ILayout * GetItemLayout(INDEX index) const
[取得] レイアウトアイテム取得.
ILayout * GetItemLayout(INDEX index)
[取得] レイアウトアイテム取得.
size_t GetItemCount(void) const
[取得] アイテム数取得.
CParallelGroup(ELocation defloc=DEFAULT)
コンストラクタ
SIZE GetMinimumSize(void) const
[取得] 最小サイズ取得.
CParallelGroup & Add(const ILayout &layout, ELocation loc)
[設定] アイテム追加.
シーケンシャルグループ定義クラス.
size_t GetGroupCount(void) const
[取得] グループ数取得.
CSequentialGroup & AddGroup(CParallelGroup &g, EDistance dis=Distance_Default, int val=0)
[追加] パラレルグループ追加.
CParallelGroup & GetGroup(INDEX index)
[取得] グループ取得.
EDistance GetGroupDistance(INDEX index) const
[取得] グループ長さ種取得.
CSequentialGroup(void)
コンストラクタ
SIZE GetMinimumSize(void) const
[取得] 最小サイズ取得.
CSequentialGroup & AutoEqualityDistance(int p=100)
[設定] 長さ平均化.
size_t GetGroupValue(INDEX index) const
[取得] グループ長さ値取得.
const CParallelGroup & GetGroup(INDEX index) const
[取得] グループ取得.
グループレイアウトアイテムクラス.
virtual bool GetMinimumSize(SIZE &_size) const
[取得] 最小サイズ取得.
void SetHorizontalGroup(CSequentialGroup &g)
[登録] 水平シーケンシャルグループ登録.
friend CParallelGroup Add(const ILayout &layout)
[作成] パラレルグループ作成&アイテム追加.
void SetVerticalGroup(CSequentialGroup &g)
[登録] 垂直シーケンシャルグループ登録.
friend CSequentialGroup AddGroup(CParallelGroup &g, EDistance dis=Distance_Default, int val=0)
[作成] シーケンシャルグループ作成&パラレルグループ追加.
CGroupLayout(void)
コンストラクタ
virtual ILayout * Clone(void) const
[作成] クローン作成.
virtual void Decide(int x, int y, WPARAM wParam, LPARAM lParam)
[処理] 決定.
friend CParallelGroup Add(ELocation defloc)
[作成] パラレルグループ作成.
EDistance
ParallelGroup の長さ種.
@ Distance_Absolute
絶対値(value は縦横の絶対値 MAKELONG(X, Y) で格納)
@ Distance_Rast
余り(一つのシーケンシャルグループに複数指定できません)
@ Distance_ItemMax
アイテム最大
@ Distance_Rate
比率(value は比率を格納)
@ Distance_Default
デフォルト( Distance_ItemMax 、最後のみ Distance_Rast になります)。
friend CParallelGroup Add(const ILayout &layout, ELocation loc)
[作成] パラレルグループ作成&アイテム追加.
ワークメモリテンプレート.
Definition: TnbDef.h:633
int ToInt(LPCSTR lpsz, int iBase=10)
[変換] INT変換(ASCII/SJIS用).
Definition: TnbStrLib.h:367
TNB Library
Definition: TnbDoxyTitle.txt:2
管理パラメータ型
Definition: TnbLayout.h:307
レイアウトインターフェース.
Definition: TnbLayout.h:34
virtual bool GetMinimumSize(SIZE &_size) const =0
[取得] 最小サイズ取得.
virtual ILayout * Clone(void) const =0
[作成] クローン作成.