diff options
Diffstat (limited to 'ktuberling')
65 files changed, 3345 insertions, 0 deletions
diff --git a/ktuberling/Makefile.am b/ktuberling/Makefile.am new file mode 100644 index 00000000..55ed363e --- /dev/null +++ b/ktuberling/Makefile.am @@ -0,0 +1,38 @@ +# this 10 paths are KDE specific. Use them: +# kde_htmldir Where your docs should go to. (contains lang subdirs) +# kde_appsdir Where your application file (.desktop) should go to. +# kde_icondir Where your icon should go to. +# kde_sounddir Where system sounds should go to. +# kde_datadir Where you install application data. (Use a subdir) +# kde_locale Where translation files should go to.(contains lang subdirs) +# kde_cgidir Where cgi-bin executables should go to. +# kde_confdir Where config files should go to. +# kde_mimedir Where mimetypes should go to. +# kde_toolbardir Where general toolbar icons should go to. +# kde_wallpaperdir Where general wallpapers should go to. + +INCLUDES= -I$(top_srcdir)/libkdegames $(all_includes) +SUBDIRS = . museum sounds pics + +bin_PROGRAMS = ktuberling + +ktuberling_SOURCES = action.cpp main.cpp toplevel.cpp playground.cpp todraw.cpp soundfactory.cpp + +ktuberling_METASOURCES = AUTO +ktuberling_LDFLAGS = $(all_libraries) $(KDE_RPATH) +ktuberling_LDADD = $(LIB_KDEGAMES) $(LIB_KFILE) -lkdeprint +ktuberling_DEPENDENCIES = $(LIB_KDEGAMES_DEP) + +KDE_ICON = ktuberling + +xdg_apps_DATA = ktuberling.desktop + +mimetypeapplicationdata_DATA = x-tuberling.desktop +mimetypeapplicationdatadir = $(kde_mimedir)/application + +appsrc_DATA = ktuberlingui.rc +appsrcdir = $(kde_datadir)/ktuberling + +messages: rc.cpp + $(XGETTEXT) rc.cpp $(ktuberling_SOURCES) pics/layout.i18n -o $(podir)/ktuberling.pot + diff --git a/ktuberling/TODO b/ktuberling/TODO new file mode 100644 index 00000000..9bc83a70 --- /dev/null +++ b/ktuberling/TODO @@ -0,0 +1,40 @@ +- Allow point and click instead of drag and drop (KDE bug #68779) + +- Better format for .tuberling files (object names instead of numbers, XML) + +- Split layout.xml in two parts : layout and sounds. The sounds.xml part would + be distributed in the ktuberling-sounds package + +- Draw a small hand when grabbing objects + +- Write title of tuberling last opened / saved on top of the window + +- Choose the current language accordingly to locale settings + +- Add a "man" page for KTuberling + +- See what's wrong with wide cursors on old Tektronix X terminals and if + there's a workaround (KDE bug #68786) + +============= Things for which I need help from other people : ================ + +- More and better localized sounds (German, Spanish, etc) + +- More and better colour gameboards and objects (KDE bug #63211) + For example : Farm with animals + Criminal identification portrait + Clown with accessories + Lizard + Dragon + Gogo (the animal) + Iguana (the animal) + Boy-Barbie + Girl-Barbie + Money (different kind of) + House + Dogs + Cats + +- Sounds in OGG Vorbis format (KDE bug #37251) + +- Text above, not below images (KDE bug #53402) diff --git a/ktuberling/action.cpp b/ktuberling/action.cpp new file mode 100644 index 00000000..a55deb04 --- /dev/null +++ b/ktuberling/action.cpp @@ -0,0 +1,20 @@ +/* ------------------------------------------------------------- + KDE Tuberling + Action stored in the undo buffer + mailto:e.bischoff@noos.fr + ------------------------------------------------------------- */ + +#include "action.h" + +// Constructor +Action::Action + (const ToDraw *drawn1, int zOrder1, + const ToDraw *drawn2, int zOrder2) +{ + if (drawn1) drawnBefore = *drawn1; + zOrderBefore = zOrder1; + + if (drawn2) drawnAfter = *drawn2; + zOrderAfter = zOrder2; +} + diff --git a/ktuberling/action.h b/ktuberling/action.h new file mode 100644 index 00000000..8fdfeb8e --- /dev/null +++ b/ktuberling/action.h @@ -0,0 +1,28 @@ +/* ------------------------------------------------------------- + KDE Tuberling + Action stored in the undo buffer + mailto:e.bischoff@noos.fr + ------------------------------------------------------------- */ + + +#ifndef _ACTION_H_ +#define _ACTION_H_ + +#include "todraw.h" + +class Action +{ + public: + Action(const ToDraw *, int, + const ToDraw *, int); + inline const ToDraw &DrawnBefore() const {return drawnBefore;} + inline int ZOrderBefore() const {return zOrderBefore;} + inline const ToDraw &DrawnAfter() const {return drawnAfter;} + inline int ZOrderAfter() const {return zOrderAfter;} + + private: + ToDraw drawnBefore, drawnAfter; + int zOrderBefore, zOrderAfter; +}; + +#endif diff --git a/ktuberling/hi128-app-ktuberling.png b/ktuberling/hi128-app-ktuberling.png Binary files differnew file mode 100644 index 00000000..1d679c0f --- /dev/null +++ b/ktuberling/hi128-app-ktuberling.png diff --git a/ktuberling/hi16-app-ktuberling.png b/ktuberling/hi16-app-ktuberling.png Binary files differnew file mode 100644 index 00000000..16759609 --- /dev/null +++ b/ktuberling/hi16-app-ktuberling.png diff --git a/ktuberling/hi22-app-ktuberling.png b/ktuberling/hi22-app-ktuberling.png Binary files differnew file mode 100644 index 00000000..865bce26 --- /dev/null +++ b/ktuberling/hi22-app-ktuberling.png diff --git a/ktuberling/hi32-app-ktuberling.png b/ktuberling/hi32-app-ktuberling.png Binary files differnew file mode 100644 index 00000000..08dc6156 --- /dev/null +++ b/ktuberling/hi32-app-ktuberling.png diff --git a/ktuberling/hi48-app-ktuberling.png b/ktuberling/hi48-app-ktuberling.png Binary files differnew file mode 100644 index 00000000..140fab6e --- /dev/null +++ b/ktuberling/hi48-app-ktuberling.png diff --git a/ktuberling/hi64-app-ktuberling.png b/ktuberling/hi64-app-ktuberling.png Binary files differnew file mode 100644 index 00000000..abe60536 --- /dev/null +++ b/ktuberling/hi64-app-ktuberling.png diff --git a/ktuberling/ktuberling.desktop b/ktuberling/ktuberling.desktop new file mode 100644 index 00000000..b6f8e709 --- /dev/null +++ b/ktuberling/ktuberling.desktop @@ -0,0 +1,128 @@ +[Desktop Entry] +Exec=ktuberling %i %m -caption "%c" %u +Name=Potato Guy +Name[af]=Aartappel Man +Name[ar]=لعبة رجل البطاطا +Name[az]=Kartof Adam +Name[be]=Бульбяш +Name[bn]=পটেটো গাই +Name[br]=Paotr ar patatez +Name[cs]=Bramborový chlapík +Name[da]=Kartoffelfyren +Name[de]=Kartoffelknülch +Name[eo]=Terpomulo +Name[es]=Papá Patata +Name[et]=Kartulimees +Name[eu]=Patata jauna +Name[fi]=Perunamies +Name[fo]=Eplamaður +Name[fr]=Monsieur patate +Name[gl]=O Nacho Pataca +Name[he]=מר תפוח אדמה +Name[hi]=पोटैटो गाइ +Name[hr]=Krumpirko +Name[hu]=Krumpli bácsi +Name[is]=Kartöflukall +Name[it]=Uomo patata +Name[ja]=福笑い +Name[km]=មនុស្សដំឡូង +Name[lt]=Bulvinis Vyrukas +Name[lv]=Kartupeļu vīrs +Name[mk]=Компирко +Name[nb]=Potetmannen +Name[nds]=Kantüffelfips +Name[ne]=पोटेटो गाई +Name[nl]=Aardappelmannetje +Name[nn]=Potetfyren +Name[pa]=ਆਲੂ ਮੁੰਡਾ +Name[pl]=Ziemniaczany facet +Name[pt]=Homem Batata +Name[pt_BR]=Homem-Batata +Name[ro]=Domnul Cartof +Name[se]=Buđetolmmái +Name[sk]=Zemiakový chlapec +Name[sl]=Krompirček +Name[sv]=Potatismannen +Name[ta]=உருளைகிழங்கு வீரர் +Name[tg]=Писараки Картошкагин +Name[th]=นายมันฝรั่ง - K +Name[tr]=Patates Adam +Name[uk]=Картопляний хлопець +Name[ven]=Munna wa dabula +Name[wa]=Monsieu Crompire +Name[xh]=Umfana wetapile +Name[zh_CN]=土豆小子 +Name[zh_TW]=馬鈴薯小子 +Name[zu]=I-Potato Guy +GenericName=Game for Children +GenericName[af]=Speletjie vir Kinders +GenericName[ar]=لعبة للأطفال +GenericName[be]=Гульня для дзяцей +GenericName[bg]=Игра за деца +GenericName[bn]=পোলাপানের খেলা +GenericName[bs]=Igra za djecu +GenericName[ca]=Joc per a la canalla +GenericName[cs]=Hra pro děti +GenericName[cy]=Gêm i Blant +GenericName[da]=Spil for børn +GenericName[de]=Spiel für Kinder +GenericName[el]=Παιχνίδι για παιδιά +GenericName[eo]=Infanludo +GenericName[es]=Juego para niños +GenericName[et]=Lastemäng +GenericName[eu]=Umeentzako jokoa +GenericName[fa]=بازی برای بچهها +GenericName[fi]=Peli lapsille +GenericName[fo]=Barnaspæl +GenericName[fr]=Jeu pour les enfants +GenericName[ga]=Cluiche do phaistí +GenericName[gl]=Xogo para Nenos +GenericName[he]=משחק לילדים +GenericName[hi]=बच्चों के लिए खेल +GenericName[hr]=Igra za djecu +GenericName[hu]=Gyermekjáték +GenericName[is]=Leikur fyrir börn +GenericName[it]=Gioco per i bambini +GenericName[ja]=子供用ゲーム +GenericName[km]=ល្បែងសម្រាប់ក្មេង +GenericName[ko]=어린이를 위한 그림 게임 +GenericName[lt]=Žaidimas vaikams +GenericName[lv]=Spēle bērniem +GenericName[mk]=Игра за деца +GenericName[nb]=Barnespill +GenericName[nds]=Speel för Kinners +GenericName[ne]=केटाकेटिका लागि खेल +GenericName[nl]=Spel voor kinderen +GenericName[nn]=Barnespel +GenericName[pa]=ਜਵਾਕਾਂ ਲਈ ਖੇਡ +GenericName[pl]=Gra dla dzieci +GenericName[pt]=Jogo para Crianças +GenericName[pt_BR]=Jogo para Crianças +GenericName[ro]=Joc pentru copii +GenericName[ru]=Клубень +GenericName[se]=Mánáidspeallu +GenericName[sk]=Hra pre deti +GenericName[sl]=Igra za otroke +GenericName[sr]=Игра за децу +GenericName[sr@Latn]=Igra za decu +GenericName[sv]=Spel för barn +GenericName[ta]=குழந்தைகளுக்கான விளையாட்டு +GenericName[tg]=Бозӣ барои бачаҳо +GenericName[th]=เกมสำหรับเด็ก +GenericName[tr]=Çocuklar için bir oyun +GenericName[uk]=Гра для дітей +GenericName[ven]=Mutambo wa Vhana +GenericName[vi]=Game cho trẻ em +GenericName[wa]=Djeu po ls efants +GenericName[xh]=Umdlalo wabantwana +GenericName[zh_CN]=孩子们的游戏 +GenericName[zh_TW]=小孩專屬遊戲 +GenericName[zu]=Umdlalo wabantwana +Type=Application +DocPath=ktuberling/index.html +Terminal=false +Icon=ktuberling +MimeType=application/x-tuberling; +X-KDE-StartupNotify=true +X-DCOP-ServiceType=Multi +Categories=Qt;KDE;Game;X-KDE-KidsGame; diff --git a/ktuberling/ktuberlingui.rc b/ktuberling/ktuberlingui.rc new file mode 100644 index 00000000..75bd3105 --- /dev/null +++ b/ktuberling/ktuberlingui.rc @@ -0,0 +1,41 @@ +<!DOCTYPE kpartgui> +<kpartgui name="ktuberling" version="1"> +<MenuBar> + <Menu name="game"><text>&Game</text> + <Action name="game_save_picture" append="save_merge"/> + </Menu> + <Menu name="playground"><text>&Playground</text> + <Action name="playground_potato_guy"/> + <Action name="playground_penguin"/> + <Action name="playground_aquarium"/> + </Menu> + <Menu name="speech"><text>&Speech</text> + <Action name="speech_no_sound"/> + <Separator/> + <Action name="speech_danish"/> + <Action name="speech_german"/> + <Action name="speech_english"/> + <Action name="speech_spanish"/> + <Action name="speech_finnish"/> + <Action name="speech_french"/> + <Action name="speech_italian"/> + <Action name="speech_lowsaxon"/> + <Action name="speech_dutch"/> + <Action name="speech_portuguese"/> + <Action name="speech_romanian"/> + <Action name="speech_slovak"/> + <Action name="speech_slovenian"/> + <Action name="speech_swedish"/> + <Action name="speech_serbian"/> + </Menu> +</MenuBar> +<ToolBar name="mainToolBar" noMerge="1"><text>Main Toolbar</text> + <Action name="game_new"/> + <Action name="game_load"/> + <Action name="game_save"/> + <Action name="game_print"/> + <Separator/> + <Action name="edit_undo"/> + <Action name="edit_redo"/> +</ToolBar> +</kpartgui> diff --git a/ktuberling/main.cpp b/ktuberling/main.cpp new file mode 100644 index 00000000..5e508e66 --- /dev/null +++ b/ktuberling/main.cpp @@ -0,0 +1,60 @@ +/* ------------------------------------------------------------- + KDE Tuberling + Main program + mailto:e.bischoff@noos.fr + ------------------------------------------------------------- */ + +#include <kapplication.h> +#include <kimageio.h> +#include <klocale.h> +#include <kcmdlineargs.h> +#include <kaboutdata.h> + +#include "toplevel.h" + +static KCmdLineOptions options[] = { + { "+<tuberling-file>", I18N_NOOP("Potato to open"), 0 }, + KCmdLineLastOption +}; + + + +static const char description[] = I18N_NOOP("Potato game for kids"); +static const char text[] = I18N_NOOP("A program by Eric Bischoff <e.bischoff@noos.fr>\nand John Calhoun.\n\nThis program is dedicated to my daughter Sunniva."); + +static const char version[] = "0.4"; + +// Main function +int main(int argc, char *argv[]) +{ + + KAboutData aboutData( "ktuberling", I18N_NOOP("KTuberling"), + version, description, KAboutData::License_GPL, + "(c) 1999-2003, The KTuberling Developers", text); + aboutData.addAuthor("Eric Bischoff", I18N_NOOP("Developer"), "e.bischoff@noos.fr"); + aboutData.addAuthor("John Calhoun", I18N_NOOP("Original concept and artwork")); + aboutData.addCredit("Agnieszka Czajkowska", I18N_NOOP("New artwork"), "agnieszka@imagegalaxy.de"); + aboutData.addCredit("Bas Willems", I18N_NOOP("New artwork"), "cybersurfer@euronet.nl"); + aboutData.addCredit("Roger Larsson", I18N_NOOP("Sounds tuning"), "roger.larsson@norran.net"); + KCmdLineArgs::init(argc, argv, &aboutData); + KCmdLineArgs::addCmdLineOptions(options); + + KApplication app; + KGlobal::locale()->insertCatalogue("libkdegames"); + KImageIO::registerFormats(); + + TopLevel *toplevel=0; + + if (app.isRestored()) + RESTORE(TopLevel) + else { + toplevel = new TopLevel(); + toplevel->show(); + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + if (args->count()) + toplevel->open(args->url(0)); + args->clear(); + } + + return app.exec(); +} diff --git a/ktuberling/museum/Makefile.am b/ktuberling/museum/Makefile.am new file mode 100644 index 00000000..50c11c10 --- /dev/null +++ b/ktuberling/museum/Makefile.am @@ -0,0 +1,10 @@ + +# add here all files +ktuberling_DATA = businessman.tuberling cool.tuberling cyclop.tuberling dali.tuberling \ + einstein.tuberling fly.tuberling grandpa.tuberling happy.tuberling \ + idiot.tuberling miss.tuberling mouse.tuberling picasso.tuberling \ + serious.tuberling \ + crazy.tuberling hippie.tuberling \ + sea.tuberling + +ktuberlingdir = $(kde_datadir)/ktuberling/museum diff --git a/ktuberling/museum/businessman.tuberling b/ktuberling/museum/businessman.tuberling new file mode 100644 index 00000000..fc26c97d --- /dev/null +++ b/ktuberling/museum/businessman.tuberling @@ -0,0 +1,28 @@ +0 +22 103 62 152 124 +12 77 110 124 139 +35 3 67 31 88 +36 126 228 160 249 +3 129 44 170 76 +3 87 45 128 77 +13 57 11 104 40 +17 165 19 212 48 +17 158 15 205 44 +17 151 12 198 41 +17 146 9 193 38 +17 140 7 187 36 +17 134 5 181 34 +13 62 7 109 36 +13 67 5 114 34 +13 73 5 120 34 +13 79 4 126 33 +13 84 3 131 32 +17 129 3 176 32 +19 137 25 184 54 +12 70 25 117 54 +25 57 58 84 98 +26 176 58 203 98 +39 106 148 150 180 +16 131 111 178 140 +32 94 126 160 156 +37 90 46 170 78 diff --git a/ktuberling/museum/cool.tuberling b/ktuberling/museum/cool.tuberling new file mode 100644 index 00000000..72ff5ec7 --- /dev/null +++ b/ktuberling/museum/cool.tuberling @@ -0,0 +1,8 @@ +0 +28 83 92 149 122 +35 66 95 94 116 +33 78 7 142 37 +3 75 41 116 73 +3 109 46 150 78 +24 150 54 177 94 +42 201 144 219 176 diff --git a/ktuberling/museum/crazy.tuberling b/ktuberling/museum/crazy.tuberling new file mode 100644 index 00000000..f32c07eb --- /dev/null +++ b/ktuberling/museum/crazy.tuberling @@ -0,0 +1,9 @@ +1 +11 102 28 147 87 +17 92 -20 155 43 +6 88 101 128 132 +4 109 100 149 131 +18 82 117 160 147 +8 81 149 176 268 +12 131 227 186 265 +13 84 244 138 282 diff --git a/ktuberling/museum/cyclop.tuberling b/ktuberling/museum/cyclop.tuberling new file mode 100644 index 00000000..fdf7ee89 --- /dev/null +++ b/ktuberling/museum/cyclop.tuberling @@ -0,0 +1,15 @@ +0 +0 109 44 150 76 +2 110 27 151 59 +32 94 149 160 179 +20 103 84 152 146 +23 58 63 84 103 +24 178 59 204 99 +17 112 19 159 48 +13 97 19 144 48 +17 175 55 222 84 +17 169 43 216 72 +17 158 29 205 58 +13 41 55 88 84 +13 43 45 90 74 +13 47 33 94 62 diff --git a/ktuberling/museum/dali.tuberling b/ktuberling/museum/dali.tuberling new file mode 100644 index 00000000..6b423c01 --- /dev/null +++ b/ktuberling/museum/dali.tuberling @@ -0,0 +1,11 @@ +0 +26 166 42 193 82 +0 82 32 123 64 +0 118 30 159 62 +15 72 72 119 101 +19 123 73 170 102 +17 168 26 215 55 +29 -3 69 63 99 +20 6 11 55 73 +6 -10 -4 31 28 +9 31 -4 72 28 diff --git a/ktuberling/museum/einstein.tuberling b/ktuberling/museum/einstein.tuberling new file mode 100644 index 00000000..9e276b4b --- /dev/null +++ b/ktuberling/museum/einstein.tuberling @@ -0,0 +1,10 @@ +0 +13 76 12 123 41 +17 140 12 187 41 +30 103 178 169 208 +34 103 163 167 185 +20 108 114 157 176 +4 143 77 184 109 +1 79 80 120 112 +24 179 80 206 120 +23 52 80 79 120 diff --git a/ktuberling/museum/fly.tuberling b/ktuberling/museum/fly.tuberling new file mode 100644 index 00000000..56e2ab82 --- /dev/null +++ b/ktuberling/museum/fly.tuberling @@ -0,0 +1,8 @@ +0 +14 42 87 89 116 +14 44 49 91 78 +21 62 25 111 87 +18 173 88 220 117 +18 171 44 218 73 +21 153 20 202 82 +22 103 151 152 213 diff --git a/ktuberling/museum/grandpa.tuberling b/ktuberling/museum/grandpa.tuberling new file mode 100644 index 00000000..81e15200 --- /dev/null +++ b/ktuberling/museum/grandpa.tuberling @@ -0,0 +1,9 @@ +0 +27 96 104 162 134 +34 99 93 163 115 +5 92 68 133 100 +5 130 70 171 102 +38 93 65 168 97 +35 4 67 32 88 +34 104 12 168 34 +33 87 4 151 34 diff --git a/ktuberling/museum/happy.tuberling b/ktuberling/museum/happy.tuberling new file mode 100644 index 00000000..265633fe --- /dev/null +++ b/ktuberling/museum/happy.tuberling @@ -0,0 +1,13 @@ +0
+21 107 76 156 138
+24 174 25 201 65
+23 59 28 86 68
+2 88 59 129 91
+2 141 59 182 91
+5 92 66 133 98
+5 137 64 178 96
+39 109 152 153 184
+13 76 49 123 78
+17 141 49 188 78
+27 99 130 165 160
+33 0 67 64 97
diff --git a/ktuberling/museum/hippie.tuberling b/ktuberling/museum/hippie.tuberling new file mode 100644 index 00000000..bc0d761f --- /dev/null +++ b/ktuberling/museum/hippie.tuberling @@ -0,0 +1,8 @@ +1 +10 75 43 173 102 +14 64 176 197 206 +15 61 168 194 198 +20 85 82 194 112 +1 89 106 129 136 +3 118 107 158 137 +18 152 107 230 137 diff --git a/ktuberling/museum/idiot.tuberling b/ktuberling/museum/idiot.tuberling new file mode 100644 index 00000000..9be66e14 --- /dev/null +++ b/ktuberling/museum/idiot.tuberling @@ -0,0 +1,10 @@ +0 +30 97 169 163 199 +22 105 62 154 124 +34 98 8 162 30 +21 4 40 53 102 +3 146 67 187 99 +0 74 67 115 99 +24 178 75 205 115 +23 52 77 79 117 +35 42 94 70 115 diff --git a/ktuberling/museum/miss.tuberling b/ktuberling/museum/miss.tuberling new file mode 100644 index 00000000..339b236a --- /dev/null +++ b/ktuberling/museum/miss.tuberling @@ -0,0 +1,11 @@ +0 +6 76 45 117 77 +9 145 47 186 79 +12 70 27 117 56 +16 144 24 191 53 +39 109 181 153 213 +42 203 145 221 177 +29 93 83 159 113 +40 68 79 83 111 +40 176 82 191 114 +36 10 113 44 134 diff --git a/ktuberling/museum/mouse.tuberling b/ktuberling/museum/mouse.tuberling new file mode 100644 index 00000000..3264c291 --- /dev/null +++ b/ktuberling/museum/mouse.tuberling @@ -0,0 +1,14 @@ +0 +13 76 49 123 78 +17 141 49 188 78 +41 95 58 122 90 +41 146 57 173 89 +19 96 113 143 142 +15 117 112 164 141 +5 112 84 153 116 +39 111 144 155 176 +5 88 59 129 91 +5 139 58 180 90 +24 175 28 201 68 +23 61 28 87 68 +15 56 189 103 218 diff --git a/ktuberling/museum/picasso.tuberling b/ktuberling/museum/picasso.tuberling new file mode 100644 index 00000000..56940ba9 --- /dev/null +++ b/ktuberling/museum/picasso.tuberling @@ -0,0 +1,10 @@ +0 +29 102 58 168 88 +24 179 92 206 132 +35 143 125 171 146 +41 104 91 131 123 +4 91 132 132 164 +23 66 145 93 185 +1 80 12 121 44 +13 89 39 136 68 +20 145 51 194 113 diff --git a/ktuberling/museum/sea.tuberling b/ktuberling/museum/sea.tuberling new file mode 100644 index 00000000..eea3ef51 --- /dev/null +++ b/ktuberling/museum/sea.tuberling @@ -0,0 +1,18 @@ +2 +11 -2 90 54 165 +1 119 27 182 74 +9 173 125 226 190 +9 197 130 250 195 +7 248 121 283 175 +1 96 23 159 70 +1 74 -1 137 46 +1 55 20 118 67 +1 70 40 133 87 +4 115 245 205 307 +1 48 -10 111 37 +1 39 -1 102 46 +1 28 44 91 91 +1 -31 6 32 53 +1 72 13 135 60 +1 104 5 167 52 +1 177 -2 240 45 diff --git a/ktuberling/museum/serious.tuberling b/ktuberling/museum/serious.tuberling new file mode 100644 index 00000000..4b5ffff3 --- /dev/null +++ b/ktuberling/museum/serious.tuberling @@ -0,0 +1,13 @@ +0 +23 75 74 102 114 +24 168 74 195 114 +32 104 154 170 184 +33 87 7 151 37 +41 135 185 162 217 +7 96 81 137 113 +10 133 83 174 115 +20 110 89 159 151 +14 85 66 132 95 +18 141 65 188 94 +35 5 72 33 93 +42 203 144 221 176 diff --git a/ktuberling/pics/Makefile.am b/ktuberling/pics/Makefile.am new file mode 100644 index 00000000..5e70846a --- /dev/null +++ b/ktuberling/pics/Makefile.am @@ -0,0 +1,8 @@ + +# add here all files +pics_DATA = penguin-game.png penguin-mask.png \ + potato-game.png potato-mask.png \ + aquarium-game.png aquarium-mask.png \ + layout.xml + +picsdir = $(kde_datadir)/ktuberling/pics diff --git a/ktuberling/pics/aquarium-game.png b/ktuberling/pics/aquarium-game.png Binary files differnew file mode 100644 index 00000000..089bdf7c --- /dev/null +++ b/ktuberling/pics/aquarium-game.png diff --git a/ktuberling/pics/aquarium-mask.png b/ktuberling/pics/aquarium-mask.png Binary files differnew file mode 100644 index 00000000..929d11be --- /dev/null +++ b/ktuberling/pics/aquarium-mask.png diff --git a/ktuberling/pics/layout.i18n b/ktuberling/pics/layout.i18n new file mode 100644 index 00000000..373203cb --- /dev/null +++ b/ktuberling/pics/layout.i18n @@ -0,0 +1,53 @@ +/* ------------------------------------------------------------- + KDE Tuberling + List of strings in layout.xml that are translatable + mailto:e.bischoff@noos.fr + ------------------------------------------------------------- */ + +i18n("Potato &Guy"); + +i18n("Eyes"); +i18n("Eyebrows"); +i18n("Noses"); +i18n("Ears"); +i18n("Mouths"); +i18n("Goodies"); + +i18n("&Penguin"); + +i18n("Eyes"); +i18n("Tie"); +i18n("Hair"); +i18n("Necklaces"); +i18n("Hats"); +i18n("Glasses"); +i18n("Scarf"); + +i18n("&Aquarium"); + +i18n("Fishes"); +i18n("Others"); + +i18n("&Danish"); +i18n("&German"); +i18n("&English"); +i18n("Sp&anish"); +i18n("Fi&nnish"); +i18n("&French"); +i18n("&Italian"); +i18n("Low Sa&xon"); +i18n("D&utch"); +i18n("&Portuguese"); +i18n("&Romanian"); +i18n("&Slovak"); +i18n("S&lovenian"); +i18n("S&wedish"); +i18n("Ser&bian"); + +i18n("NOTE_TO_THE_TRANSLATORS", +"The translators have the opportunity to translate the\n" +"sounds spoken in the game.\n" +"See the technical reference section in ktuberling's\n" +"documentation for more information on how to do that.\n" +"(translate this message as \"DONE\" when you have translated\n" +"the sounds; otherwise leave it untranslated as a reminder)"); diff --git a/ktuberling/pics/layout.xml b/ktuberling/pics/layout.xml new file mode 100644 index 00000000..c5b02fb8 --- /dev/null +++ b/ktuberling/pics/layout.xml @@ -0,0 +1,924 @@ +<!-- + KDE Tuberling + Description of the playgrounds + mailto:e.bischoff@noos.fr + + Modify this file if you want to add new playgrounds, new sounds, + or modify existing ones. If you do that, don't forget to update: + - layout.i18n (strings that might be translated) + - ktuberlingui.rc (actions associated with menu items). +--> + +<ktuberling> + + <playground gameboard="potato-game.png" masks="potato-mask.png"> + + <menuitem action="playground_potato_guy"> + <label>Potato &Guy</label> + </menuitem> + + <editablearea> + <position left=" 0" top=" 0" right="240" bottom="320" /> + <sound ref="tuberling" /> + </editablearea> + + <category> + <position left="241" top="101" right="413" bottom="115" /> + <label>Eyes</label> + </category> + + <category> + <position left="415" top="123" right="511" bottom="137" /> + <label>Eyebrows</label> + </category> + + <category> + <position left="241" top="179" right="394" bottom="193" /> + <label>Noses</label> + </category> + + <category> + <position left="395" top="179" right="511" bottom="193" /> + <label>Ears</label> + </category> + + <category> + <position left="241" top="259" right="445" bottom="273" /> + <label>Mouths</label> + </category> + + <category> + <position left="241" top="307" right="511" bottom="321" /> + <label>Goodies</label> + </category> + + <object> + <position left="242" top=" 0" right="283" bottom=" 32" /> + <sound ref="eye" /> + </object> + + <object> + <position left="242" top=" 34" right="283" bottom=" 66" /> + <sound ref="eye" /> + </object> + + <object> + <position left="242" top=" 68" right="283" bottom="100" /> + <sound ref="eye" /> + </object> + + <object> + <position left="285" top=" 0" right="326" bottom=" 32" /> + <sound ref="eye" /> + </object> + + <object> + <position left="285" top=" 34" right="326" bottom=" 66" /> + <sound ref="eye" /> + </object> + + <object> + <position left="285" top=" 68" right="326" bottom="100" /> + <sound ref="eye" /> + </object> + + <object> + <position left="328" top=" 0" right="369" bottom=" 32" /> + <sound ref="eye" /> + </object> + + <object> + <position left="328" top=" 34" right="369" bottom=" 66" /> + <sound ref="eye" /> + </object> + + <object> + <position left="328" top=" 68" right="369" bottom="100" /> + <sound ref="eye" /> + </object> + + <object> + <position left="371" top=" 0" right="412" bottom=" 32" /> + <sound ref="eye" /> + </object> + + <object> + <position left="371" top=" 34" right="412" bottom=" 66" /> + <sound ref="eye" /> + </object> + + <object> + <position left="371" top=" 68" right="412" bottom="100" /> + <sound ref="eye" /> + </object> + + <object> + <position left="415" top=" 0" right="462" bottom=" 29" /> + <sound ref="eyebrow" /> + </object> + + <object> + <position left="415" top=" 31" right="462" bottom=" 60" /> + <sound ref="eyebrow" /> + </object> + + <object> + <position left="415" top=" 62" right="462" bottom=" 91" /> + <sound ref="eyebrow" /> + </object> + + <object> + <position left="415" top=" 93" right="462" bottom="122" /> + <sound ref="eyebrow" /> + </object> + + <object> + <position left="464" top=" 0" right="511" bottom=" 29" /> + <sound ref="eyebrow" /> + </object> + + <object> + <position left="464" top=" 31" right="511" bottom=" 60" /> + <sound ref="eyebrow" /> + </object> + + <object> + <position left="464" top=" 62" right="511" bottom=" 91" /> + <sound ref="eyebrow" /> + </object> + + <object> + <position left="464" top=" 93" right="511" bottom="122" /> + <sound ref="eyebrow" /> + </object> + + <object> + <position left="242" top="116" right="291" bottom="178" /> + <sound ref="nose" /> + </object> + + <object> + <position left="293" top="116" right="342" bottom="178" /> + <sound ref="nose" /> + </object> + + <object> + <position left="344" top="116" right="393" bottom="178" /> + <sound ref="nose" /> + </object> + + <object> + <position left="397" top="138" right="423" bottom="178" /> + <sound ref="ear" /> + </object> + + <object> + <position left="426" top="138" right="452" bottom="178" /> + <sound ref="ear" /> + </object> + + <object> + <position left="455" top="138" right="481" bottom="178" /> + <sound ref="ear" /> + </object> + + <object> + <position left="484" top="138" right="510" bottom="178" /> + <sound ref="ear" /> + </object> + + <object> + <position left="242" top="195" right="308" bottom="225" /> + <sound ref="mouth" /> + </object> + + <object> + <position left="242" top="227" right="308" bottom="257" /> + <sound ref="mouth" /> + </object> + + <object> + <position left="310" top="195" right="376" bottom="225" /> + <sound ref="mouth" /> + </object> + + <object> + <position left="310" top="227" right="376" bottom="257" /> + <sound ref="mouth" /> + </object> + + <object> + <position left="378" top="195" right="444" bottom="225" /> + <sound ref="mouth" /> + </object> + + <object> + <position left="378" top="227" right="444" bottom="257" /> + <sound ref="mouth" /> + </object> + + <object> + <position left="447" top="195" right="511" bottom="225" /> + <sound ref="hat" /> + </object> + + <object> + <position left="447" top="227" right="511" bottom="249" /> + <sound ref="moustache" /> + </object> + + <object> + <position left="447" top="251" right="475" bottom="272" /> + <sound ref="cigar" /> + </object> + + <object> + <position left="477" top="251" right="511" bottom="272" /> + <sound ref="bow" /> + </object> + + <object> + <position left="242" top="274" right="322" bottom="306" /> + <sound ref="sunglasses" /> + </object> + + <object> + <position left="324" top="274" right="399" bottom="306" /> + <sound ref="spectacles" /> + </object> + + <object> + <position left="401" top="274" right="445" bottom="306" /> + <sound ref="bow" /> + </object> + + <object> + <position left="447" top="274" right="462" bottom="306" /> + <sound ref="earring" /> + </object> + + <object> + <position left="464" top="274" right="491" bottom="306" /> + <sound ref="badge" /> + </object> + + <object> + <position left="493" top="274" right="511" bottom="306" /> + <sound ref="watch" /> + </object> + + </playground> + + <playground gameboard="penguin-game.png" masks="penguin-mask.png"> + + <menuitem action="playground_penguin"> + <label>&Penguin</label> + </menuitem> + + <editablearea> + <position left=" 0" top=" 0" right="240" bottom="320" /> + <sound ref="penguin" /> + </editablearea> + + <category> + <position left="241" top=" 66" right="413" bottom=" 80" /> + <label>Eyes</label> + </category> + + <category> + <position left="415" top="123" right="511" bottom="137" /> + <label>Tie</label> + </category> + + <category> + <position left="241" top="180" right="511" bottom="194" /> + <label>Hair</label> + </category> + + <category> + <position left="241" top="259" right="377" bottom="273" /> + <label>Necklaces</label> + </category> + + <category> + <position left="379" top="259" right="511" bottom="273" /> + <label>Hats</label> + </category> + + <category> + <position left="241" top="307" right="400" bottom="321" /> + <label>Glasses</label> + </category> + + <category> + <position left="402" top="307" right="511" bottom="321" /> + <label>Scarf</label> + </category> + + <object> + <position left="243" top=" 1" right="283" bottom=" 32" /> + <sound ref="eye" /> + </object> + + <object> + <position left="243" top=" 35" right="283" bottom=" 65" /> + <sound ref="eye" /> + </object> + + <object> + <position left="286" top=" 1" right="326" bottom=" 32" /> + <sound ref="eye" /> + </object> + + <object> + <position left="286" top=" 35" right="326" bottom=" 65" /> + <sound ref="eye" /> + </object> + + <object> + <position left="329" top=" 1" right="369" bottom=" 32" /> + <sound ref="eye" /> + </object> + + <object> + <position left="329" top=" 35" right="369" bottom=" 65" /> + <sound ref="eye" /> + </object> + + <object> + <position left="372" top=" 1" right="412" bottom=" 32" /> + <sound ref="eye" /> + </object> + + <object> + <position left="372" top=" 35" right="412" bottom=" 65" /> + <sound ref="eye" /> + </object> + + <object> + <position left="416" top=" 1" right="511" bottom="120" /> + <sound ref="tie" /> + </object> + + <object> + <position left="244" top=" 81" right="390" bottom="116" /> + <sound ref="hat" /> + </object> + + <object> + <position left="243" top="119" right="341" bottom="178" /> + <sound ref="hair" /> + </object> + + <object> + <position left="345" top="119" right="390" bottom="178" /> + <sound ref="hair" /> + </object> + + <object> + <position left="397" top="140" right="452" bottom="178" /> + <sound ref="horn" /> + </object> + + <object> + <position left="455" top="140" right="509" bottom="178" /> + <sound ref="horn" /> + </object> + + <object> + <position left="243" top="195" right="376" bottom="225" /> + <sound ref="necklace" /> + </object> + + <object> + <position left="243" top="228" right="376" bottom="258" /> + <sound ref="necklace" /> + </object> + + <object> + <position left="379" top="195" right="444" bottom="258" /> + <sound ref="hat" /> + </object> + + <object> + <position left="448" top="195" right="511" bottom="258" /> + <sound ref="hat" /> + </object> + + <object> + <position left="244" top="275" right="322" bottom="305" /> + <sound ref="spectacles" /> + </object> + + <object> + <position left="325" top="275" right="398" bottom="305" /> + <sound ref="sunglasses" /> + </object> + + <object> + <position left="402" top="275" right="511" bottom="305" /> + <sound ref="scarf" /> + </object> + + </playground> + + <playground gameboard="aquarium-game.png" masks="aquarium-mask.png"> + + <menuitem action="playground_aquarium"> + <label>&Aquarium</label> + </menuitem> + + <editablearea> + <position left=" 0" top=" 0" right="320" bottom="320" /> + <sound ref="aquarium" /> + </editablearea> + + <category> + <position left=" 92" top=" 46" right="736" bottom="359" /> + <label>Fishes</label> + </category> + + <category> + <position left=" 92" top=" 46" right="736" bottom="559" /> + <label>Others</label> + </category> + + <object> + <position left=" 92" top=" 46" right="236" bottom=" 32" /> + <sound ref="fish" /> + </object> + + <object> + <position left="325" top=" 5" right="388" bottom=" 52" /> + <sound ref="fish" /> + </object> + + <object> + <position left="395" top=" 5" right="444" bottom=" 52" /> + <sound ref="fish" /> + </object> + + <object> + <position left="454" top=" 5" right="501" bottom=" 52" /> + <sound ref="fish" /> + </object> + + <object> + <position left="325" top=" 62" right="415" bottom="124" /> + <sound ref="fish" /> + </object> + + <object> + <position left="423" top=" 62" right="511" bottom="124" /> + <sound ref="fish" /> + </object> + + <object> + <position left="330" top="130" right="357" bottom="184" /> + <sound ref="seahorse" /> + </object> + + <object> + <position left="370" top="130" right="405" bottom="184" /> + <sound ref="seahorse" /> + </object> + + <object> + <position left="410" top="130" right="500" bottom="184" /> + <sound ref="fish" /> + </object> + + <object> + <position left="325" top="225" right="378" bottom="290" /> + <sound ref="jellyfish" /> + </object> + + <object> + <position left="386" top="215" right="439" bottom="290" /> + <sound ref="helmet" /> + </object> + + <object> + <position left="452" top="215" right="508" bottom="290" /> + <sound ref="treasure" /> + </object> + + </playground> + + <language code="da"> + + <menuitem action="speech_danish"> + <label>&Danish</label> + </menuitem> + + <sound name="tuberling" file="da/kartoffelfyr.wav" /> + <sound name="eye" file="da/oeje.wav" /> + <sound name="eyebrow" file="da/oejenbryn.wav" /> + <sound name="nose" file="da/naese.wav" /> + <sound name="ear" file="da/oere.wav" /> + <sound name="mouth" file="da/mund.wav" /> + <sound name="hat" file="da/hat.wav" /> + <sound name="moustache" file="da/overskaeg.wav" /> + <sound name="cigar" file="da/cigar.wav" /> + <sound name="bow" file="da/sloejfe.wav" /> + <sound name="sunglasses" file="da/solbriller.wav" /> + <sound name="spectacles" file="da/briller.wav" /> + <sound name="earring" file="da/oerering.wav" /> + <sound name="badge" file="da/politiskilt.wav" /> + <sound name="watch" file="da/ur.wav" /> + <sound name="penguin" file="da/pingvin.wav" /> + <sound name="tie" file="da/slips.wav" /> + <sound name="hair" file="da/haar.wav" /> + <sound name="horn" file="da/horn.wav" /> + <sound name="necklace" file="da/halsbaand.wav" /> + <sound name="scarf" file="da/halstoerklaede.wav" /> + + </language> + + <language code="de"> + + <menuitem action="speech_german"> + <label>&German</label> + </menuitem> + + <sound name="eye" file="de/auge.wav" /> + <sound name="eyebrow" file="de/augenbraue.wav" /> + <sound name="ear" file="de/ohr.wav" /> + <sound name="hat" file="de/hut.wav" /> + <sound name="moustache" file="de/schnurrbart.wav" /> + <sound name="bow" file="de/fliege.wav" /> + <sound name="spectacles" file="de/brille.wav" /> + <sound name="earring" file="de/ohrring.wav" /> + <sound name="badge" file="de/abzeichen.wav" /> + <sound name="watch" file="de/uhr.wav" /> + <sound name="hair" file="de/haare.wav" /> + + </language> + + <language code="en"> + + <menuitem action="speech_english"> + <label>&English</label> + </menuitem> + + <sound name="tuberling" file="en/tuberling.wav" /> + <sound name="eye" file="en/eye.wav" /> + <sound name="eyebrow" file="en/eyebrow.wav" /> + <sound name="nose" file="en/nose.wav" /> + <sound name="ear" file="en/ear.wav" /> + <sound name="mouth" file="en/mouth.wav" /> + <sound name="hat" file="en/hat.wav" /> + <sound name="moustache" file="en/moustache.wav" /> + <sound name="cigar" file="en/cigar.wav" /> + <sound name="bow" file="en/bow.wav" /> + <sound name="sunglasses" file="en/sunglasses.wav" /> + <sound name="spectacles" file="en/spectacles.wav" /> + <sound name="earring" file="en/earring.wav" /> + <sound name="badge" file="en/badge.wav" /> + <sound name="watch" file="en/watch.wav" /> + + </language> + + <language code="es"> + + <menuitem action="speech_spanish"> + <label>Sp&anish</label> + </menuitem> + + <sound name="tuberling" file="es/eltipodelapatata.wav" /> + <sound name="eye" file="es/ojo.wav" /> + <sound name="eyebrow" file="es/ceja.wav" /> + <sound name="nose" file="es/nariz.wav" /> + <sound name="ear" file="es/oreja.wav" /> + <sound name="mouth" file="es/boca.wav" /> + <sound name="hat" file="es/sombrero.wav" /> + <sound name="moustache" file="es/bigote.wav" /> + <sound name="cigar" file="es/cigarro.wav" /> + <sound name="bow" file="es/lazo.wav" /> + <sound name="sunglasses" file="es/gafasdesol.wav" /> + <sound name="spectacles" file="es/anteojos.wav" /> + <sound name="earring" file="es/pendiente.wav" /> + <sound name="badge" file="es/insignia.wav" /> + <sound name="watch" file="es/reloj.wav" /> + + </language> + + <language code="fi"> + + <menuitem action="speech_finnish"> + <label>Fi&nnish</label> + </menuitem> + + <sound name="tuberling" file="fi/perunamies.wav" /> + <sound name="eye" file="fi/silma.wav" /> + <sound name="eyebrow" file="fi/kulmakarva.wav" /> + <sound name="nose" file="fi/nena.wav" /> + <sound name="ear" file="fi/korva.wav" /> + <sound name="mouth" file="fi/suu.wav" /> + <sound name="hat" file="fi/hattu.wav" /> + <sound name="moustache" file="fi/viikset.wav" /> + <sound name="cigar" file="fi/sikari.wav" /> + <sound name="bow" file="fi/rusetti.wav" /> + <sound name="sunglasses" file="fi/aurinkolasit.wav" /> + <sound name="spectacles" file="fi/silmalasit.wav" /> + <sound name="earring" file="fi/korvakoru.wav" /> + <sound name="badge" file="fi/merkki.wav" /> + <sound name="watch" file="fi/kello.wav" /> + + </language> + + <language code="fr"> + + <menuitem action="speech_french"> + <label>&French</label> + </menuitem> + + <sound name="tuberling" file="fr/monsieur-patate.wav" /> + <sound name="eye" file="fr/oeil.wav" /> + <sound name="eyebrow" file="fr/sourcil.wav" /> + <sound name="nose" file="fr/nez.wav" /> + <sound name="ear" file="fr/oreille.wav" /> + <sound name="mouth" file="fr/bouche.wav" /> + <sound name="hat" file="fr/chapeau.wav" /> + <sound name="moustache" file="fr/moustache.wav" /> + <sound name="cigar" file="fr/cigare.wav" /> + <sound name="bow" file="fr/noeud-papillon.wav" /> + <sound name="sunglasses" file="fr/lunettes-de-soleil.wav" /> + <sound name="spectacles" file="fr/lunettes.wav" /> + <sound name="earring" file="fr/boucle-d-oreille.wav" /> + <sound name="badge" file="fr/medaille.wav" /> + <sound name="watch" file="fr/montre.wav" /> + <sound name="penguin" file="fr/pingouin.wav" /> + <sound name="tie" file="fr/cravate.wav" /> + <sound name="hair" file="fr/cheveux.wav" /> + <sound name="horn" file="fr/corne.wav" /> + <sound name="necklace" file="fr/collier.wav" /> + <sound name="scarf" file="fr/foulard.wav" /> + + </language> + + <language code="it"> + + <menuitem action="speech_italian"> + <label>&Italian</label> + </menuitem> + + <sound name="tuberling" file="it/patatone.wav" /> + <sound name="eye" file="it/occhio.wav" /> + <sound name="eyebrow" file="it/sopracciglio.wav" /> + <sound name="nose" file="it/naso.wav" /> + <sound name="ear" file="it/orecchio.wav" /> + <sound name="mouth" file="it/bocca.wav" /> + <sound name="hat" file="it/cappello.wav" /> + <sound name="moustache" file="it/baffi.wav" /> + <sound name="cigar" file="it/sigaro.wav" /> + <sound name="bow" file="it/cravattino.wav" /> + <sound name="sunglasses" file="it/occhialidasole.wav" /> + <sound name="spectacles" file="it/occhiali.wav" /> + <sound name="earring" file="it/orecchino.wav" /> + <sound name="badge" file="it/distintivo.wav" /> + <sound name="watch" file="it/orologio.wav" /> + <sound name="penguin" file="it/pinguino.wav" /> + <sound name="tie" file="it/cravatta.wav" /> + <sound name="hair" file="it/capelli.wav" /> + <sound name="horn" file="it/corno.wav" /> + <sound name="necklace" file="it/collana.wav" /> + <sound name="scarf" file="it/sciarpina.wav" /> + + </language> + + <language code="nds"> + + <menuitem action="speech_lowsaxon"> + <label>Low Sa&xon</label> + </menuitem> + + <sound name="tuberling" file="nds/kantueffel.wav" /> + <sound name="eye" file="nds/oog.wav" /> + <sound name="eyebrow" file="nds/oogbro.wav" /> + <sound name="nose" file="nds/nees.wav" /> + <sound name="ear" file="nds/ohr.wav" /> + <sound name="mouth" file="nds/mund.wav" /> + <sound name="hat" file="nds/hoot.wav" /> + <sound name="moustache" file="nds/neesboort.wav" /> + <sound name="cigar" file="nds/zigarr.wav" /> + <sound name="bow" file="nds/fleeg.wav" /> + <sound name="sunglasses" file="nds/suennbrill.wav" /> + <sound name="spectacles" file="nds/brill.wav" /> + <sound name="earring" file="nds/ohrring.wav" /> + <sound name="badge" file="nds/afteken.wav" /> + <sound name="watch" file="nds/klock.wav" /> + <sound name="penguin" file="nds/penguin.wav" /> + <sound name="tie" file="nds/slips.wav" /> + <sound name="hair" file="nds/hoor.wav" /> + <sound name="horn" file="nds/hoorn.wav" /> + <sound name="necklace" file="nds/halskeed.wav" /> + <sound name="scarf" file="nds/schaal.wav" /> + <sound name="fish" file="nds/fisch.wav" /> + <sound name="jellyfish" file="nds/quall.wav" /> + <sound name="seahorse" file="nds/seepeerd.wav" /> + <sound name="aquarium" file="nds/aquarium.wav" /> + <sound name="helmet" file="nds/duekerhoot.wav" /> + <sound name="treasure" file="nds/schatz.wav" /> + + </language> + + <language code="nl"> + + <menuitem action="speech_dutch"> + <label>D&utch</label> + </menuitem> + + <sound name="tuberling" file="nl/aardappelmannetje.wav" /> + <sound name="eye" file="nl/oog.wav" /> + <sound name="eyebrow" file="nl/wenkbrauw.wav" /> + <sound name="nose" file="nl/neus.wav" /> + <sound name="ear" file="nl/oor.wav" /> + <sound name="mouth" file="nl/mond.wav" /> + <sound name="hat" file="nl/hoed.wav" /> + <sound name="moustache" file="nl/snor.wav" /> + <sound name="cigar" file="nl/sigaar.wav" /> + <sound name="bow" file="nl/strik.wav" /> + <sound name="sunglasses" file="nl/zonnebril.wav" /> + <sound name="spectacles" file="nl/bril.wav" /> + <sound name="earring" file="nl/oorbel.wav" /> + <sound name="badge" file="nl/ster.wav" /> + <sound name="watch" file="nl/horloge.wav" /> + <sound name="penguin" file="nl/pinguin.wav" /> + <sound name="tie" file="nl/stropdas.wav" /> + <sound name="hair" file="nl/haar.wav" /> + <sound name="horn" file="nl/horens.wav" /> + <sound name="necklace" file="nl/ketting.wav" /> + <sound name="scarf" file="nl/sjaal.wav" /> + + </language> + + <language code="pt"> + + <menuitem action="speech_portuguese"> + <label>&Portuguese</label> + </menuitem> + + <sound name="tuberling" file="pt/senhor-batata.wav" /> + <sound name="eye" file="pt/olho.wav" /> + <sound name="eyebrow" file="pt/sobrancelha.wav" /> + <sound name="nose" file="pt/nariz.wav" /> + <sound name="ear" file="pt/orelha.wav" /> + <sound name="mouth" file="pt/boca.wav" /> + <sound name="hat" file="pt/chapeu.wav" /> + <sound name="moustache" file="pt/bigode.wav" /> + <sound name="cigar" file="pt/cigarro.wav" /> + <sound name="bow" file="pt/laco.wav" /> + <sound name="sunglasses" file="pt/oculos-de-sol.wav" /> + <sound name="spectacles" file="pt/oculos.wav" /> + <sound name="earring" file="pt/brincos.wav" /> + <sound name="badge" file="pt/medalha.wav" /> + <sound name="watch" file="pt/relogio.wav" /> + <sound name="penguin" file="pt/pinguim.wav" /> + <sound name="tie" file="pt/gravata.wav" /> + <sound name="hair" file="pt/cabelo.wav" /> + <sound name="horn" file="pt/corno.wav" /> + <sound name="necklace" file="pt/colares.wav" /> + <sound name="scarf" file="pt/lenco.wav" /> + + </language> + + <language code="ro"> + + <menuitem action="speech_romanian"> + <label>&Romanian</label> + </menuitem> + + <sound name="tuberling" file="ro/domnul-cartof.wav" /> + <sound name="eye" file="ro/ochi.wav" /> + <sound name="eyebrow" file="ro/sprinceana.wav" /> + <sound name="nose" file="ro/nas.wav" /> + <sound name="ear" file="ro/ureche.wav" /> + <sound name="mouth" file="ro/gura.wav" /> + <sound name="hat" file="ro/palarie.wav" /> + <sound name="moustache" file="ro/mustata.wav" /> + <sound name="cigar" file="ro/tigara.wav" /> + <sound name="bow" file="ro/papion.wav" /> + <sound name="sunglasses" file="ro/ochelari-de-soare.wav" /> + <sound name="spectacles" file="ro/ochelari.wav" /> + <sound name="earring" file="ro/cercel.wav" /> + <sound name="badge" file="ro/insigna.wav" /> + <sound name="watch" file="ro/ceas.wav" /> + <sound name="penguin" file="ro/pinguin.wav" /> + <sound name="tie" file="ro/cravata.wav" /> + <sound name="hair" file="ro/par.wav" /> + <sound name="horn" file="ro/corn.wav" /> + <sound name="necklace" file="ro/colier.wav" /> + <sound name="scarf" file="ro/fular.wav" /> + + </language> + + <language code="sk"> + + <menuitem action="speech_slovak"> + <label>&Slovak</label> + </menuitem> + + <sound name="tuberling" file="sk/zemiacik.wav" /> + <sound name="eye" file="sk/oko.wav" /> + <sound name="eyebrow" file="sk/obocie.wav" /> + <sound name="nose" file="sk/nos.wav" /> + <sound name="ear" file="sk/ucho.wav" /> + <sound name="mouth" file="sk/usta.wav" /> + <sound name="hat" file="sk/klobuk.wav" /> + <sound name="moustache" file="sk/fuzy.wav" /> + <sound name="cigar" file="sk/cigara.wav" /> + <sound name="bow" file="sk/kravata.wav" /> + <sound name="sunglasses" file="sk/slnecneokuliare.wav" /> + <sound name="spectacles" file="sk/okuliare.wav" /> + <sound name="earring" file="sk/nausnica.wav" /> + <sound name="badge" file="sk/odznak.wav" /> + <sound name="watch" file="sk/hodinky.wav" /> + + </language> + + <language code="sl"> + + <menuitem action="speech_slovenian"> + <label>S&lovenian</label> + </menuitem> + + <sound name="tuberling" file="sl/krompircek.wav" /> + <sound name="eye" file="sl/oko.wav" /> + <sound name="eyebrow" file="sl/obrvi.wav" /> + <sound name="nose" file="sl/nos.wav" /> + <sound name="ear" file="sl/uho.wav" /> + <sound name="mouth" file="sl/usta.wav" /> + <sound name="hat" file="sl/klobuk.wav" /> + <sound name="moustache" file="sl/brki.wav" /> + <sound name="cigar" file="sl/cigara.wav" /> + <sound name="bow" file="sl/metuljcek.wav" /> + <sound name="sunglasses" file="sl/soncna_ocala.wav" /> + <sound name="spectacles" file="sl/naocniki.wav" /> + <sound name="earring" file="sl/uhan.wav" /> + <sound name="badge" file="sl/znacka.wav" /> + <sound name="watch" file="sl/ura.wav" /> + <sound name="penguin" file="sl/pingvin.wav" /> + <sound name="tie" file="sl/kravata.wav" /> + <sound name="hair" file="sl/lasje.wav" /> + <sound name="horn" file="sl/rog.wav" /> + <sound name="necklace" file="sl/naocniki.wav" /> + <sound name="scarf" file="sl/sal.wav" /> + + </language> + + <language code="sv"> + + <menuitem action="speech_swedish"> + <label>S&wedish</label> + </menuitem> + + <sound name="tuberling" file="sv/potatismannen.wav" /> + <sound name="eye" file="sv/oga.wav" /> + <sound name="eyebrow" file="sv/ogonbryn.wav" /> + <sound name="nose" file="sv/nasa.wav" /> + <sound name="ear" file="sv/ora.wav" /> + <sound name="mouth" file="sv/mun.wav" /> + <sound name="hat" file="sv/hatt.wav" /> + <sound name="moustache" file="sv/mustasch.wav" /> + <sound name="cigar" file="sv/cigarr.wav" /> + <sound name="bow" file="sv/rosett.wav" /> + <sound name="sunglasses" file="sv/solglasogon.wav" /> + <sound name="spectacles" file="sv/glasogon.wav" /> + <sound name="earring" file="sv/orhange.wav" /> + <sound name="badge" file="sv/brosch.wav" /> + <sound name="watch" file="sv/klocka.wav" /> + <sound name="penguin" file="sv/pingvin.wav" /> + <sound name="tie" file="sv/slips.wav" /> + <sound name="hair" file="sv/har.wav" /> + <sound name="horn" file="sv/horn.wav" /> + <sound name="necklace" file="sv/halsband.wav" /> + <sound name="scarf" file="sv/halsduk.wav" /> + + </language> + + <language code="sr"> + + <menuitem action="speech_serbian"> + <label>Ser&bian</label> + </menuitem> + + <sound name="tuberling" file="sr/krompirko.wav" /> + <sound name="eye" file="sr/oko.wav" /> + <sound name="eyebrow" file="sr/obrva.wav" /> + <sound name="nose" file="sr/nos.wav" /> + <sound name="ear" file="sr/uvo.wav" /> + <sound name="mouth" file="sr/usta.wav" /> + <sound name="hat" file="sr/sesir.wav" /> + <sound name="moustache" file="sr/brkovi.wav" /> + <sound name="cigar" file="sr/cigara.wav" /> + <sound name="bow" file="sr/masna.wav" />--> + <sound name="sunglasses" file="sr/naocare_za_sunce.wav" /> + <sound name="spectacles" file="sr/naocare.wav" /> + <sound name="earring" file="sr/mindjusa.wav" /> + <sound name="badge" file="sr/znacka.wav" /> + <sound name="watch" file="sr/sat.wav" /> + + </language> + +</ktuberling> diff --git a/ktuberling/pics/penguin-game.png b/ktuberling/pics/penguin-game.png Binary files differnew file mode 100644 index 00000000..6bbdfe74 --- /dev/null +++ b/ktuberling/pics/penguin-game.png diff --git a/ktuberling/pics/penguin-mask.png b/ktuberling/pics/penguin-mask.png Binary files differnew file mode 100644 index 00000000..efaf0654 --- /dev/null +++ b/ktuberling/pics/penguin-mask.png diff --git a/ktuberling/pics/potato-game.png b/ktuberling/pics/potato-game.png Binary files differnew file mode 100644 index 00000000..10132333 --- /dev/null +++ b/ktuberling/pics/potato-game.png diff --git a/ktuberling/pics/potato-mask.png b/ktuberling/pics/potato-mask.png Binary files differnew file mode 100644 index 00000000..838865d3 --- /dev/null +++ b/ktuberling/pics/potato-mask.png diff --git a/ktuberling/playground.cpp b/ktuberling/playground.cpp new file mode 100644 index 00000000..367c407c --- /dev/null +++ b/ktuberling/playground.cpp @@ -0,0 +1,609 @@ +/* ------------------------------------------------------------- + KDE Tuberling + Play ground widget + mailto:e.bischoff@noos.fr + ------------------------------------------------------------- */ + +#include <stdlib.h> + +#include <kmessagebox.h> +#include <klocale.h> +#include <kstandarddirs.h> +#include <kprinter.h> + +#include <qfile.h> +#include <qpainter.h> +#include <qimage.h> +#include <qcursor.h> +#include <qdom.h> + +#include "playground.moc" +#include "toplevel.h" + +#define XMARGIN 5 +#define YMARGIN 5 + +// Constructor +PlayGround::PlayGround(TopLevel *parent, const char *name, uint selectedGameboard) + : QWidget(parent, name) +{ + topLevel = parent; + + textsLayout = objectsLayout = 0; + textsList = soundsList = 0; + draggedCursor = 0; + + toDraw.setAutoDelete(true); + history.setAutoDelete(true); + + setBackgroundColor(white); + + QDomDocument layoutsDocument; + bool ok = topLevel->loadLayout(layoutsDocument); + if (ok) ok = registerPlayGrounds(layoutsDocument); + if (ok) ok = loadPlayGround(layoutsDocument, selectedGameboard); + if (!ok) loadFailure(); + + currentAction = 0; + setupGeometry(); +} + +// Destructor +PlayGround::~PlayGround() +{ + delete [] textsLayout; + delete [] objectsLayout; + + delete [] textsList; + delete [] soundsList; + + delete draggedCursor; +} + +// Reset the play ground +void PlayGround::reset() +{ + toDraw.clear(); + history.clear(); + currentAction = 0; +} + +// Change the gameboard +void PlayGround::change(uint selectedGameboard) +{ + QDomDocument layoutsDocument; + bool ok = topLevel->loadLayout(layoutsDocument); + if (ok) ok = loadPlayGround(layoutsDocument, selectedGameboard); + if (!ok) loadFailure(); + + toDraw.clear(); + history.clear(); + currentAction = 0; + + setupGeometry(); + + update(); +} + +// Repaint all the editable area +void PlayGround::repaintAll() +{ + QRect dirtyArea + (editableArea.left() - 10, + editableArea.top() - 10, + editableArea.width() + 20, + editableArea.height() + 20); + + repaint(dirtyArea, false); +} + +// Undo last action +// Returns true if everything went fine +bool PlayGround::undo() +{ + ToDraw *newObject; + Action *undone; + int zOrder; + + if (!(undone = history.at(--currentAction))) + return false; + + zOrder = undone->ZOrderAfter(); + if (zOrder != -1) + { + // Undo an "add" or a "move" action + if (!toDraw.remove(zOrder)) return false; + } + + zOrder = undone->ZOrderBefore(); + if (zOrder != -1) + { + // Undo a "delete" or a "move" action + newObject = new ToDraw(undone->DrawnBefore()); + if (!toDraw.insert(zOrder, newObject)) + return false; + } + + return true; +} + +// Redo next action +// Returns true if everything went fine +bool PlayGround::redo() +{ + ToDraw *newObject; + Action *undone; + int zOrder; + + if (!(undone = history.at(currentAction++))) + return false; + + zOrder = undone->ZOrderBefore(); + if (zOrder != -1) + { + // Redo a "delete" or a "move" action + if (!toDraw.remove(zOrder)) return false; + } + + zOrder = undone->ZOrderAfter(); + if (zOrder != -1) + { + // Redo an "add" or a "move" action + newObject = new ToDraw(undone->DrawnAfter()); + if (!toDraw.insert(zOrder, newObject)) + return false; + } + + return true; +} + +// Save objects laid down on the editable area +bool PlayGround::saveAs(const QString & name) +{ + FILE *fp; + const ToDraw *currentObject; + + if (!(fp = fopen((const char *) QFile::encodeName(name), "w"))) return false; + + fprintf(fp, "%d\n", topLevel->getSelectedGameboard()); + for (currentObject = toDraw.first(); currentObject; currentObject = toDraw.next()) + currentObject->save(fp); + + return !fclose(fp); +} + +// Print gameboard's picture +bool PlayGround::printPicture(KPrinter &printer) const +{ + QPainter artist; + QPixmap picture(getPicture()); + + if (!artist.begin(&printer)) return false; + artist.drawPixmap(QPoint(32, 32), picture); + if (!artist.end()) return false; + return true; +} + +// Get a pixmap containing the current picture +QPixmap PlayGround::getPicture() const +{ + QPixmap result(editableArea.size()); + QPainter artist(&result); + QRect transEditableArea(editableArea); + + transEditableArea.moveBy(-XMARGIN, -YMARGIN); + artist.translate(XMARGIN - editableArea.left(), + YMARGIN - editableArea.top()); + drawGameboard(artist, transEditableArea); + return result; +} + +// Draw some text +void PlayGround::drawText(QPainter &artist, QRect &area, QString &textId) const +{ + QString label; + + label=i18n(textId.latin1()); + + artist.drawText(area, AlignCenter, label); +} + +// Paint the current picture to the given device +void PlayGround::drawGameboard( QPainter &artist, const QRect &area ) const +{ + artist.drawPixmap(area.topLeft(), gameboard, area); + + artist.setPen(white); + for (int text = 0; text < texts; text++) + drawText(artist, textsLayout[text], textsList[text]); + + artist.setPen(black); + for (QPtrListIterator<ToDraw> currentObject(toDraw); + currentObject.current(); + ++currentObject) + currentObject.current()->draw(artist, area, objectsLayout, &gameboard, &masks); +} + +// Painting event +void PlayGround::paintEvent( QPaintEvent *event ) +{ + QPoint destination(event->rect().topLeft()), + position(destination.x() - XMARGIN, + destination.y() - YMARGIN); + QRect area(position, QSize(event->rect().size())); + QPixmap cache(gameboard.size()); + QPainter artist(&cache); + + if (destination.x() < XMARGIN) destination.setX(XMARGIN); + if (destination.y() < YMARGIN) destination.setY(YMARGIN); + area = QRect(0, 0, gameboard.width(), gameboard.height()).intersect(area); + if (area.isEmpty()) return; + + drawGameboard(artist, area); + + bitBlt(this, destination, &cache, area, Qt::CopyROP); +} + +// Mouse pressed event +void PlayGround::mousePressEvent( QMouseEvent *event ) +{ + if (draggedCursor) return; + + QPoint position(event->x() - XMARGIN, + event->y() - YMARGIN); + if (!zone(position)) return; + + int draggedNumber = draggedObject.getNumber(); + QPixmap object(objectsLayout[draggedNumber].size()); + QBitmap shape(objectsLayout[draggedNumber].size()); + bitBlt(&object, QPoint(0, 0), &gameboard, objectsLayout[draggedNumber], Qt::CopyROP); + bitBlt(&shape, QPoint(0, 0), &masks, objectsLayout[draggedNumber], Qt::CopyROP); + object.setMask(shape); + + draggedCursor = new QCursor(object, position.x(), position.y()); + setCursor(*draggedCursor); + + topLevel->playSound(soundsList[draggedNumber]); +} + +// Mouse released event +void PlayGround::mouseReleaseEvent( QMouseEvent *event ) +{ + // If we are not dragging an object, ignore the event + if (!draggedCursor) return; + + QCursor arrow; + int draggedNumber = draggedObject.getNumber(); + QRect position( + event->x() - XMARGIN - draggedCursor->hotSpot().x(), + event->y() - YMARGIN - draggedCursor->hotSpot().y(), + objectsLayout[draggedNumber].width(), + objectsLayout[draggedNumber].height()); + QRect dirtyArea + (editableArea.left() - 10, + editableArea.top() - 10, + editableArea.width() + 20, + editableArea.height() + 20); + ToDraw *newObject; + Action *newAction; + + // We are not anymore dragging an object + delete draggedCursor; + draggedCursor = 0; + setCursor(arrow); + + // If we are not moving the object to the editable area + if (!dirtyArea.contains(event->pos())) + { + // ... then register its deletion (if coming from the editable area), and return + if (draggedZOrder == -1) return; + + while (history.count() > currentAction) history.removeLast(); + newAction = new Action(&draggedObject, draggedZOrder, 0, -1); + history.append(newAction); + currentAction++; + topLevel->enableUndo(true); + + return; + } + + // Register that we have one more object to draw + newObject = new ToDraw(draggedNumber, position); + toDraw.append(newObject); + + // Forget all subsequent actions in the undo buffer, and register object's addition (or its move) + while (history.count() > currentAction) history.removeLast(); + newAction = new Action(&draggedObject, draggedZOrder, newObject, toDraw.count()-1); + history.append(newAction); + currentAction++; + topLevel->enableUndo(true); + + // Repaint the editable area + position.moveBy(XMARGIN, YMARGIN); + repaint(position, false); + +} + +// Register the various playgrounds +bool PlayGround::registerPlayGrounds(QDomDocument &layoutDocument) +{ + QDomNodeList playGroundsList, menuItemsList, labelsList; + QDomElement playGroundElement, menuItemElement, labelElement; + QDomAttr actionAttribute; + + playGroundsList = layoutDocument.elementsByTagName("playground"); + if (playGroundsList.count() < 1) + return false; + + for (uint i = 0; i < playGroundsList.count(); i++) + { + playGroundElement = (const QDomElement &) playGroundsList.item(i).toElement(); + + menuItemsList = playGroundElement.elementsByTagName("menuitem"); + if (menuItemsList.count() != 1) + return false; + + menuItemElement = (const QDomElement &) menuItemsList.item(0).toElement(); + + labelsList = menuItemElement.elementsByTagName("label"); + if (labelsList.count() != 1) + return false; + + labelElement = (const QDomElement &) labelsList.item(0).toElement(); + actionAttribute = menuItemElement.attributeNode("action"); + topLevel->registerGameboard(labelElement.text(), actionAttribute.value().latin1()); + } + + return true; +} + +// Load background and draggable objects masks +bool PlayGround::loadPlayGround(QDomDocument &layoutDocument, uint toLoad) +{ + QDomNodeList playGroundsList, + editableAreasList, categoriesList, objectsList, + gameAreasList, maskAreasList, soundNamesList, labelsList; + QDomElement playGroundElement, + editableAreaElement, categoryElement, objectElement, + gameAreaElement, maskAreaElement, soundNameElement, labelElement; + QDomAttr gameboardAttribute, masksAttribute, + leftAttribute, topAttribute, rightAttribute, bottomAttribute, + refAttribute; + + playGroundsList = layoutDocument.elementsByTagName("playground"); + if (toLoad >= playGroundsList.count()) + return false; + + playGroundElement = (const QDomElement &) playGroundsList.item(toLoad).toElement(); + + gameboardAttribute = playGroundElement.attributeNode("gameboard"); + if (!gameboard.load(locate("data", "ktuberling/pics/" + gameboardAttribute.value()))) + return false; + + masksAttribute = playGroundElement.attributeNode("masks"); + if (!masks.load(locate("data", "ktuberling/pics/" + masksAttribute.value()))) + return false; + + editableAreasList = playGroundElement.elementsByTagName("editablearea"); + if (editableAreasList.count() != 1) + return false; + + editableAreaElement = (const QDomElement &) editableAreasList.item(0).toElement(); + + gameAreasList = editableAreaElement.elementsByTagName("position"); + if (gameAreasList.count() != 1) + return false; + + gameAreaElement = (const QDomElement &) gameAreasList.item(0).toElement(); + leftAttribute = gameAreaElement.attributeNode("left"); + topAttribute = gameAreaElement.attributeNode("top"); + rightAttribute = gameAreaElement.attributeNode("right"); + bottomAttribute = gameAreaElement.attributeNode("bottom"); + + editableArea.setCoords + (XMARGIN + leftAttribute.value().toInt(), + YMARGIN + topAttribute.value().toInt(), + XMARGIN + rightAttribute.value().toInt(), + YMARGIN + bottomAttribute.value().toInt()); + + soundNamesList = editableAreaElement.elementsByTagName("sound"); + if (soundNamesList.count() != 1) + return false; + + soundNameElement = (const QDomElement &) soundNamesList.item(0).toElement(); + refAttribute = soundNameElement.attributeNode("ref"); + + editableSound = refAttribute.value(); + + categoriesList = playGroundElement.elementsByTagName("category"); + texts = categoriesList.count(); + if (texts < 1) + return false; + + delete[] textsLayout; + textsLayout = new QRect[texts]; + delete[] textsList; + textsList = new QString[texts]; + + for (int text = 0; text < texts; text++) + { + categoryElement = (const QDomElement &) categoriesList.item(text).toElement(); + + gameAreasList = categoryElement.elementsByTagName("position"); + if (gameAreasList.count() != 1) + return false; + + gameAreaElement = (const QDomElement &) gameAreasList.item(0).toElement(); + leftAttribute = gameAreaElement.attributeNode("left"); + topAttribute = gameAreaElement.attributeNode("top"); + rightAttribute = gameAreaElement.attributeNode("right"); + bottomAttribute = gameAreaElement.attributeNode("bottom"); + + textsLayout[text].setCoords + (leftAttribute.value().toInt(), + topAttribute.value().toInt(), + rightAttribute.value().toInt(), + bottomAttribute.value().toInt()); + + labelsList = categoryElement.elementsByTagName("label"); + if (labelsList.count() != 1) + return false; + + labelElement = (const QDomElement &) labelsList.item(0).toElement(); + + textsList[text] = labelElement.text(); + } + + objectsList = playGroundElement.elementsByTagName("object"); + decorations = objectsList.count(); + if (decorations < 1) + return false; + + delete[] objectsLayout; + objectsLayout = new QRect[decorations]; + delete[] soundsList; + soundsList = new QString[decorations]; + + for (int decoration = 0; decoration < decorations; decoration++) + { + objectElement = (const QDomElement &) objectsList.item(decoration).toElement(); + + gameAreasList = objectElement.elementsByTagName("position"); + if (gameAreasList.count() != 1) + return false; + + gameAreaElement = (const QDomElement &) gameAreasList.item(0).toElement(); + leftAttribute = gameAreaElement.attributeNode("left"); + topAttribute = gameAreaElement.attributeNode("top"); + rightAttribute = gameAreaElement.attributeNode("right"); + bottomAttribute = gameAreaElement.attributeNode("bottom"); + + objectsLayout[decoration].setCoords + (leftAttribute.value().toInt(), + topAttribute.value().toInt(), + rightAttribute.value().toInt(), + bottomAttribute.value().toInt()); + + soundNamesList = objectElement.elementsByTagName("sound"); + if (soundNamesList.count() != 1) + return false; + + soundNameElement = (const QDomElement &) soundNamesList.item(0).toElement(); + + refAttribute = soundNameElement.attributeNode("ref"); + + soundsList[decoration] = refAttribute.value(); + } + + return true; +} + +// Report a load failure +void PlayGround::loadFailure() +{ + KMessageBox::error(topLevel, i18n("Fatal error:\n" + "Unable to load the pictures, aborting.")); + exit(-1); +} + +// Set up play ground's geometry +void PlayGround::setupGeometry() +{ + int width = gameboard.width() + 2 * XMARGIN, + height = gameboard.height() + 2 * YMARGIN; + setFixedWidth(width); + setFixedHeight(height); +} + +// In which decorative object are we? +// On return, the position is the location of the cursor's hot spot +// Returns false if we aren't in any zone +bool PlayGround::zone(QPoint &position) +{ + // Scan all available decorative objects on right side because we may be adding one + int draggedNumber; + for (draggedNumber = 0; + draggedNumber < decorations; + draggedNumber++) if (objectsLayout[draggedNumber].contains(position)) + { + position.setX(position.x() - objectsLayout[draggedNumber].x()); + position.setY(position.y() - objectsLayout[draggedNumber].y()); + + draggedObject.setNumber(draggedNumber); + draggedZOrder = -1; + + return true; + } + + // Scan all decorative objects already layed down on editable are because we may be moving or removing one + const ToDraw *currentObject; + + for (draggedZOrder = toDraw.count()-1; draggedZOrder >= 0; draggedZOrder--) + { + currentObject = toDraw.at(draggedZOrder); + if (!currentObject->getPosition().contains(position)) continue; + + QRect toUpdate(currentObject->getPosition()); + draggedObject = *currentObject; + draggedNumber = draggedObject.getNumber(); + + QBitmap shape(objectsLayout[draggedNumber].size()); + QPoint relative(position.x() - toUpdate.x(), + position.y() - toUpdate.y()); + bitBlt(&shape, QPoint(0, 0), &masks, objectsLayout[draggedNumber], Qt::CopyROP); + if (!shape.convertToImage().pixelIndex(relative.x(), relative.y())) continue; + + toDraw.remove(draggedZOrder); + toUpdate.moveBy(XMARGIN, YMARGIN); + repaint(toUpdate, false); + + position = relative; + + return true; + } + + // If we are on the gameboard itself, then play "tuberling" sound + if (editableArea.contains(position)) + topLevel->playSound(editableSound); + + return false; +} + +// Load objects and lay them down on the editable area +bool PlayGround::loadFrom(const QString &name) +{ + FILE *fp; + bool eof = false; + ToDraw readObject, *newObject; + Action *newAction; + + if (!(fp = fopen(QFile::encodeName(name), "r"))) return false; + + uint newGameboard; + int nitems = fscanf(fp, "%u\n", &newGameboard); + if (nitems == EOF) + { + fclose(fp); + return false; + } + topLevel->changeGameboard(newGameboard); + + for (;;) + { + if (!readObject.load(fp, decorations, eof)) + { + fclose(fp); + return false; + } + if (eof) + { + return !fclose(fp); + } + newObject = new ToDraw(readObject); + toDraw.append(newObject); + newAction = new Action(0, -1, newObject, toDraw.count()-1); + history.append(newAction); + currentAction++; + + } +} diff --git a/ktuberling/playground.h b/ktuberling/playground.h new file mode 100644 index 00000000..ee1a9a51 --- /dev/null +++ b/ktuberling/playground.h @@ -0,0 +1,86 @@ +/* ------------------------------------------------------------- + KDE Tuberling + Play ground widget + mailto:e.bischoff@noos.fr + ------------------------------------------------------------- */ + + +#ifndef _PLAYGROUND_H_ +#define _PLAYGROUND_H_ + +#include <kprinter.h> + +#include <qwidget.h> +#include <qbitmap.h> +#include <qptrlist.h> + +#include "todraw.h" +#include "action.h" + +class QDomDocument; +class TopLevel; + +class PlayGround : public QWidget +{ + Q_OBJECT + +public: + + PlayGround(TopLevel *parent, const char *name, uint selectedGameboard); + ~PlayGround(); + + void reset(); + void change(uint selectedGameboard); + void repaintAll(); + bool undo(); + bool redo(); + bool loadFrom(const QString &name); + bool saveAs(const QString &name); + bool printPicture(KPrinter &printer) const; + QPixmap getPicture() const; + + inline bool isFirstAction() const { return currentAction == 0; } + inline bool isLastAction() const { return currentAction >= history.count(); } + +protected: + + virtual void paintEvent(QPaintEvent *event); + virtual void mousePressEvent(QMouseEvent *event); + virtual void mouseReleaseEvent(QMouseEvent *event); + +private: + + bool registerPlayGrounds(QDomDocument &layoutDocument); + bool loadPlayGround(QDomDocument &layoutDocument, uint toLoad); + void loadFailure(); + void setupGeometry(); + bool zone(QPoint &position); + void drawText(QPainter &artist, QRect &area, QString &textId) const; + void drawGameboard(QPainter &artist, const QRect &area) const; + +private: + + QPixmap gameboard; // Picture of the game board + QBitmap masks; // Pictures of the objects' shapes + QRect editableArea; // Part of the gameboard where the player can lay down objects + QString menuItem, // Menu item describing describing this gameboard + editableSound; // Sound associated with this area + int texts, // Number of categories of objects names + decorations; // Number of draggable objects on the right side of the gameboard + QRect *textsLayout, // Positions of the categories names + *objectsLayout; // Position of the draggable objects on right side of the gameboard + QString *textsList, // List of the message numbers associated with categories + *soundsList; // List of sounds associated with each object + + QCursor *draggedCursor; // Cursor's shape for currently dragged object + ToDraw draggedObject; // Object currently dragged + int draggedZOrder; // Z-order (in to-draw buffer) of this object + + QPtrList<ToDraw> toDraw; // List of objects in z-order + QPtrList<Action> history; // List of actions in chronological order + unsigned int currentAction; // Number of current action (not the last one if used "undo" button!) + + TopLevel *topLevel; // Top-level window +}; + +#endif diff --git a/ktuberling/soundfactory.cpp b/ktuberling/soundfactory.cpp new file mode 100644 index 00000000..d9bdf48d --- /dev/null +++ b/ktuberling/soundfactory.cpp @@ -0,0 +1,148 @@ +/* ------------------------------------------------------------- + KDE Tuberling + Play ground widget + mailto:e.bischoff@noos.fr + ------------------------------------------------------------- */ + +#include <stdlib.h> + +#include <kmessagebox.h> +#include <klocale.h> +#include <kstandarddirs.h> +#include <kaudioplayer.h> + +#include <qdom.h> + +#include "soundfactory.h" +#include "soundfactory.moc" +#include "toplevel.h" + +// Constructor +SoundFactory::SoundFactory(TopLevel *parent, const char *name, uint selectedLanguage) + : QObject(parent, name) +{ + topLevel = parent; + + namesList = filesList = 0; + + QDomDocument layoutsDocument; + bool ok = topLevel->loadLayout(layoutsDocument); + if (ok) ok = registerLanguages(layoutsDocument); + if (ok) ok = loadLanguage(layoutsDocument, selectedLanguage); + if (!ok) loadFailure(); +} + +// Destructor +SoundFactory::~SoundFactory() +{ + if (namesList) delete [] namesList; + if (filesList) delete [] filesList; +} + +// Change the language +void SoundFactory::change(uint selectedLanguage) +{ + QDomDocument layoutsDocument; + bool ok = topLevel->loadLayout(layoutsDocument); + if (ok) ok = loadLanguage(layoutsDocument, selectedLanguage); + if (!ok) loadFailure(); +} + +// Play some sound +void SoundFactory::playSound(const QString &soundRef) const +{ + int sound; + QString soundFile; + + if (!topLevel->isSoundEnabled()) return; + + for (sound = 0; sound < sounds; sound++) + if (!namesList[sound].compare(soundRef)) break; + if (sound == sounds) return; + + soundFile = locate("data", "ktuberling/sounds/" + filesList[sound]); + if (soundFile == 0) return; + +//printf("%s\n", (const char *) soundFile); + KAudioPlayer::play(soundFile); +} + +// Report a load failure +void SoundFactory::loadFailure() +{ + KMessageBox::error(topLevel, i18n("Error while loading the sound names.")); +} + +// Register the various languages +bool SoundFactory::registerLanguages(QDomDocument &layoutDocument) +{ + QDomNodeList languagesList, menuItemsList, labelsList; + QDomElement languageElement, menuItemElement, labelElement; + QDomAttr codeAttribute, actionAttribute; + bool enabled; + + languagesList = layoutDocument.elementsByTagName("language"); + if (languagesList.count() < 1) + return false; + + for (uint i = 0; i < languagesList.count(); i++) + { + languageElement = (const QDomElement &) languagesList.item(i).toElement(); + codeAttribute = languageElement.attributeNode("code"); + enabled = locate("data", "ktuberling/sounds/" + codeAttribute.value() + "/") != 0; + + menuItemsList = languageElement.elementsByTagName("menuitem"); + if (menuItemsList.count() != 1) + return false; + + menuItemElement = (const QDomElement &) menuItemsList.item(0).toElement(); + + labelsList = menuItemElement.elementsByTagName("label"); + if (labelsList.count() != 1) + return false; + + labelElement = (const QDomElement &) labelsList.item(0).toElement(); + actionAttribute = menuItemElement.attributeNode("action"); + topLevel->registerLanguage(labelElement.text(), actionAttribute.value().latin1(), enabled); + } + + return true; +} + +// Load the sounds of one given language +bool SoundFactory::loadLanguage(QDomDocument &layoutDocument, uint toLoad) +{ + QDomNodeList languagesList, + soundNamesList; + QDomElement languageElement, + soundNameElement; + QDomAttr nameAttribute, fileAttribute; + + languagesList = layoutDocument.elementsByTagName("language"); + if (toLoad >= languagesList.count()) + return false; + + languageElement = (const QDomElement &) languagesList.item(toLoad).toElement(); + + soundNamesList = languageElement.elementsByTagName("sound"); + sounds = soundNamesList.count(); + if (sounds < 1) + return false; + + if (!(namesList = new QString[sounds])) + return false; + if (!(filesList = new QString[sounds])) + return false; + + for (uint sound = 0; sound < sounds; sound++) + { + soundNameElement = (const QDomElement &) soundNamesList.item(sound).toElement(); + + nameAttribute = soundNameElement.attributeNode("name"); + namesList[sound] = nameAttribute.value(); + fileAttribute = soundNameElement.attributeNode("file"); + filesList[sound] = fileAttribute.value(); + } + return true; +} + diff --git a/ktuberling/soundfactory.h b/ktuberling/soundfactory.h new file mode 100644 index 00000000..1eb0abd5 --- /dev/null +++ b/ktuberling/soundfactory.h @@ -0,0 +1,46 @@ +/* ------------------------------------------------------------- + KDE Tuberling + Sound factory + mailto:e.bischoff@noos.fr + ------------------------------------------------------------- */ + + +#ifndef _SOUNDFACTORY_H_ +#define _SOUNDFACTORY_H_ + +#include "qobject.h" + +class QDomDocument; +class TopLevel; + +class SoundFactory : public QObject +{ + Q_OBJECT + +public: + + SoundFactory(TopLevel *parent, const char *name, uint selectedLanguage); + ~SoundFactory(); + + void change(uint selectedLanguage); + void playSound(const QString &soundRef) const; + +protected: + + bool registerLanguages(QDomDocument &layoutDocument); + bool loadLanguage(QDomDocument &layoutDocument, uint toLoad); + +private: + + void loadFailure(); + +private: + + int sounds; // Number of sounds + QString *namesList, // List of sound names + *filesList; // List of sound files associated with each sound name + + TopLevel *topLevel; // Top-level window +}; + +#endif diff --git a/ktuberling/sounds/Makefile.am b/ktuberling/sounds/Makefile.am new file mode 100644 index 00000000..3f0d46b7 --- /dev/null +++ b/ktuberling/sounds/Makefile.am @@ -0,0 +1,9 @@ + +# add here all files +sound_DATA = badge.wav bow.wav cigar.wav ear.wav earring.wav eye.wav eyebrow.wav\ + hat.wav moustache.wav mouth.wav nose.wav spectacles.wav \ + sunglasses.wav tuberling.wav watch.wav + +sounddir = $(kde_datadir)/ktuberling/sounds/en + +# DONT ADD TRANSLATIONS HERE diff --git a/ktuberling/sounds/NO_TRANSLATIONS_HERE b/ktuberling/sounds/NO_TRANSLATIONS_HERE new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ktuberling/sounds/NO_TRANSLATIONS_HERE diff --git a/ktuberling/sounds/badge.wav b/ktuberling/sounds/badge.wav Binary files differnew file mode 100644 index 00000000..2e436e3a --- /dev/null +++ b/ktuberling/sounds/badge.wav diff --git a/ktuberling/sounds/bow.wav b/ktuberling/sounds/bow.wav Binary files differnew file mode 100644 index 00000000..28703029 --- /dev/null +++ b/ktuberling/sounds/bow.wav diff --git a/ktuberling/sounds/cigar.wav b/ktuberling/sounds/cigar.wav Binary files differnew file mode 100644 index 00000000..dbc72e25 --- /dev/null +++ b/ktuberling/sounds/cigar.wav diff --git a/ktuberling/sounds/ear.wav b/ktuberling/sounds/ear.wav Binary files differnew file mode 100644 index 00000000..901bac74 --- /dev/null +++ b/ktuberling/sounds/ear.wav diff --git a/ktuberling/sounds/earring.wav b/ktuberling/sounds/earring.wav Binary files differnew file mode 100644 index 00000000..e708caaf --- /dev/null +++ b/ktuberling/sounds/earring.wav diff --git a/ktuberling/sounds/eye.wav b/ktuberling/sounds/eye.wav Binary files differnew file mode 100644 index 00000000..b596d4c6 --- /dev/null +++ b/ktuberling/sounds/eye.wav diff --git a/ktuberling/sounds/eyebrow.wav b/ktuberling/sounds/eyebrow.wav Binary files differnew file mode 100644 index 00000000..d3c1b3b4 --- /dev/null +++ b/ktuberling/sounds/eyebrow.wav diff --git a/ktuberling/sounds/hat.wav b/ktuberling/sounds/hat.wav Binary files differnew file mode 100644 index 00000000..b6d92e5a --- /dev/null +++ b/ktuberling/sounds/hat.wav diff --git a/ktuberling/sounds/moustache.wav b/ktuberling/sounds/moustache.wav Binary files differnew file mode 100644 index 00000000..e671f1c8 --- /dev/null +++ b/ktuberling/sounds/moustache.wav diff --git a/ktuberling/sounds/mouth.wav b/ktuberling/sounds/mouth.wav Binary files differnew file mode 100644 index 00000000..90613e9c --- /dev/null +++ b/ktuberling/sounds/mouth.wav diff --git a/ktuberling/sounds/nose.wav b/ktuberling/sounds/nose.wav Binary files differnew file mode 100644 index 00000000..058e718f --- /dev/null +++ b/ktuberling/sounds/nose.wav diff --git a/ktuberling/sounds/spectacles.wav b/ktuberling/sounds/spectacles.wav Binary files differnew file mode 100644 index 00000000..bf0802ae --- /dev/null +++ b/ktuberling/sounds/spectacles.wav diff --git a/ktuberling/sounds/sunglasses.wav b/ktuberling/sounds/sunglasses.wav Binary files differnew file mode 100644 index 00000000..0b8f8c6d --- /dev/null +++ b/ktuberling/sounds/sunglasses.wav diff --git a/ktuberling/sounds/tuberling.wav b/ktuberling/sounds/tuberling.wav Binary files differnew file mode 100644 index 00000000..c85418b1 --- /dev/null +++ b/ktuberling/sounds/tuberling.wav diff --git a/ktuberling/sounds/watch.wav b/ktuberling/sounds/watch.wav Binary files differnew file mode 100644 index 00000000..87c03278 --- /dev/null +++ b/ktuberling/sounds/watch.wav diff --git a/ktuberling/todraw.cpp b/ktuberling/todraw.cpp new file mode 100644 index 00000000..e12c9e1b --- /dev/null +++ b/ktuberling/todraw.cpp @@ -0,0 +1,90 @@ +/* ------------------------------------------------------------- + KDE Tuberling + Object to draw on the game board + mailto:e.bischoff@noos.fr + ------------------------------------------------------------- */ + +#include <qbitmap.h> +#include <qpainter.h> + +#include "todraw.h" + +// Constructor with no arguments +ToDraw::ToDraw() + : position() +{ + number = -1; +} + +// Copy constructor +ToDraw::ToDraw(const ToDraw &model) + : position(model.position) +{ + number = model.number; +} + +// Constructor with arguments +ToDraw::ToDraw(int declaredNumber, const QRect &declaredPosition) + : position(declaredPosition) +{ + number = declaredNumber; +} + +// Affectation operator +ToDraw &ToDraw::operator=(const ToDraw &model) +{ + if (&model == this) return *this; + + position = model.position; + number = model.number; + + return *this; +} + +// Draw an object previously laid down on the game board +void ToDraw::draw(QPainter &artist, const QRect &area, + const QRect *objectsLayout, + const QPixmap *gameboard, const QBitmap *masks) const +{ + if (!position.intersects(area)) return; + + QPixmap objectPixmap(objectsLayout[number].size()); + QBitmap shapeBitmap(objectsLayout[number].size()); + + bitBlt(&objectPixmap, QPoint(0, 0), gameboard, objectsLayout[number], Qt::CopyROP); + bitBlt(&shapeBitmap, QPoint(0, 0), masks, objectsLayout[number], Qt::CopyROP); + objectPixmap.setMask(shapeBitmap); + artist.drawPixmap(position.topLeft(), objectPixmap); +} + +// Load an object from a file +bool ToDraw::load(FILE *fp, int decorations, bool &eof) +{ + int nitems; + int pl, pt, pr, pb; + + nitems = fscanf(fp, "%d\t%d %d %d %d\n", &number, &pl, &pt, &pr, &pb); + + if (nitems == EOF) + { + eof = true; + return true; + } + eof = false; + if (nitems != 5) return false; + + if (number < 0 || number >= decorations) return false; + + position.setCoords(pl, pt, pr, pb); + + return true; +} + +// Save an object to a file +void ToDraw::save(FILE *fp) const +{ + fprintf(fp, "%d\t%d %d %d %d\n", + number, + position.left(), position.top(), position.right(), position.bottom()); +} + diff --git a/ktuberling/todraw.h b/ktuberling/todraw.h new file mode 100644 index 00000000..4e46200a --- /dev/null +++ b/ktuberling/todraw.h @@ -0,0 +1,35 @@ +/* ------------------------------------------------------------- + KDE Tuberling + Object to draw on the game board + mailto:e.bischoff@noos.fr + ------------------------------------------------------------- */ + + +#ifndef _TODRAW_H_ +#define _TODRAW_H_ + +#include <qrect.h> + +#include <stdio.h> + +class ToDraw +{ + public: + ToDraw(); + ToDraw(const ToDraw &); + ToDraw(int, const QRect &); + ToDraw &operator=(const ToDraw &); + void draw(QPainter &, const QRect &, const QRect *, const QPixmap *, const QBitmap *) const; + void save(FILE *) const; + bool load(FILE *, int, bool &); + + inline int getNumber() const { return number; } + inline void setNumber(int newValue) { number = newValue; } + inline const QRect &getPosition() const { return position; } + + private: + int number; + QRect position; +}; + +#endif diff --git a/ktuberling/toplevel.cpp b/ktuberling/toplevel.cpp new file mode 100644 index 00000000..d4ad647c --- /dev/null +++ b/ktuberling/toplevel.cpp @@ -0,0 +1,611 @@ +/* ------------------------------------------------------------- + KDE Tuberling + Top level window + mailto:e.bischoff@noos.fr + ------------------------------------------------------------- */ + +#include <kapplication.h> +#include <kmessagebox.h> +#include <kfiledialog.h> +#include <klocale.h> +#include <kstandarddirs.h> +#include <kio/netaccess.h> +#include <kaction.h> +#include <kstdaction.h> +#include <kstdgameaction.h> + +#include <kprinter.h> +#include <qclipboard.h> + +#include "toplevel.moc" +#include "playground.h" +#include "soundfactory.h" + +// Constructor +TopLevel::TopLevel() + : KMainWindow(0) +{ + readOptions(); + + gameboards = 0; + languages = 0; + playGround = new PlayGround(this, "playground", selectedGameboard); + soundFactory = new SoundFactory(this, "sounds", selectedLanguage); + + setCentralWidget(playGround); + + setupKAction(); +} + +// Destructor +TopLevel::~TopLevel() +{ +} + +// Enable or disable "undo" button and menu item +void TopLevel::enableUndo(bool enable) const +{ + actionCollection()->action(KStdAction::stdName(KStdAction::Undo))->setEnabled(enable); +} + +// Enable or disable "redo" button and menu item +void TopLevel::enableRedo(bool enable) const +{ + actionCollection()->action(KStdAction::stdName(KStdAction::Redo))->setEnabled(enable); +} + +// Register an available gameboard +void TopLevel::registerGameboard(const QString &menuItem, const char *actionId) +{ + KToggleAction *t = 0; + + switch (gameboards) + { + case 0: t = new KToggleAction(i18n(menuItem.latin1()), 0, this, SLOT(gameboard0()), actionCollection(), actionId); + break; + case 1: t = new KToggleAction(i18n(menuItem.latin1()), 0, this, SLOT(gameboard1()), actionCollection(), actionId); + break; + case 2: t = new KToggleAction(i18n(menuItem.latin1()), 0, this, SLOT(gameboard2()), actionCollection(), actionId); + break; + case 3: t = new KToggleAction(i18n(menuItem.latin1()), 0, this, SLOT(gameboard3()), actionCollection(), actionId); + break; + case 4: t = new KToggleAction(i18n(menuItem.latin1()), 0, this, SLOT(gameboard4()), actionCollection(), actionId); + break; + case 5: t = new KToggleAction(i18n(menuItem.latin1()), 0, this, SLOT(gameboard5()), actionCollection(), actionId); + break; + case 6: t = new KToggleAction(i18n(menuItem.latin1()), 0, this, SLOT(gameboard6()), actionCollection(), actionId); + break; + case 7: t = new KToggleAction(i18n(menuItem.latin1()), 0, this, SLOT(gameboard7()), actionCollection(), actionId); + break; + } + + if( t ) { + if (gameboards == selectedGameboard) t->setChecked(true); + gameboardActions[gameboards] = actionId; + gameboards++; + } +} + +// Register an available language +void TopLevel::registerLanguage(const QString &menuItem, const char *actionId, bool enabled) +{ + KToggleAction *t = 0; + + switch (languages) + { + case 0: t = new KToggleAction(i18n(menuItem.latin1()), 0, this, SLOT(language0()), actionCollection(), actionId); + break; + case 1: t = new KToggleAction(i18n(menuItem.latin1()), 0, this, SLOT(language1()), actionCollection(), actionId); + break; + case 2: t = new KToggleAction(i18n(menuItem.latin1()), 0, this, SLOT(language2()), actionCollection(), actionId); + break; + case 3: t = new KToggleAction(i18n(menuItem.latin1()), 0, this, SLOT(language3()), actionCollection(), actionId); + break; + case 4: t = new KToggleAction(i18n(menuItem.latin1()), 0, this, SLOT(language4()), actionCollection(), actionId); + break; + case 5: t = new KToggleAction(i18n(menuItem.latin1()), 0, this, SLOT(language5()), actionCollection(), actionId); + break; + case 6: t = new KToggleAction(i18n(menuItem.latin1()), 0, this, SLOT(language6()), actionCollection(), actionId); + break; + case 7: t = new KToggleAction(i18n(menuItem.latin1()), 0, this, SLOT(language7()), actionCollection(), actionId); + break; + case 8: t = new KToggleAction(i18n(menuItem.latin1()), 0, this, SLOT(language8()), actionCollection(), actionId); + break; + case 9: t = new KToggleAction(i18n(menuItem.latin1()), 0, this, SLOT(language9()), actionCollection(), actionId); + break; + case 10: t = new KToggleAction(i18n(menuItem.latin1()), 0, this, SLOT(language10()), actionCollection(), actionId); + break; + case 11: t = new KToggleAction(i18n(menuItem.latin1()), 0, this, SLOT(language11()), actionCollection(), actionId); + break; + case 12: t = new KToggleAction(i18n(menuItem.latin1()), 0, this, SLOT(language12()), actionCollection(), actionId); + break; + case 13: t = new KToggleAction(i18n(menuItem.latin1()), 0, this, SLOT(language13()), actionCollection(), actionId); + break; + case 14: t = new KToggleAction(i18n(menuItem.latin1()), 0, this, SLOT(language14()), actionCollection(), actionId); + break; + case 15: t = new KToggleAction(i18n(menuItem.latin1()), 0, this, SLOT(language15()), actionCollection(), actionId); + break; + } + + if( t ) { + if (languages == selectedLanguage) t->setChecked(true); + t->setEnabled(enabled); + languageActions[languages] = actionId; + languages++; + } +} + +// Switch to another gameboard +void TopLevel::changeGameboard(uint newGameboard) +{ + // Do not accept to switch to same gameboard + if (newGameboard == selectedGameboard) { + // select this gameboard again + ((KToggleAction*) actionCollection()->action(gameboardActions[newGameboard].latin1()))->setChecked(true); + return; + } + + // Unselect preceding gameboard + ((KToggleAction*) actionCollection()->action(gameboardActions[selectedGameboard].latin1()))->setChecked(false); + + // Change gameboard in the remembered options + selectedGameboard = newGameboard; + writeOptions(); + + if( !((KToggleAction*) actionCollection()->action(gameboardActions[selectedGameboard].latin1()))->isChecked() ) + ((KToggleAction*) actionCollection()->action(gameboardActions[selectedGameboard].latin1()))->setChecked(true); + + // Change gameboard effectively + playGround->change(newGameboard); + + // Disable undo and redo actions + enableUndo(false); + enableRedo(false); +} + +// Switch to another language +void TopLevel::changeLanguage(uint newLanguage) +{ + // Do not accept to switch to same language + if (newLanguage == selectedLanguage && soundEnabled) { + // newLanguage should stay checked + ((KToggleAction*) actionCollection()->action(languageActions[newLanguage].latin1()))->setChecked(true); + return; + } + + // Unselect preceding language + if (!soundEnabled) ((KToggleAction*) actionCollection()->action("speech_no_sound"))->setChecked(false); + ((KToggleAction*) actionCollection()->action(languageActions[selectedLanguage].latin1()))->setChecked(false); + + // Change language in the remembered options + soundEnabled = true; + selectedLanguage = newLanguage; + writeOptions(); + + // Change language effectively + soundFactory->change(newLanguage); +} + +// Load the layouts file +bool TopLevel::loadLayout(QDomDocument &layoutDocument) +{ + QFile layoutFile(QFile::encodeName(locate("data", "ktuberling/pics/layout.xml"))); + if (!layoutFile.open(IO_ReadOnly)) + return false; + + if (!layoutDocument.setContent(&layoutFile)) + { + layoutFile.close(); + return false; + } + layoutFile.close(); + + return true; +} + +// Play a sound +void TopLevel::playSound(const QString &ref) const +{ + soundFactory->playSound(ref); +} + +// Read options from preferences file +void TopLevel::readOptions() +{ + KConfig *config; + QString option; + + config = KApplication::kApplication()->config(); + + config->setGroup("General"); + option = config->readEntry("Sound", "on"); + soundEnabled = option.find("on") == 0; + + option = config->readEntry("GameboardNumber", "0"); + selectedGameboard = option.toInt(); + if (selectedGameboard <= 0) selectedGameboard = 0; + if (selectedGameboard > 7) selectedGameboard = 7; + + option = config->readEntry("LanguageNumber", "2"); + selectedLanguage = option.toInt(); + if (selectedLanguage <= 0) selectedLanguage = 0; + if (selectedLanguage > 15) selectedLanguage = 15; + +} + +// Write options to preferences file +void TopLevel::writeOptions() +{ + KConfig *config; + + config = KApplication::kApplication()->config(); + + config->setGroup("General"); + config->writeEntry("Sound", soundEnabled? "on": "off"); + + config->writeEntry("GameboardNumber", selectedGameboard); + + config->writeEntry("LanguageNumber", selectedLanguage); + + config->sync(); +} + +// KAction initialization (aka menubar + toolbar init) +void TopLevel::setupKAction() +{ +//Game + KStdGameAction::gameNew(this, SLOT(fileNew()), actionCollection()); + KStdGameAction::load(this, SLOT(fileOpen()), actionCollection()); + KStdGameAction::save(this, SLOT(fileSave()), actionCollection()); + KStdGameAction::print(this, SLOT(filePrint()), actionCollection()); + KStdGameAction::quit(kapp, SLOT(quit()), actionCollection()); + (void) new KAction(i18n("Save &as Picture..."), 0, this, SLOT(filePicture()), actionCollection(), "game_save_picture"); + +//Edit + KStdAction::copy(this, SLOT(editCopy()), actionCollection()); + KStdAction::undo(this, SLOT(editUndo()), actionCollection()); + KStdAction::redo(this, SLOT(editRedo()), actionCollection()); + enableUndo(false); + enableRedo(false); + +//Speech + KToggleAction* t = new KToggleAction(i18n("&No Sound"), 0, this, SLOT(soundOff()), actionCollection(), "speech_no_sound"); + if (!soundEnabled) t->setChecked(true); + + setupGUI(); +} + +// Reset gameboard +void TopLevel::fileNew() +{ + playGround->reset(); + + enableUndo(false); + enableRedo(false); + + playGround->repaintAll(); +} + +// Load gameboard +void TopLevel::fileOpen() +{ + QString dir = locate("data", "ktuberling/museum/miss.tuberling"); + dir.truncate(dir.findRev('/') + 1); + + KURL url = KFileDialog::getOpenURL(dir, "*.tuberling"); + + open(url); +} + +void TopLevel::open(const KURL &url) +{ + if (url.isEmpty()) + return; + + QString name; + + KIO::NetAccess::download(url, name, this); + + playGround->reset(); + + if (!playGround->loadFrom(name)) + KMessageBox::error(this, i18n("Could not load file.")); + + enableUndo(!playGround->isFirstAction()); + enableRedo(false); + + playGround->repaintAll(); + + KIO::NetAccess::removeTempFile( name ); +} + +// Save gameboard +void TopLevel::fileSave() +{ + KURL url = KFileDialog::getSaveURL + ( QString::null, + "*.tuberling"); + + if (url.isEmpty()) + return; + + if( !url.isLocalFile() ) + { + KMessageBox::sorry(this, + i18n("Only saving to local files is currently " + "supported.")); + return; + } + + QString name = url.path(); + int suffix; + + suffix = name.findRev('.'); + if (suffix == -1) + { + name += ".tuberling"; + } + + if( !playGround->saveAs( name ) ) + KMessageBox::error(this, i18n("Could not save file.")); +} + +// Save gameboard as picture +void TopLevel::filePicture() +{ + QPixmap picture(playGround->getPicture()); + + KURL url = KFileDialog::getSaveURL + ( QString::null, + i18n( "*.xpm|UNIX Pixmaps (*.xpm)\n" + "*.jpg|JPEG Compressed Files (*.jpg)\n" + "*.png|Next Generation Pictures (*.png)\n" + "*.bmp|Windows Bitmaps (*.bmp)\n" + "*|All Picture Formats")); + + if( url.isEmpty() ) + return; + + if( !url.isLocalFile() ) + { + KMessageBox::sorry(this, + i18n("Only saving to local files is currently " + "supported.")); + return; + } + + QString name = url.path(); + const char *format; + int suffix; + QString end; + + suffix = name.findRev('.'); + if (suffix == -1) + { + name += ".xpm"; + end = "xpm"; + } + else end = name.mid(suffix + 1, name.length()); + + if (end == "xpm") format = "XPM"; + else if (end == "jpg") format = "JPEG"; + else if (end == "png") format = "PNG"; + else if (end == "bmp") format = "BMP"; + else + { + KMessageBox::error(this, i18n("Unknown picture format.")); + return; + } + + if (!picture.save(name, format)) + KMessageBox::error + (this, i18n("Could not save file.")); +} + +// Save gameboard as picture +void TopLevel::filePrint() +{ + KPrinter printer; + bool ok; + + ok = printer.setup(this, i18n("Print %1").arg(actionCollection()->action(gameboardActions[selectedGameboard].latin1())->plainText())); + if (!ok) return; + playGround->repaint(true); + if (!playGround->printPicture(printer)) + KMessageBox::error(this, + i18n("Could not print picture.")); + else + KMessageBox::information(this, + i18n("Picture successfully printed.")); +} + +// Copy modified area to clipboard +void TopLevel::editCopy() +{ + QClipboard *clipboard = QApplication::clipboard(); + QPixmap picture(playGround->getPicture()); + + clipboard->setPixmap(picture); +} + +// Undo last action +void TopLevel::editUndo() +{ + if (playGround->isFirstAction()) return; + + if (!playGround->undo()) return; + + if (playGround->isFirstAction()) enableUndo(false); + enableRedo(true); + + playGround->repaintAll(); +} + +// Redo last action +void TopLevel::editRedo() +{ + if (playGround->isLastAction()) return; + + if (!playGround->redo()) return; + + if (playGround->isLastAction()) enableRedo(false); + enableUndo(true); + + playGround->repaintAll(); +} + +// Switch to gameboard #0 +void TopLevel::gameboard0() +{ + changeGameboard(0); +} + +// Switch to gameboard #1 +void TopLevel::gameboard1() +{ + changeGameboard(1); +} + +// Switch to gameboard #2 +void TopLevel::gameboard2() +{ + changeGameboard(2); +} + +// Switch to gameboard #3 +void TopLevel::gameboard3() +{ + changeGameboard(3); +} + +// Switch to gameboard #4 +void TopLevel::gameboard4() +{ + changeGameboard(4); +} + +// Switch to gameboard #5 +void TopLevel::gameboard5() +{ + changeGameboard(5); +} + +// Switch to gameboard #6 +void TopLevel::gameboard6() +{ + changeGameboard(6); +} + +// Switch to gameboard #7 +void TopLevel::gameboard7() +{ + changeGameboard(7); +} + +// Toggle sound off +void TopLevel::soundOff() +{ + if (!soundEnabled) return; + + soundEnabled = false; + ((KToggleAction*) actionCollection()->action(languageActions[selectedLanguage].latin1()))->setChecked(false); + ((KToggleAction*) actionCollection()->action("speech_no_sound"))->setChecked(true); + + writeOptions(); +} + +// Switch to language #0 +void TopLevel::language0() +{ + changeLanguage(0); +} + +// Switch to language #1 +void TopLevel::language1() +{ + changeLanguage(1); +} + +// Switch to language #2 +void TopLevel::language2() +{ + changeLanguage(2); +} + +// Switch to language #3 +void TopLevel::language3() +{ + changeLanguage(3); +} + +// Switch to language #4 +void TopLevel::language4() +{ + changeLanguage(4); +} + +// Switch to language #5 +void TopLevel::language5() +{ + changeLanguage(5); +} + +// Switch to language #6 +void TopLevel::language6() +{ + changeLanguage(6); +} + +// Switch to language #7 +void TopLevel::language7() +{ + changeLanguage(7); +} + +// Switch to language #8 +void TopLevel::language8() +{ + changeLanguage(8); +} + +// Switch to language #9 +void TopLevel::language9() +{ + changeLanguage(9); +} + +// Switch to language #10 +void TopLevel::language10() +{ + changeLanguage(10); +} + +// Switch to language #11 +void TopLevel::language11() +{ + changeLanguage(11); +} + +// Switch to language #12 +void TopLevel::language12() +{ + changeLanguage(12); +} + +// Switch to language #13 +void TopLevel::language13() +{ + changeLanguage(13); +} + +// Switch to language #14 +void TopLevel::language14() +{ + changeLanguage(14); +} + +// Switch to language #15 +void TopLevel::language15() +{ + changeLanguage(15); +} diff --git a/ktuberling/toplevel.h b/ktuberling/toplevel.h new file mode 100644 index 00000000..8d67a252 --- /dev/null +++ b/ktuberling/toplevel.h @@ -0,0 +1,105 @@ +/* ------------------------------------------------------------- + KDE Tuberling + Top level window + mailto:e.bischoff@noos.fr + ------------------------------------------------------------- */ + + +#ifndef _TOPLEVEL_H_ +#define _TOPLEVEL_H_ + +#include <kmainwindow.h> +#include <kurl.h> + +class QDomDocument; +class PlayGround; +class SoundFactory; + +class TopLevel : public KMainWindow +{ + Q_OBJECT + +public: + + TopLevel(); + ~TopLevel(); + + void open(const KURL &url); + void enableUndo(bool enable) const; + void enableRedo(bool enable) const; + void registerGameboard(const QString &menuItem, const char *actionId); + void registerLanguage(const QString &menuItem, const char *actionId, bool enabled); + void changeGameboard(uint newGameboard); + void changeLanguage(uint newLanguage); + bool loadLayout(QDomDocument &layoutDocument); + void playSound(const QString &ref) const; + + inline bool isSoundEnabled() const {return soundEnabled;} + inline uint getSelectedGameboard() const {return selectedGameboard;} + +protected: + + void readOptions(); + void writeOptions(); + void setupKAction(); + +private slots: + + void fileNew(); + void fileOpen(); + void fileSave(); + void filePicture(); + void filePrint(); + void editCopy(); + void editUndo(); + void editRedo(); + void gameboard0(); + void gameboard1(); + void gameboard2(); + void gameboard3(); + void gameboard4(); + void gameboard5(); + void gameboard6(); + void gameboard7(); + void soundOff(); + void language0(); + void language1(); + void language2(); + void language3(); + void language4(); + void language5(); + void language6(); + void language7(); + void language8(); + void language9(); + void language10(); + void language11(); + void language12(); + void language13(); + void language14(); + void language15(); + +private: + + int // Menu items identificators + newID, openID, saveID, pictureID, printID, quitID, + copyID, undoID, redoID, + gameboardID, speechID; + enum { // Tool bar buttons identificators + ID_NEW, ID_OPEN, ID_SAVE, ID_PRINT, + ID_UNDO, ID_REDO, + ID_HELP }; + + bool soundEnabled; // True if the sound is enabled by user, even if there is no audio server + uint selectedGameboard, // Number of currently selected gameboard + gameboards; // Total number of gameboards + uint selectedLanguage, // Number of selected language + languages; // Total number of languages + QString gameboardActions[8], // Name of actions for registered gameboards + languageActions[16]; // Name of actions for registered languages + + PlayGround *playGround; // Play ground central widget + SoundFactory *soundFactory; // Speech organ +}; + +#endif diff --git a/ktuberling/x-tuberling.desktop b/ktuberling/x-tuberling.desktop new file mode 100644 index 00000000..9d62b1ab --- /dev/null +++ b/ktuberling/x-tuberling.desktop @@ -0,0 +1,61 @@ +# KDE Config File +[Desktop Entry] +MimeType=application/x-tuberling +Comment=Potato +Comment[ar]=بطاطا +Comment[be]=Клубень +Comment[bg]=Картоф +Comment[bn]=আলু +Comment[br]=Patatez +Comment[bs]=Krompir +Comment[cs]=Brambora +Comment[da]=Kartoffel +Comment[de]=Kartoffel +Comment[el]=Πατάτα +Comment[eo]=Terpomo +Comment[es]=Papá Patata +Comment[et]=Kartulimees +Comment[eu]=Patata +Comment[fa]=سیبزمینی +Comment[fi]=Peruna +Comment[fr]=Patate +Comment[ga]=Práta +Comment[gl]=Pataca +Comment[he]=תפוח אדמה +Comment[hi]=पोटैटो +Comment[hr]=Krumpirko +Comment[hu]=Krumpli +Comment[is]=Kartafla +Comment[it]=Patata +Comment[ja]=ポテト +Comment[km]=ដំឡូង +Comment[lt]=Bulvė +Comment[lv]=Kartupelis +Comment[mk]=Компир +Comment[nb]=Potet +Comment[nds]=Kantüffel +Comment[ne]=पोटेटो +Comment[nl]=Aardappel +Comment[nn]=Potet +Comment[pa]=ਆਲੂ +Comment[pl]=Ziemniak +Comment[pt]=Batata +Comment[pt_BR]=Batata +Comment[se]=Buđet +Comment[sk]=Zemiak +Comment[sl]=Krompirček +Comment[sv]=Potatis +Comment[ta]=உருளைகிழங்கு +Comment[tg]=Картошка +Comment[tr]=Patates +Comment[uk]=Картопля +Comment[wa]=Crompire +Comment[zh_CN]=土豆 +Comment[zh_TW]=馬鈴薯 +Icon=ktuberling +Type=MimeType +Patterns=*.tuberling; +X-KDE-AutoEmbed=false +[Property::X-KDE-NativeExtension] +Type=QString +Value=.tuberling |