Move open/save dialog from CStudio to CFileDialog

1164-fix
melex750 2017-11-15 16:19:32 -05:00 committed by Mateusz Przybył
parent e2eb5b91e0
commit 5cc565439c
16 changed files with 1680 additions and 646 deletions

View File

@ -206,6 +206,9 @@ msgstr ""
msgid "Public\\Common folder" msgid "Public\\Common folder"
msgstr "" msgstr ""
msgid "Overwrite existing file?"
msgstr ""
msgid "Original game developed by:" msgid "Original game developed by:"
msgstr "" msgstr ""
@ -286,6 +289,9 @@ msgstr ""
msgid "Previous" msgid "Previous"
msgstr "" msgstr ""
msgid "New Folder"
msgstr ""
msgid "Exercises\\Programming exercises" msgid "Exercises\\Programming exercises"
msgstr "" msgstr ""

View File

@ -929,6 +929,9 @@ msgstr "Neu"
msgid "New ..." msgid "New ..."
msgstr "Neu ..." msgstr "Neu ..."
msgid "New Folder"
msgstr ""
msgid "New bot available" msgid "New bot available"
msgstr "Neuer Roboter verfügbar" msgstr "Neuer Roboter verfügbar"
@ -1085,6 +1088,9 @@ msgstr "Ort der Meldung\\Zeigt den Ort, von dem die letzte Meldung stammt"
msgid "Original game developed by:" msgid "Original game developed by:"
msgstr "Ursprünglichen Spiel entwickelt von:" msgstr "Ursprünglichen Spiel entwickelt von:"
msgid "Overwrite existing file?"
msgstr ""
msgid "Parameters missing" msgid "Parameters missing"
msgstr "Nicht genug Parameter" msgstr "Nicht genug Parameter"

View File

@ -931,6 +931,9 @@ msgstr "Nouveau"
msgid "New ..." msgid "New ..."
msgstr "Nouveau ..." msgstr "Nouveau ..."
msgid "New Folder"
msgstr ""
msgid "New bot available" msgid "New bot available"
msgstr "Nouveau robot disponible" msgstr "Nouveau robot disponible"
@ -1087,6 +1090,9 @@ msgstr "Montrer le lieu d'un message\\Montrer le lieu du dernier message"
msgid "Original game developed by:" msgid "Original game developed by:"
msgstr "Jeu original développé par :" msgstr "Jeu original développé par :"
msgid "Overwrite existing file?"
msgstr ""
msgid "Parameters missing" msgid "Parameters missing"
msgstr "Pas assez de paramètres" msgstr "Pas assez de paramètres"

View File

@ -912,6 +912,9 @@ msgstr "Nowy"
msgid "New ..." msgid "New ..."
msgstr "Nowy ..." msgstr "Nowy ..."
msgid "New Folder"
msgstr ""
msgid "New bot available" msgid "New bot available"
msgstr "Dostępny nowy robot" msgstr "Dostępny nowy robot"
@ -1068,6 +1071,9 @@ msgstr "Miejsce nadania wiadomości\\Pokazuje skąd została wysłana ostatnia w
msgid "Original game developed by:" msgid "Original game developed by:"
msgstr "Twórcy oryginalnej gry:" msgstr "Twórcy oryginalnej gry:"
msgid "Overwrite existing file?"
msgstr ""
msgid "Parameters missing" msgid "Parameters missing"
msgstr "Brak wymaganego parametru" msgstr "Brak wymaganego parametru"

View File

@ -937,6 +937,9 @@ msgstr "Новый"
msgid "New ..." msgid "New ..."
msgstr "Новый ..." msgstr "Новый ..."
msgid "New Folder"
msgstr ""
msgid "New bot available" msgid "New bot available"
msgstr "Доступен новый бот" msgstr "Доступен новый бот"
@ -1093,6 +1096,9 @@ msgstr "Источник сообщения\\Показывает место, о
msgid "Original game developed by:" msgid "Original game developed by:"
msgstr "Оригинальная игра была разработана:" msgstr "Оригинальная игра была разработана:"
msgid "Overwrite existing file?"
msgstr ""
msgid "Parameters missing" msgid "Parameters missing"
msgstr "Отсутствуют параметры" msgstr "Отсутствуют параметры"

View File

