Skip to content

Commit

Permalink
Merge pull request #10 from nhiroyasu/develop
Browse files Browse the repository at this point in the history
v1.5.0
  • Loading branch information
nhiroyasu authored Jun 4, 2022
2 parents b4652af + 721e4ec commit fbfd74b
Show file tree
Hide file tree
Showing 17 changed files with 400 additions and 87 deletions.
10 changes: 5 additions & 5 deletions slideover-for-macos.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -261,9 +261,9 @@
4FBCEB0827C1FA5600BCF88C /* SlideOverWindowController.swift */,
4FBCEAFB27C1FA3300BCF88C /* SlideOverViewController.swift */,
4FBE65852821601D0001FB4E /* SlideOverView.swift */,
4FBCEAFF27C1FA3400BCF88C /* Main.storyboard */,
4FBE6581282157E50001FB4E /* SlideOverWindow.swift */,
4FBE658328215A540001FB4E /* SlideOverToolbar.swift */,
4FBCEAFF27C1FA3400BCF88C /* Main.storyboard */,
);
path = UI;
sourceTree = "<group>";
Expand Down Expand Up @@ -709,7 +709,7 @@
CODE_SIGN_ENTITLEMENTS = "slideover-for-macos/slideover_for_macos.entitlements";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 14;
CURRENT_PROJECT_VERSION = 15;
DEVELOPMENT_TEAM = 2CMV7D36JC;
ENABLE_HARDENED_RUNTIME = YES;
GENERATE_INFOPLIST_FILE = YES;
Expand All @@ -724,7 +724,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 1.4.0;
MARKETING_VERSION = 1.5.0;
PRODUCT_BUNDLE_IDENTIFIER = "com.nhiro1109.${BUNDLE_ID_PREFIX}slideover-for-macos";
PRODUCT_NAME = "${TARGET_NAME}";
SWIFT_EMIT_LOC_STRINGS = YES;
Expand All @@ -744,7 +744,7 @@
CODE_SIGN_ENTITLEMENTS = "slideover-for-macos/slideover_for_macos.entitlements";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 14;
CURRENT_PROJECT_VERSION = 15;
DEVELOPMENT_TEAM = 2CMV7D36JC;
ENABLE_HARDENED_RUNTIME = YES;
GENERATE_INFOPLIST_FILE = YES;
Expand All @@ -759,7 +759,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 1.4.0;
MARKETING_VERSION = 1.5.0;
PRODUCT_BUNDLE_IDENTIFIER = "com.nhiro1109.slideover-for-macos";
PRODUCT_NAME = "${DISPLAY_NAME_PREFIX}${TARGET_NAME}";
SWIFT_EMIT_LOC_STRINGS = YES;
Expand Down
12 changes: 12 additions & 0 deletions slideover-for-macos/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,16 @@ class AppDelegate: NSObject, NSApplicationDelegate {
@IBAction func didTapLicenseItem(_ sender: Any) {
notificationManager?.push(name: .openUrlForBrowser, param: "https://nhiro.notion.site/Fixture-in-Picture-License-10d29166c48d44bcba28e828afaaa667")
}

@IBAction func didTapZoomInItem(_ sender: Any) {
notificationManager?.push(name: .zoomInWebView, param: nil)
}

@IBAction func didTapZoomOutItem(_ sender: Any) {
notificationManager?.push(name: .zoomOutWebView, param: nil)
}

@IBAction func didTapZoomResetItem(_ sender: Any) {
notificationManager?.push(name: .zoomResetWebView, param: nil)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ protocol SlideOverWindowAction {
func didTapHideWindow()
func didTapHelp()
func didTapReappearButton()
func windowWillClose(size: NSSize?)
}

class SlideOverWindowActionImpl: SlideOverWindowAction {
Expand Down Expand Up @@ -77,4 +78,8 @@ class SlideOverWindowActionImpl: SlideOverWindowAction {
func didTapReappearButton() {
useCase.requestAppearWindow()
}

func windowWillClose(size: NSSize?) {
useCase.memorizeLatestWindowSize(size)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,14 @@ import QuartzCore

/// @mockable
protocol SlideOverWindowPresenter {
/// ウィンドウをtypeの位置に配置(サイズ,座標を修正)
func fixWindow(type: SlideOverKind)
func adjustWindow()
/// ウィンドウをtypeの位置に移動(座標を修正、サイズはそのまま)
func arrangeWindow(type: SlideOverKind)
/// 初期表示用arrange
func initialArrangeWindow(type: SlideOverKind, size: NSSize)
/// ウィンドウをマウスの位置によって配置(サイズ,座標を修正)
func fixWindowByMousePosition()
func reverseWindow()
func setInitialPage(url: URL?)
func loadWebPage(url: URL?)
Expand All @@ -20,6 +26,9 @@ protocol SlideOverWindowPresenter {
func resetTranslucentWindow()
func disappearWindow(completion: @escaping (Bool) -> Void)
func appearWindow(completion: @escaping (Bool) -> Void)
func zoomIn()
func zoomOut()
func resetZoom()
}

class SlideOverWindowPresenterImpl: SlideOverWindowPresenter {
Expand Down Expand Up @@ -49,14 +58,28 @@ class SlideOverWindowPresenterImpl: SlideOverWindowPresenter {
}
}

func adjustWindow() {
func fixWindowByMousePosition() {
restoreHiddenWindow()
output?.fixWindow { [weak self] window in
guard let self = self, let window = window else { return }
self.slideOverService.fixMovedWindow(for: window)
}
}

func arrangeWindow(type: SlideOverKind) {
output?.fixWindow { [weak self] window in
guard let self = self, let window = window else { return }
self.slideOverService.arrangeWindow(for: window, type: type)
}
}

func initialArrangeWindow(type: SlideOverKind, size: NSSize) {
output?.fixWindow { [weak self] window in
guard let self = self, let window = window else { return }
self.slideOverService.arrangeWindow(for: window, windowSize: size, type: type)
}
}

func reverseWindow() {
restoreHiddenWindow()
output?.fixWindow { [weak self] window in
Expand Down Expand Up @@ -131,7 +154,7 @@ class SlideOverWindowPresenterImpl: SlideOverWindowPresenter {
var window = output
window?.windowWillResizeHandler = { [weak self] currentWindow, next in
let (nextSize, type) = handler(currentWindow.frame.size, next)
self?.slideOverService.arrangeWindowPosition(for: currentWindow, size: nextSize, type: type)
self?.slideOverService.arrangeWindowPosition(for: currentWindow, windowSize: nextSize, type: type)
return nextSize
}
}
Expand Down Expand Up @@ -178,9 +201,15 @@ class SlideOverWindowPresenterImpl: SlideOverWindowPresenter {
return
}

fixWindow(type: position)
restoreHiddenWindow()
completion(true)
output.fixWindow { [weak self] window in
guard let window = window else {
completion(false)
return
}
self?.slideOverService.arrangeWindow(for: window, type: position)
self?.restoreHiddenWindow()
completion(true)
}
}

func applyTranslucentWindow() {
Expand All @@ -196,4 +225,19 @@ class SlideOverWindowPresenterImpl: SlideOverWindowPresenter {
self.output?.contentView?.hideReappearLeftButton(completion: {})
self.output?.contentView?.hideReappearRightButton(completion: {})
}

func zoomIn() {
guard let webView = output?.contentView?.webView else { return }
webView.setMagnification(webView.magnification + 0.1, centeredAt: .zero)
}

func zoomOut() {
guard let webView = output?.contentView?.webView else { return }
webView.setMagnification(webView.magnification - 0.1, centeredAt: .zero)
}

func resetZoom() {
guard let webView = output?.contentView?.webView else { return }
webView.setMagnification(1.0, centeredAt: .zero)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ protocol SlideOverWindowUseCase {
func requestDisappearWindow()
func requestAppearWindow()
func showHelpPage()
func memorizeLatestWindowSize(_ size: NSSize?)
}

class SlideOverWindowInteractor: SlideOverWindowUseCase {
Expand Down Expand Up @@ -67,12 +68,15 @@ class SlideOverWindowInteractor: SlideOverWindowUseCase {
observeSearchFocusNotification()
observeHideWindowNotification()
observeMouseEvent()
observeZoomNotifications()
setWillMoveNotification()
setRightMouseUpSubject()
resizeWindow()
registerSwitchWindowVisibilityShortcutKey()

if let latestPosition = userSettingService.latestPosition {
if let latestPosition = userSettingService.latestPosition, let latestWindowSize = userSettingService.latestWindowSize {
presenter.initialArrangeWindow(type: latestPosition, size: latestWindowSize)
} else if let latestPosition = userSettingService.latestPosition {
presenter.fixWindow(type: latestPosition)
} else {
userSettingService.latestPosition = defaultSlideOverPosition
Expand Down Expand Up @@ -148,8 +152,8 @@ class SlideOverWindowInteractor: SlideOverWindowUseCase {

private func resizeWindow() {
presenter.setResizeHandler { [weak self] current, next in
guard let currentPosition = self?.userSettingService.latestPosition else { return (next, .right) }
return (currentPosition.state.computeResize(from: current, to: next), currentPosition)
guard let currentPosition = self?.userSettingService.latestPosition, let screen = NSScreen.main else { return (next, .right) }
return (currentPosition.state.computeResize(screenSize: screen.visibleFrame.size, from: current, to: next), currentPosition)
}
}

Expand All @@ -173,6 +177,10 @@ class SlideOverWindowInteractor: SlideOverWindowUseCase {
func showHelpPage() {
presenter.openBrowser(url: helpUrl)
}

func memorizeLatestWindowSize(_ size: NSSize?) {
userSettingService.latestWindowSize = size
}
}

extension SlideOverWindowInteractor {
Expand Down Expand Up @@ -205,7 +213,7 @@ extension SlideOverWindowInteractor {
.prefix(1)
.sink { [weak self] event in
guard let self = self else { return }
self.presenter.adjustWindow()
self.presenter.fixWindowByMousePosition()
self.state.isWindowHidden = false
}
}
Expand Down Expand Up @@ -287,4 +295,18 @@ extension SlideOverWindowInteractor {
self?.presenter.loadWebPage(url: url)
}
}

private func observeZoomNotifications() {
notificationManager.observe(name: .zoomInWebView) { [weak self] _ in
self?.presenter.zoomIn()
}

notificationManager.observe(name: .zoomOutWebView) { [weak self] _ in
self?.presenter.zoomOut()
}

notificationManager.observe(name: .zoomResetWebView) { [weak self] _ in
self?.presenter.resetZoom()
}
}
}
3 changes: 3 additions & 0 deletions slideover-for-macos/Service/NotificationManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ extension Notification.Name {
static let searchFocus = Notification.Name("searchFocus")
static let hideWindow = Notification.Name("hideWindow")
static let showFeaturePresent = Notification.Name("showFeaturePresent")
static let zoomInWebView = Notification.Name("zoomInWebView")
static let zoomOutWebView = Notification.Name("zoomOutWebView")
static let zoomResetWebView = Notification.Name("zoomResetWebView")
}

/// @mockable
Expand Down
32 changes: 20 additions & 12 deletions slideover-for-macos/Service/SlideOverComputable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ let hideOffsetSpace: CGFloat = 40.0
protocol SlideOverComputable {
func computeWindowRect(screenSize: CGSize, screenOffset: CGPoint) -> CGRect
func computeWindowPoint(windowSize: CGSize, screenSize: CGSize, screenOffset: CGPoint) -> CGPoint
func computeResize(from current: NSSize, to next: NSSize) -> NSSize
func computeResize(screenSize: CGSize, from current: NSSize, to next: NSSize) -> NSSize
}

class SlideOver {
Expand All @@ -33,7 +33,7 @@ class SlideOver {
return bestHeightSize
}

func computeResize(from current: NSSize, to next: NSSize) -> NSSize {
func computeResize(screenSize: CGSize, from current: NSSize, to next: NSSize) -> NSSize {
var resultWidth = next.width
if next.width > maxWidthSize {
resultWidth = maxWidthSize
Expand Down Expand Up @@ -101,6 +101,9 @@ class SlideOver {
class Rectangle {
let aspectRatio: CGFloat = 16.0 / 9.0
let minHeightSize: CGFloat = 384.0
let minWidthSize: CGFloat = 420.0
let maxHeightRatio: CGFloat = 3.0 / 4.0
let maxWidthRatio: CGFloat = 1.0 / 2.0
var minSize: CGSize {
CGSize(width: minHeightSize * aspectRatio, height: minHeightSize)
}
Expand All @@ -115,19 +118,24 @@ class SlideOver {
}
}

func computeResize(from current: NSSize, to next: NSSize) -> NSSize {
var resultSize = NSSize(width: 0, height: 0)
if current.width != next.width {
resultSize = NSSize(width: next.width, height: next.width / aspectRatio)
func computeResize(screenSize: CGSize, from current: NSSize, to next: NSSize) -> NSSize {
let maxHeightSize = screenSize.height * maxHeightRatio
let maxWidthSize = screenSize.width * maxWidthRatio
var width = next.width
var height = next.height
if width > maxWidthSize {
width = maxWidthSize
}
if current.height != next.height {
resultSize = NSSize(width: next.height * aspectRatio, height: next.height)
if width < minWidthSize {
width = minWidthSize
}
if resultSize.height < minHeightSize {
return minSize
} else {
return resultSize
if height > maxHeightSize {
height = maxHeightSize
}
if height < minHeightSize {
height = minHeightSize
}
return NSSize(width: width, height: height)
}
}

Expand Down
26 changes: 23 additions & 3 deletions slideover-for-macos/Service/SlideOverService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ protocol SlideOverService {
func fixWindow(for window: NSWindow, type: SlideOverKind)
func fixMovedWindow(for window: NSWindow)
func reverseMoveWindow(for window: NSWindow)
func arrangeWindowPosition(for window: NSWindow, size: NSSize, type: SlideOverKind)
func arrangeWindow(for window: NSWindow, type: SlideOverKind)
func arrangeWindow(for window: NSWindow, windowSize: NSSize, type: SlideOverKind)
func arrangeWindowPosition(for window: NSWindow, windowSize: NSSize, type: SlideOverKind)
func hideWindow(for window: NSWindow, type: SlideOverKind) -> Bool
}

Expand Down Expand Up @@ -103,9 +105,27 @@ class SlideOverServiceImpl: SlideOverService {
}
}

func arrangeWindowPosition(for window: NSWindow, size: NSSize, type: SlideOverKind) {
func arrangeWindow(for window: NSWindow, type: SlideOverKind) {
guard let screen = NSScreen.main else { return }
let windowPoint = type.state.computeWindowPoint(windowSize: size, screenSize: screen.visibleFrame.size, screenOffset: screen.visibleFrame.origin)
let windowPoint = type.state.computeWindowPoint(windowSize: window.frame.size, screenSize: screen.visibleFrame.size, screenOffset: screen.visibleFrame.origin)
let windowRect = NSRect(origin: windowPoint, size: window.frame.size)
DispatchQueue.main.async {
window.setFrame(windowRect, display: true, animate: true)
}
}

func arrangeWindow(for window: NSWindow, windowSize: NSSize, type: SlideOverKind) {
guard let screen = NSScreen.main else { return }
let windowPoint = type.state.computeWindowPoint(windowSize: windowSize, screenSize: screen.visibleFrame.size, screenOffset: screen.visibleFrame.origin)
let windowRect = NSRect(origin: windowPoint, size: windowSize)
DispatchQueue.main.async {
window.setFrame(windowRect, display: true, animate: true)
}
}

func arrangeWindowPosition(for window: NSWindow, windowSize: NSSize, type: SlideOverKind) {
guard let screen = NSScreen.main else { return }
let windowPoint = type.state.computeWindowPoint(windowSize: windowSize, screenSize: screen.visibleFrame.size, screenOffset: screen.visibleFrame.origin)
DispatchQueue.main.async {
window.setFrameOrigin(windowPoint)
}
Expand Down
Loading

0 comments on commit fbfd74b

Please sign in to comment.