The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
apple_video.mm
Go to the documentation of this file.
1/*
2 Copyright (C) 2020 - 2025
3 by Martin HrubĂ˝ <hrubymar10@gmail.com>
4 Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY.
12
13 See the COPYING file for more details.
14*/
15
16#ifdef __APPLE__
17#include <TargetConditionals.h>
18#if TARGET_OS_OSX
19
20#include "apple_video.hpp"
21
22#import <AppKit/AppKit.h>
23#import <Foundation/Foundation.h>
24
25namespace desktop {
26namespace apple {
27 CGFloat get_scale_factor(int display_index) {
28 CGFloat scale_factor = 1.0f;
29
30 NSArray *screens = [NSScreen screens];
31
32 if ([screens[display_index] respondsToSelector:@selector(backingScaleFactor)]) { // Mac OS X 10.7 and later
33 scale_factor = [screens[display_index] backingScaleFactor];
34 }
35
36 return scale_factor;
37 }
38
40 {
41 // iOS-only, no-op on macOS.
42 }
43} // end namespace apple
44} // end namespace desktop
45
46#elif TARGET_OS_IOS
47
48#include "apple_video.hpp"
49
50#include <SDL3/SDL_keyboard.h>
51
52#import <UIKit/UIKit.h>
53
54static __weak UIResponder* first_responder = nil;
55
56@interface UIResponder (WesnothFirstResponderCapture)
57- (void)wesnoth_capture_first_responder:(id)sender;
58@end
59
60@implementation UIResponder (WesnothFirstResponderCapture)
61- (void)wesnoth_capture_first_responder:(id)sender
62{
63 (void)sender;
64 first_responder = self;
65}
66@end
67
68@interface wesnoth_keyboard_toolbar : NSObject
69+ (instancetype)shared;
70- (void)attach_toolbar_to_first_responder;
71@end
72
73@implementation wesnoth_keyboard_toolbar
74
75+ (instancetype)shared
76{
77 static wesnoth_keyboard_toolbar* instance = nil;
78 static dispatch_once_t once_token;
79 dispatch_once(&once_token, ^{
80 instance = [[wesnoth_keyboard_toolbar alloc] init];
81 });
82 return instance;
83}
84
85- (instancetype)init
86{
87 self = [super init];
88 if(self) {
89 [[NSNotificationCenter defaultCenter]
90 addObserver:self
91 selector:@selector(on_keyboard_will_show:)
92 name:UIKeyboardWillShowNotification
93 object:nil];
94 }
95 return self;
96}
97
98- (UIResponder*)current_first_responder
99{
100 first_responder = nil;
101 [[UIApplication sharedApplication]
102 sendAction:@selector(wesnoth_capture_first_responder:)
103 to:nil
104 from:nil
105 forEvent:nil];
106 return first_responder;
107}
108
109- (UIToolbar*)dismiss_toolbar
110{
111 static UIToolbar* toolbar = nil;
112 if(!toolbar) {
113 toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0.0, 0.0, 0.0, 44.0)];
114 UIBarButtonItem* flex = [[UIBarButtonItem alloc]
115 initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
116 target:nil
117 action:nil];
118 UIBarButtonItem* dismiss = [[UIBarButtonItem alloc]
119 initWithTitle:NSLocalizedString(@"Dismiss", @"Dismiss keyboard button")
120 style:UIBarButtonItemStyleDone
121 target:self
122 action:@selector(on_dismiss_keyboard:)];
123 [toolbar setItems:@[flex, dismiss]];
124 [toolbar sizeToFit];
125 }
126 return toolbar;
127}
128
129- (void)on_keyboard_will_show:(NSNotification*)notification
130{
131 (void)notification;
132 [self attach_toolbar_to_first_responder];
133}
134
135- (void)attach_toolbar_to_first_responder
136{
137 UIResponder* responder = [self current_first_responder];
138 if([responder isKindOfClass:[UITextField class]]) {
139 UITextField* text_field = (UITextField*)responder;
140 UIToolbar* toolbar = [self dismiss_toolbar];
141 if(text_field.inputAccessoryView != toolbar) {
142 text_field.inputAccessoryView = toolbar;
143 [text_field reloadInputViews];
144 }
145 } else if([responder isKindOfClass:[UITextView class]]) {
146 UITextView* text_view = (UITextView*)responder;
147 UIToolbar* toolbar = [self dismiss_toolbar];
148 if(text_view.inputAccessoryView != toolbar) {
149 text_view.inputAccessoryView = toolbar;
150 [text_view reloadInputViews];
151 }
152 }
153}
154
155- (void)on_dismiss_keyboard:(id)sender
156{
157 (void)sender;
158 SDL_StopTextInput();
159}
160
161@end
162
163namespace desktop {
164namespace apple {
165 CGFloat get_scale_factor(int display_index) {
166 NSArray<UIScreen*>* screens = [UIScreen screens];
167 if(display_index >= 0 && static_cast<NSUInteger>(display_index) < screens.count) {
168 return screens[display_index].scale;
169 }
170 return UIScreen.mainScreen.scale;
171 }
172
174 {
175 if([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone) {
176 [wesnoth_keyboard_toolbar shared];
177 }
178 }
179} // end namespace apple
180} // end namespace desktop
181
182#endif //end TARGET_OS_OSX / TARGET_OS_IOS
183#endif //end __APPLE__
void install_keyboard_dismiss_toolbar()
CGFloat get_scale_factor(int display_index)
struct utils::detail::formula_initer init