feed
2024年11月07日, 編集履歴
macOS用EPUBリーダアプリ「Murasaki」のver. 2.5.1が出ました。
ver. 2.5.1での変更点は、
macOS 15 Sequoia対応のQuick Look Thumbnail機能拡張を追加
Quick Look Preview機能拡張を修正
Quick Look Thumbnail拡張機能の実装によって、macOS 15 Sequoia環境でEPUBのカバー画像をサムネイルとしてFinder等で表示できるようになりました。
Quick Look Preview拡張機能の修正について。EPUBの仕様的に必須となっている項目が抜けていたとき等、読み込みエラーになってプレビューできないようになっていました。あまつさえ、実装ミスにより、そのときにクラッシュしていました。クラッシュする不具合は修正し、メタデータが不備でもプレビューはできるように変更しました。
また、プレビューの読み込みデータサイズ制限のディフォルト値を5MBから10MBに拡張しました。
どうぞよろしく。
2024年10月24日, 編集履歴
macOS用ランチャアプリケーション「Keyknockr」の新しいヴァージョン2.0.1が出ました。
ver. 2.0.1の変更点は、
macOS 15 Sequoia環境において、「直前のアプリケーションに切り替え」アクション使用時に、標準的な「/Applications
」フォルダ以外にあるアプリケーションへの切り替えができない問題を修正
軽微な問題を修正
です。
また、このヴァージョンからは、macOS 15 Sequoia以降のみをサポートとします。どうぞよろしく。
2024年09月30日, 編集履歴
macOS用EPUBリーダアプリ「Murasaki」のver. 2.5が出ました。
ver. 2.5での変更点は、
macOS 15 Sequoia以降のみをサポート
UIの調整
macOS 15 Sequoiaに対応した新しいQuick Look拡張機能を実装
です。
新しいQuick Look拡張機能に関して、macOS 15 Sequoia以降は従来のQuick Lookプラグイン形式(.qlgenerator
)がサポートされなくなったので、Sequoia以降で動作する機能拡張形式(.appex
)で実装し直しました。
それに伴い、Quick Lookの動作設定を変更できるようにもなりました。
読み込みデータサイズ制限
デフォルトのコンテントサイズ
それぞれを、Murasaki本体の設定ウィンドウから変更できるようになっています。
読み込みデータサイズ制限は、Quick LookがEPUBデータを展開、プレヴューを構成していくなかで、全データを読み込むのではなく、設定したデータサイズで読み込みを打ち切ります。大きなデータサイズのEPUBの場合、プレヴュー構成に時間が掛かることがあるための制限となります(これまでは固定値でした)。
デフォルトのコンテントサイズは、Quick Lookプレヴューの初期ウィンドウサイズを設定できます。
また、新しい拡張機能形式はシステム設定から拡張機能の有効・無効を設定することができます。
どうぞよろしくお願いします。
2024年03月03日, 編集履歴
macOS用ランチャアプリケーション「CLCL」を全面的に作り直し、名称を「Keyknockr」へと変更しました(バージョン番号は継続)。
Keyknockr(旧CLCL)はCommandキーやShiftキーなどの修飾キーを連打することで、設定したアプリケーションやURLを開くことができるランチャアプリケーションです。
今回のバージョンアップにともない、従来のLite版・有料版販売モデルから、フリーミアムモデル(基本無料+サブスクリプションによる機能解放)へと移行し、配信場所はMac App Storeへ統一されました。
v2.0ではイチからSwift/SwiftUIを用いて再構築され、新しい特殊アクションとして、
が追加されました。
「実行中のアプリケーション」アクションは現在実行中の(Dockに表示される)アプリケーションの一覧メニューがポップアップされ、そこから当該アプリケーションをアクティブ化できます。
「ポップアップメニュー」アクションは事前に設定したアプリケーションやローカルファイル、URLの一覧メニューがポップアップされ、そこから起動、アクティブ化、開く操作が実行できます。
また、「ログイン時に起動」設定を追加したので、Keyknockrの設定画面からかんたんに起動設定を変更できるようになりました。
どうぞよろしく。
以前にCLCLをGumroadで購入されていた方へはKeyknockr v2.0機能解放版を提供しています。Gumroadのシステムを通してメールを送信しているので、ご確認ください。
2024年02月20日, 編集履歴
Table
の基本的な使い方は「SwiftUI Tableの使い方 」を参照。
macOSアプリにSwiftUIのTable
を組み込み、副ボタンクリック(右クリック)によるコンテキストメニューをつけた時、テーブル行として表現されているオブジェクトに対して何らかの操作を行うような場合を考える。たとえばリスト表示にしたFinderで、ファイルやフォルダを右クリックしたときにでるコンテキストメニューをイメージしてもらうと良い。
このときTableColumn
配下の要素やTableRow
に.contextMenu(menuItems:)
モディファイアをつけてしまいがちだが、macOSアプリのテーブルに対するコンテキストメニューの自然な挙動を実現するには、Table
自体に.contextMenu(forSelectionType:menu:primaryAction:)
モディファイアをつけなければならない。
テーブルの選択状態と操作対象
テーブル行をふつうにクリックした場合、行選択の状態となり、行全体にハイライトがつく。行を右クリックした場合、行の縁だけハイライトがつき、コンテキストメニューの起点、操作対象の状態になる。このふたつは別の状態である。選択範囲とコンテキストメニューの操作対象は重なる場合もあれば、異なる場合もある。
コンテキストメニューの操作対象は以下のようになる:
行を選択していない状態から右クリックした場合、操作対象は右クリックした行になる。
行を選択している状態から選択内 の行を右クリックした場合、操作対象は選択範囲の行になる。
行を選択している状態から選択外 の行を右クリックした場合、操作対象は右クリックした行のみ になる。
表内部の行がない余白部分を右クリックした場合、操作対象のオブジェクトはない(親オブジェクトや対象を必要としない処理になる)。
上図のコンテキストメニューの内容から操作対象が変わっていることが解る。
実装
以下のような実装が良いと思う。
import SwiftUI
import UniformTypeIdentifiers
struct Bookmark : Identifiable {
var id = UUID ()
var title : String
var url : URL
}
struct ContentView : View {
@State private var sampleData : [ Bookmark ] = [
. init ( title : "Genji App" , url : URL ( string : "https://genjiapp.com" ) ! ),
. init ( title : "Apple" , url : URL ( string : "https://www.apple.com" ) ! ),
. init ( title : "Google" , url : URL ( string : "https://www.google.com" ) ! )
]
@State private var selectedIDs = Set < Bookmark . ID > ()
var body : some View {
Table ( of : Bookmark . self , selection : $ selectedIDs ) {
TableColumn ( "Title" ) { bookmark in
Text ( bookmark . title )
// .contextMenu {
// Button("ここじゃない") {
// print(bookmark)
// print(selectedIDs)
// }
// }
}
TableColumn ( "URL" ) { bookmark in
Text ( bookmark . url . absoluteString )
}
} rows : {
ForEach ( sampleData ) { bookmark in
TableRow ( bookmark )
// .contextMenu {
// Button("ここでもない") {
// print(bookmark)
// print(selectedIDs)
// }
// }
}
}
. tableStyle ( . bordered )
// ここ!
. contextMenu ( forSelectionType : Bookmark . ID . self ) { clickedRowIDs in
addButton
Button ( "Delete Bookmark" ) {
sampleData . removeAll { clickedRowIDs . contains ( $0 . id ) }
}
}
// ここはテーブル内余白を右クリックしたとき
. contextMenu {
addButton
}
. padding ()
}
var addButton : some View {
Button ( "Add Bookmark" ) {
sampleData . append ( . init ( title : "Microsoft" , url : URL ( string : "https://www.microsoft.com" ) ! ))
}
}
}
TableColumn
配下の要素に.contextMenu(menuItems:)
モディファイアをつける場合、複数の列があるときはすべてにモディファイアをつけなければならないし、右クリックに反応するのは行の中の文字がある部分だけになる。
TableRow
に.contextMenu(menuItems:)
モディファイアをつける場合、選択行とコンテキストメニューの操作対象両方を取得できるが、両者が別の型になるし、両者の重なり具合を調べて操作対象を自分で計算する必要がある。
Table
自体に.contextMenu(forSelectionType:menu:primaryAction:)
モディファイアをつける場合、第2引数menu
クロージャの引数として、標準的な操作対象となるオブジェクトのid
がSet
で取得できるので、その後の処理がストレートに記述できる。
第1引数forSelectionType
には、テーブル行を表現するオブジェクトを特定するための型を指定する。オブジェクトはIdentifiable
プロトコルに適合させているはずなので、id
プロパティの型となる。第3引数primaryAction
は、行をダブルクリックした時に実行される。
また、ドキュメントには.contextMenu(forSelectionType:menu:primaryAction:)
の第2引数menu
クロージャの引数が空のSet
の場合はテーブルの余白部分を右クリックしたことになるとあるが、macOS 14.3.1とXcode Version 15.2 (15C500b)の環境ではコンテキストメニューが出ない。上のコード例ではTable
自体にもうひとつ別の.contextMenu(menuItems:)
をつけることで、余白部分を右クリックした場合をカバーしている。