aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt4
-rw-r--r--include/cru/common/String.hpp90
-rw-r--r--include/cru/osx/graphics/quartz/TextLayout.hpp4
-rw-r--r--include/cru/osx/gui/UiApplication.hpp5
-rw-r--r--src/common/String.cpp33
-rw-r--r--src/osx/Convert.cpp4
-rw-r--r--src/osx/graphics/quartz/Font.cpp3
-rw-r--r--src/osx/graphics/quartz/TextLayout.cpp3
-rw-r--r--src/osx/gui/UiApplication.mm26
-rw-r--r--src/osx/gui/Window.mm2
10 files changed, 103 insertions, 71 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 87e15f5b..1de2d440 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3,12 +3,12 @@ cmake_minimum_required(VERSION 3.14)
set(CMAKE_TOOLCHAIN_FILE $ENV{VCPKG_INSTALLATION_ROOT}/scripts/buildsystems/vcpkg.cmake
CACHE STRING "Vcpkg toolchain file")
+set(CMAKE_CXX_STANDARD 20)
+
project(cru)
enable_testing()
-set(CMAKE_CXX_STANDARD 17)
-
set (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
diff --git a/include/cru/common/String.hpp b/include/cru/common/String.hpp
index 58abc517..0530c208 100644
--- a/include/cru/common/String.hpp
+++ b/include/cru/common/String.hpp
@@ -22,15 +22,15 @@ class StringView;
class CRU_BASE_API String {
public:
- using value_type = std::uint16_t;
+ using value_type = char16_t;
using size_type = Index;
using difference_type = Index;
- using reference = std::uint16_t&;
- using const_reference = const std::uint16_t&;
- using pointer = std::uint16_t*;
- using const_pointer = const std::uint16_t*;
- using iterator = std::uint16_t*;
- using const_iterator = const std::uint16_t*;
+ using reference = value_type&;
+ using const_reference = const value_type&;
+ using pointer = value_type*;
+ using const_pointer = const value_type*;
+ using iterator = value_type*;
+ using const_iterator = const value_type*;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
@@ -41,11 +41,9 @@ class CRU_BASE_API String {
return FromUtf8(str.data(), str.size());
}
- static String FromUtf16(const char16_t* str) {
- return String(reinterpret_cast<const_pointer>(str));
- }
+ static String FromUtf16(const char16_t* str) { return String(str); }
static String FromUtf16(const char16_t* str, Index size) {
- return String(reinterpret_cast<const_pointer>(str), size);
+ return String(str, size);
}
static String FromUtf16(std::u16string_view str) {
return FromUtf16(str.data(), str.size());
@@ -54,7 +52,7 @@ class CRU_BASE_API String {
static inline String From(StringView str);
// Never use this if you don't know what this mean!
- static String FromBuffer(std::uint16_t* buffer, Index size, Index capacity) {
+ static String FromBuffer(pointer buffer, Index size, Index capacity) {
return String{from_buffer_tag{}, buffer, size, capacity};
}
@@ -100,30 +98,30 @@ class CRU_BASE_API String {
private:
struct from_buffer_tag {};
- String(from_buffer_tag, std::uint16_t* buffer, Index size, Index capacity);
+ String(from_buffer_tag, pointer buffer, Index size, Index capacity);
public:
bool empty() const { return this->size_ == 0; }
Index size() const { return this->size_; }
Index length() const { return this->size(); }
Index capacity() const { return this->capacity_; }
- std::uint16_t* data() { return this->buffer_; }
- const std::uint16_t* data() const { return this->buffer_; }
+ pointer data() { return this->buffer_; }
+ const_pointer data() const { return this->buffer_; }
void resize(Index new_size);
void reserve(Index new_capacity);
void shrink_to_fit();
- std::uint16_t& front() { return this->operator[](0); }
- const std::uint16_t& front() const { return this->operator[](0); }
+ reference front() { return this->operator[](0); }
+ const_reference front() const { return this->operator[](0); }
- std::uint16_t& back() { return this->operator[](size_ - 1); }
- const std::uint16_t& back() const { return this->operator[](size_ - 1); }
+ reference back() { return this->operator[](size_ - 1); }
+ const_reference back() const { return this->operator[](size_ - 1); }
- const std::uint16_t* c_str() const { return buffer_; }
+ const_pointer c_str() const { return buffer_; }
- std::uint16_t& operator[](Index index) { return buffer_[index]; }
- const std::uint16_t& operator[](Index index) const { return buffer_[index]; }
+ reference operator[](Index index) { return buffer_[index]; }
+ const_reference operator[](Index index) const { return buffer_[index]; }
public:
iterator begin() { return this->buffer_; }
@@ -150,17 +148,17 @@ class CRU_BASE_API String {
public:
void clear();
- iterator insert(const_iterator pos, std::uint16_t value) {
+ iterator insert(const_iterator pos, value_type value) {
return this->insert(pos, &value, 1);
}
- iterator insert(const_iterator pos, const std::uint16_t* str, Index size);
+ iterator insert(const_iterator pos, const_iterator str, Index size);
iterator insert(const_iterator pos, StringView str);
iterator erase(const_iterator pos) { return this->erase(pos, pos + 1); }
iterator erase(const_iterator start, const_iterator end);
- void push_back(std::uint16_t value) { this->append(value); }
+ void push_back(value_type value) { this->append(value); }
void pop_back() { this->erase(cend() - 1); }
- void append(std::uint16_t value) { this->insert(cend(), value); }
- void append(const std::uint16_t* str, Index size) {
+ void append(value_type value) { this->insert(cend(), value); }
+ void append(const_iterator str, Index size) {
this->insert(cend(), str, size);
}
inline void append(StringView str);
@@ -179,10 +177,6 @@ class CRU_BASE_API String {
Range RangeFromCodeUnitToCodePoint(Range code_unit_range) const;
Range RangeFromCodePointToCodeUnit(Range code_point_range) const;
- const char16_t* Char16CStr() const {
- return reinterpret_cast<const char16_t*>(c_str());
- }
-
#ifdef CRU_PLATFORM_WINDOWS
const wchar_t* WinCStr() const {
return reinterpret_cast<const wchar_t*>(c_str());
@@ -197,10 +191,10 @@ class CRU_BASE_API String {
int Compare(const String& other) const;
private:
- static std::uint16_t kEmptyBuffer[1];
+ static char16_t kEmptyBuffer[1];
private:
- std::uint16_t* buffer_ = kEmptyBuffer;
+ char16_t* buffer_ = kEmptyBuffer;
Index size_ = 0; // not including trailing '\0'
Index capacity_ = 0; // always 1 smaller than real buffer size
};
@@ -224,7 +218,7 @@ std::enable_if_t<std::is_integral_v<T>, String> ToString(T value) {
std::to_chars(buffer.data(), buffer.data() + buffer.size(), value);
auto size = result.ptr - buffer.data();
- auto b = new std::uint16_t[size + 1];
+ auto b = new char16_t[size + 1];
b[size] = 0;
std::copy(buffer.data(), result.ptr, b);
return String::FromBuffer(b, size, size);
@@ -293,36 +287,36 @@ String String::Format(T&&... args) const {
class CRU_BASE_API StringView {
public:
- using value_type = std::uint16_t;
+ using value_type = char16_t;
using size_type = Index;
using difference_type = Index;
- using reference = std::uint16_t&;
- using const_reference = const std::uint16_t&;
- using pointer = std::uint16_t*;
- using const_pointer = const std::uint16_t*;
- using iterator = const std::uint16_t*;
- using const_iterator = const std::uint16_t*;
+ using reference = value_type&;
+ using const_reference = const value_type&;
+ using pointer = value_type*;
+ using const_pointer = const value_type*;
+ using iterator = const value_type*;
+ using const_iterator = const value_type*;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
StringView() = default;
- constexpr StringView(const std::uint16_t* ptr, Index size)
+ constexpr StringView(const_pointer ptr, Index size)
: ptr_(ptr), size_(size) {}
template <Index size>
- StringView(const char16_t (&array)[size]) : StringView(array, size) {}
- StringView(const char16_t* ptr, Index size)
- : ptr_(reinterpret_cast<const std::uint16_t*>(ptr)), size_(size) {}
+ constexpr StringView(const value_type (&array)[size])
+ : StringView(array, size) {}
StringView(const String& str) : StringView(str.data(), str.size()) {}
CRU_DEFAULT_COPY(StringView)
CRU_DEFAULT_MOVE(StringView)
+
~StringView() = default;
Index size() const { return size_; }
- const std::uint16_t* data() const { return ptr_; }
+ const value_type* data() const { return ptr_; }
public:
iterator begin() { return this->ptr_; }
@@ -354,10 +348,10 @@ class CRU_BASE_API StringView {
String ToString() const { return String(ptr_, size_); }
- std::uint16_t operator[](Index index) const { return ptr_[index]; }
+ value_type operator[](Index index) const { return ptr_[index]; }
private:
- const std::uint16_t* ptr_;
+ const char16_t* ptr_;
Index size_;
};
diff --git a/include/cru/osx/graphics/quartz/TextLayout.hpp b/include/cru/osx/graphics/quartz/TextLayout.hpp
index 96aabf90..4d23a76e 100644
--- a/include/cru/osx/graphics/quartz/TextLayout.hpp
+++ b/include/cru/osx/graphics/quartz/TextLayout.hpp
@@ -22,7 +22,7 @@ class OsxCTTextLayout : public OsxQuartzResource, public virtual ITextLayout {
String GetText() override { return text_; }
void SetText(String new_text) override;
- std::shared_ptr<IFont> GetFont() override;
+ std::shared_ptr<IFont> GetFont() override { return font_; }
void SetFont(std::shared_ptr<IFont> font) override;
void SetMaxWidth(float max_width) override;
@@ -33,7 +33,7 @@ class OsxCTTextLayout : public OsxQuartzResource, public virtual ITextLayout {
Point TextSinglePoint(Index position, bool trailing) override;
TextHitTestResult HitTest(const Point& point) override;
-private:
+ private:
void RecreateFrame();
private:
diff --git a/include/cru/osx/gui/UiApplication.hpp b/include/cru/osx/gui/UiApplication.hpp
index 5de0cc6b..a7b88010 100644
--- a/include/cru/osx/gui/UiApplication.hpp
+++ b/include/cru/osx/gui/UiApplication.hpp
@@ -6,12 +6,15 @@
#include <memory>
namespace cru::platform::gui::osx {
+class OsxWindow;
+
namespace details {
class OsxUiApplicationPrivate;
}
class OsxUiApplication : public OsxGuiResource, public virtual IUiApplication {
friend details::OsxUiApplicationPrivate;
+ friend OsxWindow;
public:
OsxUiApplication();
@@ -44,6 +47,8 @@ class OsxUiApplication : public OsxGuiResource, public virtual IUiApplication {
ICursorManager* GetCursorManager() override;
private:
+ void UnregisterWindow(OsxWindow* window);
+
std::unique_ptr<details::OsxUiApplicationPrivate> p_;
};
} // namespace cru::platform::gui::osx
diff --git a/src/common/String.cpp b/src/common/String.cpp
index 092ba406..ef5eb176 100644
--- a/src/common/String.cpp
+++ b/src/common/String.cpp
@@ -17,7 +17,7 @@ String String::FromUtf8(const char* str, Index size) {
return FromUtf16(cru::ToUtf16(std::string_view(str, size)));
}
-std::uint16_t String::kEmptyBuffer[1] = {0};
+char16_t String::kEmptyBuffer[1] = {0};
template <typename C>
Index GetStrSize(const C* str) {
@@ -28,10 +28,10 @@ Index GetStrSize(const C* str) {
return i;
}
-String::String(const std::uint16_t* str) : String(str, GetStrSize(str)) {}
+String::String(const_pointer str) : String(str, GetStrSize(str)) {}
-String::String(const std::uint16_t* str, Index size) {
- this->buffer_ = new std::uint16_t[size + 1];
+String::String(const_pointer str, Index size) {
+ this->buffer_ = new value_type[size + 1];
std::memcpy(this->buffer_, str, size * sizeof(char16_t));
this->buffer_[size] = 0;
this->size_ = size;
@@ -46,7 +46,7 @@ String::String(const wchar_t* str, Index size)
String::String(const String& other) {
if (other.size_ == 0) return;
- this->buffer_ = new std::uint16_t[other.size_ + 1];
+ this->buffer_ = new value_type[other.size_ + 1];
std::memcpy(this->buffer_, other.buffer_, other.size_ * sizeof(value_type));
this->buffer_[other.size_] = 0;
this->size_ = other.size_;
@@ -73,7 +73,7 @@ String& String::operator=(const String& other) {
this->size_ = 0;
this->capacity_ = 0;
} else {
- this->buffer_ = new std::uint16_t[other.size_ + 1];
+ this->buffer_ = new value_type[other.size_ + 1];
std::memcpy(this->buffer_, other.buffer_,
other.size_ * sizeof(value_type));
this->buffer_[other.size_] = 0;
@@ -106,8 +106,7 @@ String::~String() {
}
}
-String::String(from_buffer_tag, std::uint16_t* buffer, Index size,
- Index capacity)
+String::String(from_buffer_tag, pointer buffer, Index size, Index capacity)
: buffer_(buffer), size_(size), capacity_(capacity) {}
void String::resize(Index new_size) {
@@ -120,7 +119,7 @@ void String::resize(Index new_size) {
buffer_[size_] = 0;
} else {
reserve(new_size);
- std::memset(buffer_ + size_, 0, sizeof(std::uint16_t) * (new_size - size_));
+ std::memset(buffer_ + size_, 0, sizeof(value_type) * (new_size - size_));
buffer_[new_size] = 0;
size_ = new_size;
}
@@ -146,9 +145,9 @@ void String::reserve(Index new_capacity) {
Expects(new_capacity >= 0);
if (new_capacity <= this->capacity_) return;
if (new_capacity > 0) {
- std::uint16_t* new_buffer = new std::uint16_t[new_capacity + 1];
+ pointer new_buffer = new value_type[new_capacity + 1];
if (this->buffer_ != kEmptyBuffer) {
- memcpy(new_buffer, this->buffer_, this->size_ * sizeof(std::uint16_t));
+ memcpy(new_buffer, this->buffer_, this->size_ * sizeof(value_type));
delete[] this->buffer_;
}
new_buffer[this->size_] = 0;
@@ -157,11 +156,11 @@ void String::reserve(Index new_capacity) {
}
}
-String::iterator String::insert(const_iterator pos, const std::uint16_t* str,
+String::iterator String::insert(const_iterator pos, const_iterator str,
Index size) {
Expects(pos >= cbegin() && pos <= cend());
- std::vector<std::uint16_t> backup_buffer;
+ std::vector<value_type> backup_buffer;
if (str >= buffer_ && str < buffer_ + size_) {
backup_buffer.resize(size);
std::copy(str, str + size, backup_buffer.begin());
@@ -201,7 +200,7 @@ String::iterator String::erase(const_iterator start, const_iterator end) {
auto s = const_cast<iterator>(start);
auto e = const_cast<iterator>(end);
- std::memmove(e, s, (cend() - end) * sizeof(std::uint16_t));
+ std::memmove(e, s, (cend() - end) * sizeof(value_type));
this->size_ = new_size;
this->buffer_[new_size] = 0;
@@ -209,7 +208,7 @@ String::iterator String::erase(const_iterator start, const_iterator end) {
}
std::string String::ToUtf8() const {
- return cru::ToUtf8(std::u16string_view(Char16CStr(), size()));
+ return cru::ToUtf8(std::u16string_view(data(), size()));
}
Index String::IndexFromCodeUnitToCodePoint(Index code_unit_index) const {
@@ -250,7 +249,7 @@ String& String::operator+=(const String& other) {
}
namespace {
-inline int Compare(std::uint16_t left, std::uint16_t right) {
+inline int Compare(char16_t left, char16_t right) {
if (left < right) return -1;
if (left > right) return 1;
return 0;
@@ -286,7 +285,7 @@ namespace details {
std::vector<FormatToken> ParseToFormatTokenList(const String& str) {
std::vector<FormatToken> result;
- auto push_char = [&result](std::uint16_t c) {
+ auto push_char = [&result](char16_t c) {
if (result.empty() || result.back().type == FormatTokenType::PlaceHolder) {
result.push_back(FormatToken{FormatTokenType::Text, String{}});
}
diff --git a/src/osx/Convert.cpp b/src/osx/Convert.cpp
index 51ebedf4..a237a46f 100644
--- a/src/osx/Convert.cpp
+++ b/src/osx/Convert.cpp
@@ -1,6 +1,6 @@
#include "cru/osx/Convert.hpp"
-namespace cru::cru::platform::osx {
+namespace cru::platform::osx {
CFStringRef Convert(const String& string) {
return CFStringCreateWithBytes(
nullptr, reinterpret_cast<const UInt8*>(string.data()),
@@ -12,7 +12,7 @@ String Convert(CFStringRef string) {
kCFStringEncodingUTF16, 0);
auto l = CFDataGetLength(d);
- auto s = String(reinterpret_cast<const std::uint16_t*>(CFDataGetBytePtr(d)),
+ auto s = String(reinterpret_cast<const char16_t*>(CFDataGetBytePtr(d)),
CFDataGetLength(d) / 2);
CFRelease(d);
diff --git a/src/osx/graphics/quartz/Font.cpp b/src/osx/graphics/quartz/Font.cpp
index 600f8309..596489e4 100644
--- a/src/osx/graphics/quartz/Font.cpp
+++ b/src/osx/graphics/quartz/Font.cpp
@@ -1,9 +1,12 @@
#include "cru/osx/graphics/quartz/Font.hpp"
+#include "cru/osx/Convert.hpp"
#include "cru/osx/graphics/quartz/Convert.hpp"
#include "cru/osx/graphics/quartz/Resource.hpp"
namespace cru::platform::graphics::osx::quartz {
+using cru::platform::osx::Convert;
+
OsxCTFont::OsxCTFont(IGraphicsFactory* graphics_factory, const String& name,
float size)
: OsxQuartzResource(graphics_factory) {
diff --git a/src/osx/graphics/quartz/TextLayout.cpp b/src/osx/graphics/quartz/TextLayout.cpp
index 577eba58..6c6644e5 100644
--- a/src/osx/graphics/quartz/TextLayout.cpp
+++ b/src/osx/graphics/quartz/TextLayout.cpp
@@ -1,4 +1,5 @@
#include "cru/osx/graphics/quartz/TextLayout.hpp"
+#include "cru/osx/Convert.hpp"
#include "cru/osx/graphics/quartz/Convert.hpp"
#include "cru/osx/graphics/quartz/Resource.hpp"
#include "cru/platform/Check.hpp"
@@ -7,6 +8,8 @@
#include <limits>
namespace cru::platform::graphics::osx::quartz {
+using cru::platform::osx::Convert;
+
OsxCTTextLayout::OsxCTTextLayout(IGraphicsFactory* graphics_factory,
std::shared_ptr<OsxCTFont> font,
const String& str)
diff --git a/src/osx/gui/UiApplication.mm b/src/osx/gui/UiApplication.mm
index 2491390f..d2e6fe30 100644
--- a/src/osx/gui/UiApplication.mm
+++ b/src/osx/gui/UiApplication.mm
@@ -1,13 +1,18 @@
#include "cru/osx/gui/UiApplication.hpp"
#include "cru/osx/graphics/quartz/Factory.hpp"
+#include "cru/osx/gui/Window.hpp"
+#include "cru/platform/gui/UiApplication.hpp"
+#include "cru/platform/gui/Window.hpp"
#include <AppKit/NSApplication.h>
#include <Foundation/NSRunLoop.h>
#include <algorithm>
+#include <iterator>
#include <memory>
#include <unordered_map>
+#include <vector>
@interface AppDelegate : NSObject <NSApplicationDelegate>
- (id)init:(cru::platform::gui::osx::details::OsxUiApplicationPrivate*)p;
@@ -43,6 +48,8 @@ class OsxUiApplicationPrivate {
std::unordered_map<long long, std::function<void()>> next_tick_;
std::unordered_map<long long, NSTimer*> timers_;
+ std::vector<OsxWindow*> windows_;
+
std::unique_ptr<platform::graphics::osx::quartz::QuartzGraphicsFactory> quartz_graphics_factory_;
};
@@ -122,6 +129,25 @@ void OsxUiApplication::CancelTimer(long long id) {
p_->timers_.erase(i);
}
}
+
+std::vector<INativeWindow*> OsxUiApplication::GetAllWindow() {
+ std::vector<INativeWindow*> result;
+ std::transform(p_->windows_.cbegin(), p_->windows_.cend(), std::back_inserter(result),
+ [](OsxWindow* w) { return static_cast<INativeWindow*>(w); });
+ return result;
+}
+
+INativeWindow* OsxUiApplication::CreateWindow(INativeWindow* parent, CreateWindowFlag flags) {
+ auto window = new OsxWindow(this, parent, !(flags & CreateWindowFlags::NoCaptionAndBorder));
+ p_->windows_.push_back(window);
+ return window;
+}
+
+void OsxUiApplication::UnregisterWindow(OsxWindow* window) {
+ p_->windows_.erase(
+ std::remove(p_->windows_.begin(), p_->windows_.end(), static_cast<INativeWindow*>(window)),
+ p_->windows_.cend());
+}
}
@implementation AppDelegate
diff --git a/src/osx/gui/Window.mm b/src/osx/gui/Window.mm
index ff5572f2..c2134c76 100644
--- a/src/osx/gui/Window.mm
+++ b/src/osx/gui/Window.mm
@@ -92,6 +92,8 @@ OsxWindow::~OsxWindow() {
if (p_->window_) {
[p_->window_ close];
}
+
+ dynamic_cast<OsxUiApplication*>(GetUiApplication())->UnregisterWindow(this);
}
void OsxWindow::Close() {