[dasher: 40/43] GtkGameDisplay using dasher_editor_internal's GtkTextBuffer
- From: Patrick Welche <pwelche src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dasher: 40/43] GtkGameDisplay using dasher_editor_internal's GtkTextBuffer
- Date: Thu, 23 Jun 2011 18:59:07 +0000 (UTC)
commit 3aa7ffcb6921d278f52c4f41266833c7e4d4a3cd
Author: Alan Lawrence <acl33 inf phy cam ac uk>
Date: Mon Jun 20 16:10:53 2011 +0100
GtkGameDisplay using dasher_editor_internal's GtkTextBuffer
green/strikethrough-red/black text for entered/wrong/target
Src/Gtk2/DasherControl.cpp | 92 ++++++++++++++++++++++++++++++++++-
Src/Gtk2/DasherControl.h | 1 +
Src/Gtk2/GtkDasherControl.cpp | 12 ++---
Src/Gtk2/GtkDasherControl.h | 2 +-
Src/Gtk2/dasher_editor.cpp | 6 ++
Src/Gtk2/dasher_editor.h | 4 ++
Src/Gtk2/dasher_editor_internal.cpp | 17 +++---
7 files changed, 116 insertions(+), 18 deletions(-)
---
diff --git a/Src/Gtk2/DasherControl.cpp b/Src/Gtk2/DasherControl.cpp
index bbba009..3d950e6 100644
--- a/Src/Gtk2/DasherControl.cpp
+++ b/Src/Gtk2/DasherControl.cpp
@@ -10,6 +10,8 @@
#include "../DasherCore/Event.h"
#include "../DasherCore/ModuleManager.h"
#include "dasher_main.h"
+#include "../DasherCore/GameModule.h"
+
#include <fcntl.h>
#include <gtk/gtk.h>
@@ -333,12 +335,14 @@ void CDasherControl::HandleEvent(int iParameter) {
}
void CDasherControl::editOutput(const std::string &strText, CDasherNode *pNode) {
- g_signal_emit_by_name(GTK_WIDGET(m_pDasherControl), "dasher_edit_insert", strText.c_str(), pNode->offset());
+ if (!GetBoolParameter(BP_GAME_MODE)) //GameModule sets editbox directly
+ g_signal_emit_by_name(GTK_WIDGET(m_pDasherControl), "dasher_edit_insert", strText.c_str(), pNode->offset());
CDasherInterfaceBase::editOutput(strText, pNode);
}
void CDasherControl::editDelete(const std::string &strText, CDasherNode *pNode) {
- g_signal_emit_by_name(GTK_WIDGET(m_pDasherControl), "dasher_edit_delete", strText.c_str(), pNode->offset());
+ if (!GetBoolParameter(BP_GAME_MODE)) //GameModule sets editbox directly
+ g_signal_emit_by_name(GTK_WIDGET(m_pDasherControl), "dasher_edit_delete", strText.c_str(), pNode->offset());
CDasherInterfaceBase::editDelete(strText, pNode);
}
@@ -382,6 +386,90 @@ unsigned int CDasherControl::ctrlDelete(bool bForwards, CControlManager::EditDis
return gtk_dasher_control_ctrl_delete(m_pDasherControl,bForwards,dist);
}
+class GtkGameModule : public CGameModule {
+public:
+ GtkGameModule(CSettingsUser *pCreator, CDasherInterfaceBase *pInterface, CDasherView *pView, CDasherModel *pModel, GtkTextBuffer *pBuffer)
+ : CGameModule(pCreator, pInterface, pView, pModel), m_pBuffer(pBuffer) {
+ m_tEntered = gtk_text_buffer_create_tag(m_pBuffer, "entered", "foreground", "#00FF00", NULL);
+ m_tWrong = gtk_text_buffer_create_tag(m_pBuffer, "wrong", "foreground", "#FF0000", "strikethrough", TRUE, NULL);
+ GtkTextIter start,end;
+ gtk_text_buffer_get_start_iter(m_pBuffer, &start);
+ m_mEntered = gtk_text_buffer_create_mark(m_pBuffer, NULL, &start, true);
+ gtk_text_buffer_get_end_iter(m_pBuffer, &end);
+ m_mTarget = gtk_text_buffer_create_mark(m_pBuffer, NULL, &end, false);
+ gtk_text_buffer_delete(m_pBuffer, &start, &end);
+ }
+
+ ~GtkGameModule() {
+ GtkTextTagTable *table = gtk_text_buffer_get_tag_table(m_pBuffer);
+ gtk_text_tag_table_remove(table, m_tEntered);
+ gtk_text_tag_table_remove(table, m_tWrong);
+
+ gtk_text_buffer_delete_mark(m_pBuffer,m_mEntered);
+ gtk_text_buffer_delete_mark(m_pBuffer,m_mTarget);
+ }
+
+ void ChunkGenerated() {
+ string sText;
+ for (vector<symbol>::const_iterator it=targetSyms().begin(); it!=targetSyms().end(); it++)
+ sText += m_pAlph->GetText(*it);
+ gtk_text_buffer_set_text(m_pBuffer, sText.c_str(), -1); //-1 for length = null-terminated
+ GtkTextIter start,end;
+ gtk_text_buffer_get_start_iter(m_pBuffer, &start);
+ gtk_text_buffer_move_mark(m_pBuffer, m_mEntered, &start);
+ gtk_text_buffer_move_mark(m_pBuffer, m_mTarget, &start);
+ gtk_text_buffer_get_end_iter(m_pBuffer, &end);
+ gtk_text_buffer_remove_all_tags(m_pBuffer, &start, &end);
+ }
+ void HandleEvent(const Dasher::CEditEvent *pEvt) {
+ const int iPrev(lastCorrectSym());
+ CGameModule::HandleEvent(pEvt);
+ if (iPrev==lastCorrectSym()) {
+ GtkTextIter start,end; //of "wrong" text
+ gtk_text_buffer_get_iter_at_mark(m_pBuffer, &start, m_mEntered);
+ gtk_text_buffer_get_iter_at_mark(m_pBuffer, &end, m_mTarget);
+ gtk_text_buffer_delete(m_pBuffer, &start, &end); //invalidates end, brings m_mEntered & m_mTarget together
+ gtk_text_buffer_get_iter_at_mark(m_pBuffer, &start, m_mEntered);
+ gtk_text_buffer_get_iter_at_mark(m_pBuffer, &end, m_mTarget);
+ gtk_text_buffer_insert(m_pBuffer, &start, m_strWrong.c_str(), -1); //moves m_mEntered & m_mTarget apart
+ gtk_text_buffer_get_iter_at_mark(m_pBuffer, &start, m_mEntered);
+ gtk_text_buffer_get_iter_at_mark(m_pBuffer, &end, m_mTarget);
+ gtk_text_buffer_get_iter_at_mark(m_pBuffer, &end, m_mTarget);
+ gtk_text_buffer_apply_tag(m_pBuffer, m_tWrong, &start, &end);
+ } else {
+ GtkTextIter it,it2;
+ gtk_text_buffer_get_iter_at_mark(m_pBuffer, &it, m_mEntered);
+ gtk_text_buffer_get_iter_at_mark(m_pBuffer, &it2, m_mTarget);
+ DASHER_ASSERT(gtk_text_iter_get_offset(&it) == gtk_text_iter_get_offset(&it2));
+ if (iPrev < lastCorrectSym()) {
+ //correct text added
+ DASHER_ASSERT(iPrev == lastCorrectSym()-1);
+ gtk_text_iter_forward_chars(&it2, 1);
+ gtk_text_buffer_apply_tag(m_pBuffer, m_tEntered, &it, &it2);
+ } else {
+ //correct text erased!
+ DASHER_ASSERT(iPrev == lastCorrectSym()+1);
+ gtk_text_iter_backward_chars(&it2, 1);
+ gtk_text_buffer_remove_tag(m_pBuffer, m_tEntered, &it2, &it);
+ }
+ gtk_text_buffer_move_mark(m_pBuffer, m_mEntered, &it2);
+ gtk_text_buffer_move_mark(m_pBuffer, m_mTarget, &it2);
+ }
+ }
+ void DrawText(CDasherView *pView) {}
+private:
+ GtkTextBuffer *m_pBuffer;
+ GtkTextTag *m_tEntered, *m_tWrong;
+ GtkTextMark *m_mEntered; //just after what's been correctly entered
+ GtkTextMark *m_mTarget; //after any "wrong" text, before target; if no wrong chars, ==m_entered.
+};
+
+CGameModule *CDasherControl::CreateGameModule(CDasherView *pView,CDasherModel *pModel) {
+ if (GtkTextBuffer *buf=gtk_dasher_control_game_text_buffer(m_pDasherControl))
+ return new GtkGameModule(this, this, pView, pModel, buf);
+ return CDashIntfScreenMsgs::CreateGameModule(pView,pModel);
+}
+
void CDasherControl::ExecuteCommand(const std::string &strCommand) {
g_signal_emit_by_name(GTK_WIDGET(m_pDasherControl), "dasher_command", strCommand.c_str());
}
diff --git a/Src/Gtk2/DasherControl.h b/Src/Gtk2/DasherControl.h
index 320630e..803be1f 100644
--- a/Src/Gtk2/DasherControl.h
+++ b/Src/Gtk2/DasherControl.h
@@ -165,6 +165,7 @@ public:
///Override to emit Gtk2 signal
virtual void SetLockStatus(const string &strText, int iPercent);
+ CGameModule *CreateGameModule(CDasherView *pView, CDasherModel *pModel);
private:
virtual void ScanAlphabetFiles(std::vector<std::string> &vFileList);
virtual void ScanColourFiles(std::vector<std::string> &vFileList);
diff --git a/Src/Gtk2/GtkDasherControl.cpp b/Src/Gtk2/GtkDasherControl.cpp
index dda6d10..147f78f 100644
--- a/Src/Gtk2/GtkDasherControl.cpp
+++ b/Src/Gtk2/GtkDasherControl.cpp
@@ -28,7 +28,6 @@
struct _GtkDasherControlPrivate {
CDasherControl *pControl;
DasherEditor *pEditor;
- void* pGameHelper;
};
typedef struct _GtkDasherControlPrivate GtkDasherControlPrivate;
@@ -125,6 +124,11 @@ void gtk_dasher_control_set_editor(GtkDasherControl *pDasherControl, DasherEdito
pPrivate->pEditor = pEditor;
}
+GtkTextBuffer *gtk_dasher_control_game_text_buffer(GtkDasherControl *pDasherControl) {
+ GtkDasherControlPrivate *pPrivate = GTK_DASHER_CONTROL_GET_PRIVATE(pDasherControl);
+ return dasher_editor_game_text_buffer(pPrivate->pEditor);
+}
+
static void
gtk_dasher_control_finalize(GObject *pObject) {
GtkDasherControl *pDasherControl = GTK_DASHER_CONTROL(pObject);
@@ -288,12 +292,6 @@ gtk_dasher_control_get_module_settings(GtkDasherControl * pControl, const gchar
}
void
-gtk_dasher_control_game_helperreg(GtkDasherControl *pControl, void* gameHelper) {
- GtkDasherControlPrivate *pPrivate = GTK_DASHER_CONTROL_GET_PRIVATE(pControl);
- pPrivate->pGameHelper = gameHelper;
-}
-
-void
gtk_dasher_control_force_pause(GtkDasherControl *pControl) {
GtkDasherControlPrivate *pPrivate = GTK_DASHER_CONTROL_GET_PRIVATE(pControl);
pPrivate->pControl->Stop();
diff --git a/Src/Gtk2/GtkDasherControl.h b/Src/Gtk2/GtkDasherControl.h
index 612cf23..d7ed426 100644
--- a/Src/Gtk2/GtkDasherControl.h
+++ b/Src/Gtk2/GtkDasherControl.h
@@ -82,7 +82,7 @@ gint gtk_dasher_control_ctrl_delete(GtkDasherControl *pControl, bool bForwards,
void gtk_dasher_control_external_key_down(GtkDasherControl *pControl, int iKeyVal);
void gtk_dasher_control_external_key_up(GtkDasherControl *pControl, int iKeyVal);
gboolean gtk_dasher_control_get_module_settings(GtkDasherControl * pControl, const gchar *szModule, SModuleSettings **pSettings, gint *iCount);
-void gtk_dasher_control_game_helperreg(GtkDasherControl *pControl, void* gameHelper);
+GtkTextBuffer *gtk_dasher_control_game_text_buffer(GtkDasherControl *pPrivate);
void gtk_dasher_control_force_pause(GtkDasherControl *pControl);
void gtk_dasher_control_add_action_button(GtkDasherControl *pControl, const gchar *szCommand);
diff --git a/Src/Gtk2/dasher_editor.cpp b/Src/Gtk2/dasher_editor.cpp
index 7cf2989..c3201fe 100644
--- a/Src/Gtk2/dasher_editor.cpp
+++ b/Src/Gtk2/dasher_editor.cpp
@@ -212,6 +212,12 @@ dasher_editor_initialise(DasherEditor *pSelf, DasherAppSettings *pAppSettings, D
DASHER_EDITOR_GET_CLASS(pSelf)->initialise(pSelf, pAppSettings, pDasherMain, pXML, szFullPath);
}
+GtkTextBuffer *dasher_editor_game_text_buffer(DasherEditor *pSelf) {
+ if (DASHER_EDITOR_GET_CLASS(pSelf)->game_text_buffer)
+ return DASHER_EDITOR_GET_CLASS(pSelf)->game_text_buffer(pSelf);
+ return NULL;
+}
+
void
dasher_editor_handle_stop(DasherEditor *pSelf) {
if(DASHER_EDITOR_GET_CLASS(pSelf)->handle_stop)
diff --git a/Src/Gtk2/dasher_editor.h b/Src/Gtk2/dasher_editor.h
index f03cf4d..98c5481 100644
--- a/Src/Gtk2/dasher_editor.h
+++ b/Src/Gtk2/dasher_editor.h
@@ -61,6 +61,8 @@ struct _DasherEditorClass {
void (*grab_focus)(DasherEditor *);
gboolean (*file_changed)(DasherEditor *);
const gchar *(*get_filename)(DasherEditor *);
+ ///Get a buffer to display formatted text for game mode, if we have one
+ GtkTextBuffer *(*game_text_buffer)(DasherEditor *);
/* Signal handlers */
void (*filename_changed)(DasherEditor *);
@@ -103,6 +105,8 @@ void dasher_editor_action_set_control(DasherEditor *pSelf, int iActionID, bool b
void dasher_editor_action_set_auto(DasherEditor *pSelf, int iActionID, bool bValue);
#endif
+GtkTextBuffer *dasher_editor_game_text_buffer(DasherEditor *);
+
void dasher_editor_clear(DasherEditor *pSelf);
const gchar *dasher_editor_get_all_text(DasherEditor *pSelf);
const gchar *dasher_editor_get_new_text(DasherEditor *pSelf);
diff --git a/Src/Gtk2/dasher_editor_internal.cpp b/Src/Gtk2/dasher_editor_internal.cpp
index 280c8c5..9caed7b 100644
--- a/Src/Gtk2/dasher_editor_internal.cpp
+++ b/Src/Gtk2/dasher_editor_internal.cpp
@@ -195,6 +195,7 @@ const gchar *dasher_editor_internal_get_filename(DasherEditor *pSelf);
static void dasher_editor_internal_clear(DasherEditor *pSelf);
const gchar *dasher_editor_internal_get_all_text(DasherEditor *pSelf);
const gchar *dasher_editor_internal_get_new_text(DasherEditor *pSelf);
+static GtkTextBuffer *dasher_editor_internal_game_text_buffer(DasherEditor *pEditor);
static void dasher_editor_internal_handle_parameter_change(DasherEditor *pSelf, gint iParameter);
@@ -219,6 +220,7 @@ dasher_editor_internal_class_init(DasherEditorInternalClass *pClass) {
DasherEditorClass *pParentClass = (DasherEditorClass *)pClass;
pParentClass->initialise = dasher_editor_internal_initialise;
+ pParentClass->game_text_buffer = dasher_editor_internal_game_text_buffer;
pParentClass->command = dasher_editor_internal_command;
pParentClass->output = dasher_editor_internal_output;
pParentClass->delete_text = dasher_editor_internal_delete;
@@ -686,10 +688,12 @@ dasher_editor_internal_get_offset(DasherEditor *pSelf) {
void dasher_editor_internal_mark_changed(DasherEditorInternal *pSelf, GtkTextIter *pIter, GtkTextMark *pMark) {
const char *szMarkName(gtk_text_mark_get_name(pMark));
if(szMarkName && !strcmp(szMarkName,"insert")) {
+ DasherEditorInternalPrivate *pPrivate = DASHER_EDITOR_INTERNAL_GET_PRIVATE(pSelf);
//ACL: used to emit "offset_changed" signal from buffer, which was picked up
// by a callback registered by editor_internal, which then emitted a context_changed
// signal from the editor_internal. So just emit the context_changed directly...
- if (!DASHER_EDITOR_INTERNAL_GET_PRIVATE(pSelf)->bInControlAction) //tho not if it's the result of a control-mode edit/delete
+ if (!pPrivate->bInControlAction //tho not if it's the result of a control-mode edit/delete
+ && dasher_app_settings_get_bool(pPrivate->pAppSettings, BP_GAME_MODE)) //and not in game mode
g_signal_emit_by_name(G_OBJECT(pSelf), "context_changed", G_OBJECT(pSelf), NULL, NULL);
}
}
@@ -883,13 +887,10 @@ dasher_editor_internal_save_as(DasherEditor *pSelf, const gchar *szFilename, boo
return true;
}
-// void
-// dasher_editor_internal_start_tutorial(DasherEditor *pSelf) {
-// DasherEditorInternalPrivate *pPrivate = (DasherEditorInternalPrivate *)(pSelf->private_data);
-
-// // TODO: reimplement
-// // pPrivate->pGameModeHelper = GAME_MODE_HELPER(game_mode_helper_new(GTK_DASHER_CONTROL(pDasherWidget)));
-// }
+GtkTextBuffer *dasher_editor_internal_game_text_buffer(DasherEditor *pSelf) {
+ DasherEditorInternalPrivate *pPrivate = DASHER_EDITOR_INTERNAL_GET_PRIVATE(pSelf);
+ return pPrivate->pBuffer;
+}
gboolean
dasher_editor_internal_command(DasherEditor *pSelf, const gchar *szCommand) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]