Skip to content

Commit cab1ff0

Browse files
committed
Add iOS platform support (stub implementation)
1 parent 6ad9ad6 commit cab1ff0

File tree

14 files changed

+1207
-3
lines changed

14 files changed

+1207
-3
lines changed

examples/menu_c_example/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ add_executable(menu_c_example main.c)
1313
target_link_libraries(menu_c_example nativeapi)
1414

1515
# Platform-specific settings
16-
if(APPLE)
16+
if(CMAKE_SYSTEM_NAME STREQUAL "iOS")
17+
# iOS uses UIKit, Foundation, CoreGraphics (already linked by nativeapi)
18+
elseif(APPLE)
1719
find_library(COCOA_LIBRARY Cocoa)
1820
target_link_libraries(menu_c_example ${COCOA_LIBRARY})
1921
elseif(WIN32)

examples/menu_example/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ add_executable(menu_example main.cpp)
1313
target_link_libraries(menu_example nativeapi)
1414

1515
# Platform-specific settings
16-
if(APPLE)
16+
if(CMAKE_SYSTEM_NAME STREQUAL "iOS")
17+
# iOS uses UIKit, Foundation, CoreGraphics (already linked by nativeapi)
18+
elseif(APPLE)
1719
find_library(COCOA_LIBRARY Cocoa)
1820
target_link_libraries(menu_example ${COCOA_LIBRARY})
1921
elseif(WIN32)

src/CMakeLists.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
3030
pkg_check_modules(X11 REQUIRED IMPORTED_TARGET x11)
3131
pkg_check_modules(XI REQUIRED IMPORTED_TARGET xi)
3232
pkg_check_modules(AYATANA_APPINDICATOR REQUIRED IMPORTED_TARGET ayatana-appindicator3-0.1)
33+
elseif(CMAKE_SYSTEM_NAME STREQUAL "iOS")
34+
file(GLOB PLATFORM_SOURCES "platform/ios/*.mm")
3335
elseif(APPLE)
3436
file(GLOB PLATFORM_SOURCES "platform/macos/*.mm")
3537
elseif(WIN32)
@@ -63,7 +65,10 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
6365
endif ()
6466

6567
# Link required frameworks and libraries
66-
if(APPLE)
68+
if(CMAKE_SYSTEM_NAME STREQUAL "iOS")
69+
target_link_libraries(nativeapi PUBLIC "-framework UIKit" "-framework Foundation" "-framework CoreGraphics")
70+
target_compile_options(nativeapi PRIVATE "-x" "objective-c++")
71+
elseif(APPLE)
6772
target_link_libraries(nativeapi PUBLIC "-framework Cocoa")
6873
target_compile_options(nativeapi PRIVATE "-x" "objective-c++")
6974
elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux")
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#import <UIKit/UIKit.h>
2+
#import <Foundation/Foundation.h>
3+
#include "../../accessibility_manager.h"
4+
5+
namespace nativeapi {
6+
7+
void AccessibilityManager::Enable() {
8+
// On iOS, accessibility features are controlled by system settings
9+
// This method sets the internal flag
10+
enabled_ = true;
11+
}
12+
13+
bool AccessibilityManager::IsEnabled() {
14+
// Return the internal enabled state
15+
return enabled_;
16+
}
17+
18+
} // namespace nativeapi
19+
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#import <UIKit/UIKit.h>
2+
#import <Foundation/Foundation.h>
3+
#include <string>
4+
#include "../../application.h"
5+
6+
namespace nativeapi {
7+
8+
class Application::Impl {
9+
public:
10+
Impl() {}
11+
};
12+
13+
Application::Application() : pimpl_(std::make_unique<Impl>()) {}
14+
Application::~Application() {}
15+
16+
int Application::Run() {
17+
// On iOS, application lifecycle is managed by UIApplication
18+
// This is typically handled in the AppDelegate
19+
return 0;
20+
}
21+
22+
int Application::Run(std::shared_ptr<Window> window) {
23+
// iOS manages app lifecycle through UIApplication
24+
return 0;
25+
}
26+
27+
void Application::Quit(int exit_code) {
28+
// On iOS, apps don't exit programmatically
29+
// The system manages app lifecycle
30+
}
31+
32+
bool Application::IsRunning() const {
33+
UIApplication* app = [UIApplication sharedApplication];
34+
return app != nil;
35+
}
36+
37+
bool Application::IsSingleInstance() const {
38+
return true; // iOS apps are always single instance
39+
}
40+
41+
bool Application::SetIcon(const std::string& icon_path) {
42+
// iOS app icons are set in Info.plist
43+
return false;
44+
}
45+
46+
bool Application::SetDockIconVisible(bool visible) {
47+
// Not applicable to iOS
48+
return false;
49+
}
50+
51+
bool Application::SetMenuBar(std::shared_ptr<Menu> menu) {
52+
// iOS doesn't have a menu bar
53+
return false;
54+
}
55+
56+
std::shared_ptr<Window> Application::GetPrimaryWindow() const {
57+
return nullptr;
58+
}
59+
60+
void Application::SetPrimaryWindow(std::shared_ptr<Window> window) {
61+
// iOS manages primary window through UIApplication
62+
}
63+
64+
} // namespace nativeapi
65+

src/platform/ios/display_ios.mm

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
#import <UIKit/UIKit.h>
2+
#import <Foundation/Foundation.h>
3+
#include <string>
4+
#include "../../display.h"
5+
6+
namespace nativeapi {
7+
8+
// Private implementation class
9+
class Display::Impl {
10+
public:
11+
Impl(UIScreen* screen) : ui_screen_(screen) {}
12+
UIScreen* ui_screen_;
13+
};
14+
15+
Display::Display() : pimpl_(std::make_unique<Impl>([UIScreen mainScreen])) {}
16+
17+
Display::Display(void* display) : pimpl_(std::make_unique<Impl>((__bridge UIScreen*)display)) {}
18+
19+
Display::Display(const Display& other) : pimpl_(std::make_unique<Impl>(other.pimpl_->ui_screen_)) {}
20+
21+
Display& Display::operator=(const Display& other) {
22+
if (this != &other) {
23+
pimpl_->ui_screen_ = other.pimpl_->ui_screen_;
24+
}
25+
return *this;
26+
}
27+
28+
Display::Display(Display&& other) noexcept : pimpl_(std::move(other.pimpl_)) {}
29+
30+
Display& Display::operator=(Display&& other) noexcept {
31+
if (this != &other) {
32+
pimpl_ = std::move(other.pimpl_);
33+
}
34+
return *this;
35+
}
36+
37+
Display::~Display() {}
38+
39+
std::string Display::GetId() const {
40+
if (!pimpl_->ui_screen_) {
41+
return "";
42+
}
43+
44+
// Use the screen's bounds as a unique identifier
45+
CGRect bounds = pimpl_->ui_screen_.bounds;
46+
return std::to_string((int)bounds.origin.x) + "_" + std::to_string((int)bounds.origin.y);
47+
}
48+
49+
std::string Display::GetName() const {
50+
if (!pimpl_->ui_screen_) {
51+
return "Unknown";
52+
}
53+
54+
// iOS doesn't provide a friendly name for screens
55+
// Use scale factor and size to differentiate
56+
CGFloat scale = pimpl_->ui_screen_.scale;
57+
CGRect bounds = pimpl_->ui_screen_.bounds;
58+
59+
return std::string("Screen ") + std::to_string((int)bounds.size.width) + "x" +
60+
std::to_string((int)bounds.size.height) + "@" + std::to_string((int)scale) + "x";
61+
}
62+
63+
Point Display::GetPosition() const {
64+
if (!pimpl_->ui_screen_) {
65+
return Point{0, 0};
66+
}
67+
68+
CGRect bounds = pimpl_->ui_screen_.bounds;
69+
return Point{static_cast<double>(bounds.origin.x), static_cast<double>(bounds.origin.y)};
70+
}
71+
72+
Size Display::GetSize() const {
73+
if (!pimpl_->ui_screen_) {
74+
return Size{0, 0};
75+
}
76+
77+
CGRect bounds = pimpl_->ui_screen_.bounds;
78+
return Size{static_cast<double>(bounds.size.width), static_cast<double>(bounds.size.height)};
79+
}
80+
81+
Rectangle Display::GetWorkArea() const {
82+
if (!pimpl_->ui_screen_) {
83+
return Rectangle{0, 0, 0, 0};
84+
}
85+
86+
CGRect bounds = pimpl_->ui_screen_.bounds;
87+
return Rectangle{static_cast<double>(bounds.origin.x), static_cast<double>(bounds.origin.y),
88+
static_cast<double>(bounds.size.width), static_cast<double>(bounds.size.height)};
89+
}
90+
91+
double Display::GetScaleFactor() const {
92+
return pimpl_->ui_screen_ ? static_cast<double>(pimpl_->ui_screen_.scale) : 1.0;
93+
}
94+
95+
bool Display::IsPrimary() const {
96+
return pimpl_->ui_screen_ == [UIScreen mainScreen];
97+
}
98+
99+
DisplayOrientation Display::GetOrientation() const {
100+
if (!pimpl_->ui_screen_) {
101+
return DisplayOrientation::kPortrait;
102+
}
103+
104+
// Check orientation based on screen bounds
105+
CGRect bounds = pimpl_->ui_screen_.bounds;
106+
if (bounds.size.width > bounds.size.height) {
107+
return DisplayOrientation::kLandscape;
108+
} else {
109+
return DisplayOrientation::kPortrait;
110+
}
111+
}
112+
113+
int Display::GetRefreshRate() const {
114+
if (!pimpl_->ui_screen_) {
115+
return 60;
116+
}
117+
118+
// iOS doesn't expose refresh rate directly, return standard 60Hz
119+
return 60;
120+
}
121+
122+
int Display::GetBitDepth() const {
123+
// iOS devices typically use 32-bit color depth
124+
return 32;
125+
}
126+
127+
void* Display::GetNativeObjectInternal() const {
128+
return (__bridge void*)pimpl_->ui_screen_;
129+
}
130+
131+
} // namespace nativeapi
132+
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#import <UIKit/UIKit.h>
2+
#import <Foundation/Foundation.h>
3+
#include "../../display_manager.h"
4+
#include "../../window.h"
5+
6+
namespace nativeapi {
7+
8+
DisplayManager::DisplayManager() {
9+
// Constructor initialization
10+
}
11+
12+
DisplayManager::~DisplayManager() {}
13+
14+
std::vector<Display> DisplayManager::GetAll() {
15+
std::vector<Display> displays;
16+
17+
// Get all screens
18+
NSArray<UIScreen*>* screens = [UIScreen screens];
19+
for (UIScreen* screen in screens) {
20+
displays.push_back(Display((__bridge void*)screen));
21+
}
22+
23+
// If no screens found, add main screen
24+
if (displays.empty()) {
25+
UIScreen* mainScreen = [UIScreen mainScreen];
26+
if (mainScreen) {
27+
displays.push_back(Display((__bridge void*)mainScreen));
28+
}
29+
}
30+
31+
return displays;
32+
}
33+
34+
Display DisplayManager::GetPrimary() {
35+
// Get main screen
36+
UIScreen* mainScreen = [UIScreen mainScreen];
37+
return Display((__bridge void*)mainScreen);
38+
}
39+
40+
Point DisplayManager::GetCursorPosition() {
41+
// iOS doesn't have a cursor position concept
42+
return Point{0, 0};
43+
}
44+
45+
} // namespace nativeapi
46+

0 commit comments

Comments
 (0)