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 "interface_icons.h"
24 #include "agg_image.h"
25 #include "castle_ui.h"
26 #include "game.h"
27 #include "game_interface.h"
28 #include "heroes.h"
29 #include "icn.h"
30 #include "kingdom.h"
31 #include "settings.h"
32 #include "world.h"
33
34 namespace
35 {
36 enum
37 {
38 ICONS_WIDTH = 46,
39 ICONS_HEIGHT = 22,
40 ICONS_CURSOR_WIDTH = 56,
41 ICONS_CURSOR_HEIGHT = 32
42 };
43 }
44
IsVisible(void)45 bool Interface::IconsBar::IsVisible( void )
46 {
47 const Settings & conf = Settings::Get();
48 return !conf.ExtGameHideInterface() || conf.ShowIcons();
49 }
50
GetItemWidth(void)51 u32 Interface::IconsBar::GetItemWidth( void )
52 {
53 return ICONS_WIDTH;
54 }
55
GetItemHeight(void)56 u32 Interface::IconsBar::GetItemHeight( void )
57 {
58 return ICONS_HEIGHT;
59 }
60
RedrawCastleIcon(const Castle & castle,int32_t sx,int32_t sy)61 void Interface::RedrawCastleIcon( const Castle & castle, int32_t sx, int32_t sy )
62 {
63 fheroes2::drawCastleIcon( castle, fheroes2::Display::instance(), fheroes2::Point( sx, sy ) );
64 }
65
RedrawHeroesIcon(const Heroes & hero,s32 sx,s32 sy)66 void Interface::RedrawHeroesIcon( const Heroes & hero, s32 sx, s32 sy )
67 {
68 hero.PortraitRedraw( sx, sy, PORT_SMALL, fheroes2::Display::instance() );
69 }
70
RedrawBackground(const fheroes2::Point & pos) const71 void Interface::IconsBar::RedrawBackground( const fheroes2::Point & pos ) const
72 {
73 fheroes2::Display & display = fheroes2::Display::instance();
74 const bool isEvilInterface = Settings::Get().ExtGameEvilInterface();
75
76 const fheroes2::Sprite & icnadv = fheroes2::AGG::GetICN( isEvilInterface ? ICN::ADVBORDE : ICN::ADVBORD, 0 );
77 const fheroes2::Sprite & back = fheroes2::AGG::GetICN( isEvilInterface ? ICN::LOCATORE : ICN::LOCATORS, 1 );
78 fheroes2::Rect srcrt( icnadv.width() - RADARWIDTH - BORDERWIDTH, RADARWIDTH + 2 * BORDERWIDTH, RADARWIDTH / 2, 32 );
79
80 fheroes2::Point dstpt( pos.x, pos.y );
81 fheroes2::Blit( icnadv, srcrt.x, srcrt.y, display, dstpt.x, dstpt.y, srcrt.width, srcrt.height );
82
83 srcrt.y = srcrt.y + srcrt.height;
84 dstpt.y = dstpt.y + srcrt.height;
85 srcrt.height = 32;
86
87 if ( 2 < iconsCount ) {
88 for ( uint32_t i = 0; i < iconsCount - 2; ++i ) {
89 fheroes2::Blit( icnadv, srcrt.x, srcrt.y, display, dstpt.x, dstpt.y, srcrt.width, srcrt.height );
90 dstpt.y += srcrt.height;
91 }
92 }
93
94 srcrt.y = srcrt.y + 64;
95 srcrt.height = 32;
96 fheroes2::Blit( icnadv, srcrt.x, srcrt.y, display, dstpt.x, dstpt.y, srcrt.width, srcrt.height );
97
98 for ( u32 ii = 0; ii < iconsCount; ++ii )
99 fheroes2::Blit( back, display, pos.x + 5, pos.y + 5 + ii * ( IconsBar::GetItemHeight() + 10 ) );
100 }
101
102 /* Interface::CastleIcons */
RedrawItem(const CASTLE & item,s32 ox,s32 oy,bool current)103 void Interface::CastleIcons::RedrawItem( const CASTLE & item, s32 ox, s32 oy, bool current )
104 {
105 if ( item && show ) {
106 RedrawCastleIcon( *item, ox + 5, oy + 5 );
107
108 if ( current )
109 fheroes2::Blit( marker, fheroes2::Display::instance(), ox, oy );
110 }
111 }
112
RedrawBackground(const fheroes2::Point & pos)113 void Interface::CastleIcons::RedrawBackground( const fheroes2::Point & pos )
114 {
115 IconsBar::RedrawBackground( pos );
116 }
117
ActionCurrentUp(void)118 void Interface::CastleIcons::ActionCurrentUp( void )
119 {
120 Interface::Basic::Get().SetFocus( GetCurrent() );
121 }
122
ActionCurrentDn(void)123 void Interface::CastleIcons::ActionCurrentDn( void )
124 {
125 Interface::Basic::Get().SetFocus( GetCurrent() );
126 }
127
ActionListDoubleClick(CASTLE & item)128 void Interface::CastleIcons::ActionListDoubleClick( CASTLE & item )
129 {
130 if ( item ) {
131 Game::OpenCastleDialog( *item );
132 }
133 }
134
ActionListSingleClick(CASTLE & item)135 void Interface::CastleIcons::ActionListSingleClick( CASTLE & item )
136 {
137 if ( item ) {
138 Interface::Basic & I = Interface::Basic::Get();
139
140 I.SetFocus( item );
141 I.RedrawFocus();
142 }
143 }
144
ActionListPressRight(CASTLE & castle)145 void Interface::CastleIcons::ActionListPressRight( CASTLE & castle )
146 {
147 if ( castle ) {
148 const fheroes2::Point p( _topLeftCorner.x - 1, _topLeftCorner.y );
149 Dialog::QuickInfo( *castle, fheroes2::Rect(), p );
150 }
151 }
152
SetShow(bool f)153 void Interface::CastleIcons::SetShow( bool f )
154 {
155 IconsBar::SetShow( f );
156
157 if ( IconsBar::IsVisible() ) {
158 if ( f )
159 GetScrollbar().show();
160 else
161 GetScrollbar().hide();
162 }
163 }
164
SetPos(s32 px,s32 py)165 void Interface::CastleIcons::SetPos( s32 px, s32 py )
166 {
167 const int icnscroll = Settings::Get().ExtGameEvilInterface() ? ICN::SCROLLE : ICN::SCROLL;
168
169 _topLeftCorner = fheroes2::Point( px, py );
170 SetTopLeft( _topLeftCorner );
171 SetScrollBar( fheroes2::AGG::GetICN( icnscroll, 4 ), fheroes2::Rect( px + ICONS_CURSOR_WIDTH + 3, py + 19, 10, ICONS_CURSOR_HEIGHT * iconsCount - 38 ) );
172 SetScrollButtonUp( icnscroll, 0, 1, fheroes2::Point( px + ICONS_CURSOR_WIDTH + 1, py + 1 ) );
173 SetScrollButtonDn( icnscroll, 2, 3, fheroes2::Point( px + ICONS_CURSOR_WIDTH + 1, py + iconsCount * ICONS_CURSOR_HEIGHT - 15 ) );
174 SetAreaMaxItems( iconsCount );
175 SetAreaItems( fheroes2::Rect( px, py, ICONS_CURSOR_WIDTH, iconsCount * ICONS_CURSOR_HEIGHT ) );
176 DisableHotkeys( true );
177
178 SetListContent( world.GetKingdom( Settings::Get().CurrentColor() ).GetCastles() );
179 Reset();
180 }
181
182 /* Interface::HeroesIcons */
RedrawItem(const HEROES & item,s32 ox,s32 oy,bool current)183 void Interface::HeroesIcons::RedrawItem( const HEROES & item, s32 ox, s32 oy, bool current )
184 {
185 if ( item && show ) {
186 RedrawHeroesIcon( *item, ox + 5, oy + 5 );
187
188 if ( current )
189 fheroes2::Blit( marker, fheroes2::Display::instance(), ox, oy );
190 }
191 }
192
RedrawBackground(const fheroes2::Point & pos)193 void Interface::HeroesIcons::RedrawBackground( const fheroes2::Point & pos )
194 {
195 IconsBar::RedrawBackground( pos );
196 }
197
ActionCurrentUp(void)198 void Interface::HeroesIcons::ActionCurrentUp( void )
199 {
200 Interface::Basic::Get().SetFocus( GetCurrent() );
201 }
202
ActionCurrentDn(void)203 void Interface::HeroesIcons::ActionCurrentDn( void )
204 {
205 Interface::Basic::Get().SetFocus( GetCurrent() );
206 }
207
ActionListDoubleClick(HEROES & item)208 void Interface::HeroesIcons::ActionListDoubleClick( HEROES & item )
209 {
210 if ( item ) {
211 if ( item->Modes( Heroes::GUARDIAN ) ) {
212 Castle * castle = world.getCastle( item->GetCenter() );
213 if ( castle )
214 Game::OpenCastleDialog( *castle );
215 }
216 else
217 Game::OpenHeroesDialog( *item, false, true );
218 }
219 }
220
ActionListSingleClick(HEROES & item)221 void Interface::HeroesIcons::ActionListSingleClick( HEROES & item )
222 {
223 if ( item ) {
224 Interface::Basic & I = Interface::Basic::Get();
225
226 I.SetFocus( item );
227 I.CalculateHeroPath( item, -1 );
228 I.RedrawFocus();
229 }
230 }
231
ActionListPressRight(HEROES & item)232 void Interface::HeroesIcons::ActionListPressRight( HEROES & item )
233 {
234 if ( item ) {
235 const fheroes2::Point p( _topLeftCorner.x - 1, _topLeftCorner.y );
236 Dialog::QuickInfo( *item, fheroes2::Rect(), p );
237 }
238 }
239
SetShow(bool f)240 void Interface::HeroesIcons::SetShow( bool f )
241 {
242 IconsBar::SetShow( f );
243
244 if ( IconsBar::IsVisible() ) {
245 if ( f )
246 GetScrollbar().show();
247 else
248 GetScrollbar().hide();
249 }
250 }
251
SetPos(s32 px,s32 py)252 void Interface::HeroesIcons::SetPos( s32 px, s32 py )
253 {
254 const int icnscroll = Settings::Get().ExtGameEvilInterface() ? ICN::SCROLLE : ICN::SCROLL;
255
256 _topLeftCorner = fheroes2::Point( px, py );
257 SetTopLeft( _topLeftCorner );
258 SetScrollBar( fheroes2::AGG::GetICN( icnscroll, 4 ), fheroes2::Rect( px + ICONS_CURSOR_WIDTH + 3, py + 19, 10, ICONS_CURSOR_HEIGHT * iconsCount - 38 ) );
259 SetScrollButtonUp( icnscroll, 0, 1, fheroes2::Point( px + ICONS_CURSOR_WIDTH + 1, py + 1 ) );
260 SetScrollButtonDn( icnscroll, 2, 3, fheroes2::Point( px + ICONS_CURSOR_WIDTH + 1, py + iconsCount * ICONS_CURSOR_HEIGHT - 15 ) );
261 SetAreaMaxItems( iconsCount );
262 SetAreaItems( fheroes2::Rect( px, py, ICONS_CURSOR_WIDTH, iconsCount * ICONS_CURSOR_HEIGHT ) );
263 DisableHotkeys( true );
264
265 SetListContent( world.GetKingdom( Settings::Get().CurrentColor() ).GetHeroes() );
266 Reset();
267 }
268
269 /* Interface::IconsPanel */
IconsPanel(Basic & basic)270 Interface::IconsPanel::IconsPanel( Basic & basic )
271 : BorderWindow( fheroes2::Rect( 0, 0, 144, 128 ) )
272 , interface( basic )
273 , castleIcons( 4, sfMarker )
274 , heroesIcons( 4, sfMarker )
275 {
276 sfMarker.resize( ICONS_CURSOR_WIDTH, ICONS_CURSOR_HEIGHT );
277 sfMarker.reset();
278 fheroes2::DrawBorder( sfMarker, fheroes2::GetColorId( 0xA0, 0xE0, 0xE0 ) );
279 }
280
SavePosition(void)281 void Interface::IconsPanel::SavePosition( void )
282 {
283 Settings::Get().SetPosIcons( GetRect().getPosition() );
284 }
285
SetRedraw(icons_t type) const286 void Interface::IconsPanel::SetRedraw( icons_t type ) const
287 {
288 // is visible
289 if ( IconsBar::IsVisible() ) {
290 switch ( type ) {
291 case ICON_HEROES:
292 interface.SetRedraw( REDRAW_HEROES );
293 break;
294 case ICON_CASTLES:
295 interface.SetRedraw( REDRAW_CASTLES );
296 break;
297 default:
298 break;
299 }
300
301 interface.SetRedraw( REDRAW_ICONS );
302 }
303 }
304
SetRedraw(void) const305 void Interface::IconsPanel::SetRedraw( void ) const
306 {
307 SetRedraw( ICON_ANY );
308 }
309
SetPos(s32 ox,s32 oy)310 void Interface::IconsPanel::SetPos( s32 ox, s32 oy )
311 {
312 u32 iconsCount = 0;
313
314 if ( Settings::Get().ExtGameHideInterface() ) {
315 iconsCount = 2;
316 }
317 else {
318 const u32 count_h = ( fheroes2::Display::instance().height() - fheroes2::Display::DEFAULT_HEIGHT ) / TILEWIDTH;
319 iconsCount = count_h > 3 ? 8 : ( count_h < 3 ? 4 : 7 );
320 }
321
322 BorderWindow::SetPosition( ox, oy, 144, iconsCount * ICONS_CURSOR_HEIGHT );
323
324 const fheroes2::Rect & rect = GetArea();
325
326 heroesIcons.SetIconsCount( iconsCount );
327 castleIcons.SetIconsCount( iconsCount );
328
329 heroesIcons.SetPos( rect.x, rect.y );
330 castleIcons.SetPos( rect.x + 72, rect.y );
331 }
332
Redraw(void)333 void Interface::IconsPanel::Redraw( void )
334 {
335 // is visible
336 if ( IconsBar::IsVisible() ) {
337 // redraw border
338 if ( Settings::Get().ExtGameHideInterface() )
339 BorderWindow::Redraw();
340
341 heroesIcons.Redraw();
342 castleIcons.Redraw();
343 }
344 }
345
QueueEventProcessing(void)346 void Interface::IconsPanel::QueueEventProcessing( void )
347 {
348 if ( Settings::Get().ShowIcons() &&
349 // move border window
350 BorderWindow::QueueEventProcessing() ) {
351 interface.RedrawFocus();
352 SetRedraw();
353 }
354 else if ( heroesIcons.QueueEventProcessing() ) {
355 if ( heroesIcons.isSelected() )
356 castleIcons.Unselect();
357
358 SetRedraw();
359 }
360 else if ( castleIcons.QueueEventProcessing() ) {
361 if ( castleIcons.isSelected() )
362 heroesIcons.Unselect();
363
364 SetRedraw();
365 }
366 }
367
Select(Heroes * const hr)368 void Interface::IconsPanel::Select( Heroes * const hr )
369 {
370 castleIcons.Unselect();
371 heroesIcons.SetCurrent( hr );
372 }
373
Select(Castle * const cs)374 void Interface::IconsPanel::Select( Castle * const cs )
375 {
376 heroesIcons.Unselect();
377 castleIcons.SetCurrent( cs );
378 }
379
ResetIcons(icons_t type)380 void Interface::IconsPanel::ResetIcons( icons_t type )
381 {
382 Kingdom & kingdom = world.GetKingdom( Settings::Get().CurrentColor() );
383
384 if ( !kingdom.isControlAI() ) {
385 if ( type & ICON_HEROES ) {
386 heroesIcons.SetListContent( kingdom.GetHeroes() );
387 heroesIcons.Reset();
388 }
389
390 if ( type & ICON_CASTLES ) {
391 castleIcons.SetListContent( kingdom.GetCastles() );
392 castleIcons.Reset();
393 }
394 }
395 }
396
HideIcons(icons_t type)397 void Interface::IconsPanel::HideIcons( icons_t type )
398 {
399 if ( type & ICON_HEROES )
400 heroesIcons.SetShow( false );
401 if ( type & ICON_CASTLES )
402 castleIcons.SetShow( false );
403 }
404
ShowIcons(icons_t type)405 void Interface::IconsPanel::ShowIcons( icons_t type )
406 {
407 if ( type & ICON_HEROES )
408 heroesIcons.SetShow( true );
409 if ( type & ICON_CASTLES )
410 castleIcons.SetShow( true );
411 }
412
SetCurrentVisible(void)413 void Interface::IconsPanel::SetCurrentVisible( void )
414 {
415 if ( heroesIcons.isSelected() ) {
416 heroesIcons.SetCurrentVisible();
417 heroesIcons.Redraw();
418 }
419 else if ( castleIcons.isSelected() ) {
420 castleIcons.SetCurrentVisible();
421 castleIcons.Redraw();
422 }
423 }
424
RedrawIcons(icons_t type)425 void Interface::IconsPanel::RedrawIcons( icons_t type )
426 {
427 if ( type & ICON_HEROES )
428 heroesIcons.Redraw();
429 if ( type & ICON_CASTLES )
430 castleIcons.Redraw();
431 }
432
IsSelected(icons_t type) const433 bool Interface::IconsPanel::IsSelected( icons_t type ) const
434 {
435 if ( type & ICON_HEROES )
436 return heroesIcons.isSelected();
437 else if ( type & ICON_CASTLES )
438 return castleIcons.isSelected();
439
440 return false;
441 }
442