// DasherInterface.cpp // ///////////////////////////////////////////////////////////////////////////// // // Copyright (c) 2002 Iain Murray // ///////////////////////////////////////////////////////////////////////////// #include "DasherInterface.h" //#include "EnglishAlphabet.h" #include "CustomAlphabet.h" #include "DasherViewSquare.h" #include "PPMLanguageModel.h" #include namespace { #include "stdio.h" } using namespace Dasher; using namespace std; const string CDasherInterface::EmptyString = ""; CDasherInterface::CDasherInterface() : m_Alphabet(0), m_LanguageModel(0), m_DasherModel(0), m_DashEditbox(0), m_DasherScreen(0), m_DasherView(0), m_SettingsStore(0), m_SettingsUI(0), m_AlphIO(0), TrainContext(0), AlphabetID(""), LanguageModelID(-1), ViewID(-1), m_MaxBitRate(-1), m_DrawKeyboard(false), m_Orientation(Opts::LeftToRight), m_UserLocation("usr_"), m_SystemLocation("sys_"), m_TrainFile(""), m_DasherFont(""), m_EditFont(""), m_EditFontSize(0) { } CDasherInterface::~CDasherInterface() { if (m_LanguageModel) m_LanguageModel->ReleaseNodeContext(TrainContext); delete m_DasherModel; // The order of some of these deletions matters delete m_LanguageModel; // eg DasherModel has a pointer to LanguageModel. delete m_Alphabet; // DM baulks if LM is deleted before it is. delete m_DasherView; // Do NOT delete Edit box or Screen. This class did not create them. } void CDasherInterface::SetSettingsStore(CSettingsStore* SettingsStore) { delete m_SettingsStore; m_SettingsStore = SettingsStore; this->SettingsDefaults(m_SettingsStore); } void CDasherInterface::SetSettingsUI(CDasherSettingsInterface* SettingsUI) { delete m_SettingsUI; m_SettingsUI = SettingsUI; //this->SettingsDefaults(m_SettingsStore); m_SettingsUI->SettingsDefaults(m_SettingsStore); } void CDasherInterface::SetUserLocation(std::string UserLocation) { // Nothing clever updates. (At the moment) it is assumed that // this is set before anything much happens and that it does // not require changing. m_UserLocation = UserLocation; if (m_Alphabet!=0) m_TrainFile = m_UserLocation + m_Alphabet->GetTrainingFile(); } void CDasherInterface::SetSystemLocation(std::string SystemLocation) { // Nothing clever updates. (At the moment) it is assumed that // this is set before anything much happens and that it does // not require changing. m_SystemLocation = SystemLocation; } void CDasherInterface::CreateDasherModel() { if (m_DashEditbox!=0 && m_LanguageModel!=0) { delete m_DasherModel; m_DasherModel = new CDasherModel(m_DashEditbox, m_LanguageModel, m_Dimensions); if (m_MaxBitRate>=0) m_DasherModel->SetMaxBitrate(m_MaxBitRate); if (ViewID!=-1) ChangeView(ViewID); } } void CDasherInterface::Start() { if (m_DasherModel!=0) m_DasherModel->Start(); } void CDasherInterface::PauseAt(int MouseX, int MouseY) { if (m_DasherView!=0) m_DasherView->FlushAt(MouseX, MouseY); if (m_DashEditbox!=0) { m_DashEditbox->write_to_file(); if (m_CopyAllOnStop) m_DashEditbox->CopyAll(); } } void CDasherInterface::Unpause(unsigned long Time) { if (m_DashEditbox!=0) m_DashEditbox->unflush(); if (m_DasherModel!=0) m_DasherModel->Reset_framerate(Time); } void CDasherInterface::Redraw() { if (m_DasherView!=0) { m_DasherView->Render(); m_DasherView->Display(); } } void CDasherInterface::TapOn(int MouseX, int MouseY, unsigned long Time) { if (m_DasherView!=0) { m_DasherView->TapOnDisplay(MouseX, MouseY, Time); m_DasherView->Render(); if (m_DrawMouse==true) { m_DasherView->DrawMouse(MouseX, MouseY); } if (m_DrawKeyboard==true) { m_DasherView->DrawKeyboard(); } m_DasherView->Display(); } if (m_DasherModel!=0) m_DasherModel->NewFrame(Time); } void CDasherInterface::ChangeAlphabet(const std::string& NewAlphabetID) { if (m_SettingsUI!=0) m_SettingsUI->ChangeAlphabet(NewAlphabetID); if (m_SettingsStore!=0) m_SettingsStore->SetStringOption(Keys::ALPHABET_ID, NewAlphabetID); AlphabetID = NewAlphabetID; if (!m_AlphIO) m_AlphIO = new CAlphIO(m_SystemLocation, m_UserLocation); CAlphIO::AlphInfo Info = m_AlphIO->GetInfo(NewAlphabetID); CAlphabet* old = m_Alphabet; m_Alphabet = new CCustomAlphabet(Info); // Apply options from alphabet m_TrainFile = m_UserLocation + m_Alphabet->GetTrainingFile(); // Recreate widgets and language model if (m_DashEditbox!=0) m_DashEditbox->SetInterface(this); if (m_DasherScreen!=0) m_DasherScreen->SetInterface(this); if (LanguageModelID!=-1 || m_LanguageModel) ChangeLanguageModel(LanguageModelID); delete old; // only delete old alphabet after telling all other objects not to use it Start(); // We can only change the orientation after we have called // Start, as this will prompt a redraw, which will fail if the // model hasn't been updated for the new alphabet if (m_Orientation==Opts::Alphabet) ChangeOrientation(Opts::Alphabet); Redraw(); } void CDasherInterface::ChangeMaxBitRate(double NewMaxBitRate) { m_MaxBitRate = NewMaxBitRate; if (m_DasherModel!=0) m_DasherModel->SetMaxBitrate(m_MaxBitRate); if (m_SettingsUI!=0) m_SettingsUI->ChangeMaxBitRate(m_MaxBitRate); if (m_SettingsStore!=0) m_SettingsStore->SetLongOption(Keys::MAX_BITRATE_TIMES100, long(m_MaxBitRate*100) ); if (m_DrawKeyboard==true && m_DasherView!=NULL) { m_DasherView->DrawKeyboard(); } } void CDasherInterface::ChangeLanguageModel(unsigned int NewLanguageModelID) { LanguageModelID = NewLanguageModelID; if (m_Alphabet!=0) { if (m_LanguageModel) m_LanguageModel->ReleaseNodeContext(TrainContext); TrainContext = 0; delete m_DasherModel; // Have to delete DasherModel, or removing its LanguageModel will confuse it m_DasherModel = 0; delete m_LanguageModel; // TODO Use LanguageModelID to decide which model to use m_LanguageModel = new CPPMLanguageModel(m_Alphabet,1<<10); TrainContext = m_LanguageModel->GetRootNodeContext(); string T = m_Alphabet->GetTrainingFile(); TrainFile(m_SystemLocation+T); TrainFile(m_UserLocation+T); CreateDasherModel(); } } void CDasherInterface::ChangeScreen() { if (m_DasherView!=0) { m_DasherView->ChangeScreen(m_DasherScreen); } else { if (ViewID!=-1) ChangeView(ViewID); } } void CDasherInterface::ChangeScreen(CDasherScreen* NewScreen) { m_DasherScreen = NewScreen; m_DasherScreen->SetFont(m_DasherFont); m_DasherScreen->SetInterface(this); ChangeScreen(); Redraw(); } void CDasherInterface::ChangeView(unsigned int NewViewID) { //TODO Use DasherViewID ViewID = NewViewID; if (m_DasherScreen!=0 && m_DasherModel!=0) { delete m_DasherView; if (m_Orientation==Opts::Alphabet) m_DasherView = new CDasherViewSquare(m_DasherScreen, *m_DasherModel, GetAlphabetOrientation()); else m_DasherView = new CDasherViewSquare(m_DasherScreen, *m_DasherModel, m_Orientation); } } void CDasherInterface::ChangeOrientation(Opts::ScreenOrientations Orientation) { m_Orientation = Orientation; if (m_DasherView!=0) { if (Orientation==Opts::Alphabet) m_DasherView->ChangeOrientation(GetAlphabetOrientation()); else m_DasherView->ChangeOrientation(Orientation); } if (m_SettingsUI!=0) m_SettingsUI->ChangeOrientation(Orientation); if (m_SettingsStore!=0) m_SettingsStore->SetLongOption(Keys::SCREEN_ORIENTATION, Orientation); } void CDasherInterface::SetFileEncoding(Opts::FileEncodingFormats Encoding) { if (m_SettingsUI!=0) m_SettingsUI->SetFileEncoding(Encoding); if (m_SettingsStore!=0) m_SettingsStore->SetLongOption(Keys::FILE_ENCODING, Encoding); if (m_DashEditbox) m_DashEditbox->SetEncoding(Encoding); } void CDasherInterface::ShowToolbar(bool Value) { if (m_SettingsUI!=0) m_SettingsUI->ShowToolbar(Value); if (m_SettingsStore!=0) m_SettingsStore->SetBoolOption(Keys::SHOW_TOOLBAR, Value); } void CDasherInterface::ShowToolbarText(bool Value) { if (m_SettingsUI!=0) m_SettingsUI->ShowToolbarText(Value); if (m_SettingsStore!=0) m_SettingsStore->SetBoolOption(Keys::SHOW_TOOLBAR_TEXT, Value); } void CDasherInterface::ShowToolbarLargeIcons(bool Value) { if (m_SettingsUI!=0) m_SettingsUI->ShowToolbarLargeIcons(Value); if (m_SettingsStore!=0) m_SettingsStore->SetBoolOption(Keys::SHOW_LARGE_ICONS, Value); } void CDasherInterface::ShowSpeedSlider(bool Value) { if (m_SettingsUI!=0) m_SettingsUI->ShowSpeedSlider(Value); if (m_SettingsStore!=0) m_SettingsStore->SetBoolOption(Keys::SHOW_SLIDER, Value); } void CDasherInterface::FixLayout(bool Value) { if (m_SettingsUI!=0) m_SettingsUI->FixLayout(Value); if (m_SettingsStore!=0) m_SettingsStore->SetBoolOption(Keys::FIX_LAYOUT, Value); } void CDasherInterface::TimeStampNewFiles(bool Value) { if (m_SettingsUI!=0) m_SettingsUI->TimeStampNewFiles(Value); if (m_SettingsStore!=0) m_SettingsStore->SetBoolOption(Keys::TIME_STAMP, Value); if (m_DashEditbox!=0) m_DashEditbox->TimeStampNewFiles(Value); } void CDasherInterface::CopyAllOnStop(bool Value) { m_CopyAllOnStop = Value; if (m_SettingsUI!=0) m_SettingsUI->CopyAllOnStop(Value); if (m_SettingsStore!=0) m_SettingsStore->SetBoolOption(Keys::COPY_ALL_ON_STOP, Value); } void CDasherInterface::DrawMouse(bool Value) { m_DrawMouse = Value; if (m_SettingsUI!=0) m_SettingsUI->DrawMouse(Value); if (m_SettingsStore!=0) m_SettingsStore->SetBoolOption(Keys::DRAW_MOUSE, Value); } void CDasherInterface::StartOnSpace(bool Value) { m_StartSpace = Value; if (m_SettingsUI!=0) m_SettingsUI->StartOnSpace(Value); if (m_SettingsStore!=0) m_SettingsStore->SetBoolOption(Keys::START_SPACE, Value); } void CDasherInterface::StartOnLeft(bool Value) { m_StartLeft = Value; if (m_SettingsUI!=0) m_SettingsUI->StartOnLeft(Value); if (m_SettingsStore!=0) m_SettingsStore->SetBoolOption(Keys::START_MOUSE, Value); } void CDasherInterface::KeyControl(bool Value) { m_KeyControl = Value; if (m_SettingsUI!=0) m_SettingsUI->KeyControl(Value); if (m_SettingsStore!=0) m_SettingsStore->SetBoolOption(Keys::KEY_CONTROL, Value); } void CDasherInterface::WindowPause(bool Value) { m_KeyControl = Value; if (m_SettingsUI!=0) m_SettingsUI->WindowPause(Value); if (m_SettingsStore!=0) m_SettingsStore->SetBoolOption(Keys::WINDOW_PAUSE, Value); } void CDasherInterface::SetEditFont(string Name, long Size) { m_EditFont = Name; m_EditFontSize = Size; if (m_DashEditbox) m_DashEditbox->SetFont(Name, Size); if (m_SettingsUI!=0) m_SettingsUI->SetEditFont(Name, Size); if (m_SettingsStore!=0) { m_SettingsStore->SetStringOption(Keys::EDIT_FONT, Name); m_SettingsStore->SetLongOption(Keys::EDIT_FONT_SIZE, Size); } } void CDasherInterface::SetDasherFont(string Name) { if (m_SettingsStore!=0) m_SettingsStore->SetStringOption(Keys::DASHER_FONT, Name); m_DasherFont = Name; if (m_DasherScreen!=0) m_DasherScreen->SetFont(Name); Redraw(); } void CDasherInterface::SetDasherFontSize(FontSize fontsize) { if (m_SettingsStore!=0) m_SettingsStore->SetLongOption(Keys::DASHER_FONTSIZE, fontsize); if (m_DasherScreen!=0) { m_DasherScreen->SetFontSize(fontsize); } Redraw(); } void CDasherInterface::SetDasherDimensions(bool Value) { m_Dimensions=Value; if (m_SettingsStore!=0) m_SettingsStore->SetBoolOption(Keys::DASHER_DIMENSIONS, Value); if (m_DasherModel!=0) { m_DasherModel->Set_dimensions(Value); } if (m_SettingsUI!=0) { m_SettingsUI->SetDasherDimensions(Value); } } unsigned int CDasherInterface::GetNumberSymbols() { if (m_Alphabet!=0) return m_Alphabet->GetNumberSymbols(); else return 0; } const string& CDasherInterface::GetDisplayText(symbol Symbol) { if (m_Alphabet!=0) return m_Alphabet->GetDisplayText(Symbol); else return EmptyString; } const string& CDasherInterface::GetEditText(symbol Symbol) { if (m_Alphabet!=0) return m_Alphabet->GetText(Symbol); else return EmptyString; } int CDasherInterface::GetTextColour(symbol Symbol) { if (m_Alphabet!=0) return m_Alphabet->GetTextColour(Symbol); else return 0; } Opts::ScreenOrientations CDasherInterface::GetAlphabetOrientation() { return m_Alphabet->GetOrientation(); } Opts::AlphabetTypes CDasherInterface::GetAlphabetType() { return m_Alphabet->GetType(); } const std::string& CDasherInterface::GetTrainFile() { return m_TrainFile; } void CDasherInterface::GetAlphabets(std::vector< std::string >* AlphabetList) { if (!m_AlphIO) m_AlphIO = new CAlphIO(m_SystemLocation, m_UserLocation); m_AlphIO->GetAlphabets(AlphabetList); } const CAlphIO::AlphInfo& CDasherInterface::GetInfo(const std::string& AlphID) { if (!m_AlphIO) m_AlphIO = new CAlphIO(m_SystemLocation, m_UserLocation); return m_AlphIO->GetInfo(AlphID); } void CDasherInterface::SetInfo(const CAlphIO::AlphInfo& NewInfo) { if (!m_AlphIO) m_AlphIO = new CAlphIO(m_SystemLocation, m_UserLocation); m_AlphIO->SetInfo(NewInfo); } void CDasherInterface::DeleteAlphabet(const std::string& AlphID) { if (!m_AlphIO) m_AlphIO = new CAlphIO(m_SystemLocation, m_UserLocation); m_AlphIO->Delete(AlphID); } void CDasherInterface::ChangeEdit() { CreateDasherModel(); if (m_DasherModel!=0) m_DasherModel->Start(); if (m_DasherView!=0) m_DasherView->Render(); } void CDasherInterface::ChangeEdit(CDashEditbox* NewEdit) { m_DashEditbox = NewEdit; m_DashEditbox->SetFont(m_EditFont, m_EditFontSize); m_DashEditbox->SetInterface(this); if (m_SettingsStore!=0) m_DashEditbox->TimeStampNewFiles(m_SettingsStore->GetBoolOption(Keys::TIME_STAMP)); m_DashEditbox->New(""); ChangeEdit(); } void CDasherInterface::Train(string* TrainString, bool IsMore) { m_LanguageModel->LearnText(TrainContext, TrainString, IsMore); return; } /* I've used C style I/O because I found that C++ style I/O bloated the Win32 code enormously. The overhead of loading the buffer into the string instead of reading straight into a string seems to be negligible compared to huge requirements elsewhere. */ void CDasherInterface::TrainFile(string Filename) { if (Filename=="") return; FILE* InputFile; if ( (InputFile = fopen(Filename.c_str(), "r")) == (FILE*)0) return; const int BufferSize = 1024; char InputBuffer[BufferSize]; string StringBuffer; int NumberRead; do { NumberRead = fread(InputBuffer, 1, BufferSize-1, InputFile); InputBuffer[NumberRead] = '\0'; StringBuffer += InputBuffer; if (NumberRead == (BufferSize-1)) { m_LanguageModel->LearnText(TrainContext, &StringBuffer, true); } else { m_LanguageModel->LearnText(TrainContext, &StringBuffer, false); } } while (NumberRead==BufferSize-1); fclose(InputFile); } void CDasherInterface::GetFontSizes(std::vector *FontSizes) { FontSizes->push_back(20); FontSizes->push_back(14); FontSizes->push_back(11); FontSizes->push_back(40); FontSizes->push_back(28); FontSizes->push_back(22); FontSizes->push_back(80); FontSizes->push_back(56); FontSizes->push_back(44); } double CDasherInterface::GetCurCPM() { // return 0; } double CDasherInterface::GetCurFPS() { // return 0; }