[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Eliot-dev] eliot dic/encoding.cpp dic/encoding.h po/eliot.... [cppdic]
From: |
eliot-dev |
Subject: |
[Eliot-dev] eliot dic/encoding.cpp dic/encoding.h po/eliot.... [cppdic] |
Date: |
Sun, 16 Dec 2007 15:58:44 +0000 |
CVSROOT: /cvsroot/eliot
Module name: eliot
Branch: cppdic
Changes by: Olivier Teulière <ipkiss> 07/12/16 15:58:44
Modified files:
dic : encoding.cpp encoding.h
po : eliot.pot fr.po
utils : ncurses.cpp ncurses.h
Log message:
- new truncString() and truncAndConvert() functions to cut a string
while taking into account the display width
- many improvements in the ncurses interface:
* the box handling is now encapsulated in its own class
* many display fixes, in particular in case of resizing
* new panel showing the contents of the bag
* the readString() method now also understands Left, Right, Del,
Ctrl-U, Ctrl-K, Home, End
* the readString() method beeps if an unrecognized key is pressed
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/encoding.cpp?cvsroot=eliot&only_with_tag=cppdic&r1=1.1.2.10&r2=1.1.2.11
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/encoding.h?cvsroot=eliot&only_with_tag=cppdic&r1=1.1.2.5&r2=1.1.2.6
http://cvs.savannah.gnu.org/viewcvs/eliot/po/eliot.pot?cvsroot=eliot&only_with_tag=cppdic&r1=1.6.6.4&r2=1.6.6.5
http://cvs.savannah.gnu.org/viewcvs/eliot/po/fr.po?cvsroot=eliot&only_with_tag=cppdic&r1=1.6.6.4&r2=1.6.6.5
http://cvs.savannah.gnu.org/viewcvs/eliot/utils/ncurses.cpp?cvsroot=eliot&only_with_tag=cppdic&r1=1.22.2.7&r2=1.22.2.8
http://cvs.savannah.gnu.org/viewcvs/eliot/utils/ncurses.h?cvsroot=eliot&only_with_tag=cppdic&r1=1.6.4.1&r2=1.6.4.2
Patches:
Index: dic/encoding.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/dic/Attic/encoding.cpp,v
retrieving revision 1.1.2.10
retrieving revision 1.1.2.11
diff -u -b -r1.1.2.10 -r1.1.2.11
--- dic/encoding.cpp 10 Dec 2007 11:56:39 -0000 1.1.2.10
+++ dic/encoding.cpp 16 Dec 2007 15:58:43 -0000 1.1.2.11
@@ -194,6 +194,41 @@
}
+string truncString(const string &iStr, unsigned int iMaxWidth)
+{
+ // Heuristic: the width of a character cannot exceed the number of
+ // bytes used to represent it (even in UTF-8)
+ if (iStr.size() <= iMaxWidth)
+ return iStr;
+ return truncAndConvert(convertToWc(iStr), iMaxWidth);
+}
+
+
+string truncAndConvert(const wstring &iWstr, unsigned int iMaxWidth)
+{
+ unsigned int width = 0;
+ unsigned int pos;
+ for (pos = 0; pos < iWstr.size(); ++pos)
+ {
+ int n = wcwidth(iWstr[pos]);
+ if (n == -1)
+ {
+ ostringstream ss;
+ ss << "truncAndConvert: non printable character: " << iWstr[pos];
+ // XXX: Should we throw an exception instead? Just ignore the
problem?
+ cerr << ss.str() << endl;;
+ //throw DicException(ss.str());
+ return convertToMb(iWstr);
+ }
+ if (width + n > iMaxWidth)
+ break;
+ width += n;
+ }
+
+ return convertToMb(iWstr.substr(0, pos));
+}
+
+
string padAndConvert(const wstring &iWstr, unsigned int iLength,
bool iLeftPad, char c)
{
Index: dic/encoding.h
===================================================================
RCS file: /cvsroot/eliot/eliot/dic/Attic/encoding.h,v
retrieving revision 1.1.2.5
retrieving revision 1.1.2.6
diff -u -b -r1.1.2.5 -r1.1.2.6
--- dic/encoding.h 10 Dec 2007 11:56:39 -0000 1.1.2.5
+++ dic/encoding.h 16 Dec 2007 15:58:43 -0000 1.1.2.6
@@ -52,6 +52,20 @@
string convertToMb(wchar_t iWChar);
/**
+ * Truncate the given string to ensure that the number of columns needed
+ * to display it is at most iMaxWidth. If the string is already less wide,
+ * it is returned without truncation
+ */
+string truncString(const string &iStr, unsigned int iMaxWidth);
+
+/**
+ * Convert the given string into a multi-byte one. If the number of columns
+ * needed to display the resulting string is more than iMaxWidth, truncate it
+ * on the right before conversion
+ */
+string truncAndConvert(const wstring &iWStr, unsigned int iMaxWidth);
+
+/**
* Convert the given string into a multi-byte one. If the number of columns
* needed to display the resulting string is less than iLength, pad it with
* the given character (defaulting to space)
Index: po/eliot.pot
===================================================================
RCS file: /cvsroot/eliot/eliot/po/eliot.pot,v
retrieving revision 1.6.6.4
retrieving revision 1.6.6.5
diff -u -b -r1.6.6.4 -r1.6.6.5
--- po/eliot.pot 15 Dec 2007 20:32:34 -0000 1.6.6.4
+++ po/eliot.pot 16 Dec 2007 15:58:44 -0000 1.6.6.5
@@ -8,7 +8,7 @@
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-12-11 15:06+0100\n"
+"POT-Creation-Date: 2007-12-16 16:44+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <address@hidden>\n"
"Language-Team: LANGUAGE <address@hidden>\n"
@@ -260,252 +260,267 @@
msgid "result:"
msgstr ""
-#: utils/ncurses.cpp:192
-msgid " Scores "
+#: utils/ncurses.cpp:271
+msgid "Scores"
msgstr ""
-#: utils/ncurses.cpp:198
+#: utils/ncurses.cpp:277
#, c-format
msgid "Player %d: %d"
msgstr ""
-#: utils/ncurses.cpp:206
-msgid " Racks "
+#: utils/ncurses.cpp:286
+msgid "Racks"
msgstr ""
-#: utils/ncurses.cpp:213
+#: utils/ncurses.cpp:293
#, c-format
msgid "Player %d: %ls"
msgstr ""
-#: utils/ncurses.cpp:224 utils/ncurses.cpp:227
+#: utils/ncurses.cpp:304 utils/ncurses.cpp:307
msgid "Search complete"
msgstr ""
-#: utils/ncurses.cpp:239
-msgid " Search results "
+#: utils/ncurses.cpp:317
+msgid "Search results"
msgstr ""
-#: utils/ncurses.cpp:269
-msgid " History of the game "
+#: utils/ncurses.cpp:345
+msgid "History of the game"
msgstr ""
-#: utils/ncurses.cpp:276
+#: utils/ncurses.cpp:351
msgid " N | RACK | SOLUTION | REF | PTS | P | BONUS"
msgstr ""
-#: utils/ncurses.cpp:307
-msgid " Help "
+#: utils/ncurses.cpp:385
+msgid "Help"
msgstr ""
-#: utils/ncurses.cpp:312
+#: utils/ncurses.cpp:389
msgid "[Global]"
msgstr ""
-#: utils/ncurses.cpp:313
+#: utils/ncurses.cpp:390
msgid " h, H, ? Show/hide help box"
msgstr ""
-#: utils/ncurses.cpp:314
+#: utils/ncurses.cpp:391
msgid " y, Y Show/hide history of the game"
msgstr ""
-#: utils/ncurses.cpp:315
+#: utils/ncurses.cpp:392
+msgid ""
+" b, B Show/hide contents of the bag (including letters of the "
+"racks)"
+msgstr ""
+
+#: utils/ncurses.cpp:393
msgid " e, E Show/hide dots on empty squares of the board"
msgstr ""
-#: utils/ncurses.cpp:316
+#: utils/ncurses.cpp:394
msgid " d, D Check the existence of a word in the dictionary"
msgstr ""
-#: utils/ncurses.cpp:317
+#: utils/ncurses.cpp:395
msgid " j, J Play a word"
msgstr ""
-#: utils/ncurses.cpp:318
+#: utils/ncurses.cpp:396
msgid " s, S Save the game"
msgstr ""
-#: utils/ncurses.cpp:319
+#: utils/ncurses.cpp:397
msgid " l, L Load a game"
msgstr ""
-#: utils/ncurses.cpp:320
+#: utils/ncurses.cpp:398
msgid " q, Q Quit"
msgstr ""
-#: utils/ncurses.cpp:323
+#: utils/ncurses.cpp:401
msgid "[Training mode]"
msgstr ""
-#: utils/ncurses.cpp:324
+#: utils/ncurses.cpp:402
msgid " * Take a random rack"
msgstr ""
-#: utils/ncurses.cpp:325
+#: utils/ncurses.cpp:403
msgid " + Complete the current rack randomly"
msgstr ""
-#: utils/ncurses.cpp:326
+#: utils/ncurses.cpp:404
msgid " t, T Set the rack manually"
msgstr ""
-#: utils/ncurses.cpp:327
+#: utils/ncurses.cpp:405
msgid " c, C Compute all the possible words"
msgstr ""
-#: utils/ncurses.cpp:328
+#: utils/ncurses.cpp:406
msgid " r, R Show/hide search results"
msgstr ""
-#: utils/ncurses.cpp:331
+#: utils/ncurses.cpp:409
msgid "[Duplicate mode]"
msgstr ""
-#: utils/ncurses.cpp:332
+#: utils/ncurses.cpp:410
msgid " n, N Switch to the next human player"
msgstr ""
-#: utils/ncurses.cpp:335
+#: utils/ncurses.cpp:413
msgid "[Free game mode]"
msgstr ""
-#: utils/ncurses.cpp:336
+#: utils/ncurses.cpp:414
msgid " p, P Pass your turn (with or without changing letters)"
msgstr ""
-#: utils/ncurses.cpp:339
+#: utils/ncurses.cpp:417
msgid "[Miscellaneous]"
msgstr ""
-#: utils/ncurses.cpp:340
+#: utils/ncurses.cpp:418
msgid " <up>, <down> Navigate in a box line by line"
msgstr ""
-#: utils/ncurses.cpp:341
+#: utils/ncurses.cpp:419
msgid " <pgup>, <pgdown> Navigate in a box page by page"
msgstr ""
-#: utils/ncurses.cpp:342
+#: utils/ncurses.cpp:420
msgid " Ctrl-l Refresh the screen"
msgstr ""
-#: utils/ncurses.cpp:350
-msgid " Play a word "
+#: utils/ncurses.cpp:431 wxwin/auxframes.cc:148
+msgid "Bag"
+msgstr ""
+
+#: utils/ncurses.cpp:438
+msgid " LETTER | POINTS | FREQUENCY | REMAINING"
+msgstr ""
+
+#: utils/ncurses.cpp:491
+msgid "Play a word"
msgstr ""
#. TRANSLATORS: Align the : when translating "Played word:" and
#. "Coordinates:". For example:
#. Pl. word :
#. Coordinates:
-#: utils/ncurses.cpp:351 utils/ncurses.cpp:359
+#: utils/ncurses.cpp:492 utils/ncurses.cpp:500
msgid "Played word:"
msgstr ""
-#: utils/ncurses.cpp:352 utils/ncurses.cpp:360
+#: utils/ncurses.cpp:493 utils/ncurses.cpp:501
msgid "Coordinates:"
msgstr ""
-#: utils/ncurses.cpp:374
+#: utils/ncurses.cpp:515
msgid "Incorrect or misplaced word"
msgstr ""
-#: utils/ncurses.cpp:384
-msgid " Dictionary "
+#: utils/ncurses.cpp:530
+msgid "Dictionary"
msgstr ""
-#: utils/ncurses.cpp:385
+#: utils/ncurses.cpp:531
msgid "Enter the word to check:"
msgstr ""
-#: utils/ncurses.cpp:394
+#: utils/ncurses.cpp:540
#, c-format
msgid "The word '%ls' exists"
msgstr ""
-#: utils/ncurses.cpp:396
+#: utils/ncurses.cpp:542
#, c-format
msgid "The word '%ls' does not exist"
msgstr ""
-#: utils/ncurses.cpp:406
-msgid " Save the game "
+#: utils/ncurses.cpp:553 wxwin/mainframe.cc:464 wxwin/mainframe.cc:472
+msgid "Save the game"
msgstr ""
-#: utils/ncurses.cpp:407 utils/ncurses.cpp:436
+#: utils/ncurses.cpp:554 utils/ncurses.cpp:584
msgid "Enter the file name:"
msgstr ""
-#: utils/ncurses.cpp:417
+#: utils/ncurses.cpp:564
#, c-format
msgid "Cannot open file %ls for writing"
msgstr ""
-#: utils/ncurses.cpp:424
+#: utils/ncurses.cpp:571
#, c-format
msgid "Game saved in %ls"
msgstr ""
-#: utils/ncurses.cpp:435
-msgid " Load a game "
+#: utils/ncurses.cpp:583 wxwin/mainframe.cc:268 wxwin/mainframe.cc:389
+#: wxwin/mainframe.cc:413
+msgid "Load a game"
msgstr ""
-#: utils/ncurses.cpp:446
+#: utils/ncurses.cpp:594
#, c-format
msgid "Cannot open file %ls for reading"
msgstr ""
-#: utils/ncurses.cpp:454
+#: utils/ncurses.cpp:602
#, c-format
msgid "Invalid saved game"
msgstr ""
-#: utils/ncurses.cpp:458
+#: utils/ncurses.cpp:606
#, c-format
msgid "Game loaded"
msgstr ""
-#: utils/ncurses.cpp:473
-msgid " Pass your turn "
+#: utils/ncurses.cpp:622
+msgid "Pass your turn"
msgstr ""
-#: utils/ncurses.cpp:474
+#: utils/ncurses.cpp:623
msgid "Enter the letters to change:"
msgstr ""
-#: utils/ncurses.cpp:483
+#: utils/ncurses.cpp:632
msgid "Cannot pass the turn"
msgstr ""
-#: utils/ncurses.cpp:493
-msgid " Set rack "
+#: utils/ncurses.cpp:643
+msgid "Set rack"
msgstr ""
-#: utils/ncurses.cpp:494
+#: utils/ncurses.cpp:644
msgid "Enter the new letters:"
msgstr ""
-#: utils/ncurses.cpp:503
+#: utils/ncurses.cpp:653
msgid "Cannot take these letters from the bag"
msgstr ""
-#: utils/ncurses.cpp:814
+#: utils/ncurses.cpp:1013
msgid "Training mode"
msgstr ""
-#: utils/ncurses.cpp:816
+#: utils/ncurses.cpp:1015
msgid "Free game mode"
msgstr ""
-#: utils/ncurses.cpp:818
+#: utils/ncurses.cpp:1017
msgid "Duplicate mode"
msgstr ""
-#: utils/ncurses.cpp:821
+#: utils/ncurses.cpp:1020
msgid "Joker game"
msgstr ""
-#: utils/ncurses.cpp:822
+#: utils/ncurses.cpp:1021
msgid "[h for help]"
msgstr ""
@@ -513,10 +528,6 @@
msgid "Grid"
msgstr ""
-#: wxwin/auxframes.cc:148
-msgid "Bag"
-msgstr ""
-
#: wxwin/auxframes.cc:203
msgid "Search"
msgstr ""
@@ -770,10 +781,6 @@
msgid "&Load...\tctrl+l"
msgstr ""
-#: wxwin/mainframe.cc:268 wxwin/mainframe.cc:389 wxwin/mainframe.cc:413
-msgid "Load a game"
-msgstr ""
-
#: wxwin/mainframe.cc:269
msgid "&Save as...\tctrl+s"
msgstr ""
@@ -1067,10 +1074,6 @@
msgid "The game is empty"
msgstr ""
-#: wxwin/mainframe.cc:464 wxwin/mainframe.cc:472
-msgid "Save the game"
-msgstr ""
-
#: wxwin/mainframe.cc:471
msgid "Cannot create "
msgstr ""
Index: po/fr.po
===================================================================
RCS file: /cvsroot/eliot/eliot/po/fr.po,v
retrieving revision 1.6.6.4
retrieving revision 1.6.6.5
diff -u -b -r1.6.6.4 -r1.6.6.5
--- po/fr.po 15 Dec 2007 20:32:34 -0000 1.6.6.4
+++ po/fr.po 16 Dec 2007 15:58:44 -0000 1.6.6.5
@@ -8,12 +8,12 @@
msgstr ""
"Project-Id-Version: eliot 1.4\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-12-11 15:06+0100\n"
+"POT-Creation-Date: 2007-12-16 16:44+0100\n"
"PO-Revision-Date: 2005-02-06 20:03+0100\n"
"Last-Translator: Olivier Teuliere <address@hidden>\n"
"Language-Team: French <address@hidden>\n"
"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
@@ -136,16 +136,15 @@
msgid ""
"The file containing the letters (--letters switch) must be UTF-8 encoded."
msgstr ""
-"Le fichier contenant les lettres (option --letters) doit être encodé en "
-"UTF-8."
+"Le fichier contenant les lettres (option --letters) doit être encodé en
UTF-"
+"8."
#: dic/compdic.cpp:403
msgid ""
"Each line corresponds to one letter, and must contain 5 fields separated "
"with "
msgstr ""
-"Chaque ligne correspond à une lettre, et doit contenir 5 champs séparés "
-"par "
+"Chaque ligne correspond à une lettre, et doit contenir 5 champs séparés
par "
#: dic/compdic.cpp:404
msgid "one or more space(s)."
@@ -277,257 +276,272 @@
msgid "result:"
msgstr "résultat :"
-#: utils/ncurses.cpp:192
-msgid " Scores "
-msgstr " Scores "
+#: utils/ncurses.cpp:271
+msgid "Scores"
+msgstr "Scores"
-#: utils/ncurses.cpp:198
+#: utils/ncurses.cpp:277
#, c-format
msgid "Player %d: %d"
msgstr "Joueur %d : %d"
-#: utils/ncurses.cpp:206
-msgid " Racks "
-msgstr " Tirages "
+#: utils/ncurses.cpp:286
+msgid "Racks"
+msgstr "Tirages"
-#: utils/ncurses.cpp:213
+#: utils/ncurses.cpp:293
#, c-format
msgid "Player %d: %ls"
msgstr "Joueur %d : %ls"
-#: utils/ncurses.cpp:224 utils/ncurses.cpp:227
+#: utils/ncurses.cpp:304 utils/ncurses.cpp:307
msgid "Search complete"
msgstr "Recherche terminée"
-#: utils/ncurses.cpp:239
-msgid " Search results "
-msgstr " Résultats de la recherche "
-
-#: utils/ncurses.cpp:269
-msgid " History of the game "
-msgstr " Historique de la partie "
+#: utils/ncurses.cpp:317
+msgid "Search results"
+msgstr "Résultats de la recherche"
-#: utils/ncurses.cpp:276
+#: utils/ncurses.cpp:345
+msgid "History of the game"
+msgstr "Historique de la partie"
+
+#: utils/ncurses.cpp:351
msgid " N | RACK | SOLUTION | REF | PTS | P | BONUS"
msgstr " N | TIRAGE | SOLUTION | REF | PTS | J | BONUS"
-#: utils/ncurses.cpp:307
-msgid " Help "
-msgstr " Aide "
+#: utils/ncurses.cpp:385
+msgid "Help"
+msgstr "Aide"
-#: utils/ncurses.cpp:312
+#: utils/ncurses.cpp:389
msgid "[Global]"
msgstr "[Général]"
-#: utils/ncurses.cpp:313
+#: utils/ncurses.cpp:390
msgid " h, H, ? Show/hide help box"
msgstr " h, H, ? Afficher/cacher la boîte d'aide"
-#: utils/ncurses.cpp:314
+#: utils/ncurses.cpp:391
msgid " y, Y Show/hide history of the game"
msgstr " y, Y Afficher/cacher l'historique de la partie"
-#: utils/ncurses.cpp:315
+#: utils/ncurses.cpp:392
+msgid ""
+" b, B Show/hide contents of the bag (including letters of the "
+"racks)"
+msgstr ""
+" b, B Afficher/cacher le contenu du sac (avec les lettres des "
+"tirages)"
+
+#: utils/ncurses.cpp:393
msgid " e, E Show/hide dots on empty squares of the board"
msgstr ""
" e, E Afficher/cacher les points sur les cases vides du "
"plateau de jeu"
-#: utils/ncurses.cpp:316
+#: utils/ncurses.cpp:394
msgid " d, D Check the existence of a word in the dictionary"
-msgstr ""
-" d, D Vérifier l'existence d'un mot dans le dictionnaire"
+msgstr " d, D Vérifier l'existence d'un mot dans le
dictionnaire"
-#: utils/ncurses.cpp:317
+#: utils/ncurses.cpp:395
msgid " j, J Play a word"
msgstr " j, J Jouer un mot"
-#: utils/ncurses.cpp:318
+#: utils/ncurses.cpp:396
msgid " s, S Save the game"
msgstr " s, S Sauvegarder la partie"
-#: utils/ncurses.cpp:319
+#: utils/ncurses.cpp:397
msgid " l, L Load a game"
msgstr " l, L Charger une partie"
-#: utils/ncurses.cpp:320
+#: utils/ncurses.cpp:398
msgid " q, Q Quit"
msgstr " q, Q Quitter"
-#: utils/ncurses.cpp:323
+#: utils/ncurses.cpp:401
msgid "[Training mode]"
msgstr "[Mode entraînement]"
-#: utils/ncurses.cpp:324
+#: utils/ncurses.cpp:402
msgid " * Take a random rack"
msgstr " * Tirage aléatoire"
-#: utils/ncurses.cpp:325
+#: utils/ncurses.cpp:403
msgid " + Complete the current rack randomly"
-msgstr ""
-" + Compléter le tirage courant de manière aléatoire"
+msgstr " + Compléter le tirage courant de manière
aléatoire"
-#: utils/ncurses.cpp:326
+#: utils/ncurses.cpp:404
msgid " t, T Set the rack manually"
msgstr " t, T Entrer le tirage manuellement"
-#: utils/ncurses.cpp:327
+#: utils/ncurses.cpp:405
msgid " c, C Compute all the possible words"
msgstr " c, C Calculer tous les mots possibles"
-#: utils/ncurses.cpp:328
+#: utils/ncurses.cpp:406
msgid " r, R Show/hide search results"
msgstr " r, R Afficher/cacher les résultats de la recherche"
-#: utils/ncurses.cpp:331
+#: utils/ncurses.cpp:409
msgid "[Duplicate mode]"
msgstr "[Mode duplicate]"
-#: utils/ncurses.cpp:332
+#: utils/ncurses.cpp:410
msgid " n, N Switch to the next human player"
msgstr " n, N Passer au joueur humain suivant"
-#: utils/ncurses.cpp:335
+#: utils/ncurses.cpp:413
msgid "[Free game mode]"
msgstr "[Mode partie libre]"
-#: utils/ncurses.cpp:336
+#: utils/ncurses.cpp:414
msgid " p, P Pass your turn (with or without changing letters)"
msgstr ""
" p, P Passer son tour (en changeant ou pas certaines lettres)"
-#: utils/ncurses.cpp:339
+#: utils/ncurses.cpp:417
msgid "[Miscellaneous]"
msgstr "[Divers]"
-#: utils/ncurses.cpp:340
+#: utils/ncurses.cpp:418
msgid " <up>, <down> Navigate in a box line by line"
msgstr " <haut>, <bas> Naviguer dans une boîte ligne par ligne"
-#: utils/ncurses.cpp:341
+#: utils/ncurses.cpp:419
msgid " <pgup>, <pgdown> Navigate in a box page by page"
msgstr " <pgup>, <pgdown> Naviguer dans une boîte page par page"
-#: utils/ncurses.cpp:342
+#: utils/ncurses.cpp:420
msgid " Ctrl-l Refresh the screen"
msgstr " Ctrl-l Rafraîchir l'écran"
-#: utils/ncurses.cpp:350
-msgid " Play a word "
-msgstr " Jouer un mot "
+#: utils/ncurses.cpp:431 wxwin/auxframes.cc:148
+msgid "Bag"
+msgstr "Sac"
+
+#: utils/ncurses.cpp:438
+msgid " LETTER | POINTS | FREQUENCY | REMAINING"
+msgstr " LETTRE | POINTS |Â FREQUENCE | RESTANT"
+
+#: utils/ncurses.cpp:491
+msgid "Play a word"
+msgstr "Jouer un mot"
#. TRANSLATORS: Align the : when translating "Played word:" and
#. "Coordinates:". For example:
#. Pl. word :
#. Coordinates:
-#: utils/ncurses.cpp:351 utils/ncurses.cpp:359
+#: utils/ncurses.cpp:492 utils/ncurses.cpp:500
msgid "Played word:"
msgstr "Mot joué :"
-#: utils/ncurses.cpp:352 utils/ncurses.cpp:360
+#: utils/ncurses.cpp:493 utils/ncurses.cpp:501
msgid "Coordinates:"
msgstr "Coordonnées :"
-#: utils/ncurses.cpp:374
+#: utils/ncurses.cpp:515
msgid "Incorrect or misplaced word"
msgstr "Mot incorrect ou mal placé"
-#: utils/ncurses.cpp:384
-msgid " Dictionary "
-msgstr " Dictionnaire "
+#: utils/ncurses.cpp:530
+msgid "Dictionary"
+msgstr "Dictionnaire"
-#: utils/ncurses.cpp:385
+#: utils/ncurses.cpp:531
msgid "Enter the word to check:"
msgstr "Entrer le mot à vérifier:"
-#: utils/ncurses.cpp:394
+#: utils/ncurses.cpp:540
#, c-format
msgid "The word '%ls' exists"
msgstr "Le mot '%ls' existe"
-#: utils/ncurses.cpp:396
+#: utils/ncurses.cpp:542
#, c-format
msgid "The word '%ls' does not exist"
msgstr "Le mot '%ls' n'existe pas"
-#: utils/ncurses.cpp:406
-msgid " Save the game "
-msgstr " Sauvegarder la partie "
+#: utils/ncurses.cpp:553 wxwin/mainframe.cc:464 wxwin/mainframe.cc:472
+msgid "Save the game"
+msgstr "Sauvegarder la partie"
-#: utils/ncurses.cpp:407 utils/ncurses.cpp:436
+#: utils/ncurses.cpp:554 utils/ncurses.cpp:584
msgid "Enter the file name:"
msgstr "Entrer le nom du fichier :"
-#: utils/ncurses.cpp:417
+#: utils/ncurses.cpp:564
#, c-format
msgid "Cannot open file %ls for writing"
msgstr "Impossible d'ouvrir le fichier %ls en écriture"
-#: utils/ncurses.cpp:424
+#: utils/ncurses.cpp:571
#, c-format
msgid "Game saved in %ls"
msgstr "Partie sauvée dans %ls"
-#: utils/ncurses.cpp:435
-msgid " Load a game "
-msgstr " Charger une partie "
+#: utils/ncurses.cpp:583 wxwin/mainframe.cc:268 wxwin/mainframe.cc:389
+#: wxwin/mainframe.cc:413
+msgid "Load a game"
+msgstr "Charger une partie"
-#: utils/ncurses.cpp:446
+#: utils/ncurses.cpp:594
#, c-format
msgid "Cannot open file %ls for reading"
msgstr "Impossible d'ouvrir le fichier %ls en lecture"
-#: utils/ncurses.cpp:454
+#: utils/ncurses.cpp:602
#, c-format
msgid "Invalid saved game"
msgstr "Partie sauvée invalide"
-#: utils/ncurses.cpp:458
+#: utils/ncurses.cpp:606
#, c-format
msgid "Game loaded"
msgstr "Partie chargée"
-#: utils/ncurses.cpp:473
-msgid " Pass your turn "
-msgstr " Passer son tour "
+#: utils/ncurses.cpp:622
+msgid "Pass your turn"
+msgstr "Passer son tour"
-#: utils/ncurses.cpp:474
+#: utils/ncurses.cpp:623
msgid "Enter the letters to change:"
msgstr "Entrer les lettres à changer:"
-#: utils/ncurses.cpp:483
+#: utils/ncurses.cpp:632
msgid "Cannot pass the turn"
msgstr "Impossible de passer le tour"
-#: utils/ncurses.cpp:493
-msgid " Set rack "
-msgstr " Choix du tirage "
+#: utils/ncurses.cpp:643
+msgid "Set rack"
+msgstr "Choix du tirage"
-#: utils/ncurses.cpp:494
+#: utils/ncurses.cpp:644
msgid "Enter the new letters:"
msgstr "Entrer les nouvelles lettres:"
-#: utils/ncurses.cpp:503
+#: utils/ncurses.cpp:653
msgid "Cannot take these letters from the bag"
msgstr "Impossible de retirer ces lettres du sac"
-#: utils/ncurses.cpp:814
+#: utils/ncurses.cpp:1013
msgid "Training mode"
msgstr "Mode entraînement"
-#: utils/ncurses.cpp:816
+#: utils/ncurses.cpp:1015
msgid "Free game mode"
msgstr "Mode partie libre"
-#: utils/ncurses.cpp:818
+#: utils/ncurses.cpp:1017
msgid "Duplicate mode"
msgstr "Mode duplicate"
-#: utils/ncurses.cpp:821
+#: utils/ncurses.cpp:1020
msgid "Joker game"
msgstr "Partie joker"
-#: utils/ncurses.cpp:822
+#: utils/ncurses.cpp:1021
msgid "[h for help]"
msgstr "[h pour l'aide]"
@@ -535,21 +549,17 @@
msgid "Grid"
msgstr "Grille"
-#: wxwin/auxframes.cc:148
-msgid "Bag"
-msgstr "Sac"
-
#: wxwin/auxframes.cc:203
msgid "Search"
msgstr "Recherche"
#: wxwin/auxframes.cc:234
msgid "Check"
-msgstr "Vérification"
+msgstr "Vérification"
#: wxwin/auxframes.cc:239
msgid "Word to check"
-msgstr "Mot à vérifier"
+msgstr "Mot à vérifier"
#: wxwin/auxframes.cc:257 wxwin/configdb.cc:203 wxwin/searchpanel.cc:107
msgid "No dictionary"
@@ -714,11 +724,11 @@
#: wxwin/confsearch.cc:36
msgid "Search on joker in 7+1 panel"
-msgstr "Rechercher sur joker dans la fenêtre 7+1"
+msgstr "Rechercher sur joker dans la fenêtre 7+1"
#: wxwin/confsearch.cc:37
msgid "Check rack validity"
-msgstr "Vérifier la validité du tirage"
+msgstr "Vérifier la validité du tirage"
#: wxwin/confsearch.cc:40
msgid "Cancel last changes"
@@ -792,10 +802,6 @@
msgid "&Load...\tctrl+l"
msgstr "&Charger...\tctrl+l"
-#: wxwin/mainframe.cc:268 wxwin/mainframe.cc:389 wxwin/mainframe.cc:413
-msgid "Load a game"
-msgstr "Charger une partie"
-
#: wxwin/mainframe.cc:269
msgid "&Save as...\tctrl+s"
msgstr "&Enregistrer sous...\tctrl+s"
@@ -1089,10 +1095,6 @@
msgid "The game is empty"
msgstr "La partie est vide"
-#: wxwin/mainframe.cc:464 wxwin/mainframe.cc:472
-msgid "Save the game"
-msgstr "Sauvegarder la partie"
-
#: wxwin/mainframe.cc:471
msgid "Cannot create "
msgstr "Impossible de créer "
@@ -1194,6 +1196,18 @@
msgid "Regular expressions"
msgstr "Expressions régulières"
+#~ msgid " Racks "
+#~ msgstr " Tirages "
+
+#~ msgid " Help "
+#~ msgstr " Aide "
+
+#~ msgid " Save the game "
+#~ msgstr " Sauvegarder la partie "
+
+#~ msgid " Load a game "
+#~ msgstr " Charger une partie "
+
#~ msgid "The rack must contain at least 2 consonants and 2 vowels\n"
#~ msgstr "Le tirage doit contenir au moins 2 consonnes et 2 voyelles\n"
Index: utils/ncurses.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/utils/ncurses.cpp,v
retrieving revision 1.22.2.7
retrieving revision 1.22.2.8
diff -u -b -r1.22.2.7 -r1.22.2.8
--- utils/ncurses.cpp 15 Dec 2007 20:32:34 -0000 1.22.2.7
+++ utils/ncurses.cpp 16 Dec 2007 15:58:44 -0000 1.22.2.8
@@ -42,48 +42,126 @@
using namespace std;
-CursesIntf::CursesIntf(WINDOW *win, Game& iGame)
- : m_win(win), m_game(&iGame), m_state(DEFAULT), m_dying(false),
- m_boxStart(0), m_boxLines(0), m_boxLinesData(0), m_boxY(0),
- m_showDots(false)
+Box::Box(WINDOW *win, int y, int x, int h, int w,
+ unsigned int iHeadingLines)
+ : m_win(win), m_x(x), m_y(y), m_w(w), m_h(h),
+ m_topLine(y + 1 + iHeadingLines),
+ m_nbLines(h - 2 - iHeadingLines), m_dataStart(0), m_dataSize(0)
{
}
-CursesIntf::~CursesIntf()
+void Box::draw(const string& iTitle) const
{
- GameFactory::Instance()->releaseGame(*m_game);
- GameFactory::Destroy();
+ if (m_w > 3 && m_h > 2)
+ {
+ // Add one space before and after the title for readability
+ string title;
+ if (!iTitle.empty())
+ title = " " + iTitle + " ";
+ unsigned int l = title.size();
+ // Truncate the title if needed
+ if ((int)l > m_w - 2)
+ l = m_w - 2;
+
+ mvwaddch(m_win, m_y, m_x, ACS_ULCORNER);
+ mvwhline(m_win, m_y, m_x + 1, ACS_HLINE, (m_w - l - 2)/2);
+ mvwprintw(m_win,m_y, m_x + 1 + (m_w - l - 2)/2, "%s", title.c_str());
+ mvwhline(m_win, m_y, m_x + (m_w - l)/2 + l,
+ ACS_HLINE, m_w - 1 - ((m_w - l)/2 + l));
+ mvwaddch(m_win, m_y, m_x + m_w - 1, ACS_URCORNER);
+
+ mvwvline(m_win, m_y + 1, m_x, ACS_VLINE, m_h - 2);
+ mvwvline(m_win, m_y + 1, m_x + m_w - 1, ACS_VLINE, m_h - 2);
+
+ mvwaddch(m_win, m_y + m_h - 1, m_x, ACS_LLCORNER);
+ mvwhline(m_win, m_y + m_h - 1, m_x + 1, ACS_HLINE, m_w - 2);
+ mvwaddch(m_win, m_y + m_h - 1, m_x + m_w - 1, ACS_LRCORNER);
+ }
}
-void CursesIntf::drawBox(WINDOW *win, int y, int x, int h, int w,
- const string& iTitle)
+void Box::printDataLine(int n, int x, const char *fmt, ...) const
{
- if (w > 3 && h > 2)
+ if (n < getFirstLine() || n >= getLastLine() || m_w <= x - m_x + 1)
+ return;
+
+ va_list vl_args;
+ char *buf = NULL;
+ va_start(vl_args, fmt);
+ vasprintf(&buf, fmt, vl_args);
+ va_end(vl_args);
+
+ if (buf == NULL)
{
- int i_len = iTitle.size();
+ return;
+ }
+
+ mvwprintw(m_win, m_topLine + n - m_dataStart, x, "%s",
+ truncString(buf, m_w - 1 - x + m_x).c_str());
+ free(buf);
+}
- if (i_len > w - 2) i_len = w - 2;
- mvwaddch(win, y, x, ACS_ULCORNER);
- mvwhline(win, y, x+1, ACS_HLINE, ( w-i_len-2)/2);
- mvwprintw(win,y, x+1+(w-i_len-2)/2, "%s", iTitle.c_str());
- mvwhline(win, y, x+(w-i_len)/2+i_len,
- ACS_HLINE, w - 1 - ((w-i_len)/2+i_len));
- mvwaddch(win, y, x+w-1,ACS_URCORNER);
+bool Box::scrollOneLineUp()
+{
+ if (m_dataSize <= m_nbLines || m_dataStart == 0)
+ return false;
+ m_dataStart--;
+ return true;
+}
- mvwvline(win, y+1, x, ACS_VLINE, h-2);
- mvwvline(win, y+1, x+w-1, ACS_VLINE, h-2);
- mvwaddch(win, y+h-1, x, ACS_LLCORNER);
- mvwhline(win, y+h-1, x+1, ACS_HLINE, w - 2);
- mvwaddch(win, y+h-1, x+w-1, ACS_LRCORNER);
- }
+bool Box::scrollOneLineDown()
+{
+ if (m_dataSize <= m_nbLines || m_dataStart >= m_dataSize - 1)
+ return false;
+ m_dataStart++;
+ return true;
+}
+
+
+bool Box::scrollOnePageUp()
+{
+ if (m_dataSize <= m_nbLines)
+ return false;
+ m_dataStart -= m_nbLines;
+ if (m_dataStart < 0)
+ m_dataStart = 0;
+ return true;
}
-void CursesIntf::clearRect(WINDOW *win, int y, int x, int h, int w)
+bool Box::scrollOnePageDown()
+{
+ if (m_dataSize <= m_nbLines)
+ return false;
+ m_dataStart += m_nbLines;
+ if (m_dataStart > m_dataSize - 1)
+ m_dataStart = m_dataSize - 1;
+ return true;
+}
+
+
+bool Box::scrollBeginning()
+{
+ if (m_dataSize <= m_nbLines || m_dataStart == 0)
+ return false;
+ m_dataStart = 0;
+ return true;
+}
+
+
+bool Box::scrollEnd()
+{
+ if (m_dataSize <= m_nbLines || m_dataStart == m_dataSize - 1)
+ return false;
+ m_dataStart = m_dataSize - 1;
+ return true;
+}
+
+
+void Box::clearRect(WINDOW *win, int y, int x, int h, int w)
{
for (int i = 0; i < h; i++)
{
@@ -92,32 +170,31 @@
}
-void CursesIntf::boxPrint(WINDOW *win, int y, int x, const char *fmt, ...)
+CursesIntf::CursesIntf(WINDOW *win, Game& iGame)
+ : m_win(win), m_game(&iGame), m_state(DEFAULT), m_dying(false),
+ m_box(win, 0, 0, 0, 0), m_showDots(false)
{
- if (y < m_boxStart || y - m_boxStart >= m_boxLines)
- return;
+}
- va_list vl_args;
- char *buf = NULL;
- va_start(vl_args, fmt);
- vasprintf(&buf, fmt, vl_args);
- va_end(vl_args);
- if (buf == NULL)
- {
- return;
- }
- mvwprintw(win, m_boxY + y - m_boxStart, x, "%s", buf);
+CursesIntf::~CursesIntf()
+{
+ GameFactory::Instance()->releaseGame(*m_game);
+ GameFactory::Destroy();
}
-void CursesIntf::drawStatus(WINDOW *win, int y, int x,
- const string& iMessage, bool error)
+void CursesIntf::drawStatus(WINDOW *win, const string& iMessage, bool error)
{
+ int cols;
+ int lines;
+ getmaxyx(win, lines, cols);
+ int x = 0;
+ int y = lines - 1;
if (error)
wattron(win, COLOR_PAIR(COLOR_YELLOW));
mvwprintw(win, y, x, iMessage.c_str());
- whline(win, ' ', COLS - x - 1 - iMessage.size());
+ whline(win, ' ', cols - x - 1 - iMessage.size());
if (error)
wattron(win, COLOR_PAIR(COLOR_WHITE));
}
@@ -126,7 +203,8 @@
void CursesIntf::drawBoard(WINDOW *win, int y, int x) const
{
// Box around the board
- drawBox(win, y + 1, x + 3, 17, 47, "");
+ Box box(win, y + 1, x + 3, 17, 47);
+ box.draw();
// Print the coordinates
for (int i = 0; i < 15; i++)
@@ -189,7 +267,8 @@
void CursesIntf::drawScoresRacks(WINDOW *win, int y, int x) const
{
- drawBox(win, y, x, m_game->getNPlayers() + 2, 25, _(" Scores "));
+ Box box(win, y, x, m_game->getNPlayers() + 2, 25);
+ box.draw(_("Scores"));
for (int i = 0; i < m_game->getNPlayers(); i++)
{
if (m_game->getMode() != Game::kTRAINING && i == m_game->currPlayer())
@@ -203,7 +282,8 @@
// Distance between the 2 boxes
int yOff = m_game->getNPlayers() + 3;
- drawBox(win, y + yOff, x, m_game->getNPlayers() + 2, 25, _(" Racks "));
+ Box box2(win, y + yOff, x, m_game->getNPlayers() + 2, 25);
+ box2.draw(_("Racks"));
for (int i = 0; i < m_game->getNPlayers(); i++)
{
if (m_game->getMode() != Game::kTRAINING && i == m_game->currPlayer())
@@ -228,126 +308,187 @@
}
-void CursesIntf::drawResults(WINDOW *win, int y, int x)
+void CursesIntf::drawResults(Box &ioBox) const
{
if (m_game->getMode() != Game::kTRAINING)
return;
Training *tr_game = static_cast<Training*>(m_game);
- int h = 17;
- int w = 25;
- drawBox(win, y, x, h, w, _(" Search results "));
- m_boxY = y + 1;
- m_boxLines = h - 2;
- m_boxLinesData = tr_game->getResults().size();
+ ioBox.draw(_("Search results"));
+ ioBox.setDataSize(tr_game->getResults().size());
int i;
const Results& res = tr_game->getResults();
- for (i = m_boxStart; i < res.size() &&
- i < m_boxStart + m_boxLines; i++)
+ int x = ioBox.getLeft();
+ for (i = ioBox.getFirstLine(); i < res.size() && i < ioBox.getLastLine();
i++)
{
const Round &r = res.get(i);
wstring coord = r.getCoord().toString();
- boxPrint(win, i, x + 1, "%3d %s %3s",
+ ioBox.printDataLine(i, x, "%3d %s %3s",
r.getPoints(),
- padAndConvert(r.getWord(), w - 11, false).c_str(),
+ padAndConvert(r.getWord(), ioBox.getWidth() - 9,
false).c_str(),
convertToMb(coord).c_str());
}
// Complete the list with empty lines, to avoid trails
- for (; i < m_boxStart + m_boxLines; i++)
+ for (; i < ioBox.getLastLine(); i++)
{
- boxPrint(win, i, x + 1, string(w - 2, ' ').c_str());
+ ioBox.printDataLine(i, x + 1, string(ioBox.getWidth(), ' ').c_str());
}
}
-void CursesIntf::drawHistory(WINDOW *win, int y, int x)
+void CursesIntf::drawHistory(Box &ioBox) const
{
// To allow pseudo-scrolling, without leaving trails
- clear();
+ ioBox.clearData();
- drawBox(win, y, x, LINES - y, COLS - x, _(" History of the game "));
- m_boxY = y + 1;
- m_boxLines = LINES - y - 2;
- m_boxLinesData = m_game->getHistory().getSize();
+ ioBox.draw(_("History of the game"));
+ ioBox.setDataSize(m_game->getHistory().getSize());
+ int x = ioBox.getLeft();
+ int y = ioBox.getTop();
// Heading
- boxPrint(win, m_boxStart, x + 2,
- _(" N | RACK | SOLUTION | REF | PTS | P | BONUS"));
- mvwhline(win, y + 2, x + 2, ACS_HLINE, 55);
+ string heading = truncString(_(" N | RACK | SOLUTION | REF |
PTS | P | BONUS"),
+ ioBox.getWidth() - 1);
+ mvwprintw(m_win, y, x + 1, "%s", heading.c_str());
+ mvwhline(m_win, y + 1, x + 1, ACS_HLINE, heading.size());
int i;
- for (i = m_boxStart + 0; i < m_game->getHistory().getSize() &&
- i < m_boxStart + m_boxLines; i++)
+ for (i = ioBox.getFirstLine();
+ i < m_game->getHistory().getSize() && i < ioBox.getLastLine(); i++)
{
const Turn& t = m_game->getHistory().getTurn(i);
const Round& r = t.getRound();
wstring coord = r.getCoord().toString();
- boxPrint(win, i + 2, x + 2,
- "%2d %s %s %s %3d %1d %c",
+ ioBox.printDataLine(i, x,
+ " %2d %s %s %s %3d %1d %c",
i + 1, padAndConvert(t.getPlayedRack().toString(), 8).c_str(),
padAndConvert(r.getWord(), 15, false).c_str(),
padAndConvert(coord, 3).c_str(), r.getPoints(),
t.getPlayer(), r.getBonus() ? '*' : ' ');
}
- mvwvline(win, y + 1, x + 5, ACS_VLINE, min(i + 2 - m_boxStart,
m_boxLines));
- mvwvline(win, y + 1, x + 16, ACS_VLINE, min(i + 2 - m_boxStart,
m_boxLines));
- mvwvline(win, y + 1, x + 34, ACS_VLINE, min(i + 2 - m_boxStart,
m_boxLines));
- mvwvline(win, y + 1, x + 40, ACS_VLINE, min(i + 2 - m_boxStart,
m_boxLines));
- mvwvline(win, y + 1, x + 46, ACS_VLINE, min(i + 2 - m_boxStart,
m_boxLines));
- mvwvline(win, y + 1, x + 50, ACS_VLINE, min(i + 2 - m_boxStart,
m_boxLines));
+ int nbLines = min(i + 2 - ioBox.getFirstLine(),
+ ioBox.getLastLine() - ioBox.getFirstLine() + 2);
+ mvwvline(m_win, y, x + 4, ACS_VLINE, nbLines);
+ mvwvline(m_win, y, x + 15, ACS_VLINE, nbLines);
+ mvwvline(m_win, y, x + 33, ACS_VLINE, nbLines);
+ mvwvline(m_win, y, x + 39, ACS_VLINE, nbLines);
+ mvwvline(m_win, y, x + 45, ACS_VLINE, nbLines);
+ mvwvline(m_win, y, x + 49, ACS_VLINE, nbLines);
}
-void CursesIntf::drawHelp(WINDOW *win, int y, int x)
+void CursesIntf::drawHelp(Box &ioBox) const
{
// To allow pseudo-scrolling, without leaving trails
- clear();
-
- drawBox(win, y, x, LINES - y, COLS - x, _(" Help "));
- m_boxY = y + 1;
- m_boxLines = LINES - y - 2;
+ ioBox.clearData();
+ ioBox.draw(_("Help"));
+ int x = ioBox.getLeft() + 1;
int n = 0;
- boxPrint(win, n++, x + 2, _("[Global]"));
- boxPrint(win, n++, x + 2, _(" h, H, ? Show/hide help box"));
- boxPrint(win, n++, x + 2, _(" y, Y Show/hide history of the
game"));
- boxPrint(win, n++, x + 2, _(" e, E Show/hide dots on empty
squares of the board"));
- boxPrint(win, n++, x + 2, _(" d, D Check the existence of a
word in the dictionary"));
- boxPrint(win, n++, x + 2, _(" j, J Play a word"));
- boxPrint(win, n++, x + 2, _(" s, S Save the game"));
- boxPrint(win, n++, x + 2, _(" l, L Load a game"));
- boxPrint(win, n++, x + 2, _(" q, Q Quit"));
- boxPrint(win, n++, x + 2, "");
-
- boxPrint(win, n++, x + 2, _("[Training mode]"));
- boxPrint(win, n++, x + 2, _(" * Take a random rack"));
- boxPrint(win, n++, x + 2, _(" + Complete the current rack
randomly"));
- boxPrint(win, n++, x + 2, _(" t, T Set the rack manually"));
- boxPrint(win, n++, x + 2, _(" c, C Compute all the possible
words"));
- boxPrint(win, n++, x + 2, _(" r, R Show/hide search
results"));
- boxPrint(win, n++, x + 2, "");
-
- boxPrint(win, n++, x + 2, _("[Duplicate mode]"));
- boxPrint(win, n++, x + 2, _(" n, N Switch to the next human
player"));
- boxPrint(win, n++, x + 2, "");
-
- boxPrint(win, n++, x + 2, _("[Free game mode]"));
- boxPrint(win, n++, x + 2, _(" p, P Pass your turn (with or
without changing letters)"));
- boxPrint(win, n++, x + 2, "");
-
- boxPrint(win, n++, x + 2, _("[Miscellaneous]"));
- boxPrint(win, n++, x + 2, _(" <up>, <down> Navigate in a box line by
line"));
- boxPrint(win, n++, x + 2, _(" <pgup>, <pgdown> Navigate in a box page by
page"));
- boxPrint(win, n++, x + 2, _(" Ctrl-l Refresh the screen"));
+ ioBox.printDataLine(n++, x, _("[Global]"));
+ ioBox.printDataLine(n++, x, _(" h, H, ? Show/hide help box"));
+ ioBox.printDataLine(n++, x, _(" y, Y Show/hide history of
the game"));
+ ioBox.printDataLine(n++, x, _(" b, B Show/hide contents of
the bag (including letters of the racks)"));
+ ioBox.printDataLine(n++, x, _(" e, E Show/hide dots on empty
squares of the board"));
+ ioBox.printDataLine(n++, x, _(" d, D Check the existence of
a word in the dictionary"));
+ ioBox.printDataLine(n++, x, _(" j, J Play a word"));
+ ioBox.printDataLine(n++, x, _(" s, S Save the game"));
+ ioBox.printDataLine(n++, x, _(" l, L Load a game"));
+ ioBox.printDataLine(n++, x, _(" q, Q Quit"));
+ ioBox.printDataLine(n++, x, "");
+
+ ioBox.printDataLine(n++, x, _("[Training mode]"));
+ ioBox.printDataLine(n++, x, _(" * Take a random rack"));
+ ioBox.printDataLine(n++, x, _(" + Complete the current
rack randomly"));
+ ioBox.printDataLine(n++, x, _(" t, T Set the rack
manually"));
+ ioBox.printDataLine(n++, x, _(" c, C Compute all the
possible words"));
+ ioBox.printDataLine(n++, x, _(" r, R Show/hide search
results"));
+ ioBox.printDataLine(n++, x, "");
+
+ ioBox.printDataLine(n++, x, _("[Duplicate mode]"));
+ ioBox.printDataLine(n++, x, _(" n, N Switch to the next
human player"));
+ ioBox.printDataLine(n++, x, "");
+
+ ioBox.printDataLine(n++, x, _("[Free game mode]"));
+ ioBox.printDataLine(n++, x, _(" p, P Pass your turn (with or
without changing letters)"));
+ ioBox.printDataLine(n++, x, "");
+
+ ioBox.printDataLine(n++, x, _("[Miscellaneous]"));
+ ioBox.printDataLine(n++, x, _(" <up>, <down> Navigate in a box line
by line"));
+ ioBox.printDataLine(n++, x, _(" <pgup>, <pgdown> Navigate in a box page
by page"));
+ ioBox.printDataLine(n++, x, _(" Ctrl-l Refresh the screen"));
+
+ ioBox.setDataSize(n);
+}
+
+
+void CursesIntf::drawBag(Box &ioBox) const
+{
+ // To allow pseudo-scrolling, without leaving trails
+ ioBox.clearData();
+
+ ioBox.draw(_("Bag"));
+ vector<Tile> allTiles = m_game->getDic().getAllTiles();
+ ioBox.setDataSize(allTiles.size());
+ int x = ioBox.getLeft();
+ int y = ioBox.getTop();
+
+ // Heading
+ string heading = truncString(_(" LETTER | POINTS | FREQUENCY | REMAINING"),
+ ioBox.getWidth() - 1);
+ mvwprintw(m_win, y, x + 1, "%s", heading.c_str());
+ mvwhline(m_win, y + 1, x + 1, ACS_HLINE, heading.size());
+
+ int i;
+ for (i = ioBox.getFirstLine(); i < (int)allTiles.size() && i <
ioBox.getLastLine(); i++)
+ {
+ ioBox.printDataLine(i, ioBox.getLeft() + 1,
+ " %s %2d %2d %s",
+ padAndConvert(wstring(1, allTiles[i].toChar()),
2).c_str(),
+ allTiles[i].getPoints(),
+ allTiles[i].maxNumber(),
+
convertToMb(wstring(m_game->getBag().in(allTiles[i]),
+
allTiles[i].toChar())).c_str());
+ }
+
+ int nbLines = min(i + 2 - ioBox.getFirstLine(),
+ ioBox.getLastLine() - ioBox.getFirstLine() + 2);
+ mvwvline(m_win, y, x + 9, ACS_VLINE, nbLines);
+ mvwvline(m_win, y, x + 18, ACS_VLINE, nbLines);
+ mvwvline(m_win, y, x + 30, ACS_VLINE, nbLines);
+}
+
+
+void CursesIntf::setState(State iState)
+{
+ // Clear the previous box
+ m_box.clear();
+
+ // Get the size of the screen (better than using COLS and LINES directly,
+ // according to the manual)
+ int lines;
+ int cols;
+ getmaxyx(m_win, lines, cols);
- m_boxLinesData = n;
+ m_state = iState;
+ if (m_state == DEFAULT)
+ m_box = Box(m_win, 0, 0, 0, 0);
+ else if (m_state == RESULTS)
+ m_box = Box(m_win, 3, 54, 17, 25);
+ else if (m_state == HISTORY)
+ m_box = Box(m_win, 1, 0, lines - 1, cols, 2);
+ else if (m_state == HELP)
+ m_box = Box(m_win, 1, 0, lines - 1, cols);
+ else if (m_state == BAG)
+ m_box = Box(m_win, 1, 0, lines - 1, cols, 2);
}
void CursesIntf::playWord(WINDOW *win, int y, int x)
{
- drawBox(win, y, x, 4, 32, _(" Play a word "));
+ Box box(win, y, x, 4, 32);
+ box.draw(_("Play a word"));
mvwprintw(win, y + 1, x + 2, _("Played word:"));
mvwprintw(win, y + 2, x + 2, _("Coordinates:"));
wrefresh(win);
@@ -371,17 +512,22 @@
int res = m_game->play(coord, word);
if (res)
{
- drawStatus(win, LINES - 1, 0, _("Incorrect or misplaced word"));
+ drawStatus(win, _("Incorrect or misplaced word"));
+ }
+ else
+ {
+ // If everything went well, go back to the default view
+ setState(DEFAULT);
}
}
- m_state = DEFAULT;
- clearRect(win, y, x, 4, 32);
+ box.clear();
}
void CursesIntf::checkWord(WINDOW *win, int y, int x)
{
- drawBox(win, y, x, 4, 32, _(" Dictionary "));
+ Box box(win, y, x, 4, 32);
+ box.draw(_("Dictionary"));
mvwprintw(win, y + 1, x + 2, _("Enter the word to check:"));
wrefresh(win);
@@ -394,16 +540,17 @@
snprintf(s, 100, _("The word '%ls' exists"), word.c_str());
else
snprintf(s, 100, _("The word '%ls' does not exist"), word.c_str());
- drawStatus(win, LINES - 1, 0, s);
+ drawStatus(win, s);
}
m_state = DEFAULT;
- clearRect(win, y, x, 4, 32);
+ box.clear();
}
void CursesIntf::saveGame(WINDOW *win, int y, int x)
{
- drawBox(win, y, x, 4, 32, _(" Save the game "));
+ Box box(win, y, x, 4, 32);
+ box.draw(_("Save the game"));
mvwprintw(win, y + 1, x + 2, _("Enter the file name:"));
wrefresh(win);
@@ -423,16 +570,17 @@
fout.close();
snprintf(s, 100, _("Game saved in %ls"), filename.c_str());
}
- drawStatus(win, LINES - 1, 0, s);
+ drawStatus(win, s);
}
m_state = DEFAULT;
- clearRect(win, y, x, 4, 32);
+ box.clear();
}
void CursesIntf::loadGame(WINDOW *win, int y, int x)
{
- drawBox(win, y, x, 4, 32, _(" Load a game "));
+ Box box(win, y, x, 4, 32);
+ box.draw(_("Load a game"));
mvwprintw(win, y + 1, x + 2, _("Enter the file name:"));
wrefresh(win);
@@ -461,16 +609,17 @@
}
fclose(fin);
}
- drawStatus(win, LINES - 1, 0, s);
+ drawStatus(win, s);
}
m_state = DEFAULT;
- clearRect(win, y, x, 4, 32);
+ box.clear();
}
void CursesIntf::passTurn(WINDOW *win, int y, int x, FreeGame &iGame)
{
- drawBox(win, y, x, 4, 32, _(" Pass your turn "));
+ Box box(win, y, x, 4, 32);
+ box.draw(_("Pass your turn"));
mvwprintw(win, y + 1, x + 2, _("Enter the letters to change:"));
wrefresh(win);
@@ -480,17 +629,18 @@
int res = iGame.pass(letters, m_game->currPlayer());
if (res)
{
- drawStatus(win, LINES - 1, 0, _("Cannot pass the turn"));
+ drawStatus(win, _("Cannot pass the turn"));
}
}
m_state = DEFAULT;
- clearRect(win, y, x, 4, 32);
+ box.clear();
}
void CursesIntf::setRack(WINDOW *win, int y, int x, Training &iGame)
{
- drawBox(win, y, x, 4, 32, _(" Set rack "));
+ Box box(win, y, x, 4, 32);
+ box.draw(_("Set rack"));
mvwprintw(win, y + 1, x + 2, _("Enter the new letters:"));
wrefresh(win);
@@ -500,21 +650,26 @@
int res = iGame.setRackManual(false, letters);
if (res)
{
- drawStatus(win, LINES - 1, 0, _("Cannot take these letters from
the bag"));
+ drawStatus(win, _("Cannot take these letters from the bag"));
}
}
m_state = DEFAULT;
- clearRect(win, y, x, 4, 32);
+ box.clear();
}
bool CursesIntf::readString(WINDOW *win, int y, int x, int n, wstring &oString,
unsigned int flag)
{
+ // Save the initial position
+ int x0 = x;
wint_t c;
wmove(win, y, x);
curs_set(1);
int res;
+ // Position in the string before which to insert the next character
+ // (the character will be added at the end if pos == oString.size())
+ unsigned int pos = 0;
while ((res = get_wch(&c)) != ERR)
{
if (c == 0x1b ) // Esc
@@ -529,43 +684,98 @@
}
else if (c == 0x0c) // Ctrl-L
{
-// clear();
redraw(win);
wmove(win, y, x);
}
- else if (c == KEY_BACKSPACE && res == KEY_CODE_YES && !oString.empty())
+ else if (c == 0x0b) // Ctrl-K
+ {
+ // Remove everything after the cursor position
+ int len = oString.size() - pos;
+ oString = oString.erase(pos);
+ mvwprintw(win, y, x, string(len, ' ').c_str());
+ wmove(win, y, x);
+ }
+ else if (c == 0x15) // Ctrl-U
+ {
+ // Remove everything before the cursor position
+ oString.erase(0, pos);
+ int len = pos;
+ x = x0;
+ pos = 0;
+ mvwprintw(win, y, x0, "%s", convertToMb(oString + wstring(len, L'
')).c_str());
+ wmove(win, y, x);
+ }
+ else if (res == KEY_CODE_YES)
+ {
+ if (c == KEY_BACKSPACE && pos != 0)
+ {
+ x--;
+ pos--;
+ oString.erase(pos, 1);
+ mvwprintw(win, y, x0, "%s", convertToMb(oString + L"
").c_str());
+ wmove(win, y, x);
+ }
+ else if (c == KEY_DC)
+ {
+ oString.erase(pos, 1);
+ mvwprintw(win, y, x0, "%s", convertToMb(oString + L"
").c_str());
+ wmove(win, y, x);
+ }
+ else if (c == KEY_LEFT && pos != 0)
{
x--;
- mvwprintw(win, y, x, " ");
+ pos--;
wmove(win, y, x);
- oString.erase(oString.size() - 1);
}
- else if (res == OK && iswalnum(c) && oString.size() < (unsigned int)n)
+ else if (c == KEY_RIGHT && pos != oString.size())
{
- mvwprintw(win, y, x, "%lc", c);
x++;
- oString += c;
+ pos++;
+ wmove(win, y, x);
+ }
+ else if (c == KEY_HOME)
+ {
+ x = x0;
+ pos = 0;
+ wmove(win, y, x);
+ }
+ else if (c == KEY_END)
+ {
+ x = x0 + oString.size();
+ pos = oString.size();
+ wmove(win, y, x);
}
else
+ beep();
+ }
+ else if (res == OK && iswalnum(c) && oString.size() < (unsigned int)n)
{
- if (flag & kJOKER && c == L'?')
+ x++;
+ oString.insert(pos++, 1, c);
+ mvwprintw(win, y, x0, "%s", convertToMb(oString).c_str());
+ wmove(win, y, x);
+ }
+ else if (flag & kJOKER && c == L'?')
{
- mvwprintw(win, y, x, "%lc", c);
x++;
- oString += c;
+ oString.insert(pos++, 1, c);
+ mvwprintw(win, y, x0, "%s", convertToMb(oString).c_str());
+ wmove(win, y, x);
}
- if (flag & kFILENAME)
+ else if (flag & kFILENAME)
{
if (c == L'/' || c == L'.' || c == L'-' || c == L'_' || c ==
L' ')
{
- mvwprintw(win, y, x, "%lc", c);
x++;
oString += c;
+ mvwprintw(win, y, x0, "%s", convertToMb(oString).c_str());
+ wmove(win, y, x);
}
+ else
+ beep();
}
- }
-// else
-// mvwprintw(win, 0, 0, "%3lc", c);
+ else
+ beep();
}
curs_set(0);
return false;
@@ -651,46 +861,22 @@
if (res != 2)
return res;
}
- else // m_state is in {HELP, RESULTS, HISTORY}
+ else // m_state is in {HELP, RESULTS, HISTORY, BAG}
{
switch (iKey)
{
case KEY_HOME:
- if (m_boxLinesData <= m_boxLines && m_boxStart > 0)
- return 0;
- m_boxStart = 0;
- return 1;
+ return m_box.scrollBeginning() ? 1 : 0;
case KEY_END:
- if (m_boxLinesData <= m_boxLines &&
- m_boxStart < m_boxLinesData - 1)
- return 0;
- m_boxStart = m_boxLinesData - 1;
- return 1;
+ return m_box.scrollEnd() ? 1 : 0;
case KEY_UP:
- if (m_boxLinesData <= m_boxLines || m_boxStart <= 0)
- return 0;
- m_boxStart--;
- return 1;
+ return m_box.scrollOneLineUp() ? 1 : 0;
case KEY_DOWN:
- if (m_boxLinesData <= m_boxLines ||
- m_boxStart >= m_boxLinesData - 1)
- return 0;
- m_boxStart++;
- return 1;
+ return m_box.scrollOneLineDown() ? 1 : 0;
case KEY_PPAGE:
- if (m_boxLinesData <= m_boxLines)
- return 0;
- m_boxStart -= m_boxLines;
- if (m_boxStart < 0)
- m_boxStart = 0;
- return 1;
+ return m_box.scrollOnePageUp() ? 1 : 0;
case KEY_NPAGE:
- if (m_boxLinesData <= m_boxLines)
- return 0;
- m_boxStart += m_boxLines;
- if (m_boxStart > m_boxLinesData - 1)
- m_boxStart = m_boxLinesData - 1;
- return 1;
+ return m_box.scrollOnePageDown() ? 1 : 0;
}
}
@@ -701,10 +887,9 @@
case 'H':
case '?':
if (m_state == HELP)
- m_state = DEFAULT;
+ setState(DEFAULT);
else
- m_state = HELP;
- m_boxStart = 0;
+ setState(HELP);
clear();
return 1;
@@ -712,10 +897,9 @@
case 'y':
case 'Y':
if (m_state == HISTORY)
- m_state = DEFAULT;
+ setState(DEFAULT);
else
- m_state = HISTORY;
- m_boxStart = 0;
+ setState(HISTORY);
clear();
return 1;
@@ -725,11 +909,20 @@
if (m_game->getMode() != Game::kTRAINING)
return 0;
if (m_state == RESULTS)
- m_state = DEFAULT;
+ setState(DEFAULT);
else
- m_state = RESULTS;
- m_boxStart = 0;
- clearRect(m_win, 3, 54, 30, 25);
+ setState(RESULTS);
+ Box::clearRect(m_win, 3, 54, 30, 25);
+ return 1;
+
+ // Toggle bag
+ case 'b':
+ case 'B':
+ if (m_state == BAG)
+ setState(DEFAULT);
+ else
+ setState(BAG);
+ clear();
return 1;
// Toggle dots display
@@ -749,7 +942,7 @@
// Play a word
case 'j':
case 'J':
- if (m_state != DEFAULT)
+ if (m_state != DEFAULT && m_state != RESULTS)
return 0;
playWord(m_win, 22, 10);
return 1;
@@ -757,6 +950,8 @@
// Ctrl-L should clear and redraw the screen
case 0x0c:
clear();
+ // Force the re-definition of the current box
+ setState(m_state);
return 1;
case 'l':
@@ -776,7 +971,7 @@
// Quit
case 'q':
case 'Q':
- case 0x1b: // Esc
+ //case 0x1b: // Esc
m_dying = true;
return 0;
@@ -795,16 +990,20 @@
}
else if (m_state == RESULTS)
{
- drawResults(win, 3, 54);
+ drawResults(m_box);
drawBoard(win, 2, 0);
}
else if (m_state == HELP)
{
- drawHelp(win, 1, 0);
+ drawHelp(m_box);
}
else if (m_state == HISTORY)
{
- drawHistory(win, 1, 0);
+ drawHistory(m_box);
+ }
+ else if (m_state == BAG)
+ {
+ drawBag(m_box);
}
// Title
@@ -881,7 +1080,7 @@
// Do not echo
noecho();
- // mainIntf will take care of destroying game for us.
+ // mainIntf will take care of destroying game for us
CursesIntf mainIntf(wBoard, *game);
mainIntf.redraw(wBoard);
Index: utils/ncurses.h
===================================================================
RCS file: /cvsroot/eliot/eliot/utils/ncurses.h,v
retrieving revision 1.6.4.1
retrieving revision 1.6.4.2
diff -u -b -r1.6.4.1 -r1.6.4.2
--- utils/ncurses.h 3 Dec 2007 17:27:34 -0000 1.6.4.1
+++ utils/ncurses.h 16 Dec 2007 15:58:44 -0000 1.6.4.2
@@ -32,6 +32,69 @@
using std::wstring;
+class Box
+{
+ public:
+ // Create a titled box with the specified position and size,
+ // containing iHeadingLines non-scrolling lines.
+ // The number of data to display (with the printLine() method)
+ // can be set later using the setDataSize() method.
+ Box(WINDOW *win, int y, int x, int h, int w,
+ unsigned int iHeadingLines = 0);
+
+ // Simply draw the box (without any content)
+ void draw(const string& iTitle = "") const;
+
+ // Print data line number n (starting at 0), taking care of
+ // the current scrolling state
+ void printDataLine(int n, int x, const char *fmt, ...) const;
+
+ // Set the number of lines of the data to display
+ void setDataSize(unsigned int iNbLines) { m_dataSize = iNbLines; }
+
+ // Control scrolling
+ // Return true if redrawing is needed, false otherwise
+ bool scrollOneLineUp();
+ bool scrollOneLineDown();
+ bool scrollOnePageUp();
+ bool scrollOnePageDown();
+ bool scrollBeginning();
+ bool scrollEnd();
+
+ // Clear the box completely
+ void clear() const { clearRect(m_win, m_y, m_x, m_h, m_w); }
+ // Clear the scrolling zone of the box
+ void clearData() const { clearRect(m_win, m_topLine, m_x + 1,
+ m_nbLines, getWidth()); }
+ // Clear an arbitrary rectangular zone
+ static void clearRect(WINDOW *win, int y, int x, int h, int w);
+
+ // First line of data to display (included)
+ int getFirstLine() const { return m_dataStart; }
+ // Last line of data to display (excluded)
+ int getLastLine() const { return m_dataStart + m_nbLines; }
+
+ // First line inside the box
+ int getTop() const { return m_y + 1; }
+ // First column available for writing
+ int getLeft() const { return m_x + 1; }
+ // Client width
+ int getWidth() const { return m_w - 2; }
+
+ private:
+ WINDOW *m_win;
+ int m_x;
+ int m_y;
+ int m_w;
+ int m_h;
+ string m_title;
+ int m_topLine;
+ int m_nbLines;
+ int m_dataStart;
+ int m_dataSize;
+};
+
+
/**
* This class implements the ncurses interface.
*/
@@ -53,28 +116,27 @@
DEFAULT, // Default state
HELP, // Help panel is shown
HISTORY, // Game history panel is shown
- RESULTS // Search results panel is shown
+ RESULTS, // Search results panel is shown
+ BAG // Bag contents panel is shown
};
- // Draw a titled box with the specified position and size
- static void drawBox(WINDOW *win, int y, int x, int h, int w,
- const string& iTitle);
- // Clear a rectangular zone
- static void clearRect(WINDOW *win, int y, int x, int h, int w);
- // Print a line in a box, taking care of the current offset
- void boxPrint(WINDOW *win, int y, int x, const char *fmt, ...);
+
// Write a message in the "status line"
- void drawStatus(WINDOW *win, int y, int x,
- const string& iMessage, bool error = true);
+ void drawStatus(WINDOW *win, const string& iMessage, bool error = true);
// Draw the board, with the coordinates
void drawBoard(WINDOW *win, int y, int x) const;
// Draw the boxes for scores and racks
void drawScoresRacks(WINDOW *win, int y, int x) const;
// Draw the results panel
- void drawResults(WINDOW *win, int y, int x);
+ void drawResults(Box &ioBox) const;
// Draw the history panel
- void drawHistory(WINDOW *win, int y, int x);
+ void drawHistory(Box &ioBox) const;
// Draw the help panel
- void drawHelp(WINDOW *win, int y, int x);
+ void drawHelp(Box &ioBox) const;
+ // Draw the bag panel
+ void drawBag(Box &ioBox) const;
+
+ // Change the inner state, and initialize the corresponding box
+ void setState(State iState);
// Draw the "Play word" box, and handle the played word
void playWord(WINDOW *win, int y, int x);
void checkWord(WINDOW *win, int y, int x);
@@ -82,6 +144,7 @@
void loadGame(WINDOW *win, int y, int x);
void passTurn(WINDOW *win, int y, int x, FreeGame &iGame);
void setRack(WINDOW *win, int y, int x, Training &iGame);
+
// Get a string from the user, with a maximum length
// The string is validated if the user presses Enter (return value: true)
// and it is cancelled if the user presses Esc (return value: false)
@@ -110,14 +173,8 @@
State m_state;
// True when the user requested to quit
bool m_dying;
- // Index of the first line of data to be displayed in the current box
- int m_boxStart;
- // Number of lines of the current box (border excluded)
- int m_boxLines;
- // Number of lines of the data to be displayed in the current box
- int m_boxLinesData;
- // Index of the first line of the box where to write
- int m_boxY;
+ // Scrolling box for the current panel
+ Box m_box;
// True if dots must be shown on empty squares
bool m_showDots;
};