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.
- data/COPYING.txt +29 -0
- data/Gosu/Async.hpp +48 -0
- data/Gosu/Audio.hpp +145 -0
- data/Gosu/AutoLink.hpp +16 -0
- data/Gosu/Bitmap.hpp +85 -0
- data/Gosu/ButtonsMac.hpp +114 -0
- data/Gosu/ButtonsWin.hpp +111 -0
- data/Gosu/ButtonsX.hpp +115 -0
- data/Gosu/Color.hpp +172 -0
- data/Gosu/Directories.hpp +36 -0
- data/Gosu/Font.hpp +59 -0
- data/Gosu/Fwd.hpp +31 -0
- data/Gosu/Gosu.hpp +26 -0
- data/Gosu/Graphics.hpp +86 -0
- data/Gosu/GraphicsBase.hpp +45 -0
- data/Gosu/IO.hpp +255 -0
- data/Gosu/Image.hpp +148 -0
- data/Gosu/ImageData.hpp +45 -0
- data/Gosu/Input.hpp +116 -0
- data/Gosu/Math.hpp +95 -0
- data/Gosu/Platform.hpp +61 -0
- data/Gosu/RotFlip.hpp +116 -0
- data/Gosu/Sockets.hpp +129 -0
- data/Gosu/Text.hpp +47 -0
- data/Gosu/TextInput.hpp +57 -0
- data/Gosu/Timing.hpp +16 -0
- data/Gosu/Utility.hpp +24 -0
- data/Gosu/WinUtility.hpp +76 -0
- data/Gosu/Window.hpp +84 -0
- data/GosuImpl/Async.cpp +37 -0
- data/GosuImpl/AudioFmod.cpp +417 -0
- data/GosuImpl/AudioSDL.cpp +255 -0
- data/GosuImpl/DirectoriesMac.mm +38 -0
- data/GosuImpl/DirectoriesUnix.cpp +48 -0
- data/GosuImpl/DirectoriesWin.cpp +42 -0
- data/GosuImpl/FileUnix.cpp +100 -0
- data/GosuImpl/FileWin.cpp +83 -0
- data/GosuImpl/Graphics/Bitmap.cpp +116 -0
- data/GosuImpl/Graphics/BitmapBMP.cpp +232 -0
- data/GosuImpl/Graphics/BitmapColorKey.cpp +39 -0
- data/GosuImpl/Graphics/BitmapPNG.cpp +276 -0
- data/GosuImpl/Graphics/BitmapUtils.cpp +67 -0
- data/GosuImpl/Graphics/BlockAllocator.cpp +127 -0
- data/GosuImpl/Graphics/BlockAllocator.hpp +34 -0
- data/GosuImpl/Graphics/Color.cpp +126 -0
- data/GosuImpl/Graphics/Common.hpp +21 -0
- data/GosuImpl/Graphics/DrawOp.hpp +154 -0
- data/GosuImpl/Graphics/Font.cpp +110 -0
- data/GosuImpl/Graphics/Graphics.cpp +295 -0
- data/GosuImpl/Graphics/Image.cpp +159 -0
- data/GosuImpl/Graphics/LargeImageData.cpp +115 -0
- data/GosuImpl/Graphics/LargeImageData.hpp +37 -0
- data/GosuImpl/Graphics/RotFlip.cpp +184 -0
- data/GosuImpl/Graphics/TexChunk.cpp +77 -0
- data/GosuImpl/Graphics/TexChunk.hpp +40 -0
- data/GosuImpl/Graphics/Text.cpp +223 -0
- data/GosuImpl/Graphics/TextMac.cpp +242 -0
- data/GosuImpl/Graphics/TextPangoFT.cpp +186 -0
- data/GosuImpl/Graphics/TextWin.cpp +172 -0
- data/GosuImpl/Graphics/Texture.cpp +104 -0
- data/GosuImpl/Graphics/Texture.hpp +34 -0
- data/GosuImpl/IO.cpp +48 -0
- data/GosuImpl/InputMac.mm +677 -0
- data/GosuImpl/InputWin.cpp +444 -0
- data/GosuImpl/InputX.cpp +158 -0
- data/GosuImpl/MacUtility.hpp +48 -0
- data/GosuImpl/Math.cpp +49 -0
- data/GosuImpl/RubyGosu.swg +474 -0
- data/GosuImpl/RubyGosuStub.mm +17 -0
- data/GosuImpl/RubyGosu_DllMain.cxx +30 -0
- data/GosuImpl/RubyGosu_wrap.cxx +8521 -0
- data/GosuImpl/RubyGosu_wrap.h +31 -0
- data/GosuImpl/Sockets/CommSocket.cpp +304 -0
- data/GosuImpl/Sockets/ListenerSocket.cpp +60 -0
- data/GosuImpl/Sockets/MessageSocket.cpp +136 -0
- data/GosuImpl/Sockets/Socket.cpp +145 -0
- data/GosuImpl/Sockets/Sockets.hpp +66 -0
- data/GosuImpl/TextInputMac.mm +207 -0
- data/GosuImpl/TextInputWin.cpp +197 -0
- data/GosuImpl/TextInputX.cpp +201 -0
- data/GosuImpl/TextTTFWin.cpp +247 -0
- data/GosuImpl/TimingUnix.cpp +17 -0
- data/GosuImpl/TimingWin.cpp +28 -0
- data/GosuImpl/Utility.cpp +140 -0
- data/GosuImpl/WinMain.cpp +69 -0
- data/GosuImpl/WinUtility.cpp +137 -0
- data/GosuImpl/WindowMac.mm +466 -0
- data/GosuImpl/WindowWin.cpp +447 -0
- data/GosuImpl/WindowX.cpp +392 -0
- data/GosuImpl/X11vroot.h +118 -0
- data/README.txt +13 -0
- data/Rakefile +178 -0
- data/examples/ChipmunkIntegration.rb +275 -0
- data/examples/CptnRuby.rb +231 -0
- data/examples/MoreChipmunkAndRMagick.rb +155 -0
- data/examples/OpenGLIntegration.rb +232 -0
- data/examples/RMagickIntegration.rb +449 -0
- data/examples/TextInput.cpp +170 -0
- data/examples/TextInput.rb +139 -0
- data/examples/Tutorial.cpp +215 -0
- data/examples/Tutorial.rb +137 -0
- data/examples/media/Beep.wav +0 -0
- data/examples/media/CptnRuby Gem.png +0 -0
- data/examples/media/CptnRuby Map.txt +25 -0
- data/examples/media/CptnRuby Tileset.png +0 -0
- data/examples/media/CptnRuby.png +0 -0
- data/examples/media/Cursor.png +0 -0
- data/examples/media/Earth.png +0 -0
- data/examples/media/Explosion.wav +0 -0
- data/examples/media/LargeStar.png +0 -0
- data/examples/media/Sky.jpg +0 -0
- data/examples/media/Smoke.png +0 -0
- data/examples/media/Soldier.png +0 -0
- data/examples/media/Space.png +0 -0
- data/examples/media/Star.png +0 -0
- data/examples/media/Starfighter.bmp +0 -0
- data/linux/Makefile.in +98 -0
- data/linux/configure +5658 -0
- data/linux/configure.ac +126 -0
- data/linux/extconf.rb +11 -0
- data/mac/English.lproj/InfoPlist.strings +0 -0
- data/mac/Gosu-Info.plist +26 -0
- data/mac/Gosu.xcodeproj/project.pbxproj +1194 -0
- data/mac/RubyGosu Template-Info.plist +26 -0
- data/mac/libboost_thread_1_34_1_universal.a +0 -0
- data/mac/libboost_thread_d_1_34_1_universal.a +0 -0
- data/mac/libfmod_universal.a +0 -0
- data/mac/libpng_universal.a +0 -0
- data/mac/libz_universal.a +0 -0
- data/reference/Async_8hpp-source.html +70 -0
- data/reference/Audio_8hpp-source.html +114 -0
- data/reference/Audio_8hpp.html +50 -0
- data/reference/AutoLink_8hpp-source.html +38 -0
- data/reference/AutoLink_8hpp.html +34 -0
- data/reference/Bitmap_8hpp-source.html +85 -0
- data/reference/Bitmap_8hpp.html +58 -0
- data/reference/ButtonsMac_8hpp-source.html +133 -0
- data/reference/ButtonsWin_8hpp-source.html +133 -0
- data/reference/ButtonsX_8hpp-source.html +134 -0
- data/reference/Color_8hpp-source.html +169 -0
- data/reference/Color_8hpp.html +85 -0
- data/reference/Directories_8hpp-source.html +42 -0
- data/reference/Directories_8hpp.html +46 -0
- data/reference/Font_8hpp-source.html +65 -0
- data/reference/Font_8hpp.html +41 -0
- data/reference/Fwd_8hpp-source.html +52 -0
- data/reference/Fwd_8hpp.html +37 -0
- data/reference/Gosu_8hpp-source.html +48 -0
- data/reference/Gosu_8hpp.html +34 -0
- data/reference/GraphicsBase_8hpp-source.html +57 -0
- data/reference/GraphicsBase_8hpp.html +56 -0
- data/reference/Graphics_8hpp-source.html +96 -0
- data/reference/Graphics_8hpp.html +53 -0
- data/reference/IO_8hpp-source.html +255 -0
- data/reference/IO_8hpp.html +74 -0
- data/reference/ImageData_8hpp-source.html +62 -0
- data/reference/ImageData_8hpp.html +43 -0
- data/reference/Image_8hpp-source.html +126 -0
- data/reference/Image_8hpp.html +48 -0
- data/reference/Input_8hpp-source.html +118 -0
- data/reference/Input_8hpp.html +50 -0
- data/reference/Math_8hpp-source.html +92 -0
- data/reference/Math_8hpp.html +74 -0
- data/reference/Platform_8hpp-source.html +83 -0
- data/reference/Platform_8hpp.html +73 -0
- data/reference/RotFlip_8hpp-source.html +138 -0
- data/reference/RotFlip_8hpp.html +77 -0
- data/reference/Sockets_8hpp-source.html +130 -0
- data/reference/Sockets_8hpp.html +66 -0
- data/reference/TextInput_8hpp-source.html +64 -0
- data/reference/TextInput_8hpp.html +41 -0
- data/reference/Text_8hpp-source.html +51 -0
- data/reference/Text_8hpp.html +46 -0
- data/reference/Timing_8hpp-source.html +36 -0
- data/reference/Timing_8hpp.html +42 -0
- data/reference/Utility_8hpp-source.html +44 -0
- data/reference/Utility_8hpp.html +48 -0
- data/reference/WinUtility_8hpp-source.html +79 -0
- data/reference/WinUtility_8hpp.html +64 -0
- data/reference/Window_8hpp-source.html +91 -0
- data/reference/Window_8hpp.html +41 -0
- data/reference/annotated.html +51 -0
- data/reference/classGosu_1_1Audio-members.html +34 -0
- data/reference/classGosu_1_1Audio.html +46 -0
- data/reference/classGosu_1_1Bitmap-members.html +44 -0
- data/reference/classGosu_1_1Bitmap.html +263 -0
- data/reference/classGosu_1_1Buffer-members.html +44 -0
- data/reference/classGosu_1_1Buffer.html +78 -0
- data/reference/classGosu_1_1Buffer.png +0 -0
- data/reference/classGosu_1_1Button-members.html +36 -0
- data/reference/classGosu_1_1Button.html +143 -0
- data/reference/classGosu_1_1Color-members.html +56 -0
- data/reference/classGosu_1_1Color.html +387 -0
- data/reference/classGosu_1_1File-members.html +41 -0
- data/reference/classGosu_1_1File.html +69 -0
- data/reference/classGosu_1_1File.png +0 -0
- data/reference/classGosu_1_1Font-members.html +39 -0
- data/reference/classGosu_1_1Font.html +309 -0
- data/reference/classGosu_1_1Graphics-members.html +50 -0
- data/reference/classGosu_1_1Graphics.html +234 -0
- data/reference/classGosu_1_1Image-members.html +45 -0
- data/reference/classGosu_1_1Image.html +518 -0
- data/reference/classGosu_1_1ImageData-members.html +37 -0
- data/reference/classGosu_1_1ImageData.html +60 -0
- data/reference/classGosu_1_1Input-members.html +44 -0
- data/reference/classGosu_1_1Input.html +223 -0
- data/reference/classGosu_1_1MessageSocket-members.html +40 -0
- data/reference/classGosu_1_1MessageSocket.html +233 -0
- data/reference/classGosu_1_1Resource-members.html +39 -0
- data/reference/classGosu_1_1Resource.html +116 -0
- data/reference/classGosu_1_1Resource.png +0 -0
- data/reference/classGosu_1_1Sample-members.html +37 -0
- data/reference/classGosu_1_1Sample.html +200 -0
- data/reference/classGosu_1_1SampleInstance-members.html +38 -0
- data/reference/classGosu_1_1SampleInstance.html +169 -0
- data/reference/classGosu_1_1Song-members.html +43 -0
- data/reference/classGosu_1_1Song.html +260 -0
- data/reference/classGosu_1_1TextInput-members.html +38 -0
- data/reference/classGosu_1_1TextInput.html +121 -0
- data/reference/classGosu_1_1Window-members.html +50 -0
- data/reference/classGosu_1_1Window.html +271 -0
- data/reference/doxyfile +233 -0
- data/reference/doxygen.css +433 -0
- data/reference/doxygen.png +0 -0
- data/reference/files.html +54 -0
- data/reference/functions.html +236 -0
- data/reference/functions_enum.html +45 -0
- data/reference/functions_func.html +227 -0
- data/reference/functions_vars.html +47 -0
- data/reference/hierarchy.html +53 -0
- data/reference/index.html +26 -0
- data/reference/namespaceGosu.html +2890 -0
- data/reference/namespaceGosu_1_1Colors.html +70 -0
- data/reference/namespaceGosu_1_1Win.html +275 -0
- data/reference/namespacemembers.html +216 -0
- data/reference/namespacemembers_enum.html +52 -0
- data/reference/namespacemembers_eval.html +54 -0
- data/reference/namespacemembers_func.html +185 -0
- data/reference/namespacemembers_type.html +46 -0
- data/reference/namespacemembers_vars.html +46 -0
- data/reference/namespaces.html +35 -0
- data/reference/tab_b.gif +0 -0
- data/reference/tab_l.gif +0 -0
- data/reference/tab_r.gif +0 -0
- data/reference/tabs.css +102 -0
- data/windows/Gosu.sln +29 -0
- data/windows/Gosu.vcproj +553 -0
- data/windows/RubyGosu.vcproj +138 -0
- 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
|
+
}
|