gosu 0.7.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (249) hide show
  1. data/COPYING.txt +29 -0
  2. data/Gosu/Async.hpp +48 -0
  3. data/Gosu/Audio.hpp +145 -0
  4. data/Gosu/AutoLink.hpp +16 -0
  5. data/Gosu/Bitmap.hpp +85 -0
  6. data/Gosu/ButtonsMac.hpp +114 -0
  7. data/Gosu/ButtonsWin.hpp +111 -0
  8. data/Gosu/ButtonsX.hpp +115 -0
  9. data/Gosu/Color.hpp +172 -0
  10. data/Gosu/Directories.hpp +36 -0
  11. data/Gosu/Font.hpp +59 -0
  12. data/Gosu/Fwd.hpp +31 -0
  13. data/Gosu/Gosu.hpp +26 -0
  14. data/Gosu/Graphics.hpp +86 -0
  15. data/Gosu/GraphicsBase.hpp +45 -0
  16. data/Gosu/IO.hpp +255 -0
  17. data/Gosu/Image.hpp +148 -0
  18. data/Gosu/ImageData.hpp +45 -0
  19. data/Gosu/Input.hpp +116 -0
  20. data/Gosu/Math.hpp +95 -0
  21. data/Gosu/Platform.hpp +61 -0
  22. data/Gosu/RotFlip.hpp +116 -0
  23. data/Gosu/Sockets.hpp +129 -0
  24. data/Gosu/Text.hpp +47 -0
  25. data/Gosu/TextInput.hpp +57 -0
  26. data/Gosu/Timing.hpp +16 -0
  27. data/Gosu/Utility.hpp +24 -0
  28. data/Gosu/WinUtility.hpp +76 -0
  29. data/Gosu/Window.hpp +84 -0
  30. data/GosuImpl/Async.cpp +37 -0
  31. data/GosuImpl/AudioFmod.cpp +417 -0
  32. data/GosuImpl/AudioSDL.cpp +255 -0
  33. data/GosuImpl/DirectoriesMac.mm +38 -0
  34. data/GosuImpl/DirectoriesUnix.cpp +48 -0
  35. data/GosuImpl/DirectoriesWin.cpp +42 -0
  36. data/GosuImpl/FileUnix.cpp +100 -0
  37. data/GosuImpl/FileWin.cpp +83 -0
  38. data/GosuImpl/Graphics/Bitmap.cpp +116 -0
  39. data/GosuImpl/Graphics/BitmapBMP.cpp +232 -0
  40. data/GosuImpl/Graphics/BitmapColorKey.cpp +39 -0
  41. data/GosuImpl/Graphics/BitmapPNG.cpp +276 -0
  42. data/GosuImpl/Graphics/BitmapUtils.cpp +67 -0
  43. data/GosuImpl/Graphics/BlockAllocator.cpp +127 -0
  44. data/GosuImpl/Graphics/BlockAllocator.hpp +34 -0
  45. data/GosuImpl/Graphics/Color.cpp +126 -0
  46. data/GosuImpl/Graphics/Common.hpp +21 -0
  47. data/GosuImpl/Graphics/DrawOp.hpp +154 -0
  48. data/GosuImpl/Graphics/Font.cpp +110 -0
  49. data/GosuImpl/Graphics/Graphics.cpp +295 -0
  50. data/GosuImpl/Graphics/Image.cpp +159 -0
  51. data/GosuImpl/Graphics/LargeImageData.cpp +115 -0
  52. data/GosuImpl/Graphics/LargeImageData.hpp +37 -0
  53. data/GosuImpl/Graphics/RotFlip.cpp +184 -0
  54. data/GosuImpl/Graphics/TexChunk.cpp +77 -0
  55. data/GosuImpl/Graphics/TexChunk.hpp +40 -0
  56. data/GosuImpl/Graphics/Text.cpp +223 -0
  57. data/GosuImpl/Graphics/TextMac.cpp +242 -0
  58. data/GosuImpl/Graphics/TextPangoFT.cpp +186 -0
  59. data/GosuImpl/Graphics/TextWin.cpp +172 -0
  60. data/GosuImpl/Graphics/Texture.cpp +104 -0
  61. data/GosuImpl/Graphics/Texture.hpp +34 -0
  62. data/GosuImpl/IO.cpp +48 -0
  63. data/GosuImpl/InputMac.mm +677 -0
  64. data/GosuImpl/InputWin.cpp +444 -0
  65. data/GosuImpl/InputX.cpp +158 -0
  66. data/GosuImpl/MacUtility.hpp +48 -0
  67. data/GosuImpl/Math.cpp +49 -0
  68. data/GosuImpl/RubyGosu.swg +474 -0
  69. data/GosuImpl/RubyGosuStub.mm +17 -0
  70. data/GosuImpl/RubyGosu_DllMain.cxx +30 -0
  71. data/GosuImpl/RubyGosu_wrap.cxx +8521 -0
  72. data/GosuImpl/RubyGosu_wrap.h +31 -0
  73. data/GosuImpl/Sockets/CommSocket.cpp +304 -0
  74. data/GosuImpl/Sockets/ListenerSocket.cpp +60 -0
  75. data/GosuImpl/Sockets/MessageSocket.cpp +136 -0
  76. data/GosuImpl/Sockets/Socket.cpp +145 -0
  77. data/GosuImpl/Sockets/Sockets.hpp +66 -0
  78. data/GosuImpl/TextInputMac.mm +207 -0
  79. data/GosuImpl/TextInputWin.cpp +197 -0
  80. data/GosuImpl/TextInputX.cpp +201 -0
  81. data/GosuImpl/TextTTFWin.cpp +247 -0
  82. data/GosuImpl/TimingUnix.cpp +17 -0
  83. data/GosuImpl/TimingWin.cpp +28 -0
  84. data/GosuImpl/Utility.cpp +140 -0
  85. data/GosuImpl/WinMain.cpp +69 -0
  86. data/GosuImpl/WinUtility.cpp +137 -0
  87. data/GosuImpl/WindowMac.mm +466 -0
  88. data/GosuImpl/WindowWin.cpp +447 -0
  89. data/GosuImpl/WindowX.cpp +392 -0
  90. data/GosuImpl/X11vroot.h +118 -0
  91. data/README.txt +13 -0
  92. data/Rakefile +178 -0
  93. data/examples/ChipmunkIntegration.rb +275 -0
  94. data/examples/CptnRuby.rb +231 -0
  95. data/examples/MoreChipmunkAndRMagick.rb +155 -0
  96. data/examples/OpenGLIntegration.rb +232 -0
  97. data/examples/RMagickIntegration.rb +449 -0
  98. data/examples/TextInput.cpp +170 -0
  99. data/examples/TextInput.rb +139 -0
  100. data/examples/Tutorial.cpp +215 -0
  101. data/examples/Tutorial.rb +137 -0
  102. data/examples/media/Beep.wav +0 -0
  103. data/examples/media/CptnRuby Gem.png +0 -0
  104. data/examples/media/CptnRuby Map.txt +25 -0
  105. data/examples/media/CptnRuby Tileset.png +0 -0
  106. data/examples/media/CptnRuby.png +0 -0
  107. data/examples/media/Cursor.png +0 -0
  108. data/examples/media/Earth.png +0 -0
  109. data/examples/media/Explosion.wav +0 -0
  110. data/examples/media/LargeStar.png +0 -0
  111. data/examples/media/Sky.jpg +0 -0
  112. data/examples/media/Smoke.png +0 -0
  113. data/examples/media/Soldier.png +0 -0
  114. data/examples/media/Space.png +0 -0
  115. data/examples/media/Star.png +0 -0
  116. data/examples/media/Starfighter.bmp +0 -0
  117. data/linux/Makefile.in +98 -0
  118. data/linux/configure +5658 -0
  119. data/linux/configure.ac +126 -0
  120. data/linux/extconf.rb +11 -0
  121. data/mac/English.lproj/InfoPlist.strings +0 -0
  122. data/mac/Gosu-Info.plist +26 -0
  123. data/mac/Gosu.xcodeproj/project.pbxproj +1194 -0
  124. data/mac/RubyGosu Template-Info.plist +26 -0
  125. data/mac/libboost_thread_1_34_1_universal.a +0 -0
  126. data/mac/libboost_thread_d_1_34_1_universal.a +0 -0
  127. data/mac/libfmod_universal.a +0 -0
  128. data/mac/libpng_universal.a +0 -0
  129. data/mac/libz_universal.a +0 -0
  130. data/reference/Async_8hpp-source.html +70 -0
  131. data/reference/Audio_8hpp-source.html +114 -0
  132. data/reference/Audio_8hpp.html +50 -0
  133. data/reference/AutoLink_8hpp-source.html +38 -0
  134. data/reference/AutoLink_8hpp.html +34 -0
  135. data/reference/Bitmap_8hpp-source.html +85 -0
  136. data/reference/Bitmap_8hpp.html +58 -0
  137. data/reference/ButtonsMac_8hpp-source.html +133 -0
  138. data/reference/ButtonsWin_8hpp-source.html +133 -0
  139. data/reference/ButtonsX_8hpp-source.html +134 -0
  140. data/reference/Color_8hpp-source.html +169 -0
  141. data/reference/Color_8hpp.html +85 -0
  142. data/reference/Directories_8hpp-source.html +42 -0
  143. data/reference/Directories_8hpp.html +46 -0
  144. data/reference/Font_8hpp-source.html +65 -0
  145. data/reference/Font_8hpp.html +41 -0
  146. data/reference/Fwd_8hpp-source.html +52 -0
  147. data/reference/Fwd_8hpp.html +37 -0
  148. data/reference/Gosu_8hpp-source.html +48 -0
  149. data/reference/Gosu_8hpp.html +34 -0
  150. data/reference/GraphicsBase_8hpp-source.html +57 -0
  151. data/reference/GraphicsBase_8hpp.html +56 -0
  152. data/reference/Graphics_8hpp-source.html +96 -0
  153. data/reference/Graphics_8hpp.html +53 -0
  154. data/reference/IO_8hpp-source.html +255 -0
  155. data/reference/IO_8hpp.html +74 -0
  156. data/reference/ImageData_8hpp-source.html +62 -0
  157. data/reference/ImageData_8hpp.html +43 -0
  158. data/reference/Image_8hpp-source.html +126 -0
  159. data/reference/Image_8hpp.html +48 -0
  160. data/reference/Input_8hpp-source.html +118 -0
  161. data/reference/Input_8hpp.html +50 -0
  162. data/reference/Math_8hpp-source.html +92 -0
  163. data/reference/Math_8hpp.html +74 -0
  164. data/reference/Platform_8hpp-source.html +83 -0
  165. data/reference/Platform_8hpp.html +73 -0
  166. data/reference/RotFlip_8hpp-source.html +138 -0
  167. data/reference/RotFlip_8hpp.html +77 -0
  168. data/reference/Sockets_8hpp-source.html +130 -0
  169. data/reference/Sockets_8hpp.html +66 -0
  170. data/reference/TextInput_8hpp-source.html +64 -0
  171. data/reference/TextInput_8hpp.html +41 -0
  172. data/reference/Text_8hpp-source.html +51 -0
  173. data/reference/Text_8hpp.html +46 -0
  174. data/reference/Timing_8hpp-source.html +36 -0
  175. data/reference/Timing_8hpp.html +42 -0
  176. data/reference/Utility_8hpp-source.html +44 -0
  177. data/reference/Utility_8hpp.html +48 -0
  178. data/reference/WinUtility_8hpp-source.html +79 -0
  179. data/reference/WinUtility_8hpp.html +64 -0
  180. data/reference/Window_8hpp-source.html +91 -0
  181. data/reference/Window_8hpp.html +41 -0
  182. data/reference/annotated.html +51 -0
  183. data/reference/classGosu_1_1Audio-members.html +34 -0
  184. data/reference/classGosu_1_1Audio.html +46 -0
  185. data/reference/classGosu_1_1Bitmap-members.html +44 -0
  186. data/reference/classGosu_1_1Bitmap.html +263 -0
  187. data/reference/classGosu_1_1Buffer-members.html +44 -0
  188. data/reference/classGosu_1_1Buffer.html +78 -0
  189. data/reference/classGosu_1_1Buffer.png +0 -0
  190. data/reference/classGosu_1_1Button-members.html +36 -0
  191. data/reference/classGosu_1_1Button.html +143 -0
  192. data/reference/classGosu_1_1Color-members.html +56 -0
  193. data/reference/classGosu_1_1Color.html +387 -0
  194. data/reference/classGosu_1_1File-members.html +41 -0
  195. data/reference/classGosu_1_1File.html +69 -0
  196. data/reference/classGosu_1_1File.png +0 -0
  197. data/reference/classGosu_1_1Font-members.html +39 -0
  198. data/reference/classGosu_1_1Font.html +309 -0
  199. data/reference/classGosu_1_1Graphics-members.html +50 -0
  200. data/reference/classGosu_1_1Graphics.html +234 -0
  201. data/reference/classGosu_1_1Image-members.html +45 -0
  202. data/reference/classGosu_1_1Image.html +518 -0
  203. data/reference/classGosu_1_1ImageData-members.html +37 -0
  204. data/reference/classGosu_1_1ImageData.html +60 -0
  205. data/reference/classGosu_1_1Input-members.html +44 -0
  206. data/reference/classGosu_1_1Input.html +223 -0
  207. data/reference/classGosu_1_1MessageSocket-members.html +40 -0
  208. data/reference/classGosu_1_1MessageSocket.html +233 -0
  209. data/reference/classGosu_1_1Resource-members.html +39 -0
  210. data/reference/classGosu_1_1Resource.html +116 -0
  211. data/reference/classGosu_1_1Resource.png +0 -0
  212. data/reference/classGosu_1_1Sample-members.html +37 -0
  213. data/reference/classGosu_1_1Sample.html +200 -0
  214. data/reference/classGosu_1_1SampleInstance-members.html +38 -0
  215. data/reference/classGosu_1_1SampleInstance.html +169 -0
  216. data/reference/classGosu_1_1Song-members.html +43 -0
  217. data/reference/classGosu_1_1Song.html +260 -0
  218. data/reference/classGosu_1_1TextInput-members.html +38 -0
  219. data/reference/classGosu_1_1TextInput.html +121 -0
  220. data/reference/classGosu_1_1Window-members.html +50 -0
  221. data/reference/classGosu_1_1Window.html +271 -0
  222. data/reference/doxyfile +233 -0
  223. data/reference/doxygen.css +433 -0
  224. data/reference/doxygen.png +0 -0
  225. data/reference/files.html +54 -0
  226. data/reference/functions.html +236 -0
  227. data/reference/functions_enum.html +45 -0
  228. data/reference/functions_func.html +227 -0
  229. data/reference/functions_vars.html +47 -0
  230. data/reference/hierarchy.html +53 -0
  231. data/reference/index.html +26 -0
  232. data/reference/namespaceGosu.html +2890 -0
  233. data/reference/namespaceGosu_1_1Colors.html +70 -0
  234. data/reference/namespaceGosu_1_1Win.html +275 -0
  235. data/reference/namespacemembers.html +216 -0
  236. data/reference/namespacemembers_enum.html +52 -0
  237. data/reference/namespacemembers_eval.html +54 -0
  238. data/reference/namespacemembers_func.html +185 -0
  239. data/reference/namespacemembers_type.html +46 -0
  240. data/reference/namespacemembers_vars.html +46 -0
  241. data/reference/namespaces.html +35 -0
  242. data/reference/tab_b.gif +0 -0
  243. data/reference/tab_l.gif +0 -0
  244. data/reference/tab_r.gif +0 -0
  245. data/reference/tabs.css +102 -0
  246. data/windows/Gosu.sln +29 -0
  247. data/windows/Gosu.vcproj +553 -0
  248. data/windows/RubyGosu.vcproj +138 -0
  249. metadata +305 -0