@ -537,6 +537,8 @@ set(BASE_SOURCES
ui/displayinfo.h ui/displayinfo.h
ui/displaytext.cpp ui/displaytext.cpp
ui/displaytext.h ui/displaytext.h
ui/filedialog.cpp
ui/filedialog.h
ui/maindialog.cpp ui/maindialog.cpp
ui/maindialog.h ui/maindialog.h
ui/mainmap.cpp ui/mainmap.cpp

View File

@ -167,8 +167,13 @@ void InitializeEventTypeTexts()
EVENT_TYPE_TEXT[EVENT_DIALOG_LABEL3] = "EVENT_DIALOG_LABEL3"; EVENT_TYPE_TEXT[EVENT_DIALOG_LABEL3] = "EVENT_DIALOG_LABEL3";
EVENT_TYPE_TEXT[EVENT_DIALOG_LIST] = "EVENT_DIALOG_LIST"; EVENT_TYPE_TEXT[EVENT_DIALOG_LIST] = "EVENT_DIALOG_LIST";
EVENT_TYPE_TEXT[EVENT_DIALOG_EDIT] = "EVENT_DIALOG_EDIT"; EVENT_TYPE_TEXT[EVENT_DIALOG_EDIT] = "EVENT_DIALOG_EDIT";
EVENT_TYPE_TEXT[EVENT_DIALOG_EDIT2] = "EVENT_DIALOG_EDIT2";
EVENT_TYPE_TEXT[EVENT_DIALOG_CHECK1] = "EVENT_DIALOG_CHECK1"; EVENT_TYPE_TEXT[EVENT_DIALOG_CHECK1] = "EVENT_DIALOG_CHECK1";
EVENT_TYPE_TEXT[EVENT_DIALOG_CHECK2] = "EVENT_DIALOG_CHECK2"; EVENT_TYPE_TEXT[EVENT_DIALOG_CHECK2] = "EVENT_DIALOG_CHECK2";
EVENT_TYPE_TEXT[EVENT_DIALOG_GROUP1] = "EVENT_DIALOG_GROUP1";
EVENT_TYPE_TEXT[EVENT_DIALOG_NEWDIR] = "EVENT_DIALOG_NEWDIR";
EVENT_TYPE_TEXT[EVENT_DIALOG_ACTION] = "EVENT_DIALOG_ACTION";
EVENT_TYPE_TEXT[EVENT_DIALOG_STOP] = "EVENT_DIALOG_STOP";
EVENT_TYPE_TEXT[EVENT_INTERFACE_TRAINER] = "EVENT_INTERFACE_TRAINER"; EVENT_TYPE_TEXT[EVENT_INTERFACE_TRAINER] = "EVENT_INTERFACE_TRAINER";
EVENT_TYPE_TEXT[EVENT_INTERFACE_DEFI] = "EVENT_INTERFACE_DEFI"; EVENT_TYPE_TEXT[EVENT_INTERFACE_DEFI] = "EVENT_INTERFACE_DEFI";

View File

@ -202,8 +202,13 @@ enum EventType
EVENT_DIALOG_LABEL3 = 305, EVENT_DIALOG_LABEL3 = 305,
EVENT_DIALOG_LIST = 306, EVENT_DIALOG_LIST = 306,
EVENT_DIALOG_EDIT = 307, EVENT_DIALOG_EDIT = 307,
EVENT_DIALOG_CHECK1 = 308, EVENT_DIALOG_EDIT2 = 308,
EVENT_DIALOG_CHECK2 = 309, EVENT_DIALOG_CHECK1 = 309,
EVENT_DIALOG_CHECK2 = 310,
EVENT_DIALOG_GROUP1 = 320,
EVENT_DIALOG_NEWDIR = 330,
EVENT_DIALOG_ACTION = 348,
EVENT_DIALOG_STOP = 349,
EVENT_INTERFACE_TRAINER = 400, EVENT_INTERFACE_TRAINER = 400,
EVENT_INTERFACE_DEFI = 401, EVENT_INTERFACE_DEFI = 401,

View File

@ -174,7 +174,7 @@ bool CResourceManager::RemoveDirectory(const std::string& directory)
return false; return false;
} }
std::vector<std::string> CResourceManager::ListFiles(const std::string &directory) std::vector<std::string> CResourceManager::ListFiles(const std::string &directory, bool excludeDirs)
{ {
std::vector<std::string> result; std::vector<std::string> result;
@ -184,6 +184,11 @@ std::vector<std::string> CResourceManager::ListFiles(const std::string &director
for (char **i = files; *i != nullptr; i++) for (char **i = files; *i != nullptr; i++)
{ {
if (excludeDirs)
{
std::string path = CleanPath(directory) + "/" + (*i);
if (PHYSFS_isDirectory(path.c_str())) continue;
}
result.push_back(*i); result.push_back(*i);
} }

View File

@ -60,7 +60,7 @@ public:
static bool RemoveDirectory(const std::string& directory); static bool RemoveDirectory(const std::string& directory);
//! List files contained in directory //! List files contained in directory
static std::vector<std::string> ListFiles(const std::string &directory); static std::vector<std::string> ListFiles(const std::string &directory, bool excludeDirs = false);
//! List directories contained in directory //! List directories contained in directory
static std::vector<std::string> ListDirectories(const std::string &directory); static std::vector<std::string> ListDirectories(const std::string &directory);

View File

@ -124,6 +124,7 @@ void InitializeRestext()
stringsText[RT_IO_DIR] = TR("Folder:"); stringsText[RT_IO_DIR] = TR("Folder:");
stringsText[RT_IO_PRIVATE] = TR("Private\\Private folder"); stringsText[RT_IO_PRIVATE] = TR("Private\\Private folder");
stringsText[RT_IO_PUBLIC] = TR("Public\\Common folder"); stringsText[RT_IO_PUBLIC] = TR("Public\\Common folder");
stringsText[RT_IO_REPLACE] = TR("Overwrite existing file?");
stringsText[RT_GENERIC_DEV1] = TR("Original game developed by:"); stringsText[RT_GENERIC_DEV1] = TR("Original game developed by:");
stringsText[RT_GENERIC_DEV2] = TR("epsitec.com"); stringsText[RT_GENERIC_DEV2] = TR("epsitec.com");
@ -162,6 +163,7 @@ void InitializeRestext()
stringsEvent[EVENT_DIALOG_OK] = TR("OK"); stringsEvent[EVENT_DIALOG_OK] = TR("OK");
stringsEvent[EVENT_DIALOG_CANCEL] = TR("Cancel"); stringsEvent[EVENT_DIALOG_CANCEL] = TR("Cancel");
stringsEvent[EVENT_DIALOG_NEWDIR] = TR("New Folder");
stringsEvent[EVENT_INTERFACE_TRAINER] = TR("Exercises\\Programming exercises"); stringsEvent[EVENT_INTERFACE_TRAINER] = TR("Exercises\\Programming exercises");
stringsEvent[EVENT_INTERFACE_DEFI] = TR("Challenges\\Programming challenges"); stringsEvent[EVENT_INTERFACE_DEFI] = TR("Challenges\\Programming challenges");

View File

@ -118,6 +118,7 @@ enum ResTextType
RT_IO_DIR = 154, RT_IO_DIR = 154,
RT_IO_PRIVATE = 155, RT_IO_PRIVATE = 155,
RT_IO_PUBLIC = 156, RT_IO_PUBLIC = 156,
RT_IO_REPLACE = 157,
RT_GENERIC_DEV1 = 170, RT_GENERIC_DEV1 = 170,
RT_GENERIC_DEV2 = 171, RT_GENERIC_DEV2 = 171,

1314
src/ui/filedialog.cpp Normal file

File diff suppressed because it is too large Load Diff

179
src/ui/filedialog.h Normal file
View File

@ -0,0 +1,179 @@
/*
* This file is part of the Colobot: Gold Edition source code
* Copyright (C) 2001-2016, Daniel Roux, EPSITEC SA & TerranovaTeam
* 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
*/
#pragma once
#include "common/event.h"
#include "math/point.h"
#include <string>
#include <vector>
struct Event;
namespace Ui
{
class CEdit;
class CInterface;
class CFileDialog
{
public:
CFileDialog();
~CFileDialog();
void StartDialog();
void StopDialog();
bool EventProcess(const Event &event);
enum class Type
{
None,
Open,
Save,
};
void SetDialogType(CFileDialog::Type type) { m_dialogtype = type; }
CFileDialog::Type GetDialogType() { return m_dialogtype; }
// Set EventType for this dialog.
// If not set, a unique EventType will be used.
void SetWindowEvent(EventType type) { m_windowEvent = type; }
EventType GetWindowEvent() { return m_windowEvent; }
void SetWindowPos(Math::Point pos) { m_windowPos = pos; }
Math::Point GetWindowPos() { return m_windowPos; }
void SetWindowDim(Math::Point dim) { m_windowDim = dim; }
Math::Point GetWindowDim() { return m_windowDim; }
void SetWindowTitle(const std::string& name) { m_title = name; }
void SetUsePublicPrivate(bool usePublic);
void SetPublic(bool bPublic);
bool GetPublic();
void SetPublicFolder(const std::string& dir);
void SetPrivateFolder(const std::string& dir);
void SetBasePath(const std::string& dir);
std::string GetBasePath();
void SetSubFolderPath(const std::string& dir);
std::string GetSubFolderPath();
void SetAutoExtension(const std::string& ext) { m_extension = ext; }
void AddOptionalExtension(const std::string& ext) { m_extlist.push_back(ext); }
void SetFilename(const std::string& name);
std::string GetFilename();
void SetConfirmOverwrite(bool doCheck) { m_confirmOverwrite = doCheck; }
private:
void StartFileDialog(CFileDialog::Type type);
void AdjustDialog();
void PopulateList();
void GetListChoice();
void SearchList(const std::string &text, bool dirOnly = false);
void UpdateAction();
void UpdatePathLabel();
void UpdatePublic(bool bPublic);
void OpenFolder();
bool StartNewFolderMode();
bool StopNewFolderMode(bool bCancel = false);
bool EventNewFolder(const Event &event);
void UpdateNewFolder();
void CreateNewFolder();
bool ListItemIsFolder();
bool DirectoryExists(const std::string &name);
bool CheckFilename(const std::string& name);
bool ActionOpen();
bool ActionSave(bool checkFileExist = false);
bool StartAskOverwrite(const std::string& name);
bool StopAskOverwrite();
bool EventAskOverwrite(const Event &event);
/*!
* \brief Set the text in the file name edit box.
* \param edit Pointer to the edit box.
* \param filename Text to put in the edit box.
*/
void SetFilenameField(CEdit* edit, const std::string& filename);
/*!
* \brief Get the current directory with the current sub-directory appended.
* \param bCreate If true, the directories in question will be created.
* \return A string with the path of current directory, plus the
* current sub-directory if any.
*/
std::string SearchDirectory(bool bCreate);
private:
CEventQueue* m_eventQueue;
CInterface* m_interface;
CFileDialog::Type m_dialogtype = Type::None;
// EventType for this dialog.
// With EVENT_NULL, a unique EventType will be used.
EventType m_windowEvent = EVENT_NULL;
Math::Point m_windowPos;
Math::Point m_windowDim;
std::string m_title = "";
float m_time;
float m_lastTimeClickDir;
bool m_captureClick = false;
bool m_newFolderMode = false;
bool m_askOverwriteMode = false;
bool m_confirmOverwrite = false;
bool m_public;
std::string m_pathPublic = "";
std::string m_pathPrivate = "";
bool m_usePublicPrivate = false;
std::string m_basePath = "";
std::string m_subDirPath = "";
std::string m_filename = "";
//! The extension to add to a filename if needed
std::string m_extension = "";
//! List of extensions accepted as part of a valid file name
std::vector<std::string> m_extlist = {};
};
} // namespace Ui

View File

@ -60,6 +60,7 @@
#include "ui/controls/slider.h" #include "ui/controls/slider.h"
#include "ui/controls/target.h" #include "ui/controls/target.h"
#include "ui/controls/window.h" #include "ui/controls/window.h"
#include "ui/filedialog.h"
#include <stdio.h> #include <stdio.h>
#include <ctime> #include <ctime>
@ -93,7 +94,7 @@ CStudio::CStudio()
m_bRealTime = true; m_bRealTime = true;
m_bRunning = false; m_bRunning = false;
m_fixInfoTextTime = 0.0f; m_fixInfoTextTime = 0.0f;
m_dialog = SD_NULL; m_dialog = nullptr;
m_editCamera = Gfx::CAM_TYPE_NULL; m_editCamera = Gfx::CAM_TYPE_NULL;
} }
@ -112,7 +113,7 @@ bool CStudio::EventProcess(const Event &event)
CEdit* edit; CEdit* edit;
CSlider* slider; CSlider* slider;
if ( m_dialog != SD_NULL ) // dialogue exists? if ( m_dialog != nullptr ) // dialogue exists?
{ {
return EventDialog(event); return EventDialog(event);
} }
@ -150,11 +151,15 @@ bool CStudio::EventProcess(const Event &event)
if ( event.type == EVENT_STUDIO_OPEN ) // open? if ( event.type == EVENT_STUDIO_OPEN ) // open?
{ {
StartDialog(SD_OPEN); pw->SetFocus(edit); // focus on edit box after dialog is closed
StartDialog(event);
return true;
} }
if ( event.type == EVENT_STUDIO_SAVE ) // save? if ( event.type == EVENT_STUDIO_SAVE ) // save?
{ {
StartDialog(SD_SAVE); pw->SetFocus(edit);
StartDialog(event);
return true;
} }
if ( event.type == EVENT_STUDIO_UNDO ) // undo? if ( event.type == EVENT_STUDIO_UNDO ) // undo?
@ -182,13 +187,11 @@ bool CStudio::EventProcess(const Event &event)
ViewEditScript(); ViewEditScript();
} }
if ( event.type == EVENT_STUDIO_TOOL && // instructions? if ( event.type == EVENT_STUDIO_TOOL ) // instructions?
m_dialog == SD_NULL )
{ {
m_main->StartDisplayInfo(SATCOM_HUSTON, false); m_main->StartDisplayInfo(SATCOM_HUSTON, false);
} }
if ( event.type == EVENT_STUDIO_HELP && // help? if ( event.type == EVENT_STUDIO_HELP ) // help?
m_dialog == SD_NULL )
{ {
m_main->StartDisplayInfo(SATCOM_PROG, false); m_main->StartDisplayInfo(SATCOM_PROG, false);
} }
@ -976,6 +979,124 @@ void CStudio::SetInfoText(std::string text, bool bClickable)
} }
} }
// Beginning of the display of a dialogue.
void CStudio::StartDialog(const Event &event)
{
if ( event.type == EVENT_STUDIO_OPEN )
{
m_dialog = MakeUnique<CFileDialog>();
m_dialog->SetDialogType(CFileDialog::Type::Open);
}
if ( event.type == EVENT_STUDIO_SAVE )
{
m_dialog = MakeUnique<CFileDialog>();
m_dialog->SetDialogType(CFileDialog::Type::Save);
}
if ( m_dialog != nullptr ) // a dialog was created?
{
m_main->SetSatComLock(true); // impossible to use the SatCom
m_dialog->SetWindowEvent(EVENT_WINDOW9);
m_dialog->SetWindowPos(m_dialogPos);
m_dialog->SetWindowDim(m_dialogDim);
m_dialog->SetAutoExtension(".cbot");
m_dialog->AddOptionalExtension(".txt");
m_dialog->SetUsePublicPrivate(true);
m_dialog->SetPublic(m_settings->GetIOPublic());
m_dialog->SetPublicFolder("program");
m_dialog->SetPrivateFolder(m_main->GetPlayerProfile()->GetSaveFile("program"));
if ( event.type == EVENT_STUDIO_SAVE )
{
m_dialog->SetConfirmOverwrite(true);
// filename in CScript may include sub-folder
std::string filename = m_script->GetFilename();
if (!filename.empty())
{
size_t pos = filename.find_last_of("/");
if (pos != std::string::npos) // split subfolder from filename
{
m_dialog->SetSubFolderPath(filename.substr(0, pos));
filename = filename.substr(pos+1, filename.length()-pos-1);
}
}
m_dialog->SetFilename(filename);
}
m_dialog->StartDialog();
}
}
// End of the display of a dialogue.
void CStudio::StopDialog()
{
if ( m_dialog != nullptr ) // a dialog exists?
{
m_settings->SetIOPublic(m_dialog->GetPublic());
m_dialogPos = m_dialog->GetWindowPos();
m_dialogDim = m_dialog->GetWindowDim();
m_dialog->StopDialog();
m_dialog.reset();
}
m_main->SetSatComLock(false); // possible to use the SatCom
}
// Management of events for a dialogue.
bool CStudio::EventDialog(const Event &event)
{
if ( m_dialog != nullptr ) // a dialog exists?
{
if ( event.type == EVENT_DIALOG_STOP )
{
StopDialog();
return true;
}
if (event.type == EVENT_DIALOG_ACTION) // operation complete ?
{
CWindow* pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW3));
if ( pw == nullptr ) return false;
CEdit* pe = static_cast< CEdit* >(pw->SearchControl(EVENT_STUDIO_EDIT));
if ( pe == nullptr ) return false;
std::string path = m_dialog->GetBasePath() + "/"; // public/private folder
std::string subpath = m_dialog->GetSubFolderPath();// sub-folder
// filename in CScript may include sub-folder
std::string filename = subpath.empty() ? "" : subpath + "/";
filename += m_dialog->GetFilename();
CFileDialog::Type type = m_dialog->GetDialogType();
if ( type == CFileDialog::Type::Save )
{
if ( !pe->WriteText(path + filename) ) return true;
if ( !m_program->readOnly )
m_script->SetFilename(filename);
}
else if ( type == CFileDialog::Type::Open )
{
if ( !pe->ReadText(path + filename) ) return true;
m_script->SetFilename(filename);
ColorizeScript(pe);
}
StopDialog();
return true;
}
return m_dialog->EventProcess(event);
}
return true;
}
// Changing the size of a editing program. // Changing the size of a editing program.
@ -1097,614 +1218,4 @@ void CStudio::UpdateButtons()
button->SetState(STATE_ENABLE, !m_program->readOnly); button->SetState(STATE_ENABLE, !m_program->readOnly);
} }
} // namespace Ui
// Beginning of the display of a dialogue.
void CStudio::StartDialog(StudioDialog type)
{
CWindow* pw;
CButton* pb;
CCheck* pc;
CLabel* pla;
CList* pli;
CEdit* pe;
Math::Point pos, dim;
std::string name;
m_dialog = type;
pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW0));
if ( pw != nullptr ) pw->ClearState(STATE_ENABLE);
pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW1));
if ( pw != nullptr ) pw->ClearState(STATE_ENABLE);
pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW3));
if ( pw != nullptr ) pw->ClearState(STATE_ENABLE);
pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW3));
if ( pw != nullptr ) pw->ClearState(STATE_ENABLE);
pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW4));
if ( pw != nullptr ) pw->ClearState(STATE_ENABLE);
pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW5));
if ( pw != nullptr ) pw->ClearState(STATE_ENABLE);
//pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW6));
//if ( pw != nullptr ) pw->ClearState(STATE_VISIBLE);
pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW7));
if ( pw != nullptr ) pw->ClearState(STATE_ENABLE);
pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW8));
if ( pw != nullptr ) pw->ClearState(STATE_ENABLE);
if ( m_dialog == SD_OPEN ||
m_dialog == SD_SAVE )
{
pos = m_settings->GetIOPos();
dim = m_settings->GetIODim();
}
//? pw = m_interface->CreateWindows(pos, dim, 8, EVENT_WINDOW9);
pw = m_interface->CreateWindows(pos, dim, m_dialog==SD_OPEN?14:13, EVENT_WINDOW9);
pw->SetState(STATE_SHADOW);
pw->SetMovable(true);
pw->SetClosable(true);
pw->SetMinDim(Math::Point(320.0f/640.0f, (121.0f+18.0f*4)/480.0f));
if ( m_dialog == SD_OPEN ) GetResource(RES_TEXT, RT_IO_OPEN, name);
if ( m_dialog == SD_SAVE ) GetResource(RES_TEXT, RT_IO_SAVE, name);
pw->SetName(name);
pos = Math::Point(0.0f, 0.0f);
dim = Math::Point(0.0f, 0.0f);
if ( m_dialog == SD_OPEN ||
m_dialog == SD_SAVE )
{
GetResource(RES_TEXT, RT_IO_LIST, name);
pla = pw->CreateLabel(pos, dim, 0, EVENT_DIALOG_LABEL1, name);
pla->SetTextAlign(Gfx::TEXT_ALIGN_LEFT);
pli = pw->CreateList(pos, dim, 0, EVENT_DIALOG_LIST);
pli->SetState(STATE_SHADOW);
GetResource(RES_TEXT, RT_IO_NAME, name);
pla = pw->CreateLabel(pos, dim, 0, EVENT_DIALOG_LABEL2, name);
pla->SetTextAlign(Gfx::TEXT_ALIGN_LEFT);
pe = pw->CreateEdit(pos, dim, 0, EVENT_DIALOG_EDIT);
pe->SetState(STATE_SHADOW);
GetResource(RES_TEXT, RT_IO_DIR, name);
pla = pw->CreateLabel(pos, dim, 0, EVENT_DIALOG_LABEL3, name);
pla->SetTextAlign(Gfx::TEXT_ALIGN_LEFT);
pc = pw->CreateCheck(pos, dim, 0, EVENT_DIALOG_CHECK1);
GetResource(RES_TEXT, RT_IO_PRIVATE, name);
pc->SetName(name);
pc->SetState(STATE_SHADOW);
pc = pw->CreateCheck(pos, dim, 0, EVENT_DIALOG_CHECK2);
GetResource(RES_TEXT, RT_IO_PUBLIC, name);
pc->SetName(name);
pc->SetState(STATE_SHADOW);
pb = pw->CreateButton(pos, dim, -1, EVENT_DIALOG_OK);
pb->SetState(STATE_SHADOW);
if ( m_dialog == SD_OPEN ) GetResource(RES_TEXT, RT_IO_OPEN, name);
if ( m_dialog == SD_SAVE ) GetResource(RES_TEXT, RT_IO_SAVE, name);
pb->SetName(name);
pb = pw->CreateButton(pos, dim, -1, EVENT_DIALOG_CANCEL);
pb->SetState(STATE_SHADOW);
GetResource(RES_EVENT, EVENT_DIALOG_CANCEL, name);
pb->SetName(name);
AdjustDialog();
UpdateDialogList();
UpdateDialogPublic();
UpdateDialogAction();
if ( m_dialog == SD_SAVE )
{
SetFilenameField(pe, m_script->GetFilename());
UpdateChangeEdit();
}
pe->SetCursor(999, 0); // selects all
m_interface->SetFocus(pe);
}
m_main->SetSatComLock(true); // impossible to use the SatCom
}
// End of the display of a dialogue.
void CStudio::StopDialog()
{
CWindow* pw;
if ( m_dialog == SD_NULL ) return;
m_dialog = SD_NULL;
pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW0));
if ( pw != nullptr ) pw->SetState(STATE_ENABLE);
pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW1));
if ( pw != nullptr ) pw->SetState(STATE_ENABLE);
pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW2));
if ( pw != nullptr ) pw->SetState(STATE_ENABLE);
pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW3));
if ( pw != nullptr ) pw->SetState(STATE_ENABLE);
pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW4));
if ( pw != nullptr ) pw->SetState(STATE_ENABLE);
pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW5));
if ( pw != nullptr ) pw->SetState(STATE_ENABLE);
//pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW6));
//if ( pw != nullptr ) pw->SetState(STATE_VISIBLE);
pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW7));
if ( pw != nullptr ) pw->SetState(STATE_ENABLE);
pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW8));
if ( pw != nullptr ) pw->SetState(STATE_ENABLE);
m_interface->DeleteControl(EVENT_WINDOW9);
m_main->SetSatComLock(false); // possible to use the SatCom
}
// Adjust all controls of dialogue after a change in geometry.
void CStudio::AdjustDialog()
{
CWindow* pw;
CButton* pb;
CCheck* pc;
CLabel* pla;
CList* pli;
CEdit* pe;
Math::Point wpos, wdim, ppos, ddim;
int nli, nch;
std::string name;
pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW9));
if ( pw == nullptr ) return;
m_dialogPos = wpos = pw->GetPos();
m_dialogDim = wdim = pw->GetDim();
pw->SetPos(wpos); // to move the buttons on the titlebar
if ( m_dialog == SD_OPEN ||
m_dialog == SD_SAVE )
{
ppos.x = wpos.x+10.0f/640.0f;
ppos.y = wpos.y+wdim.y-55.0f/480.0f;
ddim.x = wdim.x-20.0f/640.0f;
ddim.y = 20.0f/480.0f;
pla = static_cast< CLabel* >(pw->SearchControl(EVENT_DIALOG_LABEL1));
if ( pla != nullptr )
{
pla->SetPos(ppos);
pla->SetDim(ddim);
}
nli = static_cast<int>((wdim.y-120.0f/480.0f)/(18.0f/480.0f));
ddim.y = nli*18.0f/480.0f+9.0f/480.0f;
ppos.y = wpos.y+wdim.y-48.0f/480.0f-ddim.y;
pli = static_cast< CList* >(pw->SearchControl(EVENT_DIALOG_LIST));
if ( pli != nullptr )
{
pli->SetPos(ppos);
pli->SetDim(ddim);
pli->SetTabs(0, ddim.x-(50.0f+140.0f+16.0f)/640.0f);
pli->SetTabs(1, 50.0f/640.0f, Gfx::TEXT_ALIGN_RIGHT);
pli->SetTabs(2, 140.0f/640.0f);
//? pli->ShowSelect();
}
ppos.y = wpos.y+30.0f/480.0f;
ddim.x = 50.0f/640.0f;
ddim.y = 20.0f/480.0f;
pla = static_cast< CLabel* >(pw->SearchControl(EVENT_DIALOG_LABEL2));
if ( pla != nullptr )
{
pla->SetPos(ppos);
pla->SetDim(ddim);
}
ppos.x += 50.0f/640.0f;
ppos.y = wpos.y+36.0f/480.0f;
ddim.x = wdim.x-170.0f/640.0f;
pe = static_cast< CEdit* >(pw->SearchControl(EVENT_DIALOG_EDIT));
if ( pe != nullptr )
{
pe->SetPos(ppos);
pe->SetDim(ddim);
nch = static_cast< int >((ddim.x*640.0f-22.0f)/5.75f);
name = pe->GetText(nch); // truncates the text according to max
pe->SetMaxChar(nch);
pe->SetText(name);
}
ppos.x = wpos.x+10.0f/640.0f;
ppos.y = wpos.y+5.0f/480.0f;
ddim.x = 50.0f/640.0f;
ddim.y = 16.0f/480.0f;
pla = static_cast< CLabel* >(pw->SearchControl(EVENT_DIALOG_LABEL3));
if ( pla != nullptr )
{
pla->SetPos(ppos);
pla->SetDim(ddim);
}
ppos.x += 50.0f/640.0f;
ppos.y = wpos.y+12.0f/480.0f;
ddim.x = 70.0f/640.0f;
pc = static_cast< CCheck* >(pw->SearchControl(EVENT_DIALOG_CHECK1));
if ( pc != nullptr )
{
pc->SetPos(ppos);
pc->SetDim(ddim);
}
ppos.x += 80.0f/640.0f;
pc = static_cast< CCheck* >(pw->SearchControl(EVENT_DIALOG_CHECK2));
if ( pc != nullptr )
{
pc->SetPos(ppos);
pc->SetDim(ddim);
}
ppos.x = wpos.x+wdim.x-100.0f/640.0f;
ppos.y = wpos.y+34.0f/480.0f;
ddim.x = 90.0f/640.0f;
ddim.y = 23.0f/480.0f;
pb = static_cast< CButton* >(pw->SearchControl(EVENT_DIALOG_OK));
if ( pb != nullptr )
{
pb->SetPos(ppos);
pb->SetDim(ddim);
}
ppos.y -= 26.0f/480.0f;
pb = static_cast< CButton* >(pw->SearchControl(EVENT_DIALOG_CANCEL));
if ( pb != nullptr )
{
pb->SetPos(ppos);
pb->SetDim(ddim);
}
}
}
// Management of the event of a dialogue.
bool CStudio::EventDialog(const Event &event)
{
if ( event.type == EVENT_WINDOW9 ) // window is moved?
{
AdjustDialog();
return true;
}
if ( m_dialog == SD_OPEN ||
m_dialog == SD_SAVE )
{
if ( event.type == EVENT_DIALOG_LIST )
{
UpdateChangeList();
}
if ( event.type == EVENT_DIALOG_EDIT )
{
UpdateChangeEdit();
}
if ( event.type == EVENT_DIALOG_CHECK1 ) // private?
{
m_settings->SetIOPublic(false);
UpdateDialogPublic();
UpdateDialogList();
}
if ( event.type == EVENT_DIALOG_CHECK2 ) // public?
{
m_settings->SetIOPublic(true);
UpdateDialogPublic();
UpdateDialogList();
}
}
if ( event.type == EVENT_DIALOG_OK ||
(event.type == EVENT_KEY_DOWN && event.GetData<KeyEventData>()->key == KEY(RETURN)) )
{
if ( m_dialog == SD_OPEN )
{
if ( !ReadProgram() ) return true;
}
if ( m_dialog == SD_SAVE )
{
if ( !WriteProgram() ) return true;
}
StopDialog();
return true;
}
CWindow* pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW9));
if ( pw == nullptr ) return false;
if ( event.type == EVENT_DIALOG_CANCEL ||
(event.type == EVENT_KEY_DOWN && event.GetData<KeyEventData>()->key == KEY(ESCAPE)) ||
event.type == pw->GetEventTypeClose() )
{
StopDialog();
return true;
}
return true;
}
// Updates the name after a click in the list.
void CStudio::UpdateChangeList()
{
CWindow* pw;
CList* pl;
CEdit* pe;
pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW9));
if ( pw == nullptr ) return;
pl = static_cast< CList* >(pw->SearchControl(EVENT_DIALOG_LIST));
if ( pl == nullptr ) return;
pe = static_cast< CEdit* >(pw->SearchControl(EVENT_DIALOG_EDIT));
if ( pe == nullptr ) return;
std::string name = pl->GetItemName(pl->GetSelect());
name = name.substr(0, name.find_first_of("\t"));
SetFilenameField(pe, name);
pe->SetCursor(999, 0); // selects all
m_interface->SetFocus(pe);
UpdateDialogAction();
}
void CStudio::SetFilenameField(CEdit* edit, const std::string& filename)
{
std::string name = filename;
if (name.length() > static_cast<unsigned int>(edit->GetMaxChar()))
{
if (name.substr(name.length()-4) == ".txt")
name = name.substr(0, name.length()-4);
if (name.length() > static_cast<unsigned int>(edit->GetMaxChar()))
{
GetLogger()->Warn("Tried to load too long filename!\n");
name = name.substr(0, edit->GetMaxChar()); // truncates according to max length
}
}
edit->SetText(name);
}
// Updates the list after a change in name.
void CStudio::UpdateChangeEdit()
{
CWindow* pw;
CList* pl;
pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW9));
if ( pw == nullptr ) return;
pl = static_cast< CList* >(pw->SearchControl(EVENT_DIALOG_LIST));
if ( pl == nullptr ) return;
pl->SetSelect(-1);
UpdateDialogAction();
}
// Updates the action button.
void CStudio::UpdateDialogAction()
{
CWindow* pw;
CEdit* pe;
CButton* pb;
std::string name;
int len, i;
bool bError;
pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW9));
if ( pw == nullptr ) return;
pe = static_cast< CEdit* >(pw->SearchControl(EVENT_DIALOG_EDIT));
if ( pe == nullptr ) return;
pb = static_cast< CButton* >(pw->SearchControl(EVENT_DIALOG_OK));
if ( pb == nullptr ) return;
name = pe->GetText(100);
len = name.size();
if ( len == 0 )
{
bError = true;
}
else
{
bError = false;
for ( i=0 ; i<len ; i++ )
{
if ( name[i] == '*' ||
name[i] == '?' ||
name[i] == ':' ||
name[i] == '<' ||
name[i] == '>' ||
name[i] == '"' ||
name[i] == '|' ||
name[i] == '/' ||
name[i] == '\\' ) bError = true;
}
}
pb->SetState(STATE_ENABLE, !bError);
}
// Updates the buttons private/public.
void CStudio::UpdateDialogPublic()
{
CWindow* pw;
CCheck* pc;
CLabel* pl;
pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW9));
if ( pw == nullptr ) return;
pc = static_cast< CCheck* >(pw->SearchControl(EVENT_DIALOG_CHECK1));
if ( pc != nullptr )
{
pc->SetState(STATE_CHECK, !m_settings->GetIOPublic());
}
pc = static_cast< CCheck* >(pw->SearchControl(EVENT_DIALOG_CHECK2));
if ( pc != nullptr )
{
pc->SetState(STATE_CHECK, m_settings->GetIOPublic());
}
pl = static_cast< CLabel* >(pw->SearchControl(EVENT_DIALOG_LABEL1));
if ( pl != nullptr )
{
// GetResource(RES_TEXT, RT_IO_LIST, name); // TODO: unused?
pl->SetName(SearchDirectory(false), false);
}
}
// Fills the list with all programs saved.
void CStudio::UpdateDialogList()
{
CWindow* pw;
CList* pl;
int i = 0;
char timestr[100];
pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW9));
if ( pw == nullptr ) return;
pl = static_cast< CList* >(pw->SearchControl(EVENT_DIALOG_LIST));
if ( pl == nullptr ) return;
pl->Flush();
if (!CResourceManager::DirectoryExists(SearchDirectory(false)))
return;
std::vector<std::string> programs = CResourceManager::ListFiles(SearchDirectory(false));
for (auto& prog : programs)
{
std::ostringstream temp;
time_t now = CResourceManager::GetLastModificationTime(SearchDirectory(false) + prog);
strftime(timestr, 99, "%x %X", localtime(&now));
temp << prog << '\t' << CResourceManager::GetFileSize(SearchDirectory(false) + prog) << " \t" << timestr;
pl->SetItemName(i++, temp.str().c_str());
}
}
// Constructs the name of the folder or open/save.
// If the folder does not exist, it will be created.
std::string CStudio::SearchDirectory(bool bCreate)
{
std::string dir;
if ( m_settings->GetIOPublic() )
{
dir = "program";
}
else
{
dir = m_main->GetPlayerProfile()->GetSaveFile("program");
}
if ( bCreate )
{
if (!CResourceManager::DirectoryExists(dir))
CResourceManager::CreateDirectory(dir);
}
return dir+"/";
}
// Reads a new program.
bool CStudio::ReadProgram()
{
CWindow* pw;
CEdit* pe;
std::string filename;
std::string dir;
size_t p;
pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW9));
if ( pw == nullptr ) return false;
pe = static_cast< CEdit* >(pw->SearchControl(EVENT_DIALOG_EDIT));
if ( pe == nullptr ) return false;
filename = pe->GetText(100);
if ( filename.empty() ) return false;
p = filename.find(".txt");
if ( p == std::string::npos )
{
filename += ".txt";
}
dir = SearchDirectory(true);
dir += filename;
pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW3));
if ( pw == nullptr ) return false;
pe = static_cast< CEdit* >(pw->SearchControl(EVENT_STUDIO_EDIT));
if ( pe == nullptr ) return false;
if ( !pe->ReadText(dir) ) return false;
m_script->SetFilename(filename);
ColorizeScript(pe);
return true;
}
// Writes the current program.
bool CStudio::WriteProgram()
{
CWindow* pw;
CEdit* pe;
std::string filename;
std::string dir;
size_t p;
pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW9));
if ( pw == nullptr ) return false;
pe = static_cast< CEdit* >(pw->SearchControl(EVENT_DIALOG_EDIT));
if ( pe == nullptr ) return false;
filename = pe->GetText(100);
if ( filename.empty() ) return false;
p = filename.find(".txt");
if ( p == std::string::npos )
{
filename += ".txt";
}
dir = SearchDirectory(true);
dir += filename;
pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW3));
if ( pw == nullptr ) return false;
pe = static_cast< CEdit* >(pw->SearchControl(EVENT_STUDIO_EDIT));
if ( pe == nullptr ) return false;
if ( !pe->WriteText(dir) ) return false;
m_script->SetFilename(filename);
return true;
}
}

View File

@ -37,16 +37,7 @@ namespace Ui
class CEdit; class CEdit;
class CInterface; class CInterface;
class CFileDialog;
enum StudioDialog
{
SD_NULL,
SD_OPEN,
SD_SAVE,
SD_FIND,
SD_REPLACE,
};
class CStudio class CStudio
@ -71,20 +62,9 @@ protected:
void UpdateFlux(); void UpdateFlux();
void UpdateButtons(); void UpdateButtons();
void StartDialog(StudioDialog type); void StartDialog(const Event &event);
void StopDialog(); void StopDialog();
void AdjustDialog();
bool EventDialog(const Event &event); bool EventDialog(const Event &event);
void UpdateChangeList();
void UpdateChangeEdit();
void UpdateDialogAction();
void UpdateDialogPublic();
void UpdateDialogList();
std::string SearchDirectory(bool bCreate);
bool ReadProgram();
bool WriteProgram();
void SetFilenameField(CEdit* edit, const std::string& filename);
protected: protected:
Gfx::CEngine* m_engine; Gfx::CEngine* m_engine;
@ -121,7 +101,7 @@ protected:
ActivePause* m_runningPause = nullptr; ActivePause* m_runningPause = nullptr;
std::string m_helpFilename; std::string m_helpFilename;
StudioDialog m_dialog; std::unique_ptr<CFileDialog> m_dialog;
}; };