colobot/src/ui/mainshort.cpp

379 lines
11 KiB
C++
Raw Normal View History

/*
* This file is part of the Colobot: Gold Edition source code
2016-02-13 13:11:30 +00:00
* Copyright (C) 2001-2016, Daniel Roux, EPSITEC SA & TerranovaTeam
2015-08-22 14:40:02 +00:00
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://gnu.org/licenses
*/
2012-09-18 22:04:21 +00:00
#include "ui/mainshort.h"
#include "app/app.h"
2015-08-31 19:57:46 +00:00
#include "app/pausemanager.h"
2015-07-16 11:46:05 +00:00
#include "common/logger.h"
#include "level/robotmain.h"
#include "object/object.h"
#include "object/object_manager.h"
2015-08-10 21:20:36 +00:00
#include "object/interface/controllable_object.h"
2015-08-10 16:16:00 +00:00
#include "object/interface/programmable_object.h"
#include "ui/controls/interface.h"
#include "ui/controls/shortcut.h"
2015-08-15 12:02:07 +00:00
#include <algorithm>
2015-08-02 09:40:47 +00:00
namespace Ui
{
// Constructor of the application card.
CMainShort::CMainShort()
{
m_event = CApplication::GetInstancePointer()->GetEventQueue();
m_engine = Gfx::CEngine::GetInstancePointer();
m_main = CRobotMain::GetInstancePointer();
m_interface = m_main->GetInterface();
2015-07-16 11:46:05 +00:00
m_shortcuts.clear();
m_bBuilding = false;
}
// Destructor of the application card.
CMainShort::~CMainShort()
{
}
void CMainShort::SetMode(bool bBuilding)
{
m_bBuilding = bBuilding;
}
// Interface creates shortcuts to the units.
bool CMainShort::CreateShortcuts()
{
Math::Point pos, dim;
if ( m_main->GetFixScene() ) return false;
2015-07-16 11:46:05 +00:00
// Delete all old controls
m_interface->DeleteControl(EVENT_OBJECT_MOVIELOCK);
m_interface->DeleteControl(EVENT_OBJECT_EDITLOCK);
2015-08-06 18:15:17 +00:00
m_interface->DeleteControl(EVENT_OBJECT_SAVING);
2015-07-16 11:46:05 +00:00
m_interface->DeleteControl(EVENT_OBJECT_SHORTCUT_MODE);
for (int i = EVENT_OBJECT_SHORTCUT; i <= EVENT_OBJECT_SHORTCUT_MAX; i++)
{
2015-07-16 11:46:05 +00:00
m_interface->DeleteControl(static_cast<EventType>(i));
}
2015-07-16 11:46:05 +00:00
m_shortcuts.clear();
Math::IntPoint size = m_engine->GetWindowSize();
float ratio = static_cast<float>(size.y) / static_cast<float>(size.x);
// Display pause / movie indicator
dim.y = 28.0f/480.0f;
dim.x = dim.y*ratio;
pos.x = 4.0f/640.0f;
pos.y = (480.0f-32.0f)/480.0f;
2015-08-06 18:15:17 +00:00
m_interface->CreateShortcut(pos, dim, 58, EVENT_OBJECT_SAVING);
if ( m_main->GetMovieLock() &&
!m_main->GetEditLock() ) // hangs during film?
{
2015-08-06 18:15:17 +00:00
m_interface->CreateShortcut(pos, dim, 128+7, EVENT_OBJECT_MOVIELOCK);
return true;
}
2015-10-01 16:55:41 +00:00
if ( !m_main->GetPauseManager()->IsPauseType(PAUSE_PHOTO) &&
(m_main->GetEditLock() ||
m_engine->GetPause()) ) // hangs during edition?
{
2015-08-06 18:15:17 +00:00
m_interface->CreateShortcut(pos, dim, 128+6, EVENT_OBJECT_EDITLOCK);
}
2015-10-01 16:55:41 +00:00
if (m_main->GetPauseManager()->IsPauseType(PAUSE_PHOTO) && m_main->GetSelect() == nullptr)
{
return true;
}
2015-08-31 19:57:46 +00:00
2015-10-01 16:55:41 +00:00
if (m_main->GetPauseManager()->IsPauseType(PAUSE_HIDE_SHORTCUTS))
2015-08-31 19:57:46 +00:00
return true;
2015-07-16 11:46:05 +00:00
// Create new shortcuts
2015-08-06 18:15:17 +00:00
m_interface->CreateShortcut(pos, dim, 128+2, EVENT_OBJECT_SHORTCUT_MODE);
pos.x += dim.x*1.2f;
2015-07-16 11:46:05 +00:00
std::vector<int> teams;
for (CObject* object : CObjectManager::GetInstancePointer()->GetAllObjects())
{
if (!object->GetDetectable())
2015-07-16 11:46:05 +00:00
continue;
if(GetShortcutIcon(object->GetType()) == -1)
continue;
if(std::find(teams.begin(), teams.end(), object->GetTeam()) == teams.end())
teams.push_back(object->GetTeam());
}
std::sort(teams.begin(), teams.end());
std::vector<Math::Point> positions;
for(unsigned int i = 0; i < teams.size(); i++)
{
positions.push_back(pos);
pos.y -= dim.y;
}
int rank = 0;
for (CObject* pObj : CObjectManager::GetInstancePointer()->GetAllObjects())
{
if ( !pObj->GetDetectable() ) continue;
2015-08-10 21:20:36 +00:00
if ( pObj->Implements(ObjectInterfaceType::Controllable) && !dynamic_cast<CControllableObject*>(pObj)->GetSelectable() ) continue;
if ( pObj->GetProxyActivate() ) continue;
2015-07-16 11:46:05 +00:00
int icon = GetShortcutIcon(pObj->GetType());
if ( icon == -1 ) continue;
unsigned int teamIndex = std::find(teams.begin(), teams.end(), pObj->GetTeam()) - teams.begin();
2015-07-16 11:46:05 +00:00
CShortcut* shortcut = m_interface->CreateShortcut(positions[teamIndex], dim, icon, static_cast<EventType>(EVENT_OBJECT_SHORTCUT+rank));
positions[teamIndex].x += dim.x;
2015-07-16 11:46:05 +00:00
m_shortcuts.push_back(pObj);
shortcut->SetTooltip(pObj->GetTooltipText());
rank ++;
2015-07-16 11:46:05 +00:00
if (rank > EVENT_OBJECT_SHORTCUT_MAX-EVENT_OBJECT_SHORTCUT)
{
GetLogger()->Warn("Not enough shortcut slots!\n");
2015-07-16 11:46:05 +00:00
break;
}
}
UpdateShortcuts();
return true;
}
2015-07-16 11:46:05 +00:00
int CMainShort::GetShortcutIcon(ObjectType type)
{
int icon = -1;
if ( m_bBuilding )
{
switch ( type )
{
case OBJECT_FACTORY: icon = 32; break;
case OBJECT_DERRICK: icon = 33; break;
case OBJECT_CONVERT: icon = 34; break;
case OBJECT_RESEARCH: icon = 35; break;
case OBJECT_STATION: icon = 36; break;
case OBJECT_TOWER: icon = 37; break;
case OBJECT_LABO: icon = 38; break;
case OBJECT_ENERGY: icon = 39; break;
case OBJECT_RADAR: icon = 40; break;
case OBJECT_INFO: icon = 44; break;
case OBJECT_REPAIR: icon = 41; break;
case OBJECT_DESTROYER: icon = 41; break;
case OBJECT_NUCLEAR: icon = 42; break;
case OBJECT_PARA: icon = 46; break;
case OBJECT_SAFE: icon = 47; break;
case OBJECT_HUSTON: icon = 48; break;
case OBJECT_BASE: icon = 43; break;
default: return -1;
}
2015-07-16 11:46:05 +00:00
}
else
{
switch ( type )
{
case OBJECT_HUMAN: icon = 8; break;
case OBJECT_MOBILEfa: icon = 11; break;
case OBJECT_MOBILEta: icon = 10; break;
case OBJECT_MOBILEwa: icon = 9; break;
case OBJECT_MOBILEia: icon = 22; break;
case OBJECT_MOBILEfb: icon = 2; break; // button4
case OBJECT_MOBILEtb: icon = 1; break;
case OBJECT_MOBILEwb: icon = 0; break;
case OBJECT_MOBILEib: icon = 3; break;
case OBJECT_MOBILEfc: icon = 17; break;
case OBJECT_MOBILEtc: icon = 16; break;
case OBJECT_MOBILEwc: icon = 15; break;
case OBJECT_MOBILEic: icon = 23; break;
case OBJECT_MOBILEfi: icon = 27; break;
case OBJECT_MOBILEti: icon = 26; break;
case OBJECT_MOBILEwi: icon = 25; break;
case OBJECT_MOBILEii: icon = 28; break;
case OBJECT_MOBILEfs: icon = 14; break;
case OBJECT_MOBILEts: icon = 13; break;
case OBJECT_MOBILEws: icon = 12; break;
case OBJECT_MOBILEis: icon = 24; break;
case OBJECT_MOBILErt: icon = 18; break;
case OBJECT_MOBILErc: icon = 19; break;
case OBJECT_MOBILErr: icon = 20; break;
case OBJECT_MOBILErs: icon = 29; break;
case OBJECT_MOBILEsa: icon = 21; break;
2017-12-22 15:51:25 +00:00
case OBJECT_MOBILEft: icon = 6; break;
case OBJECT_MOBILEtt: icon = 5; break;
case OBJECT_MOBILEwt: icon = 30; break;
2017-12-22 15:51:25 +00:00
case OBJECT_MOBILEit: icon = 7; break;
case OBJECT_MOBILEdr: icon = 48; break;
case OBJECT_APOLLO2: icon = 49; break;
default: return -1;
}
}
switch ( type )
{
case OBJECT_MOBILEfb:
case OBJECT_MOBILEtb:
case OBJECT_MOBILEwb:
case OBJECT_MOBILEib:
2017-12-22 15:51:25 +00:00
case OBJECT_MOBILEft:
case OBJECT_MOBILEtt:
case OBJECT_MOBILEit:
return 192+icon;
default:
return 128+icon;
2015-07-16 11:46:05 +00:00
}
}
// Updates the interface shortcuts to the units.
bool CMainShort::UpdateShortcuts()
{
2015-07-16 11:46:05 +00:00
for(unsigned int i = 0; i < m_shortcuts.size(); i++)
{
2015-07-16 11:46:05 +00:00
CControl* pc = m_interface->SearchControl(static_cast<EventType>(EVENT_OBJECT_SHORTCUT+i));
if ( pc != nullptr )
{
2015-08-10 21:20:36 +00:00
assert(m_shortcuts[i]->Implements(ObjectInterfaceType::Controllable));
pc->SetState(STATE_CHECK, dynamic_cast<CControllableObject*>(m_shortcuts[i])->GetSelect());
2015-08-10 16:16:00 +00:00
pc->SetState(STATE_RUN, m_shortcuts[i]->Implements(ObjectInterfaceType::Programmable) && dynamic_cast<CProgrammableObject*>(m_shortcuts[i])->IsProgram());
pc->SetState(STATE_DAMAGE, dynamic_cast<CDamageableObject*>(m_shortcuts[i])->IsDamaging());
}
}
return true;
}
// Selects an object through a shortcut.
void CMainShort::SelectShortcut(EventType event)
{
2015-07-16 11:46:05 +00:00
if (event == EVENT_OBJECT_SHORTCUT_MODE)
{
2015-07-16 11:46:05 +00:00
m_bBuilding = !m_bBuilding;
CreateShortcuts();
}
2015-07-16 11:46:05 +00:00
if(event >= EVENT_OBJECT_SHORTCUT && event <= EVENT_OBJECT_SHORTCUT_MAX)
{
unsigned int i = event-EVENT_OBJECT_SHORTCUT;
m_main->SelectObject(m_shortcuts[i]);
}
}
// Selects the next object.
void CMainShort::SelectNext()
{
if ( m_main->GetMovieLock() ||
m_main->GetEditLock() ||
m_engine->GetPause() ) return;
2015-07-16 11:46:05 +00:00
CObject* pPrev = m_main->DeselectAll();
if (m_shortcuts.size() == 0)
{
m_main->SelectObject(m_main->SearchHuman());
return;
}
// Find the current object in the list
auto it = std::find(m_shortcuts.begin(), m_shortcuts.end(), pPrev);
// Get the next one
if (it != m_shortcuts.end())
{
++it;
}
// If there is no more left, return to the first one
if (it == m_shortcuts.end())
{
it = m_shortcuts.begin();
}
m_main->SelectObject(*it);
}
// The object detected by the mouse hovers over.
CObject* CMainShort::DetectShort(Math::Point pos)
{
2015-07-16 11:46:05 +00:00
for (unsigned int i = 0; i < m_shortcuts.size(); i++)
{
2015-07-16 11:46:05 +00:00
CControl* pc = m_interface->SearchControl(static_cast<EventType>(EVENT_OBJECT_SHORTCUT+i));
if ( pc != nullptr )
{
2015-07-16 11:46:05 +00:00
Math::Point cpos = pc->GetPos();
Math::Point cdim = pc->GetDim();
if ( pos.x >= cpos.x &&
pos.x <= cpos.x+cdim.x &&
pos.y >= cpos.y &&
pos.y <= cpos.y+cdim.y )
{
return m_shortcuts[i];
}
}
}
2015-08-17 20:40:52 +00:00
return nullptr;
}
// Reports the object with the mouse hovers over.
void CMainShort::SetHighlight(CObject* pObj)
{
2015-07-16 11:46:05 +00:00
for (unsigned int i = 0; i < m_shortcuts.size(); i++)
{
2015-07-16 11:46:05 +00:00
CControl* pc = m_interface->SearchControl(static_cast<EventType>(EVENT_OBJECT_SHORTCUT+i));
if ( pc == nullptr ) continue;
if ( m_shortcuts[i] == pObj )
{
pc->SetState(STATE_HILIGHT);
pc->SetState(STATE_FRAME);
}
else
{
pc->ClearState(STATE_HILIGHT);
pc->ClearState(STATE_FRAME);
}
}
}
}