@@ -0,0 +1,145 @@
1
+ #include <Gosu/Sockets.hpp>
2
+ #include <GosuImpl/Sockets/Sockets.hpp>
3
+ #ifdef GOSU_IS_WIN
4
+ #include <Gosu/WinUtility.hpp>
5
+ #endif
6
+ #include <cstdlib>
7
+ #include <cstring>
8
+ #include <algorithm>
9
+ #include <stdexcept>
10
+
11
+ namespace Gosu
12
+ {
13
+ namespace
14
+ {
15
+ void cleanup()
16
+ {
17
+ #ifdef GOSU_IS_WIN
18
+ ::WSACleanup();
19
+ #endif
20
+ }
21
+
22
+ void needsSockLib()
23
+ {
24
+ #ifdef GOSU_IS_WIN
25
+ static bool initialized = false;
26
+ if (!initialized)
27
+ {
28
+ WSADATA data;
29
+ if (::WSAStartup(0x0202, &data) != 0)
30
+ throw std::runtime_error("Could not initialize "
31
+ "Windows sockets");
32
+
33
+ initialized = true;
34
+ std::atexit(cleanup);
35
+ }
36
+ #endif
37
+ }
38
+ }
39
+ }
40
+
41
+ int Gosu::lastSocketError()
42
+ {
43
+ #ifdef GOSU_IS_WIN
44
+ needsSockLib();
45
+ return ::WSAGetLastError();
46
+ #else
47
+ return errno;
48
+ #endif
49
+ }
50
+
51
+ GOSU_NORETURN void Gosu::throwLastSocketError()
52
+ {
53
+ #ifdef GOSU_IS_WIN
54
+ Win::throwLastError();
55
+ #else
56
+ throw std::runtime_error(strerror(errno));
57
+ #endif
58
+ }
59
+
60
+ Gosu::SocketAddress Gosu::stringToAddress(const std::string& s)
61
+ {
62
+ needsSockLib();
63
+
64
+ SocketAddress address;
65
+
66
+ // Try to interpret name as an IP number string.
67
+ address = ntohl(::inet_addr(s.c_str()));
68
+ if (address != INADDR_NONE)
69
+ return address;
70
+
71
+ // This didn't work: Resolve host name via DNS.
72
+ hostent* host = ::gethostbyname(s.c_str());
73
+ if (!host)
74
+ return 0;
75
+ in_addr addr = *reinterpret_cast<in_addr*>(host->h_addr_list[0]);
76
+ return ntohl(addr.s_addr);
77
+ }
78
+
79
+ std::string Gosu::addressToString(SocketAddress address)
80
+ {
81
+ needsSockLib();
82
+
83
+ in_addr addr;
84
+ addr.s_addr = htonl(address);
85
+ return ::inet_ntoa(addr);
86
+ }
87
+
88
+ Gosu::Socket::Socket()
89
+ : handle_(INVALID_SOCKET)
90
+ {
91
+ needsSockLib();
92
+ }
93
+
94
+ Gosu::Socket::~Socket()
95
+ {
96
+ setHandle(INVALID_SOCKET);
97
+ }
98
+
99
+ Gosu::SocketHandle Gosu::Socket::handle() const
100
+ {
101
+ return handle_;
102
+ }
103
+
104
+ void Gosu::Socket::setHandle(SocketHandle value)
105
+ {
106
+ if (handle() != INVALID_SOCKET)
107
+ {
108
+ ::closesocket(handle());
109
+ }
110
+
111
+ handle_ = value;
112
+ }
113
+
114
+ void Gosu::Socket::setBlocking(bool value)
115
+ {
116
+ u_long enable = !value;
117
+ socketCheck(::ioctlsocket(handle(), FIONBIO, &enable));
118
+ }
119
+
120
+ Gosu::SocketAddress Gosu::Socket::address() const
121
+ {
122
+ sockaddr_in addr;
123
+ int size = sizeof addr;
124
+ socketCheck(::getsockname(handle(),
125
+ reinterpret_cast<sockaddr*>(&addr),
126
+ reinterpret_cast<socklen_t*>(&size)));
127
+
128
+ return ntohl(addr.sin_addr.s_addr);
129
+ }
130
+
131
+ Gosu::SocketPort Gosu::Socket::port() const
132
+ {
133
+ sockaddr_in addr;
134
+ int size = sizeof addr;
135
+ socketCheck(::getsockname(handle(),
136
+ reinterpret_cast<sockaddr*>(&addr),
137
+ reinterpret_cast<socklen_t*>(&size)));
138
+
139
+ return ntohs(addr.sin_port);
140
+ }
141
+
142
+ void Gosu::Socket::swap(Socket& other)
143
+ {
144
+ std::swap(handle_, other.handle_);
145
+ }
@@ -0,0 +1,66 @@
1
+ #ifndef GOSUIMPL_SOCKETS_HPP
2
+ #define GOSUIMPL_SOCKETS_HPP
3
+
4
+ #include <Gosu/Platform.hpp>
5
+ #include <boost/utility.hpp>
6
+
7
+ #ifdef GOSU_IS_WIN
8
+ #include "winsock2.h"
9
+ #define GOSU_SOCK_ERR(code) WSA##code
10
+ namespace Gosu { typedef SOCKET SocketHandle; }
11
+ typedef int socklen_t;
12
+ #else
13
+ #include <sys/errno.h>
14
+ #include <sys/socket.h>
15
+ #include <netinet/in.h>
16
+ #include <arpa/inet.h>
17
+ #include <netdb.h>
18
+ #include <sys/ioctl.h>
19
+ #define GOSU_SOCK_ERR(code) code
20
+ // IMPR: Macros ok?
21
+ #define INVALID_SOCKET -1
22
+ #define SOCKET_ERROR -1
23
+ #define closesocket close
24
+ #define ioctlsocket ioctl
25
+ namespace Gosu { typedef int SocketHandle; }
26
+ #endif
27
+
28
+ namespace Gosu
29
+ {
30
+ // Owns a socket and manages library initialization.
31
+ class Socket : boost::noncopyable
32
+ {
33
+ SocketHandle handle_;
34
+
35
+ public:
36
+ Socket();
37
+ ~Socket();
38
+
39
+ SocketHandle handle() const;
40
+ void setHandle(SocketHandle value);
41
+ void setBlocking(bool value);
42
+
43
+ SocketAddress address() const;
44
+ SocketPort port() const;
45
+
46
+ void swap(Socket& other);
47
+ };
48
+
49
+ int lastSocketError();
50
+
51
+ GOSU_NORETURN void throwLastSocketError();
52
+
53
+ template<typename T>
54
+ T socketCheck(T retVal)
55
+ {
56
+ if (retVal == SOCKET_ERROR &&
57
+ lastSocketError() != GOSU_SOCK_ERR(EWOULDBLOCK))
58
+ {
59
+ throwLastSocketError();
60
+ }
61
+
62
+ return retVal;
63
+ }
64
+ }
65
+
66
+ #endif
@@ -0,0 +1,207 @@
1
+ #include <Gosu/TextInput.hpp>
2
+ #include <Gosu/ButtonsMac.hpp>
3
+ #include <GosuImpl/MacUtility.hpp>
4
+ #include <algorithm>
5
+ #include <vector>
6
+ #include <wctype.h>
7
+
8
+ #import <Cocoa/Cocoa.h>
9
+
10
+ // Sometimes macro DSLs aren't evil.
11
+ #define CARET_POS (*_caretPos)
12
+ #define SEL_START (*_selectionStart)
13
+ #define IMPL_WITH_SEL_RESET(selector) \
14
+ - (void)selector:(id)sender \
15
+ { \
16
+ [self selector##AndModifySelection:sender]; \
17
+ SEL_START = CARET_POS; \
18
+ }
19
+
20
+ @interface GosuTextInput : NSResponder
21
+ {
22
+ std::wstring* _text;
23
+ unsigned* _caretPos;
24
+ unsigned* _selectionStart;
25
+ }
26
+ @end
27
+ @implementation GosuTextInput
28
+ - (void)insertText:(id)insertString
29
+ {
30
+ // Delete (overwrite) previous selection.
31
+ if (CARET_POS != SEL_START)
32
+ {
33
+ unsigned min = std::min(CARET_POS, SEL_START);
34
+ unsigned max = std::max(CARET_POS, SEL_START);
35
+ _text->erase(_text->begin() + min, _text->begin() + max);
36
+ CARET_POS = SEL_START = min;
37
+ }
38
+
39
+ NSString* str = (NSString*)insertString;
40
+
41
+ if ([str length] == 0)
42
+ return;
43
+
44
+ std::vector<unichar> unibuf([str length]);
45
+ [str getCharacters: &unibuf[0]];
46
+
47
+ _text->insert(_text->begin() + CARET_POS, unibuf.begin(), unibuf.end());
48
+ (CARET_POS) += unibuf.size();
49
+ (SEL_START) = CARET_POS;
50
+ }
51
+
52
+ // Movement.
53
+
54
+ - (void)moveLeftAndModifySelection:(id)sender
55
+ {
56
+ if (CARET_POS > 0)
57
+ (CARET_POS) -= 1;
58
+ }
59
+ - (void)moveRightAndModifySelection:(id)sender
60
+ {
61
+ if (CARET_POS < _text->length())
62
+ (CARET_POS) += 1;
63
+ }
64
+ - (void)moveUpAndModifySelection:(id)sender
65
+ {
66
+ CARET_POS = 0;
67
+ }
68
+ - (void)moveDownAndModifySelection:(id)sender
69
+ {
70
+ CARET_POS = _text->length();
71
+ }
72
+ - (void)moveToBeginningOfLineAndModifySelection:(id)sender
73
+ {
74
+ [self moveUpAndModifySelection: sender];
75
+ }
76
+ - (void)moveToEndOfLineAndModifySelection:(id)sender
77
+ {
78
+ [self moveDownAndModifySelection: sender];
79
+ }
80
+ - (void)moveToBeginningOfDocumentAndModifySelection:(id)sender
81
+ {
82
+ [self moveUpAndModifySelection: sender];
83
+ }
84
+ - (void)moveToEndOfDocumentAndModifySelection:(id)sender
85
+ {
86
+ [self moveDownAndModifySelection: sender];
87
+ }
88
+ - (void)moveWordLeftAndModifySelection:(id)sender
89
+ {
90
+ if (CARET_POS == _text->length())
91
+ --CARET_POS;
92
+
93
+ while (CARET_POS > 0 && iswspace(_text->at(CARET_POS - 1)))
94
+ --CARET_POS;
95
+
96
+ while (CARET_POS > 0 && !iswspace(_text->at(CARET_POS - 1)))
97
+ --CARET_POS;
98
+ }
99
+ - (void)moveWordRightAndModifySelection:(id)sender
100
+ {
101
+ while (CARET_POS < _text->length() && iswspace(_text->at(CARET_POS)))
102
+ ++CARET_POS;
103
+
104
+ while (CARET_POS < _text->length() && !iswspace(_text->at(CARET_POS)))
105
+ ++CARET_POS;
106
+ }
107
+
108
+ IMPL_WITH_SEL_RESET(moveLeft)
109
+ IMPL_WITH_SEL_RESET(moveRight)
110
+ IMPL_WITH_SEL_RESET(moveUp)
111
+ IMPL_WITH_SEL_RESET(moveDown)
112
+ IMPL_WITH_SEL_RESET(moveWordLeft)
113
+ IMPL_WITH_SEL_RESET(moveWordRight)
114
+ IMPL_WITH_SEL_RESET(moveToBeginningOfLine)
115
+ IMPL_WITH_SEL_RESET(moveToEndOfLine)
116
+ IMPL_WITH_SEL_RESET(moveToBeginningOfDocument)
117
+ IMPL_WITH_SEL_RESET(moveToEndOfDocument)
118
+
119
+ // Deletion.
120
+
121
+ - (void)deleteBackward:(id)sender
122
+ {
123
+ if (CARET_POS == SEL_START && CARET_POS > 0)
124
+ --CARET_POS;
125
+ [self insertText: @""];
126
+ }
127
+ - (void)deleteForward:(id)sender
128
+ {
129
+ if (CARET_POS == SEL_START && CARET_POS < _text->length())
130
+ ++CARET_POS;
131
+ [self insertText: @""];
132
+ }
133
+
134
+ // TODO: Advanced deletion (deleteWord...)
135
+
136
+ // Selection.
137
+
138
+ - (void)selectAll:(id)sender
139
+ {
140
+ SEL_START = 0;
141
+ CARET_POS = _text->length();
142
+ }
143
+
144
+ // TODO: Cmd+A should really be hard-coded into selectAll.
145
+
146
+ // Helper to set up this instance.
147
+
148
+ - (void)setText:(std::wstring&)text andCaretPos:(unsigned&)caretPos andSelectionStart:(unsigned&)selectionStart
149
+ {
150
+ _text = &text;
151
+ _caretPos = &caretPos;
152
+ _selectionStart = &selectionStart;
153
+ }
154
+ @end
155
+
156
+ struct Gosu::TextInput::Impl
157
+ {
158
+ ObjRef<GosuTextInput> responder;
159
+ std::wstring text;
160
+ unsigned caretPos, selectionStart;
161
+ Impl() : caretPos(0), selectionStart(0) {}
162
+ };
163
+
164
+ Gosu::TextInput::TextInput()
165
+ : pimpl(new Impl)
166
+ {
167
+ pimpl->responder.reset([[GosuTextInput alloc] init]);
168
+ [pimpl->responder.get() setText: pimpl->text andCaretPos: pimpl->caretPos andSelectionStart: pimpl->selectionStart];
169
+ }
170
+
171
+ Gosu::TextInput::~TextInput()
172
+ {
173
+ }
174
+
175
+ std::wstring Gosu::TextInput::text() const
176
+ {
177
+ return pimpl->text;
178
+ }
179
+
180
+ void Gosu::TextInput::setText(const std::wstring& text)
181
+ {
182
+ pimpl->text = text;
183
+ pimpl->caretPos = pimpl->selectionStart = text.length();
184
+ }
185
+
186
+ unsigned Gosu::TextInput::caretPos() const
187
+ {
188
+ return pimpl->caretPos;
189
+ }
190
+
191
+ unsigned Gosu::TextInput::selectionStart() const
192
+ {
193
+ return pimpl->selectionStart;
194
+ }
195
+
196
+ bool Gosu::TextInput::feedNSEvent(void* event)
197
+ {
198
+ NSEvent* nsEvent = (NSEvent*)event;
199
+ long keyCode = [nsEvent keyCode];
200
+ if (keyCode != kbEscape && keyCode != kbTab && keyCode != kbReturn && keyCode != kbEnter)
201
+ {
202
+ [pimpl->responder.get() interpretKeyEvents: [NSArray arrayWithObject: nsEvent]];
203
+ return true;
204
+ }
205
+ else
206
+ return false;
207
+ }
@@ -0,0 +1,197 @@
1
+ #include <Gosu/TextInput.hpp>
2
+ #include <Gosu/ButtonsWin.hpp>
3
+ #include <algorithm>
4
+ #include <vector>
5
+ #include <wctype.h>
6
+
7
+ // OPT-IN, have you heard of it?!
8
+ #define NOMINMAX
9
+ #include <windows.h>
10
+
11
+ struct Gosu::TextInput::Impl
12
+ {
13
+ std::wstring text;
14
+ unsigned caretPos, selectionStart;
15
+ Impl() : caretPos(0), selectionStart(0) {}
16
+ };
17
+
18
+ Gosu::TextInput::TextInput()
19
+ : pimpl(new Impl)
20
+ {
21
+ }
22
+
23
+ Gosu::TextInput::~TextInput()
24
+ {
25
+ }
26
+
27
+ std::wstring Gosu::TextInput::text() const
28
+ {
29
+ return pimpl->text;
30
+ }
31
+
32
+ void Gosu::TextInput::setText(const std::wstring& text)
33
+ {
34
+ pimpl->text = text;
35
+ pimpl->caretPos = pimpl->selectionStart = text.length();
36
+ }
37
+
38
+ unsigned Gosu::TextInput::caretPos() const
39
+ {
40
+ return pimpl->caretPos;
41
+ }
42
+
43
+ unsigned Gosu::TextInput::selectionStart() const
44
+ {
45
+ return pimpl->selectionStart;
46
+ }
47
+
48
+ #define CARET_POS (pimpl->caretPos)
49
+ #define SEL_START (pimpl->selectionStart)
50
+
51
+ bool Gosu::TextInput::feedMessage(unsigned long message, unsigned long wparam, unsigned long lparam)
52
+ {
53
+ if (message == WM_CHAR && wparam >= 32 && wparam != 127)
54
+ {
55
+ // Delete (overwrite) previous selection.
56
+ if (CARET_POS != SEL_START)
57
+ {
58
+ unsigned min = std::min(CARET_POS, SEL_START);
59
+ unsigned max = std::max(CARET_POS, SEL_START);
60
+ pimpl->text.erase(pimpl->text.begin() + min, pimpl->text.begin() + max);
61
+ CARET_POS = SEL_START = min;
62
+ }
63
+
64
+ pimpl->text.insert(pimpl->text.begin() + CARET_POS, static_cast<wchar_t>(wparam));
65
+ CARET_POS += 1;
66
+ SEL_START = CARET_POS;
67
+ return true;
68
+ }
69
+
70
+ bool ctrlDown = (GetKeyState(VK_CONTROL) < 0);
71
+ bool shiftDown = (GetKeyState(VK_SHIFT) < 0);
72
+
73
+ // Char left
74
+ if (message == WM_KEYDOWN && wparam == VK_LEFT && !ctrlDown)
75
+ {
76
+ if (CARET_POS > 0)
77
+ CARET_POS -= 1;
78
+
79
+ if (!shiftDown)
80
+ SEL_START = CARET_POS;
81
+
82
+ return true;
83
+ }
84
+
85
+ // Char right
86
+ if (message == WM_KEYDOWN && wparam == VK_RIGHT && !ctrlDown)
87
+ {
88
+ if (CARET_POS < pimpl->text.length())
89
+ CARET_POS += 1;
90
+
91
+ if (!shiftDown)
92
+ SEL_START = CARET_POS;
93
+
94
+ return true;
95
+ }
96
+
97
+ // Home
98
+ if (message == WM_KEYDOWN && wparam == VK_HOME)
99
+ {
100
+ CARET_POS = 0;
101
+
102
+ if (!shiftDown)
103
+ SEL_START = CARET_POS;
104
+
105
+ return true;
106
+ }
107
+
108
+ // End
109
+ if (message == WM_KEYDOWN && wparam == VK_END)
110
+ {
111
+ CARET_POS = pimpl->text.length();
112
+
113
+ if (!shiftDown)
114
+ SEL_START = CARET_POS;
115
+
116
+ return true;
117
+ }
118
+
119
+ // Word left
120
+ if (message == WM_KEYDOWN && wparam == VK_LEFT && ctrlDown)
121
+ {
122
+ if (CARET_POS == pimpl->text.length())
123
+ --CARET_POS;
124
+
125
+ while (CARET_POS > 0 && iswspace(pimpl->text.at(CARET_POS - 1)))
126
+ --CARET_POS;
127
+
128
+ while (CARET_POS > 0 && !iswspace(pimpl->text.at(CARET_POS - 1)))
129
+ --CARET_POS;
130
+
131
+ if (!shiftDown)
132
+ SEL_START = CARET_POS;
133
+
134
+ return true;
135
+ }
136
+
137
+ // Word right
138
+ if (message == WM_KEYDOWN && wparam == VK_RIGHT && ctrlDown)
139
+ {
140
+ while (CARET_POS < pimpl->text.length() && iswspace(pimpl->text.at(CARET_POS)))
141
+ ++CARET_POS;
142
+
143
+ while (CARET_POS < pimpl->text.length() && !iswspace(pimpl->text.at(CARET_POS)))
144
+ ++CARET_POS;
145
+
146
+ if (!shiftDown)
147
+ SEL_START = CARET_POS;
148
+
149
+ return true;
150
+ }
151
+
152
+ // Delete existant selection
153
+ if (message == WM_KEYDOWN && wparam == VK_BACK)
154
+ {
155
+ if (SEL_START != CARET_POS)
156
+ {
157
+ unsigned min = std::min(CARET_POS, SEL_START);
158
+ unsigned max = std::max(CARET_POS, SEL_START);
159
+ pimpl->text.erase(pimpl->text.begin() + min, pimpl->text.begin() + max);
160
+ SEL_START = CARET_POS = min;
161
+ }
162
+ else
163
+ {
164
+ unsigned oldCaret = CARET_POS;
165
+ // Move left - either char or word
166
+ feedMessage(WM_KEYDOWN, VK_LEFT, lparam);
167
+ pimpl->text.erase(pimpl->text.begin() + CARET_POS, pimpl->text.begin() + oldCaret);
168
+ SEL_START = CARET_POS;
169
+ }
170
+
171
+ return true;
172
+ }
173
+
174
+ // Delete existant selection
175
+ if (message == WM_KEYDOWN && wparam == VK_DELETE)
176
+ {
177
+ if (SEL_START != CARET_POS)
178
+ {
179
+ unsigned min = std::min(CARET_POS, SEL_START);
180
+ unsigned max = std::max(CARET_POS, SEL_START);
181
+ pimpl->text.erase(pimpl->text.begin() + min, pimpl->text.begin() + max);
182
+ SEL_START = CARET_POS = min;
183
+ }
184
+ else
185
+ {
186
+ unsigned oldCaret = CARET_POS;
187
+ // Move right - either char or word
188
+ feedMessage(WM_KEYDOWN, VK_RIGHT, lparam);
189
+ pimpl->text.erase(pimpl->text.begin() + oldCaret, pimpl->text.begin() + CARET_POS);
190
+ SEL_START = CARET_POS = oldCaret;
191
+ }
192
+
193
+ return true;
194
+ }
195
+
196
+ return false;
197
+ }