1 /***************************************************************************
2 * Copyright (C) 2009 by Andrey Afletdinov <fheroes2@gmail.com> *
3 * *
4 * Part of the Free Heroes2 Engine: *
5 * http://sourceforge.net/projects/fheroes2 *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the *
19 * Free Software Foundation, Inc., *
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21 ***************************************************************************/
22
23 #include "agg_image.h"
24 #include "dialog.h"
25 #include "icn.h"
26 #include "screen.h"
27 #include "settings.h"
28
29 #include <algorithm>
30
31 namespace
32 {
33 const int32_t windowWidth = 288; // this is measured value
34 const int32_t buttonHeight = 40;
35 const int32_t activeAreaHeight = 35;
36
topHeight(const bool isEvilInterface)37 int32_t topHeight( const bool isEvilInterface )
38 {
39 const fheroes2::Sprite & image = fheroes2::AGG::GetICN( isEvilInterface ? ICN::BUYBUILE : ICN::BUYBUILD, 0 );
40 return image.height();
41 }
42
bottomHeight(const bool isEvilInterface)43 int32_t bottomHeight( const bool isEvilInterface )
44 {
45 const fheroes2::Sprite & image = fheroes2::AGG::GetICN( isEvilInterface ? ICN::BUYBUILE : ICN::BUYBUILD, 2 );
46 return image.height();
47 }
48
leftWidth(const bool isEvilInterface)49 int32_t leftWidth( const bool isEvilInterface )
50 {
51 const int icnId = isEvilInterface ? ICN::BUYBUILE : ICN::BUYBUILD;
52
53 const fheroes2::Sprite & image3 = fheroes2::AGG::GetICN( icnId, 3 );
54 const fheroes2::Sprite & image4 = fheroes2::AGG::GetICN( icnId, 4 );
55 const fheroes2::Sprite & image5 = fheroes2::AGG::GetICN( icnId, 5 );
56
57 int32_t widthLeft = image3.width();
58 widthLeft = std::max( widthLeft, image4.width() );
59 widthLeft = std::max( widthLeft, image5.width() );
60
61 return widthLeft;
62 }
63
rightWidth(const bool isEvilInterface)64 int32_t rightWidth( const bool isEvilInterface )
65 {
66 const int icnId = isEvilInterface ? ICN::BUYBUILE : ICN::BUYBUILD;
67
68 const fheroes2::Sprite & image0 = fheroes2::AGG::GetICN( icnId, 0 );
69 const fheroes2::Sprite & image1 = fheroes2::AGG::GetICN( icnId, 1 );
70 const fheroes2::Sprite & image2 = fheroes2::AGG::GetICN( icnId, 2 );
71
72 int32_t widthRight = image0.width();
73 widthRight = std::max( widthRight, image1.width() );
74 widthRight = std::max( widthRight, image2.width() );
75
76 return widthRight;
77 }
78
overallWidth(const bool isEvilInterface)79 int32_t overallWidth( const bool isEvilInterface )
80 {
81 return leftWidth( isEvilInterface ) + rightWidth( isEvilInterface );
82 }
83
leftOffset(const bool isEvilInterface)84 int32_t leftOffset( const bool isEvilInterface )
85 {
86 return leftWidth( isEvilInterface ) - windowWidth / 2;
87 }
88 }
89
NonFixedFrameBox(int height,int startYPos,bool showButtons)90 Dialog::NonFixedFrameBox::NonFixedFrameBox( int height, int startYPos, bool showButtons )
91 : _middleFragmentCount( 0 )
92 , _middleFragmentHeight( 0 )
93 {
94 if ( showButtons )
95 height += buttonHeight;
96
97 const bool evil = Settings::Get().ExtGameEvilInterface();
98 _middleFragmentCount = ( height <= 2 * activeAreaHeight ? 0 : 1 + ( height - 2 * activeAreaHeight ) / activeAreaHeight );
99 _middleFragmentHeight = height <= 2 * activeAreaHeight ? 0 : height - 2 * activeAreaHeight;
100 const int32_t height_top_bottom = topHeight( evil ) + bottomHeight( evil );
101
102 area.width = BOXAREA_WIDTH;
103 area.height = activeAreaHeight + activeAreaHeight + _middleFragmentHeight;
104
105 fheroes2::Display & display = fheroes2::Display::instance();
106 const int32_t leftSideOffset = leftOffset( evil );
107
108 _position.x = ( display.width() - windowWidth ) / 2 - leftSideOffset;
109 _position.y = startYPos;
110
111 if ( startYPos < 0 ) {
112 _position.y = ( ( display.height() - _middleFragmentHeight ) / 2 ) - topHeight( evil );
113 }
114
115 _restorer.reset( new fheroes2::ImageRestorer( display, _position.x, _position.y, overallWidth( evil ), height_top_bottom + _middleFragmentHeight ) );
116
117 area.x = _position.x + ( windowWidth - BOXAREA_WIDTH ) / 2 + leftSideOffset;
118 area.y = _position.y + ( topHeight( evil ) - activeAreaHeight );
119
120 redraw();
121 }
122
redraw()123 void Dialog::NonFixedFrameBox::redraw()
124 {
125 const bool isEvilInterface = Settings::Get().ExtGameEvilInterface();
126 const int buybuild = isEvilInterface ? ICN::BUYBUILE : ICN::BUYBUILD;
127
128 const int32_t overallLeftWidth = leftWidth( isEvilInterface );
129
130 // right-top
131 const fheroes2::Sprite & part0 = fheroes2::AGG::GetICN( buybuild, 0 );
132 // left-top
133 const fheroes2::Sprite & part4 = fheroes2::AGG::GetICN( buybuild, 4 );
134
135 fheroes2::Display & display = fheroes2::Display::instance();
136
137 fheroes2::Blit( part4, display, _position.x + overallLeftWidth - part4.width(), _position.y );
138 fheroes2::Blit( part0, display, _position.x + overallLeftWidth, _position.y );
139
140 _position.y += part4.height();
141
142 const int32_t posBeforeMiddle = _position.y;
143 int32_t middleLeftHeight = _middleFragmentHeight;
144 for ( uint32_t i = 0; i < _middleFragmentCount; ++i ) {
145 const int32_t chunkHeight = middleLeftHeight >= activeAreaHeight ? activeAreaHeight : middleLeftHeight;
146 // left-middle
147 const fheroes2::Sprite & sl = fheroes2::AGG::GetICN( buybuild, 5 );
148 fheroes2::Blit( sl, 0, 10, display, _position.x + overallLeftWidth - sl.width(), _position.y, sl.width(), chunkHeight );
149
150 // right-middle
151 const fheroes2::Sprite & sr = fheroes2::AGG::GetICN( buybuild, 1 );
152 fheroes2::Blit( sr, 0, 10, display, _position.x + overallLeftWidth, _position.y, sr.width(), chunkHeight );
153
154 middleLeftHeight -= chunkHeight;
155 _position.y += chunkHeight;
156 }
157
158 _position.y = posBeforeMiddle + _middleFragmentHeight;
159
160 // right-bottom
161 const fheroes2::Sprite & part2 = fheroes2::AGG::GetICN( buybuild, 2 );
162 // left-bottom
163 const fheroes2::Sprite & part6 = fheroes2::AGG::GetICN( buybuild, 6 );
164
165 fheroes2::Blit( part6, display, _position.x + overallLeftWidth - part6.width(), _position.y );
166 fheroes2::Blit( part2, display, _position.x + overallLeftWidth, _position.y );
167 }
168
~NonFixedFrameBox()169 Dialog::NonFixedFrameBox::~NonFixedFrameBox()
170 {
171 _restorer->restore();
172
173 fheroes2::Display::instance().render();
174 }
175
FrameBox(int height,bool buttons)176 Dialog::FrameBox::FrameBox( int height, bool buttons )
177 : Dialog::NonFixedFrameBox( height, -1, buttons )
178 {}
179