summaryrefslogtreecommitdiffstats
path: root/src/ui
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/control.cpp1
-rw-r--r--src/ui/control.h7
-rw-r--r--src/ui/displayinfo.cpp4
-rw-r--r--src/ui/edit.cpp9
-rw-r--r--src/ui/edit.h2
-rw-r--r--src/ui/key.cpp169
-rw-r--r--src/ui/key.h45
-rw-r--r--src/ui/maindialog.cpp117
-rw-r--r--src/ui/mainshort.cpp2
-rw-r--r--src/ui/mainshort.h2
-rw-r--r--src/ui/studio.cpp4
-rw-r--r--src/ui/test/CMakeLists.txt33
-rw-r--r--src/ui/test/edit_test.cpp73
-rw-r--r--src/ui/test/mocks/text_mock.h21
-rw-r--r--src/ui/test/stubs/app_stub.cpp26
-rw-r--r--src/ui/test/stubs/engine_stub.cpp79
-rw-r--r--src/ui/test/stubs/particle_stub.cpp291
-rw-r--r--src/ui/test/stubs/restext_stub.cpp11
-rw-r--r--src/ui/test/stubs/robotmain_stub.cpp17
19 files changed, 710 insertions, 203 deletions
diff --git a/src/ui/control.cpp b/src/ui/control.cpp
index 16769d1..718ad3b 100644
--- a/src/ui/control.cpp
+++ b/src/ui/control.cpp
@@ -21,7 +21,6 @@
namespace Ui {
// Object's constructor.
-
CControl::CControl()
{
m_iMan = CInstanceManager::GetInstancePointer();
diff --git a/src/ui/control.h b/src/ui/control.h
index e08c34d..635ae12 100644
--- a/src/ui/control.h
+++ b/src/ui/control.h
@@ -1,4 +1,4 @@
-// * This file is part of the COLOBOT source code
+// * This file is part of the COLOBOT source code;
// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
// * Copyright (C) 2012 Polish Portal of Colobot (PPC)
// *
@@ -65,8 +65,7 @@ namespace Ui {
class CControl
{
public:
- // CControl(CInstanceManager* iMan);
- CControl ();
+ CControl();
virtual ~CControl();
virtual bool Create(Math::Point pos, Math::Point dim, int icon, EventType eventType);
@@ -117,9 +116,9 @@ namespace Ui {
protected:
CInstanceManager* m_iMan;
Gfx::CEngine* m_engine;
+ Gfx::CParticle* m_particle;
CEventQueue* m_event;
CRobotMain* m_main;
- Gfx::CParticle* m_particle;
CSoundInterface* m_sound;
Math::Point m_pos; // corner upper / left
diff --git a/src/ui/displayinfo.cpp b/src/ui/displayinfo.cpp
index 9b49f68..29499bd 100644
--- a/src/ui/displayinfo.cpp
+++ b/src/ui/displayinfo.cpp
@@ -232,7 +232,7 @@ bool CDisplayInfo::EventProcess(const Event &event)
m_bInfoMaximized = false;
}
//? m_main->SetEditFull(m_bInfoMaximized);
- pw = dynamic_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW4));
+ pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW4));
if ( pw != 0 )
{
pw->SetMaximized(m_bInfoMaximized);
@@ -834,7 +834,7 @@ void CDisplayInfo::StopDisplayInfo()
if ( m_bEditLock ) // editing running program?
{
- pw = dynamic_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW3));
+ pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW3));
if ( pw != 0 )
{
pw->SetState(STATE_ENABLE); // CStudio operating
diff --git a/src/ui/edit.cpp b/src/ui/edit.cpp
index ca53a7a..e14b19d 100644
--- a/src/ui/edit.cpp
+++ b/src/ui/edit.cpp
@@ -71,8 +71,6 @@ bool IsSep(int character)
//! Object's constructor.
-
-//CEdit::CEdit(CInstanceManager* iMan) : CControl(iMan)
CEdit::CEdit () : CControl ()
{
Math::Point pos;
@@ -1796,7 +1794,7 @@ bool CEdit::ReadText(const char *filename, int addSize)
if ( SearchKey(buffer+i+5, slot) )
{
CRobotMain* main = CRobotMain::GetInstancePointer();
- res = main->GetInputBinding(slot).key;
+ res = main->GetInputBinding(slot).primary;
if ( res != 0 )
{
if ( GetResource(RES_KEY, res, iName) )
@@ -1815,7 +1813,7 @@ bool CEdit::ReadText(const char *filename, int addSize)
m_format[j] = font;
j ++;
- res = main->GetInputBinding(slot).joy;
+ res = main->GetInputBinding(slot).secondary;
if ( res != 0 )
{
if ( GetResource(RES_KEY, res, iName) )
@@ -3081,7 +3079,7 @@ void CEdit::Justif()
if ( m_format.size() == 0 )
{
// TODO check if good
-
+
i += m_engine->GetText()->Justify(m_text+i, m_fontType,
m_fontSize, width);
}
@@ -3137,6 +3135,7 @@ void CEdit::Justif()
}
if ( m_lineTotal >= EDITLINEMAX-2 ) break;
}
+
if ( m_len > 0 && m_text[m_len-1] == '\n' )
{
m_lineOffset[m_lineTotal] = m_len;
diff --git a/src/ui/edit.h b/src/ui/edit.h
index 7414372..35d8b2c 100644
--- a/src/ui/edit.h
+++ b/src/ui/edit.h
@@ -124,8 +124,8 @@ struct HyperHistory
class CEdit : public CControl
{
public:
-// CEdit(CInstanceManager* iMan);
CEdit ();
+
virtual ~CEdit();
bool Create(Math::Point pos, Math::Point dim, int icon, EventType eventType);
diff --git a/src/ui/key.cpp b/src/ui/key.cpp
index 26d99ac..9a76127 100644
--- a/src/ui/key.cpp
+++ b/src/ui/key.cpp
@@ -15,65 +15,48 @@
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
-// key.cpp
-
-
#include "ui/key.h"
-#include <string.h>
+#include "common/global.h"
+
+#include <cstring>
namespace Ui {
-void GetKeyName(char *name, int key)
+
+void GetKeyName(char* name, unsigned int key)
{
- if ( !GetResource(RES_KEY, key, name) ) {
- if (isalnum(key)) {
- name[0] = key;
- name[1] = 0;
- }
- else {
- sprintf(name, "Code %d", key);
- }
- }
+ if (!GetResource(RES_KEY, key, name))
+ sprintf(name, "Code %d", key);
}
-// Object's constructor.
-
CKey::CKey() : CControl()
{
- m_key[0] = 0;
- m_key[1] = 0;
- m_bCatch = false;
+ m_catch = false;
- m_app = CApplication::GetInstancePointer();
+ m_robotMain = CRobotMain::GetInstancePointer();
}
-// Object's destructor.
-
CKey::~CKey()
{
+ m_robotMain = nullptr;
}
-
-// Creates a new button.
-
bool CKey::Create(Math::Point pos, Math::Point dim, int icon, EventType eventMsg)
{
- char name[100];
if (eventMsg == EVENT_NULL)
eventMsg = GetUniqueEventType();
CControl::Create(pos, dim, icon, eventMsg);
+
+ char name[100];
GetResource(RES_EVENT, eventMsg, name);
SetName(std::string(name));
return true;
}
-
-// Management of an event.
-
bool CKey::EventProcess(const Event &event)
{
if (m_state & STATE_DEAD)
@@ -81,24 +64,31 @@ bool CKey::EventProcess(const Event &event)
CControl::EventProcess(event);
- if (event.type == EVENT_MOUSE_BUTTON_DOWN) {
+ if (event.type == EVENT_MOUSE_BUTTON_DOWN)
+ {
if (event.mouseButton.button == MOUSE_BUTTON_LEFT) // left
- m_bCatch = Detect(event.mousePos);
+ m_catch = Detect(event.mousePos);
}
- if (event.type == EVENT_KEY_DOWN && m_bCatch) {
- m_bCatch = false;
+ if (event.type == EVENT_KEY_DOWN && m_catch)
+ {
+ m_catch = false;
- if ( TestKey(event.key.key) ) { // impossible ?
+ if (TestKey(event.key.key)) // impossible ?
+ {
m_sound->Play(SOUND_TZOING);
- } else {
- // TODO: test for virtual, joystick, etc.
- if ( event.key.key == m_key[0] || event.key.key == m_key[1] ) {
- m_key[0] = event.key.key;
- m_key[1] = 0;
- } else {
- m_key[1] = m_key[0];
- m_key[0] = event.key.key;
+ }
+ else
+ {
+ if (event.key.key == m_binding.primary || event.key.key == m_binding.secondary)
+ {
+ m_binding.secondary = KEY_INVALID;
+ m_binding.primary = event.key.key;
+ }
+ else
+ {
+ m_binding.secondary = m_binding.primary;
+ m_binding.primary = event.key.key;
}
m_sound->Play(SOUND_CLICK);
@@ -112,96 +102,88 @@ bool CKey::EventProcess(const Event &event)
return true;
}
-
-// Seeks when a key is already used.
-
-bool CKey::TestKey(int key)
+bool CKey::TestKey(unsigned int key)
{
- if ( key == KEY(PAUSE) || key == KEY(PRINT) ) return true; // blocked key
+ if (key == KEY(PAUSE) || key == KEY(PRINT)) return true; // blocked key
- /* TODO: input bindings
- for (int i = 0; i < 20; i++) {
- for (int j = 0; j < 2; j++) {
- if (key == m_app->GetKey(i, j) ) // key used?
- m_app->SetKey(i, j, 0); // nothing!
- }
+ for (int i = 0; i < INPUT_SLOT_MAX; i++)
+ {
+ InputSlot slot = static_cast<InputSlot>(i);
+ InputBinding b = m_robotMain->GetInputBinding(slot);
+ if (key == b.primary || key == b.secondary)
+ m_robotMain->SetInputBinding(slot, InputBinding()); // nothing!
- if ( m_app->GetKey(i, 0) == 0 ) { // first free option?
- m_app->SetKey(i, 0, m_app->GetKey(i, 1)); // shift
- m_app->SetKey(i, 1, 0);
- }
- } */
+ if (b.primary == KEY_INVALID) // first free option?
+ m_robotMain->SetInputBinding(slot, InputBinding(b.secondary, b.primary)); // shift
+ }
return false; // not used
}
-
-// Draws button.
-
void CKey::Draw()
{
- Math::Point iDim, pos;
- float zoomExt, zoomInt, h;
- int icon;
- char text[100];
-
- if ( (m_state & STATE_VISIBLE) == 0 )
+ if ((m_state & STATE_VISIBLE) == 0)
return;
- iDim = m_dim;
+ Math::Point iDim = m_dim;
m_dim.x = 200.0f/640.0f;
- if ( m_state & STATE_SHADOW )
+ if (m_state & STATE_SHADOW)
DrawShadow(m_pos, m_dim);
m_engine->SetTexture("button1.png");
m_engine->SetState(Gfx::ENG_RSTATE_NORMAL); // was D3DSTATENORMAL
- zoomExt = 1.00f;
- zoomInt = 0.95f;
+ float zoomExt = 1.00f;
+ float zoomInt = 0.95f;
- icon = 2;
- if ( m_key[0] == 0 && m_key[1] == 0 ) // no shortcut?
+ int icon = 2;
+ if (m_binding.primary == KEY_INVALID && m_binding.secondary == KEY_INVALID) // no shortcut?
icon = 3;
- if ( m_state & STATE_DEFAULT ) {
+ if (m_state & STATE_DEFAULT)
+ {
DrawPart(23, 1.3f, 0.0f);
zoomExt *= 1.15f;
zoomInt *= 1.15f;
}
- if ( m_state & STATE_HILIGHT )
+ if (m_state & STATE_HILIGHT)
icon = 1;
- if ( m_state & STATE_CHECK )
+ if (m_state & STATE_CHECK)
icon = 0;
- if ( m_state & STATE_PRESS ) {
+ if (m_state & STATE_PRESS)
+ {
icon = 3;
zoomInt *= 0.9f;
}
- if ( (m_state & STATE_ENABLE) == 0 )
+ if ((m_state & STATE_ENABLE) == 0)
icon = 7;
- if ( m_state & STATE_DEAD )
+ if (m_state & STATE_DEAD)
icon = 17;
- if ( m_bCatch )
+ if (m_catch)
icon = 23;
DrawPart(icon, zoomExt, 8.0f / 256.0f); // draws the button
- h = m_engine->GetText()->GetHeight(m_fontType, m_fontSize) / 2.0f;
+ float h = m_engine->GetText()->GetHeight(m_fontType, m_fontSize) / 2.0f;
- GetKeyName(text, m_key[0]);
- if ( m_key[1] != 0 ) {
+ char text[100];
+ GetKeyName(text, m_binding.primary);
+ if (m_binding.secondary != KEY_INVALID)
+ {
GetResource(RES_TEXT, RT_KEY_OR, text+strlen(text));
- GetKeyName(text+strlen(text), m_key[1]);
+ GetKeyName(text+strlen(text), m_binding.secondary);
}
+ Math::Point pos;
pos.x = m_pos.x + m_dim.x * 0.5f;
pos.y = m_pos.y + m_dim.y * 0.5f;
pos.y -= h;
@@ -209,7 +191,7 @@ void CKey::Draw()
m_dim = iDim;
- if ( m_state & STATE_DEAD )
+ if (m_state & STATE_DEAD)
return;
// Draws the name.
@@ -219,20 +201,15 @@ void CKey::Draw()
m_engine->GetText()->DrawText(std::string(m_name), m_fontType, m_fontSize, pos, m_dim.x, Gfx::TEXT_ALIGN_LEFT, 0);
}
-
-
-void CKey::SetKey(int option, int key)
+void CKey::SetBinding(InputBinding b)
{
- if ( option < 0 || option > 1 ) return;
-
- m_key[option] = key;
+ m_binding = b;
}
-int CKey::GetKey(int option)
+InputBinding CKey::GetBinding()
{
- if ( option < 0 || option > 1 ) return 0;
-
- return m_key[option];
+ return m_binding;
}
-}
+
+} // namespace Ui
diff --git a/src/ui/key.h b/src/ui/key.h
index 1943f61..2332c9b 100644
--- a/src/ui/key.h
+++ b/src/ui/key.h
@@ -15,13 +15,13 @@
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
-// key.h
+/**
+ * \file ui/key.h
+ * \brief Key slot control
+ */
#pragma once
-#include <cctype>
-#include <string>
-
#include "ui/control.h"
#include "common/iman.h"
@@ -29,33 +29,40 @@
#include "common/restext.h"
#include "common/key.h"
-#include "app/app.h"
namespace Ui {
class CKey : public CControl
{
- public:
- CKey();
- virtual ~CKey();
+public:
+ CKey();
+ virtual ~CKey();
- bool Create(Math::Point pos, Math::Point dim, int icon, EventType eventMsg);
- bool EventProcess(const Event &event);
+ //! Creates a new key slot button
+ bool Create(Math::Point pos, Math::Point dim, int icon, EventType eventMsg);
+ //! Management of an event
+ bool EventProcess(const Event &event);
- void Draw();
+ //! Draws button
+ void Draw();
- void SetKey(int option, int key);
- int GetKey(int option);
+ //! Management of binding
+ //@{
+ void SetBinding(InputBinding b);
+ InputBinding GetBinding();
+ //@}
- protected:
- bool TestKey(int key);
+protected:
+ //! Checks if a key is already used
+ bool TestKey(unsigned int key);
- unsigned int m_key[2];
- bool m_bCatch;
+protected:
+ CRobotMain* m_robotMain;
- CApplication *m_app;
+ InputBinding m_binding;
+ bool m_catch;
};
-}
+} // namespace Ui
diff --git a/src/ui/maindialog.cpp b/src/ui/maindialog.cpp
index d7295eb..5136a41 100644
--- a/src/ui/maindialog.cpp
+++ b/src/ui/maindialog.cpp
@@ -8,7 +8,7 @@
// *
// * 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 Gfx::PARTICULAR PURPOSE. See the
+// * 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
@@ -5476,7 +5476,6 @@ void CMainDialog::SetupMemorize()
{
float fValue;
int iValue, i, j;
- char key[500];
char num[10];
GetProfile().SetLocalProfileString("Directory", "scene", m_sceneDir);
@@ -5518,21 +5517,16 @@ void CMainDialog::SetupMemorize()
// GetProfile()->SetLocalProfileInt("Setup", "UseJoystick", m_engine->GetJoystick());
// GetProfile()->SetLocalProfileInt("Setup", "MidiVolume", m_sound->GetMidiVolume());
- // key[0] = 0;
- // for ( i=0 ; i<100 ; i++ )
- // {
- // if ( m_engine->GetKey(i, 0) == 0 ) break;
-
- // for ( j=0 ; j<2 ; j++ )
- // {
- // iValue = m_engine->GetKey(i, j);
- // sprintf(num, "%d%c", iValue, j==0?'+':' ');
- // strcat(key, num);
- // }
- // }
+ std::stringstream key;
+ for (int i = 0; i < INPUT_SLOT_MAX; i++)
+ {
+ InputBinding b = m_main->GetInputBinding(static_cast<InputSlot>(i));
- /* TODO: profile
- SetLocalProfileString("Setup", "KeyMap", key); */
+ key << b.primary << " ";
+ key << b.secondary << " ";
+ }
+
+ GetProfile().SetLocalProfileString("Setup", "KeyMap", key.str());
#if _NET
if ( m_accessEnable )
@@ -5556,9 +5550,8 @@ void CMainDialog::SetupMemorize()
void CMainDialog::SetupRecall()
{
float fValue;
- int iValue, i, j;
+ int iValue;
std::string key;
- char* p;
if ( GetProfile().GetLocalProfileString("Directory", "scene", key) )
{
@@ -5747,22 +5740,18 @@ void CMainDialog::SetupRecall()
m_engine->SetEditIndentValue(iValue);
}
- // if ( GetLocalProfileString("Setup", "KeyMap", key, 500) )
- // {
- // p = key;
- // for ( i=0 ; i<100 ; i++ )
- // {
- // if ( p[0] == 0 ) break;
-
- // for ( j=0 ; j<2 ; j++ )
- // {
- // sscanf(p, "%d", &iValue);
- // m_engine->SetKey(i, j, iValue);
- // while ( *p >= '0' && *p <= '9' ) p++;
- // while ( *p == ' ' || *p == '+' ) p++;
- // }
- // }
- // }
+ if (GetProfile().GetLocalProfileString("Setup", "KeyMap", key))
+ {
+ std::stringstream skey;
+ skey.str(key);
+ for (int i = 0; i < INPUT_SLOT_MAX; i++)
+ {
+ InputBinding b;
+ skey >> b.primary;
+ skey >> b.secondary;
+ m_main->SetInputBinding(static_cast<InputSlot>(i), b);
+ }
+ }
#if _NET
if ( m_accessEnable )
@@ -5837,7 +5826,7 @@ void CMainDialog::ChangeSetupQuality(int quality)
// Redefinable keys:
-static int key_table[KEY_TOTAL] =
+static InputSlot key_table[KEY_TOTAL] =
{
INPUT_SLOT_LEFT,
INPUT_SLOT_RIGHT,
@@ -5891,37 +5880,30 @@ static EventType key_event[KEY_TOTAL] =
void CMainDialog::UpdateKey()
{
- CWindow* pw;
- CScroll* ps;
- CKey* pk;
- Math::Point pos, dim;
- int first, i;
+ CWindow* pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
+ if (pw == nullptr) return;
- pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
- if ( pw == 0 ) return;
-
- ps = static_cast<CScroll*>(pw->SearchControl(EVENT_INTERFACE_KSCROLL));
- if ( ps == 0 ) return;
+ CScroll* ps = static_cast<CScroll*>(pw->SearchControl(EVENT_INTERFACE_KSCROLL));
+ if (ps == nullptr) return;
- first = static_cast<int>(ps->GetVisibleValue()*(KEY_TOTAL-KEY_VISIBLE));
+ int first = static_cast<int>(ps->GetVisibleValue()*(KEY_TOTAL-KEY_VISIBLE));
- for ( i=0 ; i<KEY_TOTAL ; i++ )
- {
+ for (int i = 0; i < KEY_TOTAL; i++)
pw->DeleteControl(key_event[i]);
- }
+ Math::Point dim;
dim.x = 400.0f/640.0f;
dim.y = 20.0f/480.0f;
+ Math::Point pos;
pos.x = 110.0f/640.0f;
pos.y = 168.0f/480.0f + dim.y*(KEY_VISIBLE-1);
- for ( i=0 ; i<KEY_VISIBLE ; i++ )
+ for (int i = 0; i < KEY_VISIBLE; i++)
{
pw->CreateKey(pos, dim, -1, key_event[first+i]);
- pk = static_cast<CKey*>(pw->SearchControl(key_event[first+i]));
- if ( pk == 0 ) break;
- /* TODO: set input bindings
- pk->SetKey(0, m_engine->GetKey(key_table[first+i], 0));
- pk->SetKey(1, m_engine->GetKey(key_table[first+i], 1)); */
+ CKey* pk = static_cast<CKey*>(pw->SearchControl(key_event[first+i]));
+ if (pk == nullptr) break;
+
+ pk->SetBinding(m_main->GetInputBinding(key_table[first+i]));
pos.y -= dim.y;
}
}
@@ -5930,26 +5912,20 @@ void CMainDialog::UpdateKey()
void CMainDialog::ChangeKey(EventType event)
{
- CWindow* pw;
- CScroll* ps;
- CKey* pk;
- int i;
-
- pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
- if ( pw == 0 ) return;
+ CWindow* pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
+ if (pw == nullptr) return;
- ps = static_cast<CScroll*>(pw->SearchControl(EVENT_INTERFACE_KSCROLL));
- if ( ps == 0 ) return;
+ CScroll* ps = static_cast<CScroll*>(pw->SearchControl(EVENT_INTERFACE_KSCROLL));
+ if (ps == nullptr) return;
- for ( i=0 ; i<KEY_TOTAL ; i++ )
+ for (int i = 0; i < KEY_TOTAL; i++)
{
if ( key_event[i] == event )
{
- pk = static_cast<CKey*>(pw->SearchControl(key_event[i]));
- if ( pk == 0 ) break;
- /* TODO: set key binding
- m_engine->SetKey(key_table[i], 0, pk->GetKey(0));
- m_engine->SetKey(key_table[i], 1, pk->GetKey(1)); */
+ CKey* pk = static_cast<CKey*>(pw->SearchControl(key_event[i]));
+ if (pk == nullptr) break;
+
+ m_main->SetInputBinding(key_table[i], pk->GetBinding());
}
}
}
@@ -6803,4 +6779,3 @@ bool CMainDialog::NextMission()
} // namespace Ui
-
diff --git a/src/ui/mainshort.cpp b/src/ui/mainshort.cpp
index ac6d7fc..55b9612 100644
--- a/src/ui/mainshort.cpp
+++ b/src/ui/mainshort.cpp
@@ -30,7 +30,7 @@ CMainShort::CMainShort()
m_iMan->AddInstance(CLASS_SHORT, this);
m_interface = static_cast<CInterface*>(m_iMan->SearchInstance(CLASS_INTERFACE));
- m_event = static_cast<CEvent*>(m_iMan->SearchInstance(CLASS_EVENT));
+ m_event = static_cast<CEventQueue*>(m_iMan->SearchInstance(CLASS_EVENT));
m_engine = static_cast<Gfx::CEngine*>(m_iMan->SearchInstance(CLASS_ENGINE));
m_main = static_cast<CRobotMain*>(m_iMan->SearchInstance(CLASS_MAIN));
diff --git a/src/ui/mainshort.h b/src/ui/mainshort.h
index e97bdcc..0912e68 100644
--- a/src/ui/mainshort.h
+++ b/src/ui/mainshort.h
@@ -47,7 +47,7 @@ class CMainShort
protected:
CInstanceManager* m_iMan;
- CEvent* m_event;
+ CEventQueue* m_event;
Gfx::CEngine* m_engine;
CInterface* m_interface;
CRobotMain* m_main;
diff --git a/src/ui/studio.cpp b/src/ui/studio.cpp
index a581baa..2f58c95 100644
--- a/src/ui/studio.cpp
+++ b/src/ui/studio.cpp
@@ -241,8 +241,8 @@ bool CStudio::EventProcess(const Event &event)
if ( event.type == EVENT_KEY_DOWN )
{
- if ( event.key.key == m_main->GetInputBinding(INPUT_SLOT_CBOT).key ||
- event.key.key == m_main->GetInputBinding(INPUT_SLOT_CBOT).joy )
+ if ( event.key.key == m_main->GetInputBinding(INPUT_SLOT_CBOT).primary ||
+ event.key.key == m_main->GetInputBinding(INPUT_SLOT_CBOT).secondary )
{
if ( m_helpFilename.length() > 0 )
{
diff --git a/src/ui/test/CMakeLists.txt b/src/ui/test/CMakeLists.txt
new file mode 100644
index 0000000..9e11e14
--- /dev/null
+++ b/src/ui/test/CMakeLists.txt
@@ -0,0 +1,33 @@
+cmake_minimum_required(VERSION 2.8)
+
+set(CMAKE_BUILD_TYPE debug)
+set(CMAKE_CXX_FLAGS_DEBUG "-g -O0 -Wall -Wold-style-cast -std=gnu++0x")
+
+include_directories(
+.
+../..
+../../..
+${GTEST_DIR}/include
+)
+
+
+add_executable(edit_test
+ ../../common/event.cpp
+ ../../common/logger.cpp
+ ../../common/misc.cpp
+ ../../common/iman.cpp
+ ../../common/stringutils.cpp
+ ../../graphics/engine/text.cpp
+ ../button.cpp
+ ../control.cpp
+ ../edit.cpp
+ ../scroll.cpp
+ stubs/app_stub.cpp
+ stubs/engine_stub.cpp
+ stubs/particle_stub.cpp
+ stubs/restext_stub.cpp
+ stubs/robotmain_stub.cpp
+ edit_test.cpp)
+target_link_libraries(edit_test gtest gmock ${SDL_LIBRARY} ${SDLTTF_LIBRARY})
+
+add_test(edit_test ./edit_test)
diff --git a/src/ui/test/edit_test.cpp b/src/ui/test/edit_test.cpp
new file mode 100644
index 0000000..489b873
--- /dev/null
+++ b/src/ui/test/edit_test.cpp
@@ -0,0 +1,73 @@
+#include "../edit.h"
+#include "../../app/app.h"
+#include "mocks/text_mock.h"
+#include <gtest/gtest.h>
+#include <gmock/gmock.h>
+#include <fstream>
+
+class CEditTest : public testing::Test
+{
+public:
+ CEditTest(){};
+
+ virtual void SetUp()
+ {
+ m_engine = new Gfx::CEngine(&m_iMan, NULL);
+
+ m_iMan.AddInstance(CLASS_ENGINE, m_engine);
+ m_edit = new Ui::CEdit;
+ }
+
+ virtual void TearDown()
+ {
+ m_iMan.DeleteInstance(CLASS_ENGINE, m_engine);
+ delete m_engine;
+ m_engine = NULL;
+ delete m_edit;
+ m_edit = NULL;
+
+ }
+ virtual ~CEditTest()
+ {
+
+ };
+
+protected:
+ CInstanceManager m_iMan;
+ CApplication m_app;
+ Gfx::CEngine * m_engine;
+ Ui::CEdit * m_edit;
+ CLogger m_logger;
+};
+
+using ::testing::_;
+using ::testing::Return;
+
+TEST_F(CEditTest, WriteTest)
+{
+ ASSERT_TRUE(true);
+ CTextMock * text = dynamic_cast<CTextMock *>(m_engine->GetText());
+ EXPECT_CALL(*text, GetCharWidth(_, _, _, _)).WillRepeatedly(Return(1.0f));
+ EXPECT_CALL(*text, GetStringWidth(_, _, _)).WillOnce(Return(1.0f));
+ std::string filename = "test.file";
+ m_edit->SetMaxChar(Ui::EDITSTUDIOMAX);
+ m_edit->SetAutoIndent(true);
+ std::string inputScript = "{\ntext1\ntext2\n\ntext3\n{\ntext4\n}\n}";
+ std::string expectedScript = "{\r\n\ttext1\r\n\ttext2\r\n\t\r\n\ttext3\r\n\t{\r\n\t\ttext4\r\n\t}\r\n}";
+ m_edit->SetText(inputScript.c_str(), true);
+ GetLogger()->Info("Writing text \n");
+ m_edit->WriteText("script.txt");
+
+ std::fstream scriptFile;
+
+ scriptFile.open("script.txt", std::ios_base::binary | std::ios_base::in);
+ std::string outputScript((std::istreambuf_iterator<char>(scriptFile)), std::istreambuf_iterator<char>());
+ ASSERT_STREQ(expectedScript.c_str(), outputScript.c_str());
+}
+
+int main(int argc, char *argv[])
+{
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
+
diff --git a/src/ui/test/mocks/text_mock.h b/src/ui/test/mocks/text_mock.h
new file mode 100644
index 0000000..59a6c48
--- /dev/null
+++ b/src/ui/test/mocks/text_mock.h
@@ -0,0 +1,21 @@
+#include "../../graphics/engine/text.h"
+#include <gmock/gmock.h>
+#include "../../common/logger.h"
+
+
+class CTextMock : public Gfx::CText
+{
+public:
+ CTextMock(CInstanceManager *iMan, Gfx::CEngine* engine) : CText(iMan, engine)
+ {
+ }
+
+ virtual ~CTextMock()
+ {
+ };
+
+ MOCK_METHOD4(GetCharWidth, float(Gfx::UTF8Char, Gfx::FontType, float, float));
+ MOCK_METHOD3(GetStringWidth, float(const std::string &, Gfx::FontType, float));
+
+};
+
diff --git a/src/ui/test/stubs/app_stub.cpp b/src/ui/test/stubs/app_stub.cpp
new file mode 100644
index 0000000..5dd79e4
--- /dev/null
+++ b/src/ui/test/stubs/app_stub.cpp
@@ -0,0 +1,26 @@
+#include "../../app/app.h"
+#include "../../graphics/opengl/gldevice.h"
+
+template<> CApplication* CSingleton<CApplication>::mInstance = nullptr;
+
+namespace Gfx {
+
+GLDeviceConfig::GLDeviceConfig()
+{
+}
+
+} /* Gfx */
+CApplication::CApplication()
+{
+}
+
+CApplication::~CApplication()
+{
+}
+
+std::string CApplication::GetDataFilePath(DataDir /* dataDir */, const std::string& subpath)
+{
+ return subpath;
+}
+
+
diff --git a/src/ui/test/stubs/engine_stub.cpp b/src/ui/test/stubs/engine_stub.cpp
new file mode 100644
index 0000000..6ec6006
--- /dev/null
+++ b/src/ui/test/stubs/engine_stub.cpp
@@ -0,0 +1,79 @@
+#include "../../graphics/engine/engine.h"
+#include "../../graphics/engine/text.h"
+#include "../mocks/text_mock.h"
+
+namespace Gfx {
+
+CEngine::CEngine(CInstanceManager* iMan, CApplication* app) :
+ m_iMan(iMan), m_app(app)
+{
+ m_text = new CTextMock(m_iMan, this);
+ m_text->Create();
+}
+
+CEngine::~CEngine()
+{
+ delete m_text;
+ m_text = NULL;
+}
+
+Math::Point CEngine::WindowToInterfaceSize(Math::IntPoint size)
+{
+ return Math::Point(size.x, size.y);
+}
+
+void CEngine::SetState(int state, const Color& color)
+{
+ if (state == m_lastState && color == m_lastColor)
+ return;
+
+ m_lastState = state;
+ m_lastColor = color;
+}
+
+Math::IntPoint CEngine::GetWindowSize()
+{
+ return m_size;
+}
+
+void CEngine::AddStatisticTriangle(int count)
+{
+ m_statisticTriangle += count;
+}
+
+void CEngine::SetMouseType(EngineMouseType type)
+{
+ m_mouseType = type;
+}
+
+bool CEngine::SetTexture(const std::string& /* name */, int /* stage */)
+{
+ return true;
+}
+
+CText* CEngine::GetText()
+{
+ return m_text;
+}
+
+CDevice* CEngine::GetDevice()
+{
+ return m_device;
+}
+
+int CEngine::GetEditIndentValue()
+{
+ return m_editIndentValue;
+}
+
+void CEngine::DeleteTexture(const std::string& /* texName */)
+{
+}
+Texture CEngine::LoadTexture(const std::string& /* name */)
+{
+ Texture texture;
+ return texture;
+}
+
+} /* Gfx */
+
diff --git a/src/ui/test/stubs/particle_stub.cpp b/src/ui/test/stubs/particle_stub.cpp
new file mode 100644
index 0000000..41f07cc
--- /dev/null
+++ b/src/ui/test/stubs/particle_stub.cpp
@@ -0,0 +1,291 @@
+#include "graphics/engine/particle.h"
+
+#include "common/logger.h"
+
+
+// Graphics module namespace
+namespace Gfx {
+
+
+CParticle::CParticle(CInstanceManager* iMan, CEngine* engine)
+{
+ GetLogger()->Trace("CParticle::CParticle() stub!\n");
+ // TODO!
+}
+
+CParticle::~CParticle()
+{
+ GetLogger()->Trace("CParticle::~CParticle() stub!\n");
+ // TODO!
+}
+
+void CParticle::SetDevice(CDevice* device)
+{
+ GetLogger()->Trace("CParticle::SetDevice() stub!\n");
+ // TODO!
+}
+
+void CParticle::FlushParticle()
+{
+ GetLogger()->Trace("CParticle::FlushParticle() stub!\n");
+ // TODO!
+}
+
+void CParticle::FlushParticle(int sheet)
+{
+ GetLogger()->Trace("CParticle::FlushParticle() stub!\n");
+ // TODO!
+}
+
+int CParticle::CreateParticle(Math::Vector pos, Math::Vector speed, Math::Point dim,
+ ParticleType type, float duration, float mass,
+ float windSensitivity, int sheet)
+{
+ GetLogger()->Trace("CParticle::CreateParticle() stub!\n");
+ // TODO!
+ return 0;
+}
+
+int CParticle::CreateFrag(Math::Vector pos, Math::Vector speed, EngineTriangle *triangle,
+ ParticleType type, float duration, float mass,
+ float windSensitivity, int sheet)
+{
+ GetLogger()->Trace("CParticle::CreateFrag() stub!\n");
+ // TODO!
+ return 0;
+}
+
+int CParticle::CreatePart(Math::Vector pos, Math::Vector speed, ParticleType type,
+ float duration, float mass, float weight,
+ float windSensitivity, int sheet)
+{
+ GetLogger()->Trace("CParticle::CreatePart() stub!\n");
+ // TODO!
+ return 0;
+}
+
+int CParticle::CreateRay(Math::Vector pos, Math::Vector goal, ParticleType type, Math::Point dim,
+ float duration, int sheet)
+{
+ GetLogger()->Trace("CParticle::CreateRay() stub!\n");
+ // TODO!
+ return 0;
+}
+
+int CParticle::CreateTrack(Math::Vector pos, Math::Vector speed, Math::Point dim, ParticleType type,
+ float duration, float mass, float length, float width)
+{
+ GetLogger()->Trace("CParticle::CreateTrack() stub!\n");
+ // TODO!
+ return 0;
+}
+
+void CParticle::CreateWheelTrace(const Math::Vector &p1, const Math::Vector &p2, const Math::Vector &p3,
+ const Math::Vector &p4, ParticleType type)
+{
+ GetLogger()->Trace("CParticle::CreateWheelTrace() stub!\n");
+ // TODO!
+}
+
+void CParticle::DeleteParticle(ParticleType type)
+{
+ GetLogger()->Trace("CParticle::DeleteParticle() stub!\n");
+ // TODO!
+}
+
+void CParticle::DeleteParticle(int channel)
+{
+ GetLogger()->Trace("CParticle::DeleteParticle() stub!\n");
+ // TODO!
+}
+
+void CParticle::SetObjectLink(int channel, CObject *object)
+{
+ GetLogger()->Trace("CParticle::SetObjectLink() stub!\n");
+ // TODO!
+}
+
+void CParticle::SetObjectFather(int channel, CObject *object)
+{
+ GetLogger()->Trace("CParticle::SetObjectFather() stub!\n");
+ // TODO!
+}
+
+void CParticle::SetPosition(int channel, Math::Vector pos)
+{
+ GetLogger()->Trace("CParticle::SetPosition() stub!\n");
+ // TODO!
+}
+
+void CParticle::SetDimension(int channel, Math::Point dim)
+{
+ GetLogger()->Trace("CParticle::SetDimension() stub!\n");
+ // TODO!
+}
+
+void CParticle::SetZoom(int channel, float zoom)
+{
+ GetLogger()->Trace("CParticle::SetZoom() stub!\n");
+ // TODO!
+}
+
+void CParticle::SetAngle(int channel, float angle)
+{
+ GetLogger()->Trace("CParticle::SetAngle() stub!\n");
+ // TODO!
+}
+
+void CParticle::SetIntensity(int channel, float intensity)
+{
+ GetLogger()->Trace("CParticle::SetIntensity() stub!\n");
+ // TODO!
+}
+
+void CParticle::SetParam(int channel, Math::Vector pos, Math::Point dim, float zoom, float angle, float intensity)
+{
+ GetLogger()->Trace("CParticle::SetParam() stub!\n");
+ // TODO!
+}
+
+void CParticle::SetPhase(int channel, ParticlePhase phase, float duration)
+{
+ GetLogger()->Trace("CParticle::SetPhase() stub!\n");
+ // TODO!
+}
+
+bool CParticle::GetPosition(int channel, Math::Vector &pos)
+{
+ GetLogger()->Trace("CParticle::GetPosition() stub!\n");
+ // TODO!
+ return true;
+}
+
+Color CParticle::GetFogColor(Math::Vector pos)
+{
+ GetLogger()->Trace("CParticle::GetFogColor() stub!\n");
+ // TODO!
+ return Color();
+}
+
+void CParticle::SetFrameUpdate(int sheet, bool update)
+{
+ GetLogger()->Trace("CParticle::SetFrameUpdate() stub!\n");
+ // TODO!
+}
+
+void CParticle::FrameParticle(float rTime)
+{
+ GetLogger()->Trace("CParticle::FrameParticle() stub!\n");
+ // TODO!
+}
+
+void CParticle::DrawParticle(int sheet)
+{
+ GetLogger()->Trace("CParticle::DrawParticle() stub!\n");
+ // TODO!
+}
+
+bool CParticle::WriteWheelTrace(const char *filename, int width, int height, Math::Vector dl, Math::Vector ur)
+{
+ GetLogger()->Trace("CParticle::WriteWheelTrace() stub!\n");
+ // TODO!
+ return true;
+}
+
+void CParticle::DeleteRank(int rank)
+{
+ GetLogger()->Trace("CParticle::DeleteRank() stub!\n");
+ // TODO!
+}
+
+bool CParticle::CheckChannel(int &channel)
+{
+ GetLogger()->Trace("CParticle::CheckChannel() stub!\n");
+ // TODO!
+ return true;
+}
+
+void CParticle::DrawParticleTriangle(int i)
+{
+ GetLogger()->Trace("CParticle::DrawParticleTriangle() stub!\n");
+ // TODO!
+}
+
+void CParticle::DrawParticleNorm(int i)
+{
+ GetLogger()->Trace("CParticle::DrawParticleNorm() stub!\n");
+ // TODO!
+}
+
+void CParticle::DrawParticleFlat(int i)
+{
+ GetLogger()->Trace("CParticle::DrawParticleFlat() stub!\n");
+ // TODO!
+}
+
+void CParticle::DrawParticleFog(int i)
+{
+ GetLogger()->Trace("CParticle::DrawParticleFog() stub!\n");
+ // TODO!
+}
+
+void CParticle::DrawParticleRay(int i)
+{
+ GetLogger()->Trace("CParticle::DrawParticleRay() stub!\n");
+ // TODO!
+}
+
+void CParticle::DrawParticleSphere(int i)
+{
+ GetLogger()->Trace("CParticle::DrawParticleSphere() stub!\n");
+ // TODO!
+}
+
+void CParticle::DrawParticleCylinder(int i)
+{
+ GetLogger()->Trace("CParticle::DrawParticleCylinder() stub!\n");
+ // TODO!
+}
+
+void CParticle::DrawParticleWheel(int i)
+{
+ GetLogger()->Trace("CParticle::DrawParticleWheel() stub!\n");
+ // TODO!
+}
+
+CObject* CParticle::SearchObjectGun(Math::Vector old, Math::Vector pos, ParticleType type, CObject *father)
+{
+ GetLogger()->Trace("CParticle::SearchObjectGun() stub!\n");
+ // TODO!
+ return nullptr;
+}
+
+CObject* CParticle::SearchObjectRay(Math::Vector pos, Math::Vector goal, ParticleType type, CObject *father)
+{
+ GetLogger()->Trace("CParticle::SearchObjectRay() stub!\n");
+ // TODO!
+ return nullptr;
+}
+
+void CParticle::Play(Sound sound, Math::Vector pos, float amplitude)
+{
+ GetLogger()->Trace("CParticle::Play() stub!\n");
+ // TODO!
+}
+
+bool CParticle::TrackMove(int i, Math::Vector pos, float progress)
+{
+ GetLogger()->Trace("CParticle::TrackMove() stub!\n");
+ // TODO!
+ return true;
+}
+
+void CParticle::TrackDraw(int i, ParticleType type)
+{
+ GetLogger()->Trace("CParticle::TrackDraw() stub!\n");
+ // TODO!
+}
+
+
+} // namespace Gfx
+
diff --git a/src/ui/test/stubs/restext_stub.cpp b/src/ui/test/stubs/restext_stub.cpp
new file mode 100644
index 0000000..c1986ca
--- /dev/null
+++ b/src/ui/test/stubs/restext_stub.cpp
@@ -0,0 +1,11 @@
+#include "../../common/restext.h"
+bool GetResource(ResType /* type */, int /* num */, char* /* text */)
+{
+ return true;
+}
+
+bool SearchKey(const char * /* cmd */, InputSlot & /* key */)
+{
+ return true;
+}
+
diff --git a/src/ui/test/stubs/robotmain_stub.cpp b/src/ui/test/stubs/robotmain_stub.cpp
new file mode 100644
index 0000000..93e0e82
--- /dev/null
+++ b/src/ui/test/stubs/robotmain_stub.cpp
@@ -0,0 +1,17 @@
+#include "../../object/robotmain.h"
+
+
+template<> CRobotMain* CSingleton<CRobotMain>::mInstance = nullptr;
+
+bool CRobotMain::GetGlint()
+{
+ return false;
+}
+
+const InputBinding& CRobotMain::GetInputBinding(InputSlot slot)
+{
+ unsigned int index = static_cast<unsigned int>(slot);
+ assert(index >= 0 && index < INPUT_SLOT_MAX);
+ return m_inputBindings[index];
+}
+