diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-03-21 14:29:51 +0200 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-03-21 14:29:51 +0200 |
commit | 2f9e203058df442921fc0151ddc5fe9b68b87935 (patch) | |
tree | 5441025fcf4e974e82128f65376650bec7a941bb | |
parent | b93ba1bfb860c2a4b5bf46c77f3f0d11b4eb1282 (diff) |
iOS: Save to Files; hide toolbar on scroll
There is no downloads directory on mobile. Instead, the downloaded file is temporarily cached and given to the iOS document picker to export.
Added an option to hide the bottom toolbar while scrolling down.
-rw-r--r-- | src/app.c | 23 | ||||
-rw-r--r-- | src/defs.h | 8 | ||||
-rw-r--r-- | src/ios.h | 6 | ||||
-rw-r--r-- | src/ios.m | 41 | ||||
-rw-r--r-- | src/prefs.c | 1 | ||||
-rw-r--r-- | src/prefs.h | 1 | ||||
-rw-r--r-- | src/ui/documentwidget.c | 63 | ||||
-rw-r--r-- | src/ui/util.c | 5 | ||||
-rw-r--r-- | src/ui/widget.c | 33 | ||||
-rw-r--r-- | src/ui/widget.h | 3 | ||||
-rw-r--r-- | src/ui/window.c | 33 | ||||
-rw-r--r-- | src/ui/window.h | 1 |
12 files changed, 175 insertions, 43 deletions
@@ -276,6 +276,14 @@ static const char *downloadDir_App_(void) { | |||
276 | } | 276 | } |
277 | } | 277 | } |
278 | #endif | 278 | #endif |
279 | #if defined (iPlatformAppleMobile) | ||
280 | /* Save to a local cache directory from where the user can export to the cloud. */ | ||
281 | const iString *dlDir = cleanedCStr_Path("~/Library/Caches/Downloads"); | ||
282 | if (!fileExists_FileInfo(dlDir)) { | ||
283 | makeDirs_Path(dlDir); | ||
284 | } | ||
285 | return cstr_String(dlDir); | ||
286 | #endif | ||
279 | return defaultDownloadDir_App_; | 287 | return defaultDownloadDir_App_; |
280 | } | 288 | } |
281 | 289 | ||
@@ -313,6 +321,11 @@ static void loadPrefs_App_(iApp *d) { | |||
313 | d->initialWindowRect = init_Rect( | 321 | d->initialWindowRect = init_Rect( |
314 | pos.x, pos.y, argLabel_Command(cmd, "width"), argLabel_Command(cmd, "height")); | 322 | pos.x, pos.y, argLabel_Command(cmd, "width"), argLabel_Command(cmd, "height")); |
315 | } | 323 | } |
324 | #if !defined (LAGRANGE_DOWNLOAD_EDIT) | ||
325 | else if (equal_Command(cmd, "downloads")) { | ||
326 | continue; /* can't change downloads directory */ | ||
327 | } | ||
328 | #endif | ||
316 | else { | 329 | else { |
317 | postCommandString_App(&cmdStr); | 330 | postCommandString_App(&cmdStr); |
318 | } | 331 | } |
@@ -1311,6 +1324,8 @@ static iBool handlePrefsCommands_(iWidget *d, const char *cmd) { | |||
1311 | isSelected_Widget(findChild_Widget(d, "prefs.smoothscroll"))); | 1324 | isSelected_Widget(findChild_Widget(d, "prefs.smoothscroll"))); |
1312 | postCommandf_App("imageloadscroll arg:%d", | 1325 | postCommandf_App("imageloadscroll arg:%d", |
1313 | isSelected_Widget(findChild_Widget(d, "prefs.imageloadscroll"))); | 1326 | isSelected_Widget(findChild_Widget(d, "prefs.imageloadscroll"))); |
1327 | postCommandf_App("hidetoolbarscroll arg:%d", | ||
1328 | isSelected_Widget(findChild_Widget(d, "prefs.hidetoolbarscroll"))); | ||
1314 | postCommandf_App("ostheme arg:%d", | 1329 | postCommandf_App("ostheme arg:%d", |
1315 | isSelected_Widget(findChild_Widget(d, "prefs.ostheme"))); | 1330 | isSelected_Widget(findChild_Widget(d, "prefs.ostheme"))); |
1316 | postCommandf_App("decodeurls arg:%d", | 1331 | postCommandf_App("decodeurls arg:%d", |
@@ -1592,6 +1607,13 @@ iBool handleCommand_App(const char *cmd) { | |||
1592 | d->prefs.loadImageInsteadOfScrolling = arg_Command(cmd); | 1607 | d->prefs.loadImageInsteadOfScrolling = arg_Command(cmd); |
1593 | return iTrue; | 1608 | return iTrue; |
1594 | } | 1609 | } |
1610 | else if (equal_Command(cmd, "hidetoolbarscroll")) { | ||
1611 | d->prefs.hideToolbarOnScroll = arg_Command(cmd); | ||
1612 | if (!d->prefs.hideToolbarOnScroll) { | ||
1613 | showToolbars_Window(d->window, iTrue); | ||
1614 | } | ||
1615 | return iTrue; | ||
1616 | } | ||
1595 | else if (equal_Command(cmd, "theme.set")) { | 1617 | else if (equal_Command(cmd, "theme.set")) { |
1596 | const int isAuto = argLabel_Command(cmd, "auto"); | 1618 | const int isAuto = argLabel_Command(cmd, "auto"); |
1597 | d->prefs.theme = arg_Command(cmd); | 1619 | d->prefs.theme = arg_Command(cmd); |
@@ -1864,6 +1886,7 @@ iBool handleCommand_App(const char *cmd) { | |||
1864 | setToggle_Widget(findChild_Widget(dlg, "prefs.hoverlink"), d->prefs.hoverLink); | 1886 | setToggle_Widget(findChild_Widget(dlg, "prefs.hoverlink"), d->prefs.hoverLink); |
1865 | setToggle_Widget(findChild_Widget(dlg, "prefs.smoothscroll"), d->prefs.smoothScrolling); | 1887 | setToggle_Widget(findChild_Widget(dlg, "prefs.smoothscroll"), d->prefs.smoothScrolling); |
1866 | setToggle_Widget(findChild_Widget(dlg, "prefs.imageloadscroll"), d->prefs.loadImageInsteadOfScrolling); | 1888 | setToggle_Widget(findChild_Widget(dlg, "prefs.imageloadscroll"), d->prefs.loadImageInsteadOfScrolling); |
1889 | setToggle_Widget(findChild_Widget(dlg, "prefs.hidetoolbarscroll"), d->prefs.hideToolbarOnScroll); | ||
1867 | setToggle_Widget(findChild_Widget(dlg, "prefs.ostheme"), d->prefs.useSystemTheme); | 1890 | setToggle_Widget(findChild_Widget(dlg, "prefs.ostheme"), d->prefs.useSystemTheme); |
1868 | setToggle_Widget(findChild_Widget(dlg, "prefs.customframe"), d->prefs.customFrame); | 1891 | setToggle_Widget(findChild_Widget(dlg, "prefs.customframe"), d->prefs.customFrame); |
1869 | setToggle_Widget(findChild_Widget(dlg, "prefs.retainwindow"), d->prefs.retainWindowSize); | 1892 | setToggle_Widget(findChild_Widget(dlg, "prefs.retainwindow"), d->prefs.retainWindowSize); |
@@ -82,3 +82,11 @@ enum iFileVersion { | |||
82 | #define unhappy_Icon "\U0001f641" | 82 | #define unhappy_Icon "\U0001f641" |
83 | #define globe_Icon "\U0001f310" | 83 | #define globe_Icon "\U0001f310" |
84 | #define magnifyingGlass_Icon "\U0001f50d" | 84 | #define magnifyingGlass_Icon "\U0001f50d" |
85 | |||
86 | /* UI labels that depend on the platform */ | ||
87 | |||
88 | #if defined (iPlatformMobile) | ||
89 | # define saveToDownloads_Label "Save to Files" | ||
90 | #else | ||
91 | # define saveToDownloads_Label "Save to Downloads" | ||
92 | #endif | ||
@@ -32,7 +32,9 @@ enum iHapticEffect { | |||
32 | 32 | ||
33 | void setupApplication_iOS (void); | 33 | void setupApplication_iOS (void); |
34 | void setupWindow_iOS (iWindow *window); | 34 | void setupWindow_iOS (iWindow *window); |
35 | iBool isPhone_iOS (void); | ||
36 | void safeAreaInsets_iOS (float *left, float *top, float *right, float *bottom); | ||
37 | iBool processEvent_iOS (const SDL_Event *); | 35 | iBool processEvent_iOS (const SDL_Event *); |
38 | void playHapticEffect_iOS (enum iHapticEffect effect); | 36 | void playHapticEffect_iOS (enum iHapticEffect effect); |
37 | void exportDownloadedFile_iOS(const iString *path); | ||
38 | |||
39 | iBool isPhone_iOS (void); | ||
40 | void safeAreaInsets_iOS (float *left, float *top, float *right, float *bottom); | ||
@@ -120,7 +120,9 @@ API_AVAILABLE(ios(13.0)) | |||
120 | 120 | ||
121 | /*----------------------------------------------------------------------------------------------*/ | 121 | /*----------------------------------------------------------------------------------------------*/ |
122 | 122 | ||
123 | @interface AppState : NSObject | 123 | @interface AppState : NSObject<UIDocumentPickerDelegate> { |
124 | iString *fileBeingSaved; | ||
125 | } | ||
124 | @property (nonatomic, assign) BOOL isHapticsAvailable; | 126 | @property (nonatomic, assign) BOOL isHapticsAvailable; |
125 | @property (nonatomic, strong) NSObject *haptic; | 127 | @property (nonatomic, strong) NSObject *haptic; |
126 | @end | 128 | @end |
@@ -129,6 +131,23 @@ static AppState *appState_; | |||
129 | 131 | ||
130 | @implementation AppState | 132 | @implementation AppState |
131 | 133 | ||
134 | -(instancetype)init { | ||
135 | self = [super init]; | ||
136 | fileBeingSaved = NULL; | ||
137 | return self; | ||
138 | } | ||
139 | |||
140 | -(void)setFileBeingSaved:(const iString *)path { | ||
141 | fileBeingSaved = copy_String(path); | ||
142 | } | ||
143 | |||
144 | -(void)removeSavedFile { | ||
145 | /* The file was copied to an external location, so the cached copy is not needed. */ | ||
146 | remove(cstr_String(fileBeingSaved)); | ||
147 | delete_String(fileBeingSaved); | ||
148 | fileBeingSaved = NULL; | ||
149 | } | ||
150 | |||
132 | -(void)setupHaptics { | 151 | -(void)setupHaptics { |
133 | if (@available(iOS 13.0, *)) { | 152 | if (@available(iOS 13.0, *)) { |
134 | self.isHapticsAvailable = CHHapticEngine.capabilitiesForHardware.supportsHaptics; | 153 | self.isHapticsAvailable = CHHapticEngine.capabilitiesForHardware.supportsHaptics; |
@@ -145,6 +164,15 @@ static AppState *appState_; | |||
145 | } | 164 | } |
146 | } | 165 | } |
147 | 166 | ||
167 | - (void)documentPicker:(UIDocumentPickerViewController *)controller | ||
168 | didPickDocumentsAtURLs:(NSArray<NSURL *> *)urls { | ||
169 | [self removeSavedFile]; | ||
170 | } | ||
171 | |||
172 | - (void)documentPickerWasCancelled:(UIDocumentPickerViewController *)controller { | ||
173 | [self removeSavedFile]; | ||
174 | } | ||
175 | |||
148 | -(void)keyboardOnScreen:(NSNotification *)notification { | 176 | -(void)keyboardOnScreen:(NSNotification *)notification { |
149 | NSDictionary *info = notification.userInfo; | 177 | NSDictionary *info = notification.userInfo; |
150 | NSValue *value = info[UIKeyboardFrameEndUserInfoKey]; | 178 | NSValue *value = info[UIKeyboardFrameEndUserInfoKey]; |
@@ -257,3 +285,14 @@ iBool processEvent_iOS(const SDL_Event *ev) { | |||
257 | } | 285 | } |
258 | return iFalse; /* allow normal processing */ | 286 | return iFalse; /* allow normal processing */ |
259 | } | 287 | } |
288 | |||
289 | void exportDownloadedFile_iOS(const iString *path) { | ||
290 | NSURL *url = [NSURL fileURLWithPath:[[NSString alloc] initWithCString:cstr_String(path) | ||
291 | encoding:NSUTF8StringEncoding]]; | ||
292 | UIDocumentPickerViewController *picker = [[UIDocumentPickerViewController alloc] | ||
293 | initWithURL:url | ||
294 | inMode:UIDocumentPickerModeExportToService]; | ||
295 | picker.delegate = appState_; | ||
296 | [appState_ setFileBeingSaved:path]; | ||
297 | [viewController_(get_Window()) presentViewController:picker animated:YES completion:nil]; | ||
298 | } | ||
diff --git a/src/prefs.c b/src/prefs.c index b9b59836..a4f12e20 100644 --- a/src/prefs.c +++ b/src/prefs.c | |||
@@ -36,6 +36,7 @@ void init_Prefs(iPrefs *d) { | |||
36 | d->uiScale = 1.0f; /* default set elsewhere */ | 36 | d->uiScale = 1.0f; /* default set elsewhere */ |
37 | d->zoomPercent = 100; | 37 | d->zoomPercent = 100; |
38 | d->sideIcon = iTrue; | 38 | d->sideIcon = iTrue; |
39 | d->hideToolbarOnScroll = iTrue; | ||
39 | d->hoverLink = iTrue; | 40 | d->hoverLink = iTrue; |
40 | d->smoothScrolling = iTrue; | 41 | d->smoothScrolling = iTrue; |
41 | d->loadImageInsteadOfScrolling = iFalse; | 42 | d->loadImageInsteadOfScrolling = iFalse; |
diff --git a/src/prefs.h b/src/prefs.h index 13b91568..130f11e2 100644 --- a/src/prefs.h +++ b/src/prefs.h | |||
@@ -46,6 +46,7 @@ struct Impl_Prefs { | |||
46 | float uiScale; | 46 | float uiScale; |
47 | int zoomPercent; | 47 | int zoomPercent; |
48 | iBool sideIcon; | 48 | iBool sideIcon; |
49 | iBool hideToolbarOnScroll; | ||
49 | /* Behavior */ | 50 | /* Behavior */ |
50 | iString downloadDir; | 51 | iString downloadDir; |
51 | iBool hoverLink; | 52 | iBool hoverLink; |
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index d9b78a4d..0b9757d4 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c | |||
@@ -48,6 +48,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | |||
48 | #include "visbuf.h" | 48 | #include "visbuf.h" |
49 | #include "visited.h" | 49 | #include "visited.h" |
50 | 50 | ||
51 | #if defined (iPlatformAppleMobile) | ||
52 | # include "ios.h" | ||
53 | #endif | ||
54 | |||
51 | #include <the_Foundation/file.h> | 55 | #include <the_Foundation/file.h> |
52 | #include <the_Foundation/fileinfo.h> | 56 | #include <the_Foundation/fileinfo.h> |
53 | #include <the_Foundation/objectlist.h> | 57 | #include <the_Foundation/objectlist.h> |
@@ -220,6 +224,7 @@ struct Impl_DocumentWidget { | |||
220 | SDL_Texture * sideIconBuf; | 224 | SDL_Texture * sideIconBuf; |
221 | iTextBuf * timestampBuf; | 225 | iTextBuf * timestampBuf; |
222 | iTranslation * translation; | 226 | iTranslation * translation; |
227 | iWidget * phoneToolbar; | ||
223 | }; | 228 | }; |
224 | 229 | ||
225 | iDefineObjectConstruction(DocumentWidget) | 230 | iDefineObjectConstruction(DocumentWidget) |
@@ -231,6 +236,7 @@ void init_DocumentWidget(iDocumentWidget *d) { | |||
231 | setFlags_Widget(w, hover_WidgetFlag, iTrue); | 236 | setFlags_Widget(w, hover_WidgetFlag, iTrue); |
232 | init_PersistentDocumentState(&d->mod); | 237 | init_PersistentDocumentState(&d->mod); |
233 | d->flags = 0; | 238 | d->flags = 0; |
239 | d->phoneToolbar = NULL; | ||
234 | iZap(d->certExpiry); | 240 | iZap(d->certExpiry); |
235 | d->certFingerprint = new_Block(0); | 241 | d->certFingerprint = new_Block(0); |
236 | d->certFlags = 0; | 242 | d->certFlags = 0; |
@@ -440,8 +446,13 @@ static float normScrollPos_DocumentWidget_(const iDocumentWidget *d) { | |||
440 | } | 446 | } |
441 | 447 | ||
442 | static int scrollMax_DocumentWidget_(const iDocumentWidget *d) { | 448 | static int scrollMax_DocumentWidget_(const iDocumentWidget *d) { |
443 | return size_GmDocument(d->doc).y - height_Rect(bounds_Widget(constAs_Widget(d))) + | 449 | int sm = size_GmDocument(d->doc).y - height_Rect(bounds_Widget(constAs_Widget(d))) + |
444 | (hasSiteBanner_GmDocument(d->doc) ? 1 : 2) * d->pageMargin * gap_UI; | 450 | (hasSiteBanner_GmDocument(d->doc) ? 1 : 2) * d->pageMargin * gap_UI; |
451 | if (d->phoneToolbar) { | ||
452 | sm += rootSize_Window(get_Window()).y - | ||
453 | top_Rect(boundsWithoutVisualOffset_Widget(d->phoneToolbar)); | ||
454 | } | ||
455 | return sm; | ||
445 | } | 456 | } |
446 | 457 | ||
447 | static void invalidateLink_DocumentWidget_(iDocumentWidget *d, iGmLinkId id) { | 458 | static void invalidateLink_DocumentWidget_(iDocumentWidget *d, iGmLinkId id) { |
@@ -815,9 +826,10 @@ static void showErrorPage_DocumentWidget_(iDocumentWidget *d, enum iGmStatusCode | |||
815 | appendFormat_String(src, | 826 | appendFormat_String(src, |
816 | "\n```\n%s\n```\n" | 827 | "\n```\n%s\n```\n" |
817 | "You can save it as a file to your Downloads folder, though. " | 828 | "You can save it as a file to your Downloads folder, though. " |
818 | "Press %s or select \"Save to Downloads\" from the menu.", | 829 | "Press %s or select \"%s\" from the menu.", |
819 | cstr_String(meta), | 830 | cstr_String(meta), |
820 | cstr_String(key)); | 831 | cstr_String(key), |
832 | saveToDownloads_Label); | ||
821 | break; | 833 | break; |
822 | } | 834 | } |
823 | case slowDown_GmStatusCode: | 835 | case slowDown_GmStatusCode: |
@@ -1085,6 +1097,14 @@ static void smoothScroll_DocumentWidget_(iDocumentWidget *d, int offset, int dur | |||
1085 | const int scrollMax = scrollMax_DocumentWidget_(d); | 1097 | const int scrollMax = scrollMax_DocumentWidget_(d); |
1086 | if (scrollMax > 0) { | 1098 | if (scrollMax > 0) { |
1087 | destY = iMin(destY, scrollMax); | 1099 | destY = iMin(destY, scrollMax); |
1100 | if (deviceType_App() == phone_AppDeviceType) { | ||
1101 | if (destY == scrollMax) { | ||
1102 | showToolbars_Window(get_Window(), iTrue); | ||
1103 | } | ||
1104 | else if (prefs_App()->hideToolbarOnScroll && iAbs(offset) > 5) { | ||
1105 | showToolbars_Window(get_Window(), offset < 0); | ||
1106 | } | ||
1107 | } | ||
1088 | } | 1108 | } |
1089 | else { | 1109 | else { |
1090 | destY = 0; | 1110 | destY = 0; |
@@ -1443,12 +1463,17 @@ static void saveToDownloads_(const iString *url, const iString *mime, const iBlo | |||
1443 | iFile *f = new_File(savePath); | 1463 | iFile *f = new_File(savePath); |
1444 | if (open_File(f, writeOnly_FileMode)) { | 1464 | if (open_File(f, writeOnly_FileMode)) { |
1445 | write_File(f, content); | 1465 | write_File(f, content); |
1466 | close_File(f); | ||
1446 | const size_t size = size_Block(content); | 1467 | const size_t size = size_Block(content); |
1447 | const iBool isMega = size >= 1000000; | 1468 | const iBool isMega = size >= 1000000; |
1469 | #if defined (iPlatformAppleMobile) | ||
1470 | exportDownloadedFile_iOS(savePath); | ||
1471 | #else | ||
1448 | makeMessage_Widget(uiHeading_ColorEscape "FILE SAVED", | 1472 | makeMessage_Widget(uiHeading_ColorEscape "FILE SAVED", |
1449 | format_CStr("%s\nSize: %.3f %s", cstr_String(path_File(f)), | 1473 | format_CStr("%s\nSize: %.3f %s", cstr_String(path_File(f)), |
1450 | isMega ? size / 1.0e6f : (size / 1.0e3f), | 1474 | isMega ? size / 1.0e6f : (size / 1.0e3f), |
1451 | isMega ? "MB" : "KB")); | 1475 | isMega ? "MB" : "KB")); |
1476 | #endif | ||
1452 | } | 1477 | } |
1453 | else { | 1478 | else { |
1454 | makeMessage_Widget(uiTextCaution_ColorEscape "ERROR SAVING FILE", | 1479 | makeMessage_Widget(uiTextCaution_ColorEscape "ERROR SAVING FILE", |
@@ -1496,8 +1521,8 @@ static const int homeRowKeys_[] = { | |||
1496 | static iBool updateDocumentWidthRetainingScrollPosition_DocumentWidget_(iDocumentWidget *d, | 1521 | static iBool updateDocumentWidthRetainingScrollPosition_DocumentWidget_(iDocumentWidget *d, |
1497 | iBool keepCenter) { | 1522 | iBool keepCenter) { |
1498 | const int newWidth = documentWidth_DocumentWidget_(d); | 1523 | const int newWidth = documentWidth_DocumentWidget_(d); |
1499 | if (newWidth == size_GmDocument(d->doc).x) { | 1524 | if (newWidth == size_GmDocument(d->doc).x && !keepCenter /* not a font change */) { |
1500 | return iFalse; /* hasn't changed */ | 1525 | return iFalse; |
1501 | } | 1526 | } |
1502 | /* Font changes (i.e., zooming) will keep the view centered, otherwise keep the top | 1527 | /* Font changes (i.e., zooming) will keep the view centered, otherwise keep the top |
1503 | of the visible area fixed. */ | 1528 | of the visible area fixed. */ |
@@ -1526,6 +1551,7 @@ static iBool updateDocumentWidthRetainingScrollPosition_DocumentWidget_(iDocumen | |||
1526 | scrollTo_DocumentWidget_(d, mid_Rect(run->bounds).y, iTrue); | 1551 | scrollTo_DocumentWidget_(d, mid_Rect(run->bounds).y, iTrue); |
1527 | } | 1552 | } |
1528 | } | 1553 | } |
1554 | return iTrue; | ||
1529 | } | 1555 | } |
1530 | 1556 | ||
1531 | static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) { | 1557 | static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) { |
@@ -1533,6 +1559,7 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) | |||
1533 | if (equal_Command(cmd, "window.resized") || equal_Command(cmd, "font.changed")) { | 1559 | if (equal_Command(cmd, "window.resized") || equal_Command(cmd, "font.changed")) { |
1534 | /* Alt/Option key may be involved in window size changes. */ | 1560 | /* Alt/Option key may be involved in window size changes. */ |
1535 | iChangeFlags(d->flags, showLinkNumbers_DocumentWidgetFlag, iFalse); | 1561 | iChangeFlags(d->flags, showLinkNumbers_DocumentWidgetFlag, iFalse); |
1562 | d->phoneToolbar = findWidget_App("toolbar"); | ||
1536 | const iBool keepCenter = equal_Command(cmd, "font.changed"); | 1563 | const iBool keepCenter = equal_Command(cmd, "font.changed"); |
1537 | updateDocumentWidthRetainingScrollPosition_DocumentWidget_(d, keepCenter); | 1564 | updateDocumentWidthRetainingScrollPosition_DocumentWidget_(d, keepCenter); |
1538 | updateSideIconBuf_DocumentWidget_(d); | 1565 | updateSideIconBuf_DocumentWidget_(d); |
@@ -2361,36 +2388,16 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e | |||
2361 | } | 2388 | } |
2362 | } | 2389 | } |
2363 | else if (ev->type == SDL_MOUSEWHEEL && isHover_Widget(w)) { | 2390 | else if (ev->type == SDL_MOUSEWHEEL && isHover_Widget(w)) { |
2364 | /* TODO: Maybe clean this up a bit? Wheel events are used for scrolling | ||
2365 | but they are calculated differently based on device/mouse/trackpad. */ | ||
2366 | const iInt2 mouseCoord = mouseCoord_Window(get_Window()); | 2391 | const iInt2 mouseCoord = mouseCoord_Window(get_Window()); |
2367 | if (isPerPixel_MouseWheelEvent(&ev->wheel)) { | 2392 | if (isPerPixel_MouseWheelEvent(&ev->wheel)) { |
2368 | stop_Anim(&d->scrollY); | 2393 | stop_Anim(&d->scrollY); |
2369 | iInt2 wheel = init_I2(ev->wheel.x, ev->wheel.y); | 2394 | iInt2 wheel = init_I2(ev->wheel.x, ev->wheel.y); |
2370 | //# if defined (iPlatformAppleMobile) | ||
2371 | // wheel.x = -wheel.x; | ||
2372 | //# else | ||
2373 | // /* Wheel mounts are in points. */ | ||
2374 | // mulfv_I2(&wheel, get_Window()->pixelRatio); | ||
2375 | // /* Only scroll on one axis at a time. */ | ||
2376 | // if (iAbs(wheel.x) > iAbs(wheel.y)) { | ||
2377 | // wheel.y = 0; | ||
2378 | // } | ||
2379 | // else { | ||
2380 | // wheel.x = 0; | ||
2381 | // } | ||
2382 | //# endif | ||
2383 | scroll_DocumentWidget_(d, -wheel.y); | 2395 | scroll_DocumentWidget_(d, -wheel.y); |
2384 | scrollWideBlock_DocumentWidget_(d, mouseCoord, -wheel.x, 0); | 2396 | scrollWideBlock_DocumentWidget_(d, mouseCoord, -wheel.x, 0); |
2385 | } | 2397 | } |
2386 | else { | 2398 | else { |
2387 | /* Traditional mouse wheel. */ | 2399 | /* Traditional mouse wheel. */ |
2388 | //#if defined (iPlatformApple) | ||
2389 | // /* Disregard wheel acceleration applied by the OS. */ | ||
2390 | // const int amount = iSign(ev->wheel.y); | ||
2391 | //#else | ||
2392 | const int amount = ev->wheel.y; | 2400 | const int amount = ev->wheel.y; |
2393 | //#endif | ||
2394 | if (keyMods_Sym(modState_Keys()) == KMOD_PRIMARY) { | 2401 | if (keyMods_Sym(modState_Keys()) == KMOD_PRIMARY) { |
2395 | postCommandf_App("zoom.delta arg:%d", amount > 0 ? 10 : -10); | 2402 | postCommandf_App("zoom.delta arg:%d", amount > 0 ? 10 : -10); |
2396 | return iTrue; | 2403 | return iTrue; |
@@ -2513,7 +2520,7 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e | |||
2513 | d->contextLink->mediaType != download_GmRunMediaType) { | 2520 | d->contextLink->mediaType != download_GmRunMediaType) { |
2514 | if (isFinished_GmRequest(mediaReq->req)) { | 2521 | if (isFinished_GmRequest(mediaReq->req)) { |
2515 | pushBack_Array(&items, | 2522 | pushBack_Array(&items, |
2516 | &(iMenuItem){ download_Icon " Save to Downloads", | 2523 | &(iMenuItem){ download_Icon " " saveToDownloads_Label, |
2517 | 0, | 2524 | 0, |
2518 | 0, | 2525 | 0, |
2519 | format_CStr("document.media.save link:%u", | 2526 | format_CStr("document.media.save link:%u", |
@@ -2558,7 +2565,7 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e | |||
2558 | &items, | 2565 | &items, |
2559 | (iMenuItem[]){ | 2566 | (iMenuItem[]){ |
2560 | { "Copy Page Source", 'c', KMOD_PRIMARY, "copy" }, | 2567 | { "Copy Page Source", 'c', KMOD_PRIMARY, "copy" }, |
2561 | { download_Icon " Save to Downloads", SDLK_s, KMOD_PRIMARY, "document.save" } }, | 2568 | { download_Icon " " saveToDownloads_Label, SDLK_s, KMOD_PRIMARY, "document.save" } }, |
2562 | 2); | 2569 | 2); |
2563 | } | 2570 | } |
2564 | } | 2571 | } |
diff --git a/src/ui/util.c b/src/ui/util.c index 8fbe5d41..d68ae738 100644 --- a/src/ui/util.c +++ b/src/ui/util.c | |||
@@ -986,7 +986,6 @@ static iBool isTwoColumnPage_(iWidget *d) { | |||
986 | 986 | ||
987 | static iBool isOmittedPref_(const iString *id) { | 987 | static iBool isOmittedPref_(const iString *id) { |
988 | static const char *omittedPrefs[] = { | 988 | static const char *omittedPrefs[] = { |
989 | "prefs.downloads", | ||
990 | "prefs.smoothscroll", | 989 | "prefs.smoothscroll", |
991 | "prefs.imageloadscroll", | 990 | "prefs.imageloadscroll", |
992 | "prefs.retainwindow", | 991 | "prefs.retainwindow", |
@@ -1812,6 +1811,10 @@ iWidget *makePreferences_Widget(void) { | |||
1812 | addChild_Widget(values, iClob(makeToggle_Widget("prefs.smoothscroll"))); | 1811 | addChild_Widget(values, iClob(makeToggle_Widget("prefs.smoothscroll"))); |
1813 | addChild_Widget(headings, iClob(makeHeading_Widget("Load image on scroll:"))); | 1812 | addChild_Widget(headings, iClob(makeHeading_Widget("Load image on scroll:"))); |
1814 | addChild_Widget(values, iClob(makeToggle_Widget("prefs.imageloadscroll"))); | 1813 | addChild_Widget(values, iClob(makeToggle_Widget("prefs.imageloadscroll"))); |
1814 | if (deviceType_App() == phone_AppDeviceType) { | ||
1815 | addChild_Widget(headings, iClob(makeHeading_Widget("Hide toolbar on scroll:"))); | ||
1816 | addChild_Widget(values, iClob(makeToggle_Widget("prefs.hidetoolbarscroll"))); | ||
1817 | } | ||
1815 | } | 1818 | } |
1816 | /* Window. */ { | 1819 | /* Window. */ { |
1817 | appendTwoColumnPage_(tabs, "Interface", '2', &headings, &values); | 1820 | appendTwoColumnPage_(tabs, "Interface", '2', &headings, &values); |
diff --git a/src/ui/widget.c b/src/ui/widget.c index 81853c2a..23891999 100644 --- a/src/ui/widget.c +++ b/src/ui/widget.c | |||
@@ -223,6 +223,9 @@ void setVisualOffset_Widget(iWidget *d, int value, uint32_t span, int animFlags) | |||
223 | setFlags_Widget(d, visualOffset_WidgetFlag, iTrue); | 223 | setFlags_Widget(d, visualOffset_WidgetFlag, iTrue); |
224 | if (span == 0) { | 224 | if (span == 0) { |
225 | init_Anim(&d->visualOffset, value); | 225 | init_Anim(&d->visualOffset, value); |
226 | if (value == 0) { | ||
227 | setFlags_Widget(d, visualOffset_WidgetFlag, iFalse); /* offset is being reset */ | ||
228 | } | ||
226 | } | 229 | } |
227 | else { | 230 | else { |
228 | setValue_Anim(&d->visualOffset, value, span); | 231 | setValue_Anim(&d->visualOffset, value, span); |
@@ -346,6 +349,9 @@ void arrange_Widget(iWidget *d) { | |||
346 | else if (d->flags & moveToParentRightEdge_WidgetFlag) { | 349 | else if (d->flags & moveToParentRightEdge_WidgetFlag) { |
347 | d->rect.pos.x = width_Rect(innerRect_Widget_(d->parent)) - width_Rect(d->rect); | 350 | d->rect.pos.x = width_Rect(innerRect_Widget_(d->parent)) - width_Rect(d->rect); |
348 | } | 351 | } |
352 | else if (d->flags & moveToParentBottomEdge_WidgetFlag) { | ||
353 | d->rect.pos.y = height_Rect(innerRect_Widget_(d->parent)) - height_Rect(d->rect); | ||
354 | } | ||
349 | else if (d->flags & centerHorizontal_WidgetFlag) { | 355 | else if (d->flags & centerHorizontal_WidgetFlag) { |
350 | centerHorizontal_Widget_(d); | 356 | centerHorizontal_Widget_(d); |
351 | } | 357 | } |
@@ -455,8 +461,12 @@ void arrange_Widget(iWidget *d) { | |||
455 | iForEach(ObjectList, i, d->children) { | 461 | iForEach(ObjectList, i, d->children) { |
456 | iWidget *child = as_Widget(i.object); | 462 | iWidget *child = as_Widget(i.object); |
457 | if (isArranged_Widget_(child) && ~child->flags & parentCannotResize_WidgetFlag) { | 463 | if (isArranged_Widget_(child) && ~child->flags & parentCannotResize_WidgetFlag) { |
458 | if (dirs.x) setWidth_Widget_(child, child->flags & unpadded_WidgetFlag ? unpaddedChildSize.x : childSize.x); | 464 | if (dirs.x) { |
459 | if (dirs.y) setHeight_Widget_(child, child->flags & unpadded_WidgetFlag ? unpaddedChildSize.y : childSize.y); | 465 | setWidth_Widget_(child, child->flags & unpadded_WidgetFlag ? unpaddedChildSize.x : childSize.x); |
466 | } | ||
467 | if (dirs.y && ~child->flags & parentCannotResizeHeight_WidgetFlag) { | ||
468 | setHeight_Widget_(child, child->flags & unpadded_WidgetFlag ? unpaddedChildSize.y : childSize.y); | ||
469 | } | ||
460 | } | 470 | } |
461 | } | 471 | } |
462 | } | 472 | } |
@@ -493,7 +503,8 @@ void arrange_Widget(iWidget *d) { | |||
493 | pos.y += child->rect.size.y; | 503 | pos.y += child->rect.size.y; |
494 | } | 504 | } |
495 | } | 505 | } |
496 | else if ((d->flags & resizeChildren_WidgetFlag) == resizeChildren_WidgetFlag) { | 506 | else if ((d->flags & resizeChildren_WidgetFlag) == resizeChildren_WidgetFlag && |
507 | ~child->flags & moveToParentBottomEdge_WidgetFlag) { | ||
497 | child->rect.pos = pos; | 508 | child->rect.pos = pos; |
498 | } | 509 | } |
499 | else if (d->flags & resizeWidthOfChildren_WidgetFlag) { | 510 | else if (d->flags & resizeWidthOfChildren_WidgetFlag) { |
@@ -522,7 +533,9 @@ void arrange_Widget(iWidget *d) { | |||
522 | iForEach(ObjectList, j, d->children) { | 533 | iForEach(ObjectList, j, d->children) { |
523 | iWidget *child = as_Widget(j.object); | 534 | iWidget *child = as_Widget(j.object); |
524 | if (child->flags & | 535 | if (child->flags & |
525 | (resizeToParentWidth_WidgetFlag | moveToParentLeftEdge_WidgetFlag | | 536 | (resizeToParentWidth_WidgetFlag | |
537 | moveToParentLeftEdge_WidgetFlag | | ||
538 | moveToParentBottomEdge_WidgetFlag | | ||
526 | moveToParentRightEdge_WidgetFlag)) { | 539 | moveToParentRightEdge_WidgetFlag)) { |
527 | arrange_Widget(child); | 540 | arrange_Widget(child); |
528 | } | 541 | } |
@@ -542,6 +555,10 @@ void arrange_Widget(iWidget *d) { | |||
542 | } | 555 | } |
543 | } | 556 | } |
544 | } | 557 | } |
558 | // if (d->flags & moveToParentBottomEdge_WidgetFlag) { | ||
559 | // /* TODO: Fix this: not DRY. See beginning of method. */ | ||
560 | // d->rect.pos.y = height_Rect(innerRect_Widget_(d->parent)) - height_Rect(d->rect); | ||
561 | // } | ||
545 | if (d->flags & centerHorizontal_WidgetFlag) { | 562 | if (d->flags & centerHorizontal_WidgetFlag) { |
546 | centerHorizontal_Widget_(d); | 563 | centerHorizontal_Widget_(d); |
547 | } | 564 | } |
@@ -574,6 +591,14 @@ iRect bounds_Widget(const iWidget *d) { | |||
574 | return bounds; | 591 | return bounds; |
575 | } | 592 | } |
576 | 593 | ||
594 | iRect boundsWithoutVisualOffset_Widget(const iWidget *d) { | ||
595 | iRect bounds = d->rect; | ||
596 | for (const iWidget *w = d->parent; w; w = w->parent) { | ||
597 | addv_I2(&bounds.pos, w->rect.pos); | ||
598 | } | ||
599 | return bounds; | ||
600 | } | ||
601 | |||
577 | iInt2 localCoord_Widget(const iWidget *d, iInt2 coord) { | 602 | iInt2 localCoord_Widget(const iWidget *d, iInt2 coord) { |
578 | for (const iWidget *w = d; w; w = w->parent) { | 603 | for (const iWidget *w = d; w; w = w->parent) { |
579 | subv_I2(&coord, w->rect.pos); | 604 | subv_I2(&coord, w->rect.pos); |
diff --git a/src/ui/widget.h b/src/ui/widget.h index 90ccac8e..ad7ce168 100644 --- a/src/ui/widget.h +++ b/src/ui/widget.h | |||
@@ -110,6 +110,8 @@ enum iWidgetFlag { | |||
110 | #define dragged_WidgetFlag iBit64(54) | 110 | #define dragged_WidgetFlag iBit64(54) |
111 | #define hittable_WidgetFlag iBit64(55) | 111 | #define hittable_WidgetFlag iBit64(55) |
112 | #define safePadding_WidgetFlag iBit64(56) /* padded using safe area insets */ | 112 | #define safePadding_WidgetFlag iBit64(56) /* padded using safe area insets */ |
113 | #define moveToParentBottomEdge_WidgetFlag iBit64(57) | ||
114 | #define parentCannotResizeHeight_WidgetFlag iBit64(58) | ||
113 | 115 | ||
114 | enum iWidgetAddPos { | 116 | enum iWidgetAddPos { |
115 | back_WidgetAddPos, | 117 | back_WidgetAddPos, |
@@ -165,6 +167,7 @@ const iString *id_Widget (const iWidget *); | |||
165 | int64_t flags_Widget (const iWidget *); | 167 | int64_t flags_Widget (const iWidget *); |
166 | iRect bounds_Widget (const iWidget *); /* outer bounds */ | 168 | iRect bounds_Widget (const iWidget *); /* outer bounds */ |
167 | iRect innerBounds_Widget (const iWidget *); | 169 | iRect innerBounds_Widget (const iWidget *); |
170 | iRect boundsWithoutVisualOffset_Widget(const iWidget *); | ||
168 | iInt2 localCoord_Widget (const iWidget *, iInt2 coord); | 171 | iInt2 localCoord_Widget (const iWidget *, iInt2 coord); |
169 | iBool contains_Widget (const iWidget *, iInt2 coord); | 172 | iBool contains_Widget (const iWidget *, iInt2 coord); |
170 | iBool containsExpanded_Widget (const iWidget *, iInt2 coord, int expand); | 173 | iBool containsExpanded_Widget (const iWidget *, iInt2 coord, int expand); |
diff --git a/src/ui/window.c b/src/ui/window.c index 1249a0b4..bd2b1493 100644 --- a/src/ui/window.c +++ b/src/ui/window.c | |||
@@ -191,7 +191,7 @@ static const iMenuItem navMenuItems_[] = { | |||
191 | { add_Icon " New Tab", 't', KMOD_PRIMARY, "tabs.new" }, | 191 | { add_Icon " New Tab", 't', KMOD_PRIMARY, "tabs.new" }, |
192 | { "Open Location...", SDLK_l, KMOD_PRIMARY, "navigate.focus" }, | 192 | { "Open Location...", SDLK_l, KMOD_PRIMARY, "navigate.focus" }, |
193 | { "---", 0, 0, NULL }, | 193 | { "---", 0, 0, NULL }, |
194 | { download_Icon " Save to Downloads", SDLK_s, KMOD_PRIMARY, "document.save" }, | 194 | { download_Icon " " saveToDownloads_Label, SDLK_s, KMOD_PRIMARY, "document.save" }, |
195 | { "Copy Source Text", SDLK_c, KMOD_PRIMARY, "copy" }, | 195 | { "Copy Source Text", SDLK_c, KMOD_PRIMARY, "copy" }, |
196 | { "---", 0, 0, NULL }, | 196 | { "---", 0, 0, NULL }, |
197 | { leftHalf_Icon " Toggle Left Sidebar", SDLK_l, KMOD_PRIMARY | KMOD_SHIFT, "sidebar.toggle" }, | 197 | { leftHalf_Icon " Toggle Left Sidebar", SDLK_l, KMOD_PRIMARY | KMOD_SHIFT, "sidebar.toggle" }, |
@@ -259,7 +259,7 @@ static const iMenuItem fileMenuItems_[] = { | |||
259 | { "New Tab", SDLK_t, KMOD_PRIMARY, "tabs.new" }, | 259 | { "New Tab", SDLK_t, KMOD_PRIMARY, "tabs.new" }, |
260 | { "Open Location...", SDLK_l, KMOD_PRIMARY, "navigate.focus" }, | 260 | { "Open Location...", SDLK_l, KMOD_PRIMARY, "navigate.focus" }, |
261 | { "---", 0, 0, NULL }, | 261 | { "---", 0, 0, NULL }, |
262 | { "Save to Downloads", SDLK_s, KMOD_PRIMARY, "document.save" }, | 262 | { saveToDownloads_Label, SDLK_s, KMOD_PRIMARY, "document.save" }, |
263 | }; | 263 | }; |
264 | 264 | ||
265 | static const iMenuItem editMenuItems_[] = { | 265 | static const iMenuItem editMenuItems_[] = { |
@@ -576,7 +576,9 @@ static iBool handleNavBarCommands_(iWidget *navBar, const char *cmd) { | |||
576 | if (isPhone) { | 576 | if (isPhone) { |
577 | static const char *buttons[] = { "navbar.back", "navbar.forward", "navbar.sidebar", | 577 | static const char *buttons[] = { "navbar.back", "navbar.forward", "navbar.sidebar", |
578 | "navbar.ident", "navbar.home", "navbar.menu" }; | 578 | "navbar.ident", "navbar.home", "navbar.menu" }; |
579 | setFlags_Widget(findWidget_App("toolbar"), hidden_WidgetFlag, isLandscape_App()); | 579 | iWidget *toolBar = findWidget_App("toolbar"); |
580 | setVisualOffset_Widget(toolBar, 0, 0, 0); | ||
581 | setFlags_Widget(toolBar, hidden_WidgetFlag, isLandscape_App()); | ||
580 | iForIndices(i, buttons) { | 582 | iForIndices(i, buttons) { |
581 | iLabelWidget *btn = findChild_Widget(navBar, buttons[i]); | 583 | iLabelWidget *btn = findChild_Widget(navBar, buttons[i]); |
582 | setFlags_Widget(as_Widget(btn), hidden_WidgetFlag, isPortrait_App()); | 584 | setFlags_Widget(as_Widget(btn), hidden_WidgetFlag, isPortrait_App()); |
@@ -936,7 +938,6 @@ static void setupUserInterface_Window(iWindow *d) { | |||
936 | setBackgroundColor_Widget(winBar, uiBackground_ColorId); | 938 | setBackgroundColor_Widget(winBar, uiBackground_ColorId); |
937 | } | 939 | } |
938 | #endif | 940 | #endif |
939 | |||
940 | /* Navigation bar. */ { | 941 | /* Navigation bar. */ { |
941 | iWidget *navBar = new_Widget(); | 942 | iWidget *navBar = new_Widget(); |
942 | setId_Widget(navBar, "navbar"); | 943 | setId_Widget(navBar, "navbar"); |
@@ -1119,8 +1120,9 @@ static void setupUserInterface_Window(iWindow *d) { | |||
1119 | setBackgroundColor_Widget(searchBar, uiBackground_ColorId); | 1120 | setBackgroundColor_Widget(searchBar, uiBackground_ColorId); |
1120 | setCommandHandler_Widget(searchBar, handleSearchBarCommands_); | 1121 | setCommandHandler_Widget(searchBar, handleSearchBarCommands_); |
1121 | addChildFlags_Widget( | 1122 | addChildFlags_Widget( |
1122 | searchBar, iClob(new_LabelWidget(magnifyingGlass_Icon " Text", NULL)), frameless_WidgetFlag); | 1123 | searchBar, iClob(new_LabelWidget(magnifyingGlass_Icon, NULL)), frameless_WidgetFlag); |
1123 | iInputWidget *input = new_InputWidget(0); | 1124 | iInputWidget *input = new_InputWidget(0); |
1125 | setHint_InputWidget(input, "Find text on page"); | ||
1124 | setSelectAllOnFocus_InputWidget(input, iTrue); | 1126 | setSelectAllOnFocus_InputWidget(input, iTrue); |
1125 | setEatEscape_InputWidget(input, iFalse); /* unfocus and close with one keypress */ | 1127 | setEatEscape_InputWidget(input, iFalse); /* unfocus and close with one keypress */ |
1126 | setId_Widget(addChildFlags_Widget(searchBar, iClob(input), expand_WidgetFlag), | 1128 | setId_Widget(addChildFlags_Widget(searchBar, iClob(input), expand_WidgetFlag), |
@@ -1133,10 +1135,12 @@ static void setupUserInterface_Window(iWindow *d) { | |||
1133 | /* Bottom toolbar. */ | 1135 | /* Bottom toolbar. */ |
1134 | if (isPhone_iOS()) { | 1136 | if (isPhone_iOS()) { |
1135 | iWidget *toolBar = new_Widget(); | 1137 | iWidget *toolBar = new_Widget(); |
1136 | addChild_Widget(div, iClob(toolBar)); | 1138 | addChild_Widget(d->root, iClob(toolBar)); |
1137 | setId_Widget(toolBar, "toolbar"); | 1139 | setId_Widget(toolBar, "toolbar"); |
1138 | setCommandHandler_Widget(toolBar, handleToolBarCommands_); | 1140 | setCommandHandler_Widget(toolBar, handleToolBarCommands_); |
1139 | setFlags_Widget(toolBar, collapse_WidgetFlag | resizeWidthOfChildren_WidgetFlag | | 1141 | setFlags_Widget(toolBar, moveToParentBottomEdge_WidgetFlag | |
1142 | parentCannotResizeHeight_WidgetFlag | | ||
1143 | resizeWidthOfChildren_WidgetFlag | | ||
1140 | arrangeHeight_WidgetFlag | arrangeHorizontal_WidgetFlag, iTrue); | 1144 | arrangeHeight_WidgetFlag | arrangeHorizontal_WidgetFlag, iTrue); |
1141 | setBackgroundColor_Widget(toolBar, tmBannerBackground_ColorId); | 1145 | setBackgroundColor_Widget(toolBar, tmBannerBackground_ColorId); |
1142 | addChildFlags_Widget(toolBar, iClob(newLargeIcon_LabelWidget("\U0001f870", "navigate.back")), frameless_WidgetFlag); | 1146 | addChildFlags_Widget(toolBar, iClob(newLargeIcon_LabelWidget("\U0001f870", "navigate.back")), frameless_WidgetFlag); |
@@ -1214,6 +1218,21 @@ static void setupUserInterface_Window(iWindow *d) { | |||
1214 | updateMetrics_Window_(d); | 1218 | updateMetrics_Window_(d); |
1215 | } | 1219 | } |
1216 | 1220 | ||
1221 | void showToolbars_Window(iWindow *d, iBool show) { | ||
1222 | if (isLandscape_App()) return; | ||
1223 | iWidget *toolBar = findChild_Widget(d->root, "toolbar"); | ||
1224 | if (!toolBar) return; | ||
1225 | const int height = rootSize_Window(d).y - top_Rect(boundsWithoutVisualOffset_Widget(toolBar)); | ||
1226 | if (show && !isVisible_Widget(toolBar)) { | ||
1227 | setFlags_Widget(toolBar, hidden_WidgetFlag, iFalse); | ||
1228 | setVisualOffset_Widget(toolBar, 0, 200, easeOut_AnimFlag); | ||
1229 | } | ||
1230 | else if (!show && isVisible_Widget(toolBar)) { | ||
1231 | setFlags_Widget(toolBar, hidden_WidgetFlag, iTrue); | ||
1232 | setVisualOffset_Widget(toolBar, height, 200, easeOut_AnimFlag); | ||
1233 | } | ||
1234 | } | ||
1235 | |||
1217 | static void updateRootSize_Window_(iWindow *d, iBool notifyAlways) { | 1236 | static void updateRootSize_Window_(iWindow *d, iBool notifyAlways) { |
1218 | iInt2 *size = &d->root->rect.size; | 1237 | iInt2 *size = &d->root->rect.size; |
1219 | const iInt2 oldSize = *size; | 1238 | const iInt2 oldSize = *size; |
diff --git a/src/ui/window.h b/src/ui/window.h index cd2e3814..7303acb2 100644 --- a/src/ui/window.h +++ b/src/ui/window.h | |||
@@ -91,6 +91,7 @@ void setCursor_Window (iWindow *, int cursor); | |||
91 | void setSnap_Window (iWindow *, int snapMode); | 91 | void setSnap_Window (iWindow *, int snapMode); |
92 | void setKeyboardHeight_Window(iWindow *, int height); | 92 | void setKeyboardHeight_Window(iWindow *, int height); |
93 | void dismissPortraitPhoneSidebars_Window (iWindow *); | 93 | void dismissPortraitPhoneSidebars_Window (iWindow *); |
94 | void showToolbars_Window (iWindow *, iBool show); | ||
94 | iBool postContextClick_Window (iWindow *, const SDL_MouseButtonEvent *); | 95 | iBool postContextClick_Window (iWindow *, const SDL_MouseButtonEvent *); |
95 | 96 | ||
96 | uint32_t id_Window (const iWindow *); | 97 | uint32_t id_Window (const iWindow *); |