OSDN Git Service

fix build system ofmoflib1 and saisei1
[moflib/moflib.git] / moflib-1.0 / src / mof / widget / TextCompiler.cpp
1 #include "mof/widget/TextCompiler.hpp"
2 #include "mof/widget/WidgetView.hpp"
3 #include <algorithm>
4 #include <boost/regex.hpp>
5 #include <memory>
6 #include "mof/ConsoleIO.hpp"
7 #include "mof/Sprite.hpp"
8 #include "mof/Font.hpp"
9 #include "mof/widget/Page.hpp"
10 #include "mof/widget/GridLayout.hpp"
11 #include "mof/widget/flow_layout.hpp"
12 #include "mof/widget/Container.hpp"
13 #include "mof/streams.hpp"
14 #include "mof/widget/mofml_parser.hpp"
15
16 namespace {
17 //{{{ PageBehaviorSettings
18         struct PageBehaviorSettings
19         {
20                 mof::Manipulator<mof::Vector2D>::Handler position;
21                 mof::Manipulator<mof::Color4f>::Handler color;
22                 mof::FrameNumber periodOfPosition;
23                 mof::FrameNumber periodOfColor;
24
25                 std::shared_ptr<PageBehaviorSettings> clone()
26                 {
27                         std::shared_ptr<PageBehaviorSettings> p = std::make_shared<PageBehaviorSettings>();
28                         p->periodOfPosition = periodOfPosition;
29                         p->periodOfColor = periodOfColor;
30                         p->position = position;
31                         p->color = color;
32                         return p;
33                 }
34         };
35 //}}}
36     class SpriteWidgetViewAdapter : public mof::widget::WidgetView
37     {
38         std::unique_ptr<mof::Sprite> pSprite_;
39                 mof::Vector2D preferredSize_;
40                 std::shared_ptr<const PageBehaviorSettings> openSettings_;
41                 std::shared_ptr<const PageBehaviorSettings> closeSettings_;
42                 mof::ReferenceWrapper<mof::Vector2D> positionWrapper_;
43                 mof::ReferenceWrapper<mof::Color4f> colorWrapper_;
44     public:
45 //{{{ constructor
46         SpriteWidgetViewAdapter
47                 (
48                         std::unique_ptr<mof::Sprite>&& pSprite,
49                         std::shared_ptr<const PageBehaviorSettings> openSettings,
50                         std::shared_ptr<const PageBehaviorSettings> closeSettings
51                 )
52         : pSprite_(std::move(pSprite)), openSettings_(openSettings), closeSettings_(closeSettings)
53         {
54                         pSprite_->setVisible(true);
55             pSprite_->getPositionStream() << m_positionStream << positionWrapper_.makeRef(mof::Vector2D(0, 0));
56             pSprite_->getColorStream() << m_colorStream << colorWrapper_.makeRef(mof::Color4f(0, 1, 1, 1));
57                         preferredSize_ = pSprite_->getSizeStream().value();
58                         m_sizeStream << preferredSize_;
59         }
60 //}}}
61 //{{{ destructor
62         virtual ~SpriteWidgetViewAdapter(){}
63 //}}}
64 //{{{ show
65         virtual mof::FrameNumber show(bool immidiately)
66                 {
67                         /*if (immidiately) {
68                                 positionWrapper_.replace(openSettings_->periodOfPosition, openSettings_->position);
69                                 colorWrapper_.replace(openSettings_->periodOfColor, openSettings_->color);
70                                 return 0;
71                         }*/
72                         positionWrapper_.replace(0, getPositionStream(), openSettings_->position);
73                         colorWrapper_.replace(0, getColorStream(), openSettings_->color);
74                         return max(openSettings_->periodOfPosition, openSettings_->periodOfColor);
75                 }
76 //}}}
77 //{{{ hide
78         virtual mof::FrameNumber hide(bool immidiately)
79                 {
80                         /*if (immidiately) {
81                                 positionWrapper_.replace(closeSettings_->periodOfPosition, closeSettings_->position);
82                                 colorWrapper_.replace(closeSettings_->periodOfColor, closeSettings_->color);
83                                 return 0;
84                         }*/
85                         positionWrapper_.replace(0, getPositionStream(), closeSettings_->position);
86                         colorWrapper_.replace(0, getColorStream(), closeSettings_->color);
87                         return max(closeSettings_->periodOfPosition, closeSettings_->periodOfColor);
88                 }
89 //}}}
90 //{{{ focus
91         virtual mof::FrameNumber focus(bool immidiately){ return show(immidiately); }
92 //}}}
93 //{{{ blur
94         virtual mof::FrameNumber blur(bool immidiately){ return hide(immidiately); }
95 //}}}
96 //{{{ click
97         virtual mof::FrameNumber click(bool){return 0;}
98 //}}}
99 //{{{ getPreferredSize
100                 virtual mof::Vector2D getPreferredSize() const { return preferredSize_; }
101 //}}} 
102 //{{{ update
103         void update()
104         {
105             m_positionStream.update();
106             m_sizeStream.update();
107             m_colorStream.update();
108             pSprite_->getPositionStream().update();
109             pSprite_->getSizeStream().update();
110             pSprite_->getColorStream().update();
111             pSprite_->getRectangleCoordinatesStream().update();
112         }
113 //}}}
114 //{{{ draw
115         void draw() const { pSprite_->draw(); }
116 //}}} 
117 //{{{ setVisible
118         void setVisible(bool visible) { pSprite_->setVisible(visible); }
119 //}}} 
120     };
121
122
123 }
124
125 namespace mof
126 {
127 namespace widget
128 {
129 //{{{ Impl
130     struct TextCompiler::Impl
131     {
132         mof::Font font_;
133                 std::shared_ptr<PageBehaviorSettings> openSettings_;
134                 std::shared_ptr<PageBehaviorSettings> closeSettings_;
135                 boost::function<mof::Texture::ptr (const mof::tstring&)> texture_factory_;
136                 mof::widget::mofml_parser parser;
137 //{{{ constructor
138             Impl(const mof::Font& font)
139         : font_(font)
140         {
141                         openSettings_ = std::make_shared<PageBehaviorSettings>();
142                         closeSettings_ = std::make_shared<PageBehaviorSettings>();
143
144                         openSettings_->position = closeSettings_->position = mof::makeConstantHandler(mof::Vector2D(0, 0));
145                         openSettings_->color = mof::makeConstantHandler(mof::Color4f(1, 1, 1, 1));
146                         closeSettings_->color = mof::makeConstantHandler(mof::Color4f(0, 1, 1, 1));
147                         openSettings_->periodOfPosition = openSettings_->periodOfColor = 0;
148                         closeSettings_->periodOfPosition = closeSettings_->periodOfColor = 0;
149         }
150 //}}}
151 //{{{ make_line_widget_
152                 mof::widget::WidgetView::ptr make_line_widget_(const std::vector<mof::widget::WidgetView::ptr>& widgets_on_a_line) 
153                 {
154                         if (widgets_on_a_line.size() == 1) {
155                                 return widgets_on_a_line.front();
156                         }
157                         else  {
158                                 WidgetView::ptr p = std::make_shared<Container>
159                         (
160                                 widgets_on_a_line.front(), widgets_on_a_line.back() ,
161                                 mof::makeFactoryMethod<GridLayout>(GridLayout::HORIZONTAL , 0 )
162                         );
163                                 return p;
164                         }
165                 }
166 //}}}
167 //{{{ make_layout_widget_
168                 mof::widget::WidgetView::ptr make_layout_widget_
169                 (
170                         const std::vector<mof::widget::WidgetView::ptr>& widgets_in_layout, 
171                         const mof::widget::mofml_parser::layout_end_node& layout_node
172                 ) 
173                 {       
174                         using namespace mof::widget;
175
176                         flow_layout::xalign xa = layout_node.xalign;
177                         flow_layout::yalign ya = layout_node.yalign;
178                         size_t width = layout_node.width;
179                         size_t height = layout_node.height;
180                         WidgetView::ptr p = std::make_shared<Container>
181                         (
182                         widgets_in_layout.front(), widgets_in_layout.back() ,
183                         mof::makeFactoryMethod<flow_layout>(xa, ya, width, height)
184                         );
185                         return p;
186                 }
187 //}}}
188 //{{{ recursive
189                 void recursive // TODO 改名
190                 (
191                 const mof::tstring& text,
192                 std::vector<mof::widget::WidgetView::ptr>& result,
193                         const mof::Font& font
194                 )
195                 {
196                         using namespace std;
197                         using namespace mof::widget;
198
199                         parser.set_text(text);
200                         mof::font_context context;
201                         std::vector<std::vector<mof::widget::WidgetView::ptr>> layout_widgets(1);
202
203                         while (parser.has_next_node()) {
204                                 mofml_parser::node node = parser.next_node();
205                                 // ノードの内容を解釈してコンテキストに変換
206                                 if (node.which() == mofml_parser::TEXT) {
207                                         auto& text_node = boost::get<mofml_parser::text_node>(node);
208                                         context.font_color = text_node.font_color;
209                                         std::unique_ptr<mof::Sprite> pSprite
210                                                 (
211                                                         mof::Sprite::createTextSprite(mof::Font(font.name().c_str(), font.size(), context), text_node.text)
212                                                 );
213                                         auto p = std::make_shared<SpriteWidgetViewAdapter>(std::move(pSprite), openSettings_, closeSettings_);
214                                         layout_widgets.back().push_back(p);// 新しいノードを積む
215                                 }
216                                 else if (node.which() == mofml_parser::IMAGE) {
217                                         auto& image_node = boost::get<mofml_parser::image_node>(node);
218                                         std::unique_ptr<mof::Sprite> pSprite
219                                                 (
220                                                         new Sprite
221                                                         (
222                                                                 Rectangle<int>(0, 0, image_node.width, image_node.height),              
223                                                                 texture_factory_(image_node.src),
224                                                                 image_node.t_rect
225                                                         )
226                                                 );
227                                         auto p = std::make_shared<SpriteWidgetViewAdapter>(std::move(pSprite), openSettings_, closeSettings_);
228                                         layout_widgets.back().push_back(p);// 新しいノードを積む
229                                 }
230                                 else if (node.which() == mofml_parser::NEW_LINE || node.which() == mofml_parser::END) {
231                                         if (!layout_widgets[0].empty()) {
232                                                 // 1行分のウィジェットをまとめて、横方向に配置
233                                                 result.push_back(make_line_widget_(layout_widgets[0]));
234                                                 layout_widgets[0].clear();
235                                         }
236                                 }
237                                 else if (node.which() == mofml_parser::LAYOUT_START) {
238                                         layout_widgets.push_back(std::vector<mof::widget::WidgetView::ptr>());
239                                 }
240                                 else if (node.which() == mofml_parser::LAYOUT_END) {
241                                         auto& layout_node = boost::get<mofml_parser::layout_end_node>(node);
242                                         auto& widgets = layout_widgets.back();
243                                         if (!widgets.empty()) (++layout_widgets.rbegin())->push_back(make_layout_widget_(widgets, layout_node));
244                                         layout_widgets.pop_back();
245                                 }
246
247                         }
248
249                 }
250 //}}}   
251     };
252 //}}}
253 //{{{ constructor
254     TextCompiler::TextCompiler(const mof::Font& font)
255     : pImpl_(new Impl(font))
256     { 
257                 pImpl_->texture_factory_ = [](const mof::tstring& path){ return std::make_shared<mof::Texture>(path); };
258     }
259 //}}}
260 //{{{ constructor
261     TextCompiler::TextCompiler(const mof::Font& font, const boost::function<mof::Texture::ptr (const mof::tstring&)>& factory)
262     : pImpl_(new Impl(font))
263     { 
264                 pImpl_->texture_factory_ = factory;
265     }
266 //}}}
267 //{{{ destructor
268     TextCompiler::~TextCompiler()
269     { 
270     }
271 //}}}
272 //{{{ set_texture_factory
273         void TextCompiler::set_texture_factory
274         (
275                 const boost::function<mof::Texture::ptr (const mof::tstring&)>& factory
276         )
277         {
278                 pImpl_->texture_factory_ = factory;
279         }
280 //}}}
281 //{{{ compile
282     std::auto_ptr<mof::widget::Page> TextCompiler::compile(const mof::tstring& text)
283     {
284         using namespace mof::widget;
285         using namespace boost;
286         using mof::Sprite;
287         using mof::widget::GridLayout;
288         
289             std::vector< std::shared_ptr<WidgetView> > result;
290             pImpl_->recursive(text, result, pImpl_->font_);
291         
292          
293         return std::auto_ptr<Page>
294             (
295                 new Page
296                 (
297                     std::make_shared<Container>
298                     (
299                         result.front(), result.back() ,
300                         mof::makeFactoryMethod<GridLayout>(GridLayout::VERTICAL , 0 )
301                     ) ,
302                     _T("not implemented")
303                 )
304             );
305     }
306 //}}}
307 //{{{ compile_d
308     std::auto_ptr<mof::widget::WidgetView> TextCompiler::compile_d(const mof::tstring& text)
309     {
310         using namespace mof::widget;
311         using namespace boost;
312         using mof::Sprite;
313         using mof::widget::GridLayout;
314         
315             std::vector<WidgetView::ptr> result;
316             pImpl_->recursive(text, result, pImpl_->font_);
317         
318         return std::auto_ptr<WidgetView>
319             (
320                 new Container
321                 (
322                    result.front(), result.back() ,
323                    mof::makeFactoryMethod<GridLayout>(GridLayout::VERTICAL , 0 )
324                 ) 
325             );
326     }
327 //}}}
328 //{{{ setBehaviorOnPosition
329         void TextCompiler::setBehaviorOnPosition
330         (
331                 BehaviorTarget target,
332                 mof::Manipulator<mof::Vector2D>::Handler position,
333                 FrameNumber period
334         )
335         {
336                 switch (target) {
337                         case TextCompiler::PAGE_OPEN : 
338                         {
339                                 std::shared_ptr<PageBehaviorSettings> p = pImpl_->openSettings_;        
340                                 p->position = position;
341                                 p->periodOfPosition = period;
342                                 pImpl_->openSettings_ = p;
343                                 break;
344                         }
345                         case TextCompiler::PAGE_CLOSE : 
346                         {
347                                 std::shared_ptr<PageBehaviorSettings> p = pImpl_->closeSettings_;       
348                                 p->position = position;
349                                 p->periodOfPosition = period;
350                                 pImpl_->closeSettings_ = p;
351                                 break;
352                         }
353
354                 }
355         }
356 //}}}   
357 //{{{ setBehaviorOnColor
358         void TextCompiler::setBehaviorOnColor
359         (
360                 BehaviorTarget target,
361                 mof::Manipulator<mof::Color4f>::Handler color,
362                 FrameNumber period
363         )
364         {
365                 switch (target) {
366                         case TextCompiler::PAGE_OPEN : 
367                         {
368                                 std::shared_ptr<PageBehaviorSettings> p = pImpl_->openSettings_;        
369                                 p->color = color;
370                                 p->periodOfColor = period;
371                                 pImpl_->openSettings_ = p;
372                                 break;
373                         }
374                         case TextCompiler::PAGE_CLOSE : 
375                         {
376                                 std::shared_ptr<PageBehaviorSettings> p = pImpl_->closeSettings_;       
377                                 p->color = color;
378                                 p->periodOfColor = period;
379                                 pImpl_->closeSettings_ = p;
380                                 break;
381                         }
382
383                 }
384
385         }
386 ///}}}
387 }// namespace widget
388 }// namespace mof
389