OSDN Git Service

fix cmake/Macros.cmake
[moflib/moflib.git] / moflib-1.0 / moflib / moflib / mof / widget / GridLayout.cpp
1 #include <mof/widget/GridLayout.hpp>
2 #include <mof/widget/WidgetView.hpp>
3 #include <mof/widget/VerticalClipping.hpp>
4 #include <mof/widget/HorizontalClipping.hpp>
5 #include <mof/streams.hpp>
6 #include <mof/utilities.hpp>
7 #include "mof/ConsoleIO.hpp"
8 #include <algorithm>
9 #include <vector>
10 #include <memory>
11
12 using std::shared_ptr;
13  
14
15 //{{{ Impl
16 struct mof::widget::GridLayout::Impl
17 {
18         
19         mof::widget::GridLayout::Direction direction;
20         int span , margin;
21     int width , height;// preferredSize
22     std::vector< shared_ptr<WidgetView> > views;
23     std::vector<Vector2D> positions;
24
25         Impl(Direction _direction , int span_ , int margin_ )
26         : 
27         direction(_direction) , span(span_) , margin(margin_) ,
28                 width(0) , height(0)
29         {}
30         
31
32         ~Impl()
33     {
34         }
35 };
36 //}}}
37 //{{{ GridLayout
38 mof::widget::GridLayout::GridLayout
39 (
40         Direction direction , int span , int margin
41 )
42 : m_pImpl( new Impl( direction , span , margin ) )
43 {
44 }
45 //}}}
46 //{{{ ~GridLayout
47 mof::widget::GridLayout::~GridLayout( )
48 {
49 }
50 //}}}
51 //{{{ add
52 void mof::widget::GridLayout::add(shared_ptr<WidgetView> pView)
53 {
54     mof::Vector2D size = pView->getPreferredSize();
55     m_pImpl->views.push_back(pView);
56     
57     if(m_pImpl->direction == VERTICAL)
58     {
59         m_pImpl->positions.push_back( mof::Vector2D(0 , m_pImpl->height));
60         if( !m_pImpl->views.empty( ) )m_pImpl->height += m_pImpl->margin;
61         m_pImpl->width = m_pImpl->width < size.x 
62             ? mof::real2int(size.x) 
63             : m_pImpl->width;
64             m_pImpl->height += mof::real2int(size.y);
65     }
66     else if(m_pImpl->direction == HORIZONTAL)
67     {
68         m_pImpl->positions.push_back( mof::Vector2D(m_pImpl->width , 0));
69         if( !m_pImpl->views.empty( ) )m_pImpl->width += m_pImpl->margin;
70             m_pImpl->width += mof::real2int(size.x);
71         m_pImpl->height = m_pImpl->height < size.y 
72             ? mof::real2int(size.y) 
73             : m_pImpl->height;
74     }
75 }
76 //}}}
77 //{{{ getLength
78 size_t mof::widget::GridLayout::getLength() const
79 {
80     return m_pImpl->positions.size();
81 }
82 //}}}
83 //{{{ getPreferredSize
84 mof::Vector2D mof::widget::GridLayout::getPreferredSize() const
85 {
86     return mof::Vector2D(m_pImpl->width , m_pImpl->height);
87 }
88 //}}}
89 //{{{ connect
90 void mof::widget::GridLayout::connect(WidgetView* pParentView) 
91 {
92     size_t i = 0;
93     if(m_pImpl->direction == VERTICAL)
94     {
95                 float py = pParentView->getPositionStream().value().y + pParentView->getPreferredSize().y;
96         foreach(WidgetView::ptr pView, m_pImpl->views) 
97         {
98             pView->getPositionStream() << m_pImpl->positions[i++] << pParentView->getPositionStream();
99                         {
100                                 // 幅は親のサイズに合わせる
101                 mof::Vector2D filter(1, 0);
102                                 float cy = pView->getPositionStream().value().y + pView->getPreferredSize().y;
103                                 float d = py - cy;// 親と子の終点の差
104                 pView->getSizeStream() 
105                         << -pView->getPreferredSize()
106                         << mof::makeFilterHandler(pParentView->getSizeStream().toManipulator(), filter)//TODO この時点のフレームが非ゼロだと問題が起こるかも?
107                                         << std::make_shared<VerticalClipping>(pParentView->getSizeStream().toManipulator(), pView->getPreferredSize().y, d);
108                         }
109         }
110     }
111     else
112     {
113                 float px = pParentView->getPositionStream().value().x + pParentView->getPreferredSize().x;
114         foreach(WidgetView::ptr pView, m_pImpl->views) 
115         {
116             pView->getPositionStream() << m_pImpl->positions[i++] << pParentView->getPositionStream();
117                         {
118                                 // 高さは親のサイズに合わせる
119                 mof::Vector2D filter(0, 1);
120                                 float cx = pView->getPositionStream().value().x + pView->getPreferredSize().x;
121                                 float d = px - cx;// 親と子の終点の差
122                 pView->getSizeStream() 
123                         << -pView->getPreferredSize()
124                         << mof::makeFilterHandler(pParentView->getSizeStream().toManipulator(), filter)//TODO この時点のフレームが非ゼロだと問題が起こるかも?
125                                         << std::make_shared<HorizontalClipping>(pParentView->getSizeStream().toManipulator(), pView->getPreferredSize().x, d);
126                         }
127
128         }
129     }
130 }
131 //}}}
132 //{{{ getAdjacencyAsUp
133 int mof::widget::GridLayout::getAdjacencyAsUp(int index) const
134 {
135     if(m_pImpl->direction == VERTICAL)return mof::rotation_mod(index-1 , m_pImpl->positions.size());
136     else return index;
137 }
138 //}}}
139 //{{{ getAdjacencyAsDown
140 int mof::widget::GridLayout::getAdjacencyAsDown(int index) const
141 {
142     if(m_pImpl->direction == VERTICAL)return mof::rotation_mod(index+1 , m_pImpl->positions.size());
143     else return index;
144 }
145 //}}}
146 //{{{ getAdjacencyAsLeft
147 int mof::widget::GridLayout::getAdjacencyAsLeft(int index) const
148 {
149     if(m_pImpl->direction == HORIZONTAL)return mof::rotation_mod(index-1 , m_pImpl->positions.size());
150     else return index;
151 }
152 //}}}
153 //{{{ getAdjacencyAsRight
154 int mof::widget::GridLayout::getAdjacencyAsRight(int index) const
155 {
156     if(m_pImpl->direction == HORIZONTAL)return mof::rotation_mod(index+1 , m_pImpl->positions.size());
157     else return index;
158 }
159 //}}}