summaryrefslogtreecommitdiff
path: root/ios
diff options
context:
space:
mode:
authorJon Nermut <jon.nermut@gmail.com>2018-01-23 15:18:42 +1100
committerjan iversen <jani@libreoffice.org>2018-01-23 10:56:50 +0100
commit810dfda5556c5e0f0cc65f01c9634996951fd3e5 (patch)
treeac9f0833216ddef74977f0fef60090fb1f9a31bd /ios
parent91b4e4531621b7afb2dbab1a8aa62c92da66951a (diff)
iOS: implement tabs for spreadsheets
Change-Id: I210d68f013e56efd90da004891b872434ce65f68 Reviewed-on: https://gerrit.libreoffice.org/48368 Reviewed-by: jan iversen <jani@libreoffice.org> Tested-by: jan iversen <jani@libreoffice.org>
Diffstat (limited to 'ios')
-rw-r--r--ios/LibreOfficeLight/LibreOfficeLight.xcodeproj/project.pbxproj8
-rw-r--r--ios/LibreOfficeLight/LibreOfficeLight/ButtonScrollView.swift145
-rwxr-xr-xios/LibreOfficeLight/LibreOfficeLight/DocumentController.swift39
-rw-r--r--ios/LibreOfficeLight/LibreOfficeLight/LOKit/DocumentHolder.swift14
-rw-r--r--ios/LibreOfficeLight/LibreOfficeLight/UIViewExtensions.swift74
-rwxr-xr-xios/LibreOfficeLight/LibreOfficeLight/en.lproj/Main.storyboard6
6 files changed, 281 insertions, 5 deletions
diff --git a/ios/LibreOfficeLight/LibreOfficeLight.xcodeproj/project.pbxproj b/ios/LibreOfficeLight/LibreOfficeLight.xcodeproj/project.pbxproj
index 315d4d18151b..4897f40a1641 100644
--- a/ios/LibreOfficeLight/LibreOfficeLight.xcodeproj/project.pbxproj
+++ b/ios/LibreOfficeLight/LibreOfficeLight.xcodeproj/project.pbxproj
@@ -35,6 +35,8 @@
39EF4E2F1FA500C9001914AC /* PropertiesController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39EF4E2E1FA500C9001914AC /* PropertiesController.swift */; };
FC31D01E2012F65500E7F402 /* DocumentHolder.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC31D01D2012F65500E7F402 /* DocumentHolder.swift */; };
FC31D0202012F6D300E7F402 /* RenderCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC31D01F2012F6D300E7F402 /* RenderCache.swift */; };
+ FC31D02B2013500E00E7F402 /* ButtonScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC31D02A2013500E00E7F402 /* ButtonScrollView.swift */; };
+ FC31D02D2015DE1700E7F402 /* UIViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC31D02C2015DE1700E7F402 /* UIViewExtensions.swift */; };
FCAB1CB82009DB6900F1CC34 /* DocumentOverlaysView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCAB1CB72009DB6900F1CC34 /* DocumentOverlaysView.swift */; };
FCC2E3FA2004A01500CEB504 /* Document.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCC2E3F62004A01400CEB504 /* Document.swift */; };
FCC2E3FC2004A01500CEB504 /* LibreOfficeKitWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCC2E3F82004A01400CEB504 /* LibreOfficeKitWrapper.swift */; };
@@ -87,6 +89,8 @@
FC31D0132012EE4A00E7F402 /* LibreOfficeKitTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LibreOfficeKitTypes.h; sourceTree = "<group>"; };
FC31D01D2012F65500E7F402 /* DocumentHolder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DocumentHolder.swift; sourceTree = "<group>"; };
FC31D01F2012F6D300E7F402 /* RenderCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RenderCache.swift; sourceTree = "<group>"; };
+ FC31D02A2013500E00E7F402 /* ButtonScrollView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonScrollView.swift; sourceTree = "<group>"; };
+ FC31D02C2015DE1700E7F402 /* UIViewExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIViewExtensions.swift; sourceTree = "<group>"; };
FCAB1CB72009DB6900F1CC34 /* DocumentOverlaysView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DocumentOverlaysView.swift; sourceTree = "<group>"; };
FCC2E3F62004A01400CEB504 /* Document.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Document.swift; sourceTree = "<group>"; };
FCC2E3F82004A01400CEB504 /* LibreOfficeKitWrapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LibreOfficeKitWrapper.swift; sourceTree = "<group>"; };
@@ -172,11 +176,13 @@
39EE81531FA644E800B73AB8 /* Info.plist */,
39503A6F1F94C4AC00F19C78 /* lokit-Bridging-Header.h */,
397E08FD1E597BD8001374E0 /* AppDelegate.swift */,
+ FC31D02A2013500E00E7F402 /* ButtonScrollView.swift */,
3992D8591E5B762A00BEA987 /* DocumentController.swift */,
FCAB1CB72009DB6900F1CC34 /* DocumentOverlaysView.swift */,
FCC2E3FE2004B59B00CEB504 /* DocumentTiledView.swift */,
39284DB21FA5F207006F43E4 /* DocumentActions.swift */,
39EF4E2E1FA500C9001914AC /* PropertiesController.swift */,
+ FC31D02C2015DE1700E7F402 /* UIViewExtensions.swift */,
392ED9B21E5E4B03005C8435 /* ViewPrintManager.swift */,
399648461E5B87DC00E73E83 /* ViewProperties.swift */,
397E09011E597BD8001374E0 /* Main.storyboard */,
@@ -341,8 +347,10 @@
3992D85A1E5B762A00BEA987 /* DocumentController.swift in Sources */,
FCC2E3FD2004A01500CEB504 /* LOKitThread.swift in Sources */,
397E08FE1E597BD8001374E0 /* AppDelegate.swift in Sources */,
+ FC31D02B2013500E00E7F402 /* ButtonScrollView.swift in Sources */,
FCC2E3FA2004A01500CEB504 /* Document.swift in Sources */,
FCC2E3FF2004B59B00CEB504 /* DocumentTiledView.swift in Sources */,
+ FC31D02D2015DE1700E7F402 /* UIViewExtensions.swift in Sources */,
FCC2E4052004B74000CEB504 /* AsyncUtil.swift in Sources */,
39EF4E2F1FA500C9001914AC /* PropertiesController.swift in Sources */,
);
diff --git a/ios/LibreOfficeLight/LibreOfficeLight/ButtonScrollView.swift b/ios/LibreOfficeLight/LibreOfficeLight/ButtonScrollView.swift
new file mode 100644
index 000000000000..279ad22123b6
--- /dev/null
+++ b/ios/LibreOfficeLight/LibreOfficeLight/ButtonScrollView.swift
@@ -0,0 +1,145 @@
+//
+// This file is part of the LibreOffice project.
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+//
+import UIKit
+
+/// Scrollable list of buttons.
+/// Kind of like a tab bar, but doesn't maintain or switch between views, just calls back on click
+open class ButtonScrollView: UIScrollView
+{
+ var buttonList: ButtonList? = nil
+
+ var buttonClickedCallback: ( (Int) -> () )? = nil
+
+ var selectedIndex: Int?
+ {
+ get {
+ return buttonList?.selectedIndex
+ }
+ set {
+ buttonList?.selectedIndex = selectedIndex
+ }
+ }
+
+ public override init(frame: CGRect)
+ {
+ super.init(frame: frame)
+ }
+
+ public required init?(coder aDecoder: NSCoder)
+ {
+ super.init(coder: aDecoder)
+ }
+
+ public func setButtonLabels(labels: [String])
+ {
+ if let bl = buttonList
+ {
+ bl.removeFromSuperview()
+ }
+ let bl = ButtonList(frame: CGRect(x:0, y:0, width: self.frame.width, height:44),
+ labels: labels,
+ owner: self)
+ self.addSubview(bl)
+ self.contentSize = bl.frame.size
+ self.buttonList = bl
+ }
+}
+
+/// Horizontally layed out buttons, living within the owned scroll view
+open class ButtonList: UIView
+{
+ let labels: [String]
+ let gap: CGFloat = 10.0
+ let topGap: CGFloat = 8
+ weak var owner: ButtonScrollView? = nil
+
+ var buttonBackground = UIColor(white: 0.6, alpha: 1)
+ var selectedButtonBackground = UIColor.white
+
+ var selectedIndex: Int? = 0
+ {
+ didSet {
+ runOnMain {
+ self.highlightSelectedIndex()
+ }
+ }
+ }
+
+ public init(frame: CGRect, labels: [String], owner: ButtonScrollView)
+ {
+ self.labels = labels
+ self.owner = owner
+ super.init(frame: frame)
+ self.backgroundColor = UIColor(white: 0.9, alpha: 1)
+
+ var idx = 0
+ for label in labels
+ {
+ let b = UIButton(type: .custom)
+ b.setTitle(label, for: .normal)
+ b.backgroundColor = buttonBackground
+ b.contentEdgeInsets = UIEdgeInsets(top: 4, left: 4, bottom: 4, right: 4)
+ b.layer.cornerRadius = 4
+ b.tag = idx
+ b.addTarget(self, action: #selector(buttonTapped), for: UIControlEvents.touchUpInside)
+ self.addSubview(b)
+ idx += 1
+ }
+ self.layoutSubviews()
+ }
+
+ @objc func buttonTapped(sender: UIButton, forEvent event: UIEvent)
+ {
+ let idx = sender.tag
+ owner?.buttonClickedCallback?(idx)
+ self.selectedIndex = idx
+ }
+
+ public required init?(coder aDecoder: NSCoder)
+ {
+ fatalError("init(coder:) has not been implemented")
+ }
+
+ public var buttons: [UIButton]
+ {
+ return self.subviews.flatMap({ $0 as? UIButton })
+ }
+
+ open override func layoutSubviews()
+ {
+
+ var x: CGFloat = gap
+ for button in buttons
+ {
+ button.sizeToFit()
+ let s = button.frame.size
+ button.frame = CGRect(x: x, y: topGap, width: s.width, height: s.height)
+ x = x + (s.width + gap)
+ }
+ highlightSelectedIndex()
+ self.frame = CGRect(x:0, y: 0, width: x, height: self.frame.height)
+ }
+
+ open func highlightSelectedIndex()
+ {
+ for (index, button) in buttons.enumerated()
+ {
+ if (index == selectedIndex)
+ {
+ button.backgroundColor = selectedButtonBackground
+ button.setTitleColor(.black, for: .normal)
+ }
+ else
+ {
+ button.backgroundColor = buttonBackground
+ button.setTitleColor(.white, for: .normal)
+ }
+
+ }
+ }
+}
diff --git a/ios/LibreOfficeLight/LibreOfficeLight/DocumentController.swift b/ios/LibreOfficeLight/LibreOfficeLight/DocumentController.swift
index 3decec85410a..88c3ccdcd67e 100755
--- a/ios/LibreOfficeLight/LibreOfficeLight/DocumentController.swift
+++ b/ios/LibreOfficeLight/LibreOfficeLight/DocumentController.swift
@@ -26,10 +26,13 @@ class DocumentController: UIViewController, MenuDelegate, UIDocumentBrowserViewC
// holds known document types
var KnownDocumentTypes : [String] = []
+ var zeroInsets: UIEdgeInsets = .zero
+
@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var mask: UIView!
@IBOutlet weak var progressBar: UIProgressView!
@IBOutlet weak var searchBar: UISearchBar!
+ @IBOutlet weak var buttonScrollView: ButtonScrollView!
deinit
{
@@ -61,10 +64,12 @@ class DocumentController: UIViewController, MenuDelegate, UIDocumentBrowserViewC
override func viewDidAppear(_ animated: Bool)
{
super.viewDidAppear(animated)
- //let res = Bundle.main.url(forResource: "example", withExtension: "odt")
- //let res = Bundle.main.url(forResource: "example2", withExtension: "docx")
- let res = Bundle.main.url(forResource: "testdata/1", withExtension: "pptx")
+ // Always load the 'welcome' file, as per the android app
+ let res = Bundle.main.url(forResource: "example", withExtension: "odt")
+
+ // uncomment for test data in resources until the doc picker works properly
+ //let res = Bundle.main.url(forResource: "testdata/2", withExtension: "xlsx")
if let exampleDoc = res
{
@@ -416,6 +421,30 @@ class DocumentController: UIViewController, MenuDelegate, UIDocumentBrowserViewC
docView.addSubview(overlay)
self.documentOverlaysView = overlay
+ // button view - used for spreadsheet tabs
+ if doc.isSpeadsheet
+ {
+ buttonScrollView.isHidden = false
+ buttonScrollView.setButtonLabels(labels: doc.partNames)
+ buttonScrollView.buttonClickedCallback = {
+ [weak self] index in
+ self?.document?.async {
+ $0.setPart(nPart: Int32(index))
+ runOnMain {
+ self?.documentView?.setNeedsDisplay()
+ }
+ }
+ }
+ // make room for the scroll view
+ zeroInsets = UIEdgeInsets(top: 0, left: 0, bottom: buttonScrollView.height, right: 0)
+ }
+ else
+ {
+ zeroInsets = .zero
+ buttonScrollView.isHidden = true
+ }
+ scrollView.contentInset = zeroInsets
+
// debugging view borders
/*
self.scrollView.layer.borderColor = UIColor.red.cgColor
@@ -563,7 +592,7 @@ extension DocumentController
@objc func keyboardWillHide(notification: NSNotification)
{
print("keyboardWillHide")
- scrollView.contentInset = .zero
- scrollView.scrollIndicatorInsets = .zero
+ scrollView.contentInset = zeroInsets
+ scrollView.scrollIndicatorInsets = zeroInsets
}
}
diff --git a/ios/LibreOfficeLight/LibreOfficeLight/LOKit/DocumentHolder.swift b/ios/LibreOfficeLight/LibreOfficeLight/LOKit/DocumentHolder.swift
index a380cc45edd0..c0760b8614a4 100644
--- a/ios/LibreOfficeLight/LibreOfficeLight/LOKit/DocumentHolder.swift
+++ b/ios/LibreOfficeLight/LibreOfficeLight/LOKit/DocumentHolder.swift
@@ -26,17 +26,31 @@ public class DocumentHolder
public let documentSize: CGSize
public let views: Int32
public let parts: Int32
+ public let partNames: [String]
public private(set) var currentPart: Int32 = 0
init(doc: Document)
{
self.doc = doc
+
+ // we go and get a bunch of document properties and store them in properties
+ // this allows easy access to these without threading issues
+ // when we get to editing they will have to be invalidated
+
self.documentType = doc.getDocumentType()
documentSize = doc.getDocumentSizeAsCGSize()
views = doc.getViewsCount()
parts = doc.getParts()
+ var partNames = [String]()
+ for i in 0..<parts
+ {
+ let n = doc.getPartName(nPart: i) ?? ""
+ partNames.append(n)
+ }
+ self.partNames = partNames
+
doc.registerCallback() {
[weak self] typ, payload in
self?.onDocumentEvent(type: typ, payload: payload)
diff --git a/ios/LibreOfficeLight/LibreOfficeLight/UIViewExtensions.swift b/ios/LibreOfficeLight/LibreOfficeLight/UIViewExtensions.swift
new file mode 100644
index 000000000000..1c0322331e51
--- /dev/null
+++ b/ios/LibreOfficeLight/LibreOfficeLight/UIViewExtensions.swift
@@ -0,0 +1,74 @@
+//
+// This file is part of the LibreOffice project.
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+//
+
+import UIKit
+
+public extension UIView
+{
+ public var height: CGFloat
+ {
+ get
+ {
+ return frame.size.height
+ }
+ set
+ {
+ frame.size.height = newValue
+ }
+ }
+
+ public var size: CGSize
+ {
+ get
+ {
+ return frame.size
+ }
+ set
+ {
+ width = newValue.width
+ height = newValue.height
+ }
+ }
+
+ public var width: CGFloat
+ {
+ get
+ {
+ return frame.size.width
+ }
+ set
+ {
+ frame.size.width = newValue
+ }
+ }
+
+ public var x: CGFloat
+ {
+ get
+ {
+ return frame.origin.x
+ }
+ set
+ {
+ frame.origin.x = newValue
+ }
+ }
+
+
+ public var y: CGFloat
+ {
+ get
+ {
+ return frame.origin.y
+ }
+ set
+ {
+ frame.origin.y = newValue
+ }
+ }
+}
diff --git a/ios/LibreOfficeLight/LibreOfficeLight/en.lproj/Main.storyboard b/ios/LibreOfficeLight/LibreOfficeLight/en.lproj/Main.storyboard
index ccc91115c5e0..ffd5059d06a9 100755
--- a/ios/LibreOfficeLight/LibreOfficeLight/en.lproj/Main.storyboard
+++ b/ios/LibreOfficeLight/LibreOfficeLight/en.lproj/Main.storyboard
@@ -30,6 +30,11 @@
<outlet property="delegate" destination="vXZ-lx-hvc" id="mWv-AB-k2W"/>
</connections>
</scrollView>
+ <view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8HF-MM-fd0" userLabel="ButtonBar" customClass="ButtonScrollView" customModule="LibreOfficeLight" customModuleProvider="target">
+ <rect key="frame" x="0.0" y="980" width="768" height="44"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ </view>
<view opaque="NO" userInteractionEnabled="NO" alpha="0.5" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="URZ-zU-xtO" userLabel="Mask">
<rect key="frame" x="0.0" y="64" width="768" height="960"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
@@ -76,6 +81,7 @@
</navigationItem>
<simulatedToolbarMetrics key="simulatedBottomBarMetrics"/>
<connections>
+ <outlet property="buttonScrollView" destination="8HF-MM-fd0" id="Mlq-CV-p8N"/>
<outlet property="mask" destination="URZ-zU-xtO" id="pkw-v3-0gr"/>
<outlet property="progressBar" destination="hRJ-mR-Vnv" id="4lJ-kG-9SW"/>
<outlet property="scrollView" destination="cJ7-wO-9D1" id="U50-LO-plb"/>