diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 65679af..0000000 --- a/.travis.yml +++ /dev/null @@ -1,6 +0,0 @@ -language: python -python: - - "3.9" -script: - - cd python - - python3 -m unittest diff --git a/README.md b/README.md index 7ac03a8..a2d4224 100644 --- a/README.md +++ b/README.md @@ -8,11 +8,9 @@ azookeyのカスタムタブのデータファイルを作成するための補 現在以下を含みます。 * Swift向け生成ツール -* Python向け生成ツール -* JSON/Swift/Python用ドキュメント +* JSON/Swiftドキュメント * [JSON用ドキュメント](./json/howToMake.md) * [Swift用ドキュメント](./swift/howToMake.md) - * [Python用ドキュメント](./python/howToMake.md) ## Examples diff --git a/python/README.md b/python/README.md deleted file mode 100644 index bd45ce6..0000000 --- a/python/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# 環境 - -Python3.9以上。 - -# テスト - -```bash -python3 -m unittest -``` diff --git a/python/hieroglyphs.py b/python/hieroglyphs.py deleted file mode 100644 index 596cdf3..0000000 --- a/python/hieroglyphs.py +++ /dev/null @@ -1,116 +0,0 @@ -from source.custard import * - -#ヒエログリフの文字のリストを取得 -hieroglyphs = list(map(lambda x: chr(x), range(0x13000, 0x133FF+1))) - -#キーのリストを作成 -hieroglyphs_keys = [ - KeyData( - specifier=GridScrollSpecifier(index=0), - key=SystemKey(SystemKeyType.change_keyboard) - ), - KeyData( - specifier=GridScrollSpecifier(index=1), - key=CustomKey( - design=KeyDesign( - label=TextLabel(text="←"), - color=KeyColor.special - ), - press_actions=[ - MoveCursorAction(-1) - ], - longpress_actions=LongpressAction( - repeat=[ - MoveCursorAction(-1) - ] - ), - variations=[] - ) - ), - KeyData( - specifier=GridScrollSpecifier(index=2), - key=CustomKey( - design=KeyDesign( - label=TextLabel(text="→"), - color=KeyColor.special - ), - press_actions=[ - MoveCursorAction(1) - ], - longpress_actions=LongpressAction( - repeat=[ - MoveCursorAction(1) - ] - ), - variations=[] - ) - ), - KeyData( - specifier=GridScrollSpecifier(index=3), - key=CustomKey( - design=KeyDesign( - label=SystemImageLabel(identifier="list.bullet"), - color=KeyColor.special - ), - press_actions=[ - ToggleTabBarAction() - ], - longpress_actions=LongpressAction(), - variations=[] - ) - ), - KeyData( - specifier=GridScrollSpecifier(index=4), - key=CustomKey( - design=KeyDesign( - label=SystemImageLabel(identifier="delete.left"), - color=KeyColor.special - ), - press_actions=[ - DeleteAction(1) - ], - longpress_actions=LongpressAction( - repeat=[ - MoveCursorAction(1) - ] - ), - variations=[] - ) - ), -] - -for glyph in hieroglyphs: - key = CustomKey( - design=KeyDesign( - label=TextLabel(text=glyph), - color=KeyColor.normal - ), - press_actions=[ - InputAction(glyph) - ], - longpress_actions=LongpressAction(), - variations=[] - ) - keydata = KeyData( - specifier=GridScrollSpecifier(index=len(hieroglyphs_keys)), - key=key - ) - hieroglyphs_keys.append(keydata) - -#カスタードオブジェクトを作成 -hieroglyphs_custard = Custard( - identifier="Hieroglyphs", - language=Language.none, - input_style=InputStyle.direct, - metadata=Metadata( - custard_version="1.0", - display_name="ヒエログリフ", - ), - interface=Interface( - key_style=KeyStyle.tenkey_style, - key_layout=GridScrollLayout( - direction=ScrollDirection.vertical, row_count=8, column_count=4.2), - keys=hieroglyphs_keys - ) -) -hieroglyphs_custard.write(name="hieroglyphs") diff --git a/python/howToMake.md b/python/howToMake.md deleted file mode 100644 index 6cd208a..0000000 --- a/python/howToMake.md +++ /dev/null @@ -1,512 +0,0 @@ -# Custardファイルの作り方 - -カスタードファイルはjson形式のデータです。拡張子は`txt`, `json`, `custard`のうちどれかである必要があります。 - -## キーの記述 - -キーボードでキーは最も大切な要素です。custardファイルではキーは次のように記述します。 - -```python -CustomKey( - design = KeyDesign( - label = TextLabel(text = "@#/&_"), - color = KeyColor.normal - ), - press_actions = [ - InputAction("@") - ], - longpress_actions = LongpressAction(), - variations = [] -) -``` - -このデータは - -* ラベルが「@#/&_」であり -* 色は普通のキーと同じであり -* 押すと「@」を入力し -* 長押ししても何もせず -* フリックや長押しによる候補変更は行われない - -キーを表現しています。順番に見てみましょう。 - -### デザイン - -最初の引数は`design`です。これは`KeyDesign`というオブジェクトで、キーのデザインを指定します。 - -```python -design = KeyDesign( - label = TextLabel(text = "@#/&_"), - color = KeyColor.normal -), -``` - -`label`はキーに表示されるラベルです。ラベルに指定できる値は次の通りです。 - -| オブジェクト | 初期化の引数 | 説明 | -| ---------------- | --------------- | ------------------------------------------------------------ | -| TextLabel | text: str | 指定した文字をラベルとして表示します。 | -| MainAndSubLabel | main: str, sub: str | `main`に指定した1文字を1行目に大きめに、`sub`に指定した文字を2行目に小さめに表示します。 | -| SystemImageLabel | identifier: str | 指定した名前の画像をラベルとして表示します。指定できる値の一例は以下の通りです。
この画像は[SFSymbols](https://developer.apple.com/sf-symbols/)から取得されます。 | - - - -`color`はキーの色です。azooKeyは着せ替えに対応しているため、キーの色は環境によって変わります。これは`KeyColor`という列挙型の値で、以下の値を指定できます。 - -| 識別子 | 説明 | -| -------- | ---------------------------------------- | -| normal | 通常の入力キーの色です。 | -| special | タブ移動キーや削除キーの色です。 | -| selected | 選択中のタブや押されているキーの色です。 | -| unimportant | 重要度の低いキーの色です。 | - -### アクション - -次の引数は`press_actions`です。これはキーを単純に押した際のアクションの配列です。キーを押して離した段階で、配列の順序で動作が実行されます。 - -アクションは例えば以下のように記述されています。 - -```python -press_actions = [ - InputAction("@") -], -``` - -`InputAction` インスタンスは `text` メンバーで指定された文字列を入力するアクションを表します。 - -azooKeyでは`InputAction`の他にいくつかの動作を行うことができます。 - -| 関数 | メンバー変数 | 挙動 | -| :----------------------------- | :----------------------------------------------- | :----------------------------------------------------------- | -| InputAction | text: str | 引数textを入力します | -| DeleteAction | count: int | (countの絶対値)文字を削除します。負の値が指定されている場合は文末方向に削除します。 | -| MoveCursorAction | count: int | (countの絶対値)文字分カーソルを移動します。負の値が指定されている場合は文頭方向に移動します。 | -| MoveTabAction | tab_type: "custom" | "system"
text: str | textで指定したタブに移動します。tab_typeが`system`の場合はazooKeyが標準で搭載しているタブに移動し、`custom`の場合はtextを持ったカスタムタブに移動します。システムタブとして指定できる値は後に記述します。 | -| SelectCandidateAction | type: str
value: int | 引数で指定した候補を選択状態にします。typeは4種類あります。`"first"`(最初の候補)と`"last"`(最後の候補)の場合は`"value"`の指定は不要です。`"exact"`(value個目の候補を選択)と`"offset"`(value個隣の候補を選択)の場合は`"value"`に数値を指定してください。 | -| CompleteAction | なし | 変換を確定します | -| CompleteCharacterFormAction | forms: list[CharacterForm] | 入力中の文字列をformsで指定した形式に変換して確定します。 | -| ReplaceLastCharactersAction | table: {str: str} | カーソル文頭方向の文字列を引数のtableに基づいて置換します。例えばカーソル文頭方向の文字列が`"abcdef"`であり、テーブルに`"def":":="`が指定されている場合は`"abc:="`と置換されます。 | -| ReplaceDefaultAction | replace_type: ReplaceType
fallbacks: list[ReplaceType] | azooKeyが標準で用いている「濁点・半濁点・小書き・大文字・小文字」の切り替えアクションです。 | -| SmartDeleteAction | direction: ScanDirection
targets: list[str] | directionに`ScanDirection.forward`または`ScanDirection.backward`を指定します。targetsに指定した文字のいずれかがカーソル進行方向に現れるまで削除を繰り返します。例えば文頭方向の文字列が`"Yes, it is"`であり、`direction = ScanDirection.backward, target = [","]`であった場合、この操作の実行後に`" it is"`が削除されます。 | -| SmartDeleteDefaultAction | なし | azooKeyが標準で用いている「文頭まで削除」のアクションです。 | -| SmartMoveCursorAction | direction: ScanDirection
targets: list[str] | directionに`ScanDirection.forward`または`ScanDirection.backward`を指定します。targetsに指定した文字のいずれかがカーソル進行方向に現れるまでカーソルの移動を繰り返します。例えば文頭方向の文字列が`"Yes, it is"`であり、`direction = ScanDirection.backward, targets = [","]`であった場合、この操作の実行後にカーソルが`"Yes,\| it is"`まで移動します。 | -| EnableResizingModeAction | なし | 片手モードの編集状態に移動します。編集状態ではキー操作などが行えないため、disable_resizing_modeは用意されていません。 | -| ToggleCursorBarAction | なし | カーソルバーの表示をtoggleします。 | -| ToggleTabBarAction | なし | タブバーの表示をtoggleします。 | -| ToggleCapsLockStateAction | なし | caps lockをtoggleします。 | -| DismissKeyboardAction | なし | キーボードを閉じます。 | -| PasteAction | なし | コピーしている文字列をペーストします。フルアクセスがない場合動作しません。 | -| LaunchApplicationAction | scheme_type: Literal['azooKey', 'shortcuts']
target: str | scheme_typeで指定されたアプリケーションをscheme://(target)として開きます。scheme_typeには`"azooKey"`か`"shortcuts"`のみを指定できます。 | - -続く引数の`longpress_actions`は`LongpressAction`というオブジェクトで、ほぼ`press_actions`と同じです。 - -```python -class LongpressAction(object): - def __init__(self, duration: LongpressDuration = LongpressDuration.normal. start: list[Action] = [], repeat: list[Action] = []): - pass -``` - -ここで`start`は長押しの開始時に一度だけ実行される動作、`repeat`は長押しの間繰り返し実行される動作です。それぞれ上で書いたものと同様にアクションの配列を指定します。また、`duration`は長押しと判定されるまでの時間で、`LongpressDuration.light`を指定するとデフォルトの`LongpressDuration.normal`より短い長押し時間でアクションが実行されるようになります。 - -#### システムタブ - -以下を文字列で指定してください。 - -| 識別子 | 説明 | -| ------------------- | ------------------------------------------------------------ | -| user_japanese | ユーザの設定に合わせた日本語タブ | -| user_english | ユーザの設定に合わせた英語タブ | -| flick_japanese | フリック入力の日本語タブ | -| flick_english | フリック入力の英語タブ | -| flick_numbersymbols | フリック入力の数字・記号タブ | -| qwerty_japanese[^2] | ローマ字入力の日本語タブ | -| qwerty_english[^2] | ローマ字入力の英語タブ | -| qwerty_numbers[^2] | ローマ字入力の数字タブ | -| qwerty_symbols[^2] | ローマ字入力の記号タブ | -| emoji_tab | 絵文字タブ | -| clipboard_history_tab | クリップボードの履歴タブ(フルアクセスが必要です) | -| last_tab | このタブの前のタブ
もしも履歴がない場合、現在のタブの指定になります | - -### バリエーション - -バリエーションは「メインとなるキーに付随して選択可能な別種のキー」のことです。簡単にはフリック入力における上下左右に現れるキー、あるいはローマ字入力において長押しで選択できる候補のことを指しています。`variations`には`VariationData`というオブジェクトの配列を指定します。 - -上のキーではバリエーションは指定していませんが、実際にバリエーションを作る際は次のように書きます。 - -```python -variations = [ - FlickVariationData( - direction = FlickDirection.left, - key = Variation( - design = VariationDesign( - label = TextLabel(text = "#"), - ), - press_actions = [ - InputAction("#") - ], - longpress_actions = LongpressAction() - ) - ), - FlickVariationData( - direction = FlickDirection.top, - key = Variation( - design = VariationDesign( - label = TextLabel(text = "/"), - ), - press_actions = [ - InputAction("/") - ], - longpress_actions = LongpressAction() - ) - ), -] -``` - -少し長いですが、中身はここまでみてきたキーとほぼ変わりません。違いは - -* 型が`FlickVariationData`であり -* デザインの指定がラベルのみであり -* `variations`の指定がなく -* `direction`の指定がある - -ことです。 - -バリエーションはその出現する条件によって異なる型で表現されます。 - -| オブジェクト | 必要な引数 | 説明 | -| -------------------------- | --------------------------------------------- | ------------------------------------------------------------ | -| FlickVariationData | direction: FlickDirection
key: Variation | `direction`として指定する`left,top,right,bottom`の方向のフリックで表示されるバリエーションです。 | -| LongpressVariationData[^3] | key: Variation | qwertyキーボードなどで見られる長押しして表示される候補のバリエーションです。配列に指定した順に表示されます。
これが指定されている場合、キーの`longpress_actions`に指定した値は無視されます。またバリエーションの`longpress_actions`は現状無効です。 | - -以上でキーの記述の説明は終わりです。 - -## インターフェースの記述 - -インターフェースとはキーを含む画面全体のことです。例えば以下のような形をしています。 - -```python -Interface( - key_layout = GridFitLayout(row_count = 2, column_count = 2), - key_style = KeyStyle.tenkey_style, - keys = [ - KeyData( - specifier = GridFitSpecifier(x = 0, y = 1), - key = {キーのデータ} - ), - (省略) - ] -) -``` - -### レイアウト - -`key_layout`とはキーを配置する方法です。`Layout`オブジェクトを指定します。指定できるのは以下の二つの値です。 - -| オブジェクト | 引数 | 説明 | -| ---------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | -| GridFitLayout | row_count: int
column_count: int | 画面全体に収まるように格子状にキーを配置するレイアウトです。横にrow_count個、縦にcolumn_count個のキーを並べます。 | -| GridScrollLayout | direction: ScrollDirection
row_count: float
column_count: float | 画面をスクロールできる状態にして格子状にキーを配置するレイアウトです。
スクロールの方向を示すdirectionには`ScrollDirection.vertical`または`ScrollDirection.horizontal`を指定し、row_countとcolumn_countを指定します。
スクロール方向に垂直な向きのキー数は切り捨てて整数として利用されますが、平行な向きのキー数は小数のまま用います。
このレイアウトが指定されている場合、キーの`variations`は一切無効になります。 | - -### スタイル - -引数`key_style`は`KeyStyle`型で、処理系にどのようにキーを扱えばいいかを知らせるための値です。`tenkey_style`または`pc_style`を指定してください。 - -片手モードの状態は端末の向きとスタイルによって決まります。レイアウトが`grid_scroll`である場合はフリック操作とサジェストは無効化されます。 - -| スタイル | 説明 | -| ------------ | ------------------------------------------------------------ | -| tenkey_style | 携帯打ちやフリック式のかな入力、九宮格輸入法などで用いられる、10キーを模した形状のキーボードに対して指定してください。
variationはflick_variationのみが有効になります。
縦方向のスペーシングは狭めになります。
サジェストはキーを長押しすると表示され、キーとflick_variationが表示されます。 | -| pc_style | Qwerty配列やJisかな配列など、パソコンのキーボードを模した形状のキーボードに対して指定してください。
variationはlongpress_variationのみが有効になります。
縦方向のスペーシングは広めになります。
サジェストはキーを押すと表示され、押し続けるとlongpress_variationが表示されます。 | - -### キー - -`keys`とは`KeyData`というオブジェクトの配列です。ここには以下のような形のオブジェクトが入ります。 - -```python - KeyData( - specifier = GridFitSpecifier(x = 0, y = 1), - key = CustomKey(...) -) -``` - -引数`specifier`はキーの位置を調整するために必要な値です。指定できる値は次の2種類です。 - -| オブジェクト | 引数 | 説明 | -| ------------------- | ----------------------------------------------------------- | ------------------------------------------------------------ | -| GridFitSpecifier | x: int
y: int
width: int = 1
height: int = 1 | grid_fitレイアウト上でキーをどの位置に配置するかを指定します。
キーの左上が(x, y)となり、widthとheightの分だけ縦横に広がります。
widthとheightは省略可能です。 | -| GridScrollSpecifier | index: int | grid_scrollレイアウト上で最初から数えた順番を指定します。
0から順に指定し、間を開けてはいけません。 | - -以下は例です。 - -```python -#grid_fitの場合 -specifier = GridFitSpecifier(x = 0, y = 1) - -#grid_scrollの場合 -specifier = GridScrollSpecifier(index = 42) -``` - -`key`はキーの実体を指定する値で、`SystemKey`または`CustomKey`を指定します。`Customkey`は上で確認したキーのデータです。 - -`SystemKey`は特殊なキーを指定するための値です。引数の`identifier`は`SystemKeyType`という列挙型で指定します。以下から指定してください。 - -| 識別子 | 説明 | -| ----------------- | ------------------------------------------------------------ | -| change_keyboard | 地球儀キー(キーボード切り替えキー)。ホームボタンがない端末ではカーソルバーの表示キーに切り替わります。ホームボタンがない端末ではカーソルバーの表示キーに切り替わります。 | -| enter | 改行・確定キー。 | -| upper_lower | 大文字・小文字キー。 | -| next_candidate | 入力状態に応じて「空白」と「次候補」が切り替わるキー。 | -| flick_kogaki | ユーザがカスタムしている可能性のあるフリックの「小゙゚」キー。grid_fitのtenkey_style以外での利用は非推奨。 | -| flick_kutoten | ユーザがカスタムしている可能性のあるフリックの「、。?!」キー。grid_fitのtenkey_style以外での利用は非推奨。 | -| flick_hira_tab | ユーザがカスタムしている可能性のあるフリックの「あいう」キー。grid_fitのtenkey_style以外での利用は非推奨。 | -| flick_abc_tab | ユーザがカスタムしている可能性のあるフリックの「abc」キー。grid_fitのtenkey_style以外での利用は非推奨。 | -| flick_star123_tab | ユーザがカスタムしている可能性のあるフリックの「☆123」キー。grid_fitのtenkey_style以外での利用は非推奨。 | - -以上でインターフェースの記述の説明は終わりです。 - -## カスタードの記述 - -あと少しです!カスタードは以下のように記述します。 - -```python -Custard( - identifier = "my_flick", - language = Language.ja_JP, - input_style = InputStyle.direct, - metadata = MetaData(custard_version = "1.0", display_name = "私のフリック"), - interface = {インターフェースの記述} -) -``` - -`identifier`はカスタードを識別するための文字列です。他のものと被らない値を指定してください。 - -`language`は`Language`という列挙型で、変換対象の言語です。以下の値が指定できます。 - -| 識別子 | 説明 | -| --------- | ---------------------------------------------------- | -| ja_JP | 日本語(共通語) | -| en_US | 英語(アメリカ) | -| el_GR | ギリシャ語 | -| undefined | 指定なし。変換候補は出るので記号などの入力で用いる。 | -| none | 変換なし。 | - -`input_style`は`InputStyle`という列挙型で、入力方式です。以下の値が指定できます。 - -| 識別子 | 説明 | -| ---------- | ---------------------------- | -| direct | 入力をそのまま用います。 | -| roman2kana | ローマ字かな入力を行います。 | - -`metadata`は`Metadata`型の値で、キーボードの動作とは無関係な情報を格納します。現在は以下の2つの値を指定してください。 - -* `custard_version`は規格のバージョン情報です。この資料に基づいて作成する場合`"1.0"`を指定してください。 -* `display_name`はタブバーなどでデフォルトで用いられる名称です。 - -`interface`には上で記述したとおりのインターフェースの記述を行います。 - -### 複数のカスタードファイルを1つにまとめる - -カスタードのデータを配列で指定することで、読み込み側が複数のファイルを一括で読み込めます。 - -```Python -custards = [ - {カスタードの記述1}, - {カスタードの記述2}, - {カスタードの記述3}, -] -``` - -以上でカスタードの記述の説明は終わりです。 - -## ツール - -特定の状況でより簡単に記述するため、ユーティリティが用意されています。 - -### キーの作成 - -以下の2つの関数が用意されています。 - -```python -CustomKey.flickSimpleInputs(center: str, subs: list[str], centerLabel: str = None) -> CustomKey - -CustomKey.flickSimpleInputAndLabels(center: Union[tuple[str, str], str], left: Union[tuple[str, str], str, None] = None, top: Union[tuple[str, str], str, None] = None, right: Union[tuple[str, str], str, None] = None, bottom: Union[tuple[str, str], str, None] = None) -> CustomKey -``` - -`CustomKey.flickSimpleInputs`では、中心の文字とフリックで入力する文字を順番に指定することで`CustomKey`オブジェクトを作成します。以下のように用いることができます。 - -```python -key = CustomKey.flickSimpleInputs(center = "あ", subs = ["い", "う", "え", "お"], centerLabel = "あいう") -``` - -`CustomKey.flickSimpleInputAndLabels`では、フリックで入力する文字にもラベルを指定することができます。以下のように用いることができます。 - -```python -key = CustomKey.flickSimpleInputAndLabels( - center = ("😸", ":smile_cat:"), - left = ("😿", ":crying_cat_face:"), - right = ("😻", ":heart_eyes_cat:"), -) -``` - -この関数では、ラベルと入力が同じ場合に指定を省略することができます。 - -```python -key = CustomKey.flickSimpleInputAndLabels( - center = ("あ", "あ゛"), å - left = ("い", "い゛"), - top = "ゔ", - right = ("え", "え゛"), - bottom = ("お", "お゛") -) -``` - -### 書き出し - -書き出しのための関数が用意されています。 - -```python -#指定したpathにcustardファイルを書き出します -custard.write(to = path) - -#resultディレクトリ内に指定した名前でcustardファイルを書き出します -custard.write(name = path) - -#resultディレクトリ内に指定した名前で上書きを許可しながらcustardファイルを書き出します -custard.write(name = path, allow_overwrite = True) -``` - -複数のCustardオブジェクトを1つのファイルとして書き出す場合は`CustardList`オブジェクトに包みます。書き出しはCustardオブジェクトと同様に行うことができます。 - -```python -custardList = CustardList([custard1, custard2, custard3]) - -#指定したpathにcustardのリストのファイルを書き出します -custardList.write(to = path) -``` - -## 用例 - -例としてUnicodeに登録されているヒエログリフを入力できるスクロール可能なタブを作りましょう。 - -```python -from source.custard import * -#ヒエログリフの文字のリストを取得 -hieroglyphs = list(map(lambda x: chr(x), range(0x13000, 0x133FF+1))) - -#キーのリストを作成 -hieroglyphs_keys = [ - KeyData( - specifier = GridScrollSpecifier(index = 0), - key = SystemKey(SystemKeyType.change_keyboard) - ), - KeyData( - specifier = GridScrollSpecifier(index = 1), - key = CustomKey( - design = KeyDesign( - label = TextLabel(text = "←"), - color = KeyColor.special - ), - press_actions = [ - MoveCursorAction(-1) - ], - longpress_actions = LongpressAction( - repeat = [ - MoveCursorAction(-1) - ] - ), - variations = [] - ) - ), - KeyData( - specifier = GridScrollSpecifier(index = 2), - key = CustomKey( - design = KeyDesign( - label = TextLabel(text = "→"), - color = KeyColor.special - ), - press_actions = [ - MoveCursorAction(1) - ], - longpress_actions = LongpressAction( - repeat = [ - MoveCursorAction(1) - ] - ), - variations = [] - ) - ), - KeyData( - specifier = GridScrollSpecifier(index = 3), - key = CustomKey( - design = KeyDesign( - label = SystemImageLabel(identifier = "list.bullet"), - color = KeyColor.special - ), - press_actions = [ - ToggleTabBarAction() - ], - longpress_actions = LongpressAction(), - variations = [] - ) - ), - KeyData( - specifier = GridScrollSpecifier(index = 4), - key = CustomKey( - design = KeyDesign( - label = SystemImageLabel(identifier = "delete.left"), - color = KeyColor.special - ), - press_actions = [ - DeleteAction(1) - ], - longpress_actions = LongpressAction( - repeat = [ - MoveCursorAction(1) - ] - ), - variations = [] - ) - ), -] - -for glyph in hieroglyphs: - key = CustomKey( - design = KeyDesign( - label = TextLabel(text = glyph), - color = KeyColor.normal - ), - press_actions = [ - InputAction(glyph) - ], - longpress_actions = LongpressAction(), - variations = [] - ) - keydata = KeyData( - specifier = GridScrollSpecifier(index = len(hieroglyphs_keys)), - key = key - ) - hieroglyphs_keys.append(keydata) - -#カスタードオブジェクトを作成 -hieroglyphs_custard = Custard( - identifier = "Hieroglyphs", - language = Language.none, - input_style = InputStyle.direct, - metadata = Metadata( - custard_version = "1.0", - display_name = "ヒエログリフ", - ), - interface = Interface( - key_style = KeyStyle.tenkey_style, - key_layout = GridScrollLayout(direction = ScrollDirection.vertical, row_count = 8, column_count = 4.2), - keys = hieroglyphs_keys - ) -) -hieroglyphs_custard.write(to = "hieroglyphs.json") -``` - ---- - -[^2]: ここではpc_styleではなくqwertyと呼んでいます。これはこのタブの配列がqwertyであるからです。 -[^3]: ここではqwerty_variationあるいはpc_style_variationではなくlongpress_variationと呼んでいます。variationがそれが現れる条件となる操作によって分類されるからです。 - diff --git a/python/my_custard.py b/python/my_custard.py deleted file mode 100644 index 43ade11..0000000 --- a/python/my_custard.py +++ /dev/null @@ -1,110 +0,0 @@ -from source.custard import * - -custard = Custard( - identifier="my_custard", - language=Language.ja_JP, - input_style=InputStyle.direct, - metadata=Metadata( - custard_version="1.0", - display_name="私のカスタード", - ), - interface=Interface( - key_style=KeyStyle.tenkey_style, - key_layout=GridFitLayout(row_count=2, column_count=2), - keys=[ - KeyData( - specifier=GridFitSpecifier(x=0, y=0), - key=SystemKey(SystemKeyType.change_keyboard) - ), - KeyData( - specifier=GridFitSpecifier(x=0, y=1), - key=CustomKey( - design=KeyDesign( - label=TextLabel(text="あ"), - color=KeyColor.normal - ), - press_actions=[], - longpress_actions=LongpressAction( - start=[ - DeleteAction(1), - ] - ), - variations=[ - FlickVariationData( - direction=FlickDirection.left, - key=Variation( - design=VariationDesign( - label=TextLabel(text="い"), - ), - press_actions=[ - InputAction("い") - ], - longpress_actions=LongpressAction() - ) - ) - ] - ) - ), - - KeyData( - specifier=GridFitSpecifier(x=1, y=0), - key=CustomKey( - design=KeyDesign( - label=TextLabel(text="あ"), - color=KeyColor.normal - ), - press_actions=[], - longpress_actions=LongpressAction( - start=[ - DeleteAction(1), - ] - ), - variations=[ - FlickVariationData( - direction=FlickDirection.left, - key=Variation( - design=VariationDesign( - label=TextLabel(text="い"), - ), - press_actions=[ - InputAction("い") - ], - ) - ) - ] - ) - ), - - KeyData( - specifier=GridFitSpecifier(x=1, y=1), - key=CustomKey( - design=KeyDesign( - label=TextLabel(text="あ"), - color=KeyColor.normal - ), - press_actions=[], - longpress_actions=LongpressAction( - start=[ - DeleteAction(1), - ] - ), - variations=[ - FlickVariationData( - direction=FlickDirection.left, - key=Variation( - design=VariationDesign( - label=TextLabel(text="い"), - ), - press_actions=[ - InputAction("い") - ], - ) - ) - ] - ) - ), - ] - ) -) - -custard.write(name="my_custard") diff --git a/python/number_font.py b/python/number_font.py deleted file mode 100644 index d800360..0000000 --- a/python/number_font.py +++ /dev/null @@ -1,114 +0,0 @@ -from source.custard import * - - -def pc_style_input_key(char: str) -> CustomKey: - return CustomKey( - design=KeyDesign( - label=TextLabel(text=char), - color=KeyColor.normal - ), - press_actions=[ - InputAction(char) - ], - longpress_actions=LongpressAction(), - variations=[] - ) - - -keys: list[KeyData] = [] - -numbers = [ - list("1234567890"), - list("①②③④⑤⑥⑦⑧⑨⓪"), - list("𝟙𝟚𝟛𝟜𝟝𝟞𝟟𝟠𝟡𝟘"), - list("𝟏𝟐𝟑𝟒𝟓𝟔𝟕𝟖𝟗𝟎") -] - -for i in range(len(numbers)): - for j in range(len(numbers[i])): - x, y = (j, i) - keyData = KeyData( - specifier=GridFitSpecifier(x=x, y=y), - key=pc_style_input_key(numbers[i][j]) - ) - keys.append(keyData) - -keys.append(KeyData( - specifier=GridFitSpecifier(x=0, y=4), - key=CustomKey( - design=KeyDesign( - label=SystemImageLabel("list.bullet"), - color=KeyColor.special - ), - press_actions=[ - ToggleTabBarAction() - ], - longpress_actions=LongpressAction(), - variations=[] - ) -)) - -keys.append(KeyData( - specifier=GridFitSpecifier(x=1, y=4), - key=SystemKey(SystemKeyType.change_keyboard) -)) - -keys.append(KeyData( - specifier=GridFitSpecifier(x=2, y=4), - key=CustomKey( - design=KeyDesign( - label=SystemImageLabel("delete.left"), - color=KeyColor.special - ), - press_actions=[ - DeleteAction(1) - ], - longpress_actions=LongpressAction( - repeat=[ - DeleteAction(1) - ] - ), - variations=[] - ) -)) - -keys.append(KeyData( - specifier=GridFitSpecifier(x=3, y=4, width=4, height=1), - key=CustomKey( - design=KeyDesign( - label=TextLabel("空白"), - color=KeyColor.normal - ), - press_actions=[ - InputAction(" ") - ], - longpress_actions=LongpressAction( - start=[ - ToggleTabBarAction() - ] - ), - variations=[] - ) -)) - -keys.append(KeyData( - specifier=GridFitSpecifier(x=7, y=4, width=3, height=1), - key=SystemKey(SystemKeyType.enter) -)) - -#カスタードオブジェクトを作成 -hieroglyphs_custard = Custard( - identifier="number_font", - language=Language.none, - input_style=InputStyle.direct, - metadata=Metadata( - custard_version="1.0", - display_name="装飾数字", - ), - interface=Interface( - key_style=KeyStyle.pc_style, - key_layout=GridFitLayout(row_count=10, column_count=5), - keys=keys - ) -) -hieroglyphs_custard.write(name="number_font") diff --git a/python/sippori_dakuten.py b/python/sippori_dakuten.py deleted file mode 100644 index 06b1178..0000000 --- a/python/sippori_dakuten.py +++ /dev/null @@ -1,548 +0,0 @@ -from source.custard import * - -key_あ = CustomKey.flickSimpleInputs( - center="あ", - subs=list("いうえお") -) -key_か = CustomKey.flickSimpleInputs( - center="か", - subs=list("きくけこ") -) -key_さ = CustomKey.flickSimpleInputs( - center="さ", - subs=list("しすせそ") -) -key_た = CustomKey.flickSimpleInputs( - center="た", - subs=list("ちつてと") -) -key_な = CustomKey.flickSimpleInputs( - center="な", - subs=list("にぬねの") -) -key_は = CustomKey.flickSimpleInputs( - center="は", - subs=list("ひふへほ") -) -key_ま = CustomKey.flickSimpleInputs( - center="ま", - subs=list("みむめも") -) -key_や = CustomKey.flickSimpleInputs( - center="や", - subs=list("「ゆ」よ") -) -key_ら = CustomKey.flickSimpleInputs( - center="ら", - subs=list("りるれろ") -) -key_わ = CustomKey.flickSimpleInputs( - center="わ", - subs=list("をんー") -) -hiragana_replaceAction = ReplaceLastCharactersAction({ - #あ行 - #あ→ぁ→あ゛→ぁ゛→あ - "あ": "ぁ", - "ぁ": chr(0xE082), - chr(0xE082): chr(0xE0B0), - chr(0xE0B0): "あ", - #い→ぃ→い゛→ぃ゛→い - "い": "ぃ", - "ぃ": chr(0xE083), - chr(0xE083): chr(0xE0B1), - chr(0xE0B1): "い", - #う→ぅ→ゔ→ぅ゛→う - "う": "ぅ", - "ぅ": "ゔ", - "ゔ": chr(0xE0B2), - chr(0xE0B2): "う", - #え→ぇ→え゛→ぇ゛→え - "え": "ぇ", - "ぇ": chr(0xE084), - chr(0xE084): chr(0xE0B3), - chr(0xE0B3): "え", - #お→ぉ→お゛→ぉ゛→お - "お": "ぉ", - "ぉ": chr(0xE085), - chr(0xE085): chr(0xE0B4), - chr(0xE0B4): "お", - - #か行 - "か": "が", - "が": "か", - "き": "ぎ", - "ぎ": "き", - "く": "ぐ", - "ぐ": "く", - "け": "げ", - "げ": "け", - "こ": "ご", - "ご": "こ", - - #さ行 - "さ": "ざ", - "ざ": "さ", - "し": "じ", - "じ": "し", - "す": "ず", - "ず": "す", - "せ": "ぜ", - "ぜ": "せ", - "そ": "ぞ", - "ぞ": "そ", - - #た行 - "た": "だ", - "だ": "た", - "ち": "ぢ", - "ぢ": "ち", - #つ→っ→づ→っ゛→つ - "つ": "っ", - "っ": "づ", - "づ": chr(0xE0B7), - chr(0xE0B7): "つ", - "て": "で", - "で": "て", - "と": "ど", - "ど": "と", - - #な行 - "な": chr(0xE09A), - chr(0xE09A): "な", - "に": chr(0xE09B), - chr(0xE09B): "に", - "ぬ": chr(0xE09C), - chr(0xE09C): "ぬ", - "ね": chr(0xE09D), - chr(0xE09D): "ね", - "の": chr(0xE09E), - chr(0xE09E): "の", - - #は行 - "は": "ば", - "ば": "ぱ", - "ぱ": "は", - "ひ": "び", - "び": "ぴ", - "ぴ": "ひ", - "ふ": "ぶ", - "ぶ": "ぷ", - "ぷ": "ふ", - "へ": "べ", - "べ": "ぺ", - "ぺ": "へ", - "ほ": "ぼ", - "ぼ": "ぽ", - "ぽ": "ほ", - - #ま行 - "ま": chr(0xE09F), - chr(0xE09F): "ま", - "み": chr(0xE0A0), - chr(0xE0A0): "み", - "む": chr(0xE0A1), - chr(0xE0A1): "む", - "め": chr(0xE0A2), - chr(0xE0A2): "め", - "も": chr(0xE0A3), - chr(0xE0A3): "も", - - #や行 - #や→ゃ→や゛→ゃ゛ - "や": "ゃ", - "ゃ": chr(0xE0A4), - chr(0xE0A4): chr(0xE0B8), - chr(0xE0B8): "や", - "ゆ": "ゅ", - "ゅ": chr(0xE0A5), - chr(0xE0A5): chr(0xE0B9), - chr(0xE0B9): "ゆ", - "よ": "ょ", - "ょ": chr(0xE0A6), - chr(0xE0A6): chr(0xE0BA), - chr(0xE0BA): "よ", - - #ら行 - "ら": chr(0xE0A7), - chr(0xE0A7): "ら", - "り": chr(0xE0A8), - chr(0xE0A8): "り", - "る": chr(0xE0A9), - chr(0xE0A9): "る", - "れ": chr(0xE0AA), - chr(0xE0AA): "れ", - "ろ": chr(0xE0AB), - chr(0xE0AB): "ろ", - - #わ行 - "わ": "ゎ", - "ゎ": chr(0xE0AC), - chr(0xE0AC): chr(0xE0BB), - chr(0xE0BB): "わ", - "ゐ": chr(0xE0AD), - chr(0xE0AE): "ゐ", - "ゑ": chr(0xE0AE), - chr(0xE0AD): "ゑ", - "を": chr(0xE0AF), - chr(0xE0AF): "を", - - "ん": chr(0xE086), - chr(0xE086): "ん", - - "ー": chr(0xE0DB), - chr(0xE0DB): "ー" -}) - -key_dakuten = CustomKey( - design=KeyDesign( - label=TextLabel("小゙゚"), - color=KeyColor.normal - ), - press_actions=[ - hiragana_replaceAction - ], - variations=[ - FlickVariationData( - direction=FlickDirection.left, - key=Variation( - design=VariationDesign(TextLabel("ゐ")), - press_actions=[ - InputAction("ゐ") - ], - ) - ), - FlickVariationData( - direction=FlickDirection.top, - key=Variation( - design=VariationDesign(TextLabel("ア゙イ゙ヴ")), - press_actions=[ - MoveTabAction(tab_type=TabType.custom, - text="sippori_dakuten_katakana") - ], - ) - ), - FlickVariationData( - direction=FlickDirection.right, - key=Variation( - design=VariationDesign(TextLabel("ゑ")), - press_actions=[ - InputAction("ゑ") - ], - ) - ) - ] -) -#キーを一覧する -hiragana_keys = [ - KeyData(specifier=GridFitSpecifier(0, 0), key=SystemKey(SystemKeyType.flick_star123_tab)), - KeyData(specifier=GridFitSpecifier(0, 1), key=SystemKey(SystemKeyType.flick_abc_tab)), - KeyData(specifier=GridFitSpecifier(0, 2), key=SystemKey(SystemKeyType.flick_hira_tab)), - KeyData(specifier=GridFitSpecifier(0, 3), key=SystemKey(SystemKeyType.change_keyboard)), - KeyData(specifier=GridFitSpecifier(1, 0), key=key_あ), - KeyData(specifier=GridFitSpecifier(2, 0), key=key_か), - KeyData(specifier=GridFitSpecifier(3, 0), key=key_さ), - KeyData(specifier=GridFitSpecifier(1, 1), key=key_た), - KeyData(specifier=GridFitSpecifier(2, 1), key=key_な), - KeyData(specifier=GridFitSpecifier(3, 1), key=key_は), - KeyData(specifier=GridFitSpecifier(1, 2), key=key_ま), - KeyData(specifier=GridFitSpecifier(2, 2), key=key_や), - KeyData(specifier=GridFitSpecifier(3, 2), key=key_ら), - KeyData(specifier=GridFitSpecifier(1, 3), key=key_dakuten), - KeyData(specifier=GridFitSpecifier(2, 3), key=key_わ), - KeyData(specifier=GridFitSpecifier(3, 3), key=SystemKey(SystemKeyType.flick_kutoten)), - KeyData(specifier=GridFitSpecifier(4, 0), key=CustomKey.flickDelete()), - KeyData(specifier=GridFitSpecifier(4, 1), key=CustomKey.flickSpace()), - KeyData(specifier=GridFitSpecifier(4, 2, width=1, height=2), key=SystemKey(SystemKeyType.enter)), -] - -key_ア = CustomKey.flickSimpleInputs( - center="ア", - subs=list("イウエオ") -) -key_カ = CustomKey.flickSimpleInputs( - center="カ", - subs=list("キクケコ") -) -key_サ = CustomKey.flickSimpleInputs( - center="サ", - subs=list("シスセソ") -) -key_タ = CustomKey.flickSimpleInputs( - center="タ", - subs=list("チツテト") -) -key_ナ = CustomKey.flickSimpleInputs( - center="ナ", - subs=list("ニヌネノ") -) -key_ハ = CustomKey.flickSimpleInputs( - center="ハ", - subs=list("ヒフヘホ") -) -key_マ = CustomKey.flickSimpleInputs( - center="マ", - subs=list("ミムメモ") -) -key_ヤ = CustomKey.flickSimpleInputs( - center="ヤ", - subs=list("「ユ」ヨ") -) -key_ラ = CustomKey.flickSimpleInputs( - center="ラ", - subs=list("リルレロ") -) -key_ワ = CustomKey.flickSimpleInputs( - center="ワ", - subs=list("ヲンー") -) -katakana_replaceAction = ReplaceLastCharactersAction({ - #ア行 - #ア→ァ→ア゛→ァ゛→ア - "ア": "ァ", - "ァ": chr(0xE087), - chr(0xE087): chr(0xE0CE), - chr(0xE0CE): "ア", - #イ→ィ→イ゛→ィ゛→イ - "イ": "ィ", - "ィ": chr(0xE088), - chr(0xE088): chr(0xE0CF), - chr(0xE0CF): "イ", - #ウ→ゥ→ヴ→ゥ゛→ウ - "ウ": "ゥ", - "ゥ": "ヴ", - "ヴ": chr(0xE0D0), - chr(0xE0D0): "ウ", - #エ→ェ→エ゛→ェ゛→エ - "エ": "ェ", - "ェ": chr(0xE089), - chr(0xE089): chr(0xE0D1), - chr(0xE0D1): "エ", - #オ→ォ→オ゛→ォ゛→オ - "オ": "ォ", - "ォ": chr(0xE08A), - chr(0xE08A): chr(0xE0D2), - chr(0xE0D2): "オ", - - #カ行 - "カ": "ガ", - "ガ": "カ", - "キ": "ギ", - "ギ": "キ", - "ク": "グ", - "グ": "ク", - "ケ": "ゲ", - "ゲ": "ケ", - "コ": "ゴ", - "ゴ": "コ", - - #サ行 - "サ": "ザ", - "ザ": "サ", - "シ": "ジ", - "ジ": "シ", - "ス": "ズ", - "ズ": "ス", - "セ": "ゼ", - "ゼ": "セ", - "ソ": "ゾ", - "ゾ": "ソ", - - #タ行 - "タ": "ダ", - "ダ": "タ", - "チ": "ヂ", - "ヂ": "チ", - #ツ→ッ→ヅ→ッ゛→ツ - "ツ": "ッ", - "ッ": "ヅ", - "ヅ": chr(0xE0D5), - chr(0xE0D5): "ツ", - "テ": "デ", - "デ": "テ", - "ト": "ド", - "ド": "ト", - - #ナ行 - "ナ": chr(0xE0BC), - chr(0xE0BC): "ナ", - "ニ": chr(0xE0BD), - chr(0xE0BD): "ニ", - "ヌ": chr(0xE0BE), - chr(0xE0BE): "ヌ", - "ネ": chr(0xE0BF), - chr(0xE0BF): "ネ", - "ノ": chr(0xE0C0), - chr(0xE0C0): "ノ", - - #ハ行 - "ハ": "バ", - "バ": "パ", - "パ": "ハ", - "ヒ": "ビ", - "ビ": "ピ", - "ピ": "ヒ", - "フ": "ブ", - "ブ": "プ", - "プ": "フ", - "ヘ": "ベ", - "ベ": "ペ", - "ペ": "ヘ", - "ホ": "ボ", - "ボ": "ポ", - "ポ": "ホ", - - #マ行 - "マ": chr(0xE0C1), - chr(0xE0C1): "マ", - "ミ": chr(0xE0C2), - chr(0xE0C2): "ミ", - "ム": chr(0xE0C3), - chr(0xE0C3): "ム", - "メ": chr(0xE0C4), - chr(0xE0C4): "メ", - "モ": chr(0xE0C5), - chr(0xE0C5): "モ", - - #ヤ行 - #ヤ→ャ→ヤ゛→ャ゛ - "ヤ": "ャ", - "ャ": chr(0xE0C6), - chr(0xE0C6): chr(0xE0D6), - chr(0xE0D6): "ヤ", - "ユ": "ュ", - "ュ": chr(0xE0C7), - chr(0xE0C7): chr(0xE0D7), - chr(0xE0D7): "ユ", - "ヨ": "ョ", - "ョ": chr(0xE0C8), - chr(0xE0C8): chr(0xE0D8), - chr(0xE0D8): "ヨ", - - #ラ行 - "ラ": chr(0xE0C9), - chr(0xE0C9): "ラ", - "リ": chr(0xE0CA), - chr(0xE0CA): "リ", - "ル": chr(0xE0CB), - chr(0xE0CB): "ル", - "レ": chr(0xE0CC), - chr(0xE0CC): "レ", - "ロ": chr(0xE0CD), - chr(0xE0CD): "ロ", - - #ワ行 - "ワ": "ヮ", - "ヮ": "ヷ", - "ヷ": chr(0xE0D9), - chr(0xE0D9): "ワ", - "ヰ": "ヸ", - "ヸ": "ヰ", - "ヱ": "ヹ", - "ヹ": "ヱ", - "ヲ": "ヺ", - "ヺ": "ヲ", - - "ン": chr(0xE08B), - chr(0xE08B): "ン", - - "ー": chr(0xE0DB), - chr(0xE0DB): "ー" -}) - -key_dakuten = CustomKey( - design=KeyDesign( - label=TextLabel("小゙゚"), - color=KeyColor.normal - ), - press_actions=[ - katakana_replaceAction - ], - variations=[ - FlickVariationData( - direction=FlickDirection.left, - key=Variation( - design=VariationDesign(TextLabel("ヰ")), - press_actions=[ - InputAction("ヰ") - ], - ) - ), - FlickVariationData( - direction=FlickDirection.top, - key=Variation( - design=VariationDesign(TextLabel("あ゙い゙ゔ")), - press_actions=[ - MoveTabAction(tab_type=TabType.custom, - text="sippori_dakuten_hiragana") - ], - ) - ), - FlickVariationData( - direction=FlickDirection.right, - key=Variation( - design=VariationDesign(TextLabel("ヱ")), - press_actions=[ - InputAction("ヱ") - ], - ) - ) - ] -) -#キーを一覧する -katakana_keys = [ - KeyData(specifier=GridFitSpecifier(0, 0), key=SystemKey(SystemKeyType.flick_star123_tab)), - KeyData(specifier=GridFitSpecifier(0, 1), key=SystemKey(SystemKeyType.flick_abc_tab)), - KeyData(specifier=GridFitSpecifier(0, 2), key=SystemKey(SystemKeyType.flick_hira_tab)), - KeyData(specifier=GridFitSpecifier(0, 3), key=SystemKey(SystemKeyType.change_keyboard)), - KeyData(specifier=GridFitSpecifier(1, 0), key=key_ア), - KeyData(specifier=GridFitSpecifier(2, 0), key=key_カ), - KeyData(specifier=GridFitSpecifier(3, 0), key=key_サ), - KeyData(specifier=GridFitSpecifier(1, 1), key=key_タ), - KeyData(specifier=GridFitSpecifier(2, 1), key=key_ナ), - KeyData(specifier=GridFitSpecifier(3, 1), key=key_ハ), - KeyData(specifier=GridFitSpecifier(1, 2), key=key_マ), - KeyData(specifier=GridFitSpecifier(2, 2), key=key_ヤ), - KeyData(specifier=GridFitSpecifier(3, 2), key=key_ラ), - KeyData(specifier=GridFitSpecifier(1, 3), key=key_dakuten), - KeyData(specifier=GridFitSpecifier(2, 3), key=key_ワ), - KeyData(specifier=GridFitSpecifier(3, 3), key=SystemKey(SystemKeyType.flick_kutoten)), - KeyData(specifier=GridFitSpecifier(4, 0), key=CustomKey.flickDelete()), - KeyData(specifier=GridFitSpecifier(4, 1), key=CustomKey.flickSpace()), - KeyData(specifier=GridFitSpecifier(4, 2, width=1, height=2), key=SystemKey(SystemKeyType.enter)), -] - - -#カスタードオブジェクトを作成 -sippori_dakuten_hiragana = Custard( - identifier="sippori_dakuten_hiragana", - language=Language.none, - input_style=InputStyle.direct, - metadata=Metadata( - custard_version="1.0", - display_name="しっぽり明朝濁点ひらがな", - ), - interface=Interface( - key_style=KeyStyle.tenkey_style, - key_layout=GridFitLayout(5, 4), - keys=hiragana_keys - ) -) - -#カスタードオブジェクトを作成 -sippori_dakuten_katakana = Custard( - identifier="sippori_dakuten_katakana", - language=Language.none, - input_style=InputStyle.direct, - metadata=Metadata( - custard_version="1.0", - display_name="しっぽり明朝濁点カタカナ", - ), - interface=Interface( - key_style=KeyStyle.tenkey_style, - key_layout=GridFitLayout(5, 4), - keys=katakana_keys - ) -) - -CustardList([sippori_dakuten_hiragana, sippori_dakuten_katakana]).write(name="sippori_dakuten", allow_overwrite=True) \ No newline at end of file diff --git a/python/source/__init__.py b/python/source/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/python/source/actions.py b/python/source/actions.py deleted file mode 100644 index 88413a4..0000000 --- a/python/source/actions.py +++ /dev/null @@ -1,302 +0,0 @@ -from __future__ import annotations -from enum import Enum, unique -from typing import Literal - - -class ActionDefaultArguments: - scan_targets = ["、", "。", "!", "?", ".", ",", ".", ",", "\n"] - - -@unique -class ScanDirection(str, Enum): - forward = "forward" - backward = "backward" - - -class Action: - """ - 全てのActionの継承元となるクラス。 - metaclassによって、自動的に割り当てられる。 - """ - pass - - -class ActionMeta(type): - """ - 全てのActionのメタクラス。 - メンバー`type`を持つかの検証と、継承元の割り当てを行う。 - Actionを作る際は、このクラスをmetaclassとして指定すればよい。 - """ - def __new__(meta, name, bases, attributes): - bases = (Action,) - if not "type" in attributes: - raise TypeError("Action has no type!") - return type.__new__(meta, name, bases, attributes) - - -class InputAction(metaclass=ActionMeta): - type = "input" - - def __init__(self, text: str): - """ - 文字を入力するアクション - Parameters - ---------- - text: str - 入力する文字 - """ - self.text = text - - -class ReplaceLastCharactersAction(metaclass=ActionMeta): - type = "replace_last_characters" - - def __init__(self, table: dict[str, str]): - """ - 最後の文字を置換するアクション - Parameters - ---------- - table: dict[str, str] - 置換に用いるテーブル - """ - self.table = table - -@unique -class ReplaceType(str, Enum): - default = "default" - dakuten = "dakuten" - handakuten = "handakuten" - kogaki = "kogaki" - - -class ReplaceDefaultAction(metaclass=ActionMeta): - """ - azooKeyデフォルトの置換アクション - """ - type = "replace_default" - def __init__(self, replace_type: ReplaceType = ReplaceType.default, fallbacks: list[ReplaceType] = []): - """ - 最後の文字を置換するアクション - Parameters - ---------- - replace_type: ReplaceType - 置換の種類。 - fallbacks: list[ReplaceType] - 最初に設定した置換が成功しなかった場合のフォールバック - """ - self.replace_type = replace_type - self.fallbacks = fallbacks - - -@unique -class CharacterForm(str, Enum): - hiragana = "hiragana" - katakana = "katakana" - halfwidth_katakana = "halfwidth_katakana" - uppercase = "uppercase" - lowercase = "lowercase" - - -class CompleteCharacterFormAction(metaclass=ActionMeta): - type = "complete_character_form" - - def __init__(self, forms: list[CharacterForm]): - """指定した形式に変換して確定するアクション""" - self.forms = forms - - -@unique -class TabType(str, Enum): - system = "system" - custom = "custom" - - -class MoveTabAction(metaclass=ActionMeta): - type = "move_tab" - - def __init__(self, tab_type: TabType, text: str): - """ - タブを移動するアクション - Parameters - ---------- - tab_type: TabType - タブのタイプ。"custom"または"system"を指定。 - text: str - タブの識別子 - """ - self.tab_type = tab_type - self.identifier = text - - -class MoveCursorAction(metaclass=ActionMeta): - type = "move_cursor" - - def __init__(self, count: int): - """ - カーソルを移動するアクション - Parameters - ---------- - count: int - 移動する文字数。負の値を指定した場合文頭方向に移動。 - """ - self.count = count - - -class SmartMoveCursorAction(metaclass=ActionMeta): - type = "smart_move_cursor" - - def __init__(self, direction: ScanDirection, targets: list[str]): - """ - 指定した文字の隣までカーソルを移動するアクション - Parameters - ---------- - direction: ScanDirection - 移動の向きを"forward"または"backward"で指定。 - targets: list[str] - 停止条件となる文字のリスト。 - """ - self.direction = direction - self.targets = targets - - -class LaunchApplicationAction(metaclass=ActionMeta): - type = "launch_application" - - def __init__(self, scheme_type: Literal['azooKey', 'shortcuts'], target: str): - """ - アプリケーションを起動するアクション。 - schemeとしてazooKeyを選んだ場合、'azooKey://' + targetを開く。 - schemeとしてshortcutsを選んだ場合、'shortcuts://' + targetを開く。 - target = run-shortcut?name=<ショートカット名>とすることで、任意のショートカットを開くことができる。 - Parameters - ---------- - scheme_type: Literal['azooKey', 'shortcuts'] - target: str - """ - self.scheme_type = scheme_type - self.target = target - - -class SelectCandidateAction(metaclass=ActionMeta): - type = "select_candidate" - - def __init__(self, selection_type: Literal['first', 'last', 'exact', 'offset'], value: int = None): - """ - 候補を選択するアクション。 - Parameters - ---------- - selection_type: Literal['first', 'last', 'exact', 'offset'] - value: int, selection_typeとして'exact'と'offset'を選んだ場合、valueの引数をあわせて指定する - """ - if value is not None: - self.selection = { "type": selection_type, "value": value } - else: - self.selection = { "type": selection_type } - -class DeleteAction(metaclass=ActionMeta): - type = "delete" - - def __init__(self, count: int): - """ - 文字を削除するアクション - Parameters - ---------- - count: int - 削除する文字数。負の値を指定した場合は文末方向の文字を削除。 - """ - self.count = count - - -class SmartDeleteAction(metaclass=ActionMeta): - type = "smart_delete" - - def __init__(self, direction: ScanDirection, targets: list[str]): - """ - 指定した文字の隣まで文字を削除するアクション - Parameters - ---------- - direction: ScanDirection - 削除する向きを"forward"または"backward"で指定。 - targets: list[str] - 停止条件となる文字のリスト。 - """ - self.direction = direction - self.targets = targets - - -class SmartDeleteDefaultAction(metaclass=ActionMeta): - """ - azooKeyデフォルトの文頭まで削除アクション - """ - type = "smart_delete_default" - - -class EnableResizingModeAction(metaclass=ActionMeta): - """ - 片手モードの調整を始めるアクション - """ - type = "enable_resizing_mode" - - -class ToggleCursorBarAction(metaclass=ActionMeta): - """ - カーソルバーの表示状態をtoggleするアクション - """ - type = "toggle_cursor_bar" - - -class ToggleTabBarAction(metaclass=ActionMeta): - """ - タブバーの表示状態をtoggleするアクション - """ - type = "toggle_tab_bar" - - -class ToggleCapsLockStateAction(metaclass=ActionMeta): - """ - Caps lockの状態をtoggleするアクション - """ - type = "toggle_caps_lock_state" - - -class DismissKeyboardAction(metaclass=ActionMeta): - """ - キーボードを閉じるアクション - """ - type = "dismiss_keyboard" - -class CompleteAction(metaclass=ActionMeta): - """ - 確定するアクション - """ - type = "complete" - -class PasteAction(metaclass=ActionMeta): - """ - ペーストを実行するアクション - """ - type = "paste" - - -@unique -class LongpressDuration(str, Enum): - normal = "normal" - light = "light" - - -class LongpressAction(object): - def __init__(self, duration: LongpressDuration = LongpressDuration.normal, start: list[Action] = [], repeat: list[Action] = []): - """ - イニシャライザ - Parameters - ---------- - duration: LongpressDuration = .normal - 長押しが成立する判定までにかかる時間の目安 - start: list[dict] = [] - 長押しが成立した段階で実行されるアクションのリスト - repeat: list[dict] = [] - 長押しが成立している間繰り返し実行されるアクションのリスト - """ - self.duration = duration - self.start = start - self.repeat = repeat diff --git a/python/source/custard.py b/python/source/custard.py deleted file mode 100644 index 8488b27..0000000 --- a/python/source/custard.py +++ /dev/null @@ -1,115 +0,0 @@ -from __future__ import annotations -from pathlib import Path -from .layout import * -from .keys import * -from .json import to_json -import json -from enum import Enum, unique - - -class CustardJSONEncoder(json.JSONEncoder): - def default(self, o): - if isinstance(o, Custard): - return to_json(o) - if isinstance(o, CustardList): - return to_json(o.custards) - # 他の型はdefaultのエンコード方式を使用 - return super(CustardJSONEncoder, self).default(o) - - -@unique -class Language(str, Enum): - ja_JP = "ja_JP" - en_US = "en_US" - el_GR = "el_GR" - none = "none" - undefined = "undefined" - - -@unique -class InputStyle(str, Enum): - direct = "direct" - roman2kana = "roman2kana" - - -@unique -class KeyStyle(str, Enum): - tenkey_style = "tenkey_style" - pc_style = "pc_style" - - -class Interface(object): - def __init__(self, key_layout: Layout, key_style: KeyStyle, keys: list[KeyData]): - self.key_layout = key_layout - self.key_style = key_style - self.keys = keys - - -class Metadata(object): - def __init__(self, custard_version: str, display_name: str): - self.custard_version = custard_version - self.display_name = display_name - - -class Custard(object): - def __init__(self, identifier: str, language: Language, input_style: InputStyle, metadata: Metadata, interface: Interface): - self.identifier = identifier - self.language = language - self.input_style = input_style - self.metadata = metadata - self.interface = interface - - def write(self, to: str = None, name: str = None, allow_overwrite: bool = False): - """ - Custardファイルを出力する関数 - Parameters - ---------- - to: str = None - 出力先のパスを指定 - name: str = None - 出力先のパスを指定しない場合にファイル名を指定 - allow_overwrite: bool = False - 上書きを許可するか否か - """ - pass - - -class CustardList(object): - def __init__(self, custards: list[Custard]): - self.custards = custards - - def write(self, to: str = None, name: str = None, allow_overwrite: bool = False): - """ - Custardファイルを出力する関数 - Parameters - ---------- - to: str = None - 出力先のパスを指定 - name: str = None - 出力先のパスを指定しない場合にファイル名を指定 - allow_overwrite: bool = False - 上書きを許可するか否か - """ - pass - - -def write(self, to: str = None, name: str = None, allow_overwrite: bool = False): - if to is None: - result_directory_path = Path('__file__').resolve().parent / 'results' - if not result_directory_path.exists(): - result_directory_path.mkdir() - if name is None: - name = 'custard' - target = result_directory_path / f'{name}.json' - number = 1 - while target.exists() and not allow_overwrite: - number += 1 - target = result_directory_path / f'{name}#{number}.json' - to = str(target) - - with open(f"{to}", mode="w") as f: - f.write(json.dumps(self, cls=CustardJSONEncoder, ensure_ascii=False)) - - -Custard.write = write -CustardList.write = write diff --git a/python/source/design.py b/python/source/design.py deleted file mode 100644 index a6565fb..0000000 --- a/python/source/design.py +++ /dev/null @@ -1,41 +0,0 @@ -from __future__ import annotations -import json -from enum import Enum, unique - - -@unique -class KeyColor(str, Enum): - normal = "normal" - special = "special" - selected = "selected" - unimportant = "unimportant" - - -class KeyLabel(object): - pass - - -class TextLabel(KeyLabel): - def __init__(self, text: str): - self.text = text - -class SystemImageLabel(KeyLabel): - def __init__(self, identifier: str): - self.system_image = identifier - -class MainAndSubLabel(KeyLabel): - def __init__(self, main: str, sub: str): - self.type = "main_and_sub" - self.main = main - self.sub = sub - - -class KeyDesign: - def __init__(self, label: KeyLabel, color: KeyColor): - self.label = label - self.color = color - - -class VariationDesign: - def __init__(self, label: KeyLabel): - self.label = label diff --git a/python/source/json.py b/python/source/json.py deleted file mode 100644 index 8449c71..0000000 --- a/python/source/json.py +++ /dev/null @@ -1,69 +0,0 @@ -from __future__ import annotations -from enum import Enum -import collections - -_ignore_objects = [] -def ignore_json(func): - """ - デコレーター修飾されたメソッドをjsonに含まない際に利用するデコレーター。 - デコレーターが複数ある際は、他のjson系以外のデコレーターより上部にくるように指定する。 - 例:@propertyと@rename_jsonと@ignore_jsonがある時:@propertyを一番下にする。 - @ignore_jsonと@rename_jsonの順序は問わない。 - """ - _ignore_objects.append(func) - return func - -_rename_objects = {} -def rename_json(export_name): - """ - デコレーター修飾されたメソッドをjsonに含む際に、キー名を変更するデコレーター。 - デコレーターが複数ある際は、他のjson系以外のデコレーターより上部にくるように指定する。 - 例:@propertyと@rename_jsonと@ignore_jsonがある時:@propertyを一番下にする。 - @ignore_jsonと@rename_jsonの順序は問わない。 - """ - def _rename_json(func): - _rename_objects[func] = export_name - return func - return _rename_json - -def _make_json(dict, instance): - json = {} - for key in dict: - value = dict[key] - if value in _ignore_objects: continue - if key.startswith('_'): continue - if callable(value): continue - if isinstance(value, collections.abc.Hashable) and value in _rename_objects: - json[_rename_objects[value]] = _to_json(value, instance) - else: - json[key] = _to_json(value, instance) - return json - -def _to_json(value, instance = None): - if isinstance(value, Enum): - return value - elif isinstance(value, list): - return list(map(lambda item: _to_json(item, instance), value)) - elif not instance is None and isinstance(value, property): - return value.__get__(instance) - elif hasattr(value, '__dict__'): - return { - **_make_json(value.__dict__, value), - **_make_json(value.__class__.__dict__, value) - } - return value - -def to_json(value): - """ - あらゆるものを、JSON Serializableにする。 - Enumはそのまま維持されるので、JSONになるわけではない。 - クラスのインスタンスは、メンバー変数・デコレーター修飾されたメソッド(propertyなど)が書き出される。 - 普通のメソッドは書きだされない。 - ※_で名前が開始されるメンバーなどは書きだされない。 - - Parameters - ---------- - value: Any - JSON Serializableにするもの。 - """ - return _to_json(value) diff --git a/python/source/keys.py b/python/source/keys.py deleted file mode 100644 index bf56ea9..0000000 --- a/python/source/keys.py +++ /dev/null @@ -1,215 +0,0 @@ -from __future__ import annotations -import json -from .variations import * -from .design import * -from .actions import * -from .json import ignore_json, rename_json -from enum import Enum, unique -from typing import Union - - -class Specifier(object): - pass - - -class GridFitSpecifier(Specifier): - @ignore_json - @property - def type(self): - return "grid_fit" - - def __init__(self, x: int, y: int, width: int = 1, height: int = 1): - self.x = x - self.y = y - self.width = width - self.height = height - - -class GridScrollSpecifier(Specifier): - @ignore_json - @property - def type(self): - return "grid_scroll" - - def __init__(self, index: int): - self.index = index - - -class Key(object): - pass - - -class CustomKey(Key): - @ignore_json - @property - def type(self): return "custom" - - def __init__(self, design: KeyDesign, press_actions: list[Action], longpress_actions: LongpressAction = LongpressAction(), variations: list[VariationData] = []): - self.design = design - self.press_actions = press_actions - self.longpress_actions = longpress_actions - self.variations = variations - - #utility - @ignore_json - @staticmethod - def flickSimpleInputs(center: str, subs: list[str], centerLabel: str = None): - variations: [FlickVariationData] = [] - for (letter, direction) in zip(subs, [FlickDirection.left, FlickDirection.top, FlickDirection.right, FlickDirection.bottom]): - variations.append( - FlickVariationData( - direction=direction, - key=Variation( - design=VariationDesign(TextLabel(letter)), - press_actions=[ - InputAction(letter) - ] - ) - ) - ) - - if centerLabel is None: - centerLabel = center - - return CustomKey( - design=KeyDesign(TextLabel(centerLabel), KeyColor.normal), - press_actions=[ - InputAction(center) - ], - variations=variations - ) - - #utility - @ignore_json - @staticmethod - def flickSimpleInputAndLabels(center: Union[tuple[str, str], str], left: Union[tuple[str, str], str, None] = None, top: Union[tuple[str, str], str, None] = None, right: Union[tuple[str, str], str, None] = None, bottom: Union[tuple[str, str], str, None] = None): - variations: [FlickVariationData] = [] - for (argument, direction) in zip([left, top, right, bottom], [FlickDirection.left, FlickDirection.top, FlickDirection.right, FlickDirection.bottom]): - if type(argument) is tuple: - label = argument[0] - input = argument[1] - elif type(argument) is str: - label = argument - input = argument - else: - continue - variations.append( - FlickVariationData( - direction=direction, - key=Variation( - design=VariationDesign(TextLabel(label)), - press_actions=[ - InputAction(input) - ] - ) - ) - ) - - if type(center) is tuple: - label = center[0] - input = center[1] - elif type(center) is str: - label = center - input = center - - return CustomKey( - design=KeyDesign(TextLabel(label), KeyColor.normal), - press_actions=[ - InputAction(input) - ], - variations=variations - ) - - #utility - @ignore_json - @staticmethod - def flickDelete(): - return CustomKey( - design=KeyDesign(SystemImageLabel( - "delete.left"), KeyColor.special), - press_actions=[DeleteAction(1)], - longpress_actions=LongpressAction(repeat=[DeleteAction(1)]), - variations=[ - FlickVariationData( - FlickDirection.left, - Variation( - design=VariationDesign(SystemImageLabel("xmark")), - press_actions=[SmartDeleteDefaultAction()] - ) - ) - ] - ) - - #utility - @ignore_json - @staticmethod - def flickSpace(): - return CustomKey( - design=KeyDesign(TextLabel("空白"), KeyColor.special), - press_actions=[InputAction(" ")], - longpress_actions=LongpressAction( - start=[ToggleCursorBarAction()]), - variations=[ - FlickVariationData( - FlickDirection.left, - Variation( - design=VariationDesign(TextLabel("←")), - press_actions=[MoveCursorAction(-1)], - longpress_actions=LongpressAction( - repeat=[MoveCursorAction(-1)]) - ) - ), - FlickVariationData( - FlickDirection.top, - Variation( - design=VariationDesign(TextLabel("全角")), - press_actions=[InputAction(" ")] - ) - ), - FlickVariationData( - FlickDirection.bottom, - Variation( - design=VariationDesign(TextLabel("tab")), - press_actions=[InputAction("\t")] - ) - ), - ] - ) - - -@unique -class SystemKeyType(str, Enum): - change_keyboard = "change_keyboard" - enter = "enter" - upper_lower = "upper_lower" - next_candidate = "next_candidate" - flick_kogaki = "flick_kogaki" - flick_kutoten = "flick_kutoten" - flick_hira_tab = "flick_hira_tab" - flick_abc_tab = "flick_abc_tab" - flick_star123_tab = "flick_star123_tab" - - -class SystemKey(Key): - @ignore_json - @property - def type(self): return "system" - - def __init__(self, identifier: SystemKeyType): - self._identifier = identifier - - @rename_json("type") - @property - def identifier(self): return self._identifier - - -class KeyData(object): - def __init__(self, specifier: Specifier, key: Key): - self.specifier = specifier - self.key = key - - @property - def specifier_type(self): return self.specifier.type - - @property - def key_type(self): return self.key.type diff --git a/python/source/layout.py b/python/source/layout.py deleted file mode 100644 index ebcae70..0000000 --- a/python/source/layout.py +++ /dev/null @@ -1,30 +0,0 @@ -from __future__ import annotations -import json -from enum import Enum, unique - - -class Layout(object): - pass - - -class GridFitLayout(Layout): - type: str = "grid_fit" - - def __init__(self, row_count, column_count): - self.row_count = row_count - self.column_count = column_count - - -@unique -class ScrollDirection(str, Enum): - vertical = "vertical" - horizontal = "horizontal" - - -class GridScrollLayout(Layout): - type: str = "grid_scroll" - - def __init__(self, direction: ScrollDirection, row_count: float, column_count: float): - self.direction = direction - self.row_count = row_count - self.column_count = column_count diff --git a/python/source/variations.py b/python/source/variations.py deleted file mode 100644 index cb0579e..0000000 --- a/python/source/variations.py +++ /dev/null @@ -1,38 +0,0 @@ -from __future__ import annotations -import json -from .design import * -from .actions import * -from enum import Enum, unique - - -class Variation(object): - def __init__(self, design: VariationDesign, press_actions: list[Action], longpress_actions: LongpressAction = LongpressAction()): - self.design = design - self.press_actions = press_actions - self.longpress_actions = longpress_actions - - -class VariationData(object): - pass - - -@unique -class FlickDirection(str, Enum): - left = "left" - top = "top" - right = "right" - bottom = "bottom" - - -class FlickVariationData(VariationData): - type = "flick_variation" - - def __init__(self, direction: FlickDirection, key: Variation): - self.direction = direction - self.key = key - -class LongpressVariationData(VariationData): - type = "longpress_variation" - - def __init__(self, key: Variation): - self.key = key diff --git a/python/test/__init__.py b/python/test/__init__.py deleted file mode 100644 index 8b13789..0000000 --- a/python/test/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/python/test/test_actions.py b/python/test/test_actions.py deleted file mode 100644 index f847c44..0000000 --- a/python/test/test_actions.py +++ /dev/null @@ -1,266 +0,0 @@ -from source.json import to_json -from source.actions import * -import unittest -import sys -import json -from pathlib import Path -sys.path.append(str(Path('__file__').resolve().parent)) - - -class TestActions(unittest.TestCase): - """test class of actions.py - """ - - def test_InputAction(self): - """test method for InputAction - """ - actual = to_json(InputAction("hoge😊√異")) - expected_json = { - "type": "input", - "text": "hoge😊√異" - } - self.assertEqual(expected_json, actual) - - def test_ReplaceLastCharactersAction(self): - """test method for ReplaceLastCharactersAction - """ - actual = to_json(ReplaceLastCharactersAction( - {"あ": "ぁ", "か": "が", "😆": "😭"})) - expected_json = { - "type": "replace_last_characters", - "table": {"あ": "ぁ", "か": "が", "😆": "😭"} - } - self.assertEqual(expected_json, actual) - - def test_MoveTabAction(self): - """test method for MoveTabAction - """ - actual = to_json(MoveTabAction( - tab_type=TabType.custom, text="flick_greek")) - expected_json = { - "type": "move_tab", - "tab_type": TabType.custom, - "identifier": "flick_greek" - } - self.assertEqual(expected_json, actual) - - actual = to_json(MoveTabAction( - tab_type=TabType.system, text="flick_kutoten")) - expected_json = { - "type": "move_tab", - "tab_type": TabType.system, - "identifier": "flick_kutoten" - } - self.assertEqual(expected_json, actual) - - def test_MoveCursorAction(self): - """test method for MoveCursorAction - """ - actual = to_json(MoveCursorAction(3)) - expected_json = { - "type": "move_cursor", - "count": 3 - } - self.assertEqual(expected_json, actual) - - actual = to_json(MoveCursorAction(-2)) - expected_json = { - "type": "move_cursor", - "count": -2 - } - self.assertEqual(expected_json, actual) - - def test_LaunchApplicationAction(self): - """test method for LaunchApplicationAction - """ - actual = to_json(LaunchApplicationAction( - "shortcuts", "run_shortcut?name=take_picture")) - expected_json = { - "type": "launch_application", - "scheme_type": "shortcuts", - "target": "run_shortcut?name=take_picture" - } - self.assertEqual(expected_json, actual) - - def test_SmartMoveCursorAction(self): - """test method for SmartMoveCursorAction - """ - actual = to_json(SmartMoveCursorAction(ScanDirection.forward, targets=[ - "!", "?", ".", ",", ":", ";"])) - expected_json = { - "type": "smart_move_cursor", - "direction": ScanDirection.forward, - "targets": ["!", "?", ".", ",", ":", ";"] - } - self.assertEqual(expected_json, actual) - - def test_SelectCandidateAction(self): - """test method for SelectCandidateAction - """ - actual = to_json(SelectCandidateAction("first")) - expected_json = { - "type": "select_candidate", - "selection": {"type": "first"} - } - self.assertEqual(expected_json, actual) - actual = to_json(SelectCandidateAction("exact", 5)) - expected_json = { - "type": "select_candidate", - "selection": {"type": "exact", "value": 5} - } - self.assertEqual(expected_json, actual) - - def test_DeleteAction(self): - """test method for DeleteAction - """ - actual = to_json(DeleteAction(12)) - expected_json = { - "type": "delete", - "count": 12, - } - self.assertEqual(expected_json, actual) - - actual = to_json(DeleteAction(-4)) - expected_json = { - "type": "delete", - "count": -4, - } - self.assertEqual(expected_json, actual) - - def test_SmartDeleteAction(self): - """test method for SmartDeleteAction - """ - actual = to_json(SmartDeleteAction(ScanDirection.forward, targets=[ - "!", "?", ".", ",", ":", ";"])) - expected_json = { - "type": "smart_delete", - "direction": ScanDirection.forward, - "targets": ["!", "?", ".", ",", ":", ";"] - } - self.assertEqual(expected_json, actual) - - def test_ReplaceDefaultAction(self): - """test method for ReplaceDefault - """ - actual = to_json(ReplaceDefaultAction(ReplaceType.handakuten, fallbacks=[ReplaceType.default])) - expected_json = { - "type": "replace_default", - "replace_type": "handakuten", - "fallbacks": ["default"] - } - self.assertEqual(expected_json, actual) - - def test_CompleteCharacterFormAction(self): - actual = to_json(CompleteCharacterFormAction([ - CharacterForm.katakana, CharacterForm.uppercase])) - expected_json = { - "type": "complete_character_form", - "forms": [CharacterForm.katakana, CharacterForm.uppercase] - } - self.assertEqual(expected_json, actual) - - actual = to_json(CompleteCharacterFormAction([CharacterForm.hiragana])) - expected_json = { - "type": "complete_character_form", - "forms": [CharacterForm.hiragana] - } - self.assertEqual(expected_json, actual) - - def test_NoArgumentsAction(self): - """test method for actions without arguments - """ - actual = to_json(SmartDeleteDefaultAction()) - expected_json = { - "type": "smart_delete_default", - } - self.assertEqual(expected_json, actual) - - actual = to_json(EnableResizingModeAction()) - expected_json = { - "type": "enable_resizing_mode", - } - self.assertEqual(expected_json, actual) - - actual = to_json(ToggleCursorBarAction()) - expected_json = { - "type": "toggle_cursor_bar", - } - self.assertEqual(expected_json, actual) - - actual = to_json(ToggleTabBarAction()) - expected_json = { - "type": "toggle_tab_bar", - } - self.assertEqual(expected_json, actual) - - actual = to_json(ToggleCapsLockStateAction()) - expected_json = { - "type": "toggle_caps_lock_state", - } - self.assertEqual(expected_json, actual) - - actual = to_json(DismissKeyboardAction()) - expected_json = { - "type": "dismiss_keyboard", - } - self.assertEqual(expected_json, actual) - - actual = to_json(PasteAction()) - expected_json = { - "type": "paste", - } - self.assertEqual(expected_json, actual) - - def test_LongpressAction(self): - """test method for LongpressAction - """ - - input = InputAction("happy") - delete = DeleteAction(-1) - smart_move_cursor = SmartMoveCursorAction( - ScanDirection.backward, targets=["0"]) - dismiss_keyboard = DismissKeyboardAction() - action = LongpressAction(start=[input, delete], repeat=[ - smart_move_cursor, dismiss_keyboard]) - - expected_json = { - "duration": "normal", - "start": [to_json(input), to_json(delete)], - "repeat": [to_json(smart_move_cursor), to_json(dismiss_keyboard)] - } - - self.assertEqual(expected_json, to_json(action)) - - action = LongpressAction(duration=LongpressDuration.light, - start=[input, delete], repeat=[ - smart_move_cursor, dismiss_keyboard]) - - expected_json = { - "duration": "light", - "start": [to_json(input), to_json(delete)], - "repeat": [to_json(smart_move_cursor), to_json(dismiss_keyboard)] - } - - self.assertEqual(expected_json, to_json(action)) - - def test_ScanDirection(self): - """test method for ScanDirection - """ - actual = json.dumps(ScanDirection.backward) - self.assertEqual("\"backward\"", actual) - - actual = json.dumps(ScanDirection.forward) - self.assertEqual("\"forward\"", actual) - - def test_TabType(self): - """test method for TabType - """ - actual = json.dumps(TabType.system) - self.assertEqual("\"system\"", actual) - - actual = json.dumps(TabType.custom) - self.assertEqual("\"custom\"", actual) - - -if __name__ == "__main__": - unittest.main() diff --git a/python/test/test_custard.py b/python/test/test_custard.py deleted file mode 100644 index 54491ea..0000000 --- a/python/test/test_custard.py +++ /dev/null @@ -1,107 +0,0 @@ -import unittest -import sys -from pathlib import Path -sys.path.append(str(Path('__file__').resolve().parent)) -from source.custard import * -from source.json import to_json - - -class TestCustard(unittest.TestCase): - """test class of custard.py - """ - - def test_Interface(self): - """test method for Interface - """ - layout = GridFitLayout(5, 4) - style = KeyStyle.tenkey_style - key = KeyData(GridFitSpecifier(3, 3), SystemKey( - SystemKeyType.flick_star123_tab)) - - interface = Interface(layout, style, [key]) - expected_json = { - "key_layout": to_json(layout), - "key_style": style, - "keys": [to_json(key)], - } - self.assertEqual(expected_json, to_json(interface)) - - def test_Metadata(self): - """test method for Metadata - """ - metadata = Metadata("1.0", "アインシュタインロンポウ") - expected_json = { - "custard_version": "1.0", - "display_name": "アインシュタインロンポウ", - } - self.assertEqual(expected_json, to_json(metadata)) - - def test_Language(self): - """test method for Language - """ - actual = json.dumps(Language.el_GR) - self.assertEqual("\"el_GR\"", actual) - - actual = json.dumps(Language.none) - self.assertEqual("\"none\"", actual) - - actual = json.dumps(Language.ja_JP) - self.assertEqual("\"ja_JP\"", actual) - - actual = json.dumps(Language.en_US) - self.assertEqual("\"en_US\"", actual) - - actual = json.dumps(Language.undefined) - self.assertEqual("\"undefined\"", actual) - - def test_InputStyle(self): - """test method for InputStyle - """ - actual = json.dumps(InputStyle.direct) - self.assertEqual("\"direct\"", actual) - - actual = json.dumps(InputStyle.roman2kana) - self.assertEqual("\"roman2kana\"", actual) - - def test_KeyStyle(self): - """test method for KeyStyle - """ - actual = json.dumps(KeyStyle.pc_style) - self.assertEqual("\"pc_style\"", actual) - - actual = json.dumps(KeyStyle.tenkey_style) - self.assertEqual("\"tenkey_style\"", actual) - - def test_Custard(self): - """test method for Custard - """ - layout = GridScrollLayout(ScrollDirection.horizontal, 4, 3.9) - style = KeyStyle.pc_style - key = KeyData(GridScrollSpecifier(134), SystemKey( - SystemKeyType.change_keyboard)) - - interface = Interface(layout, style, [key]) - metadata = Metadata("99.99", "全然善処") - identifier = "zen^3sho!" - language = Language.el_GR - input_style = InputStyle.direct - custard = Custard( - identifier=identifier, - language=language, - input_style=input_style, - metadata=metadata, - interface=interface - ) - - expected_json = { - "identifier": identifier, - "language": language, - "input_style": input_style, - "metadata": to_json(metadata), - "interface": to_json(interface) - } - self.assertEqual(expected_json, to_json(custard)) - - -if __name__ == "__main__": - unittest.main() diff --git a/python/test/test_design.py b/python/test/test_design.py deleted file mode 100644 index 792fa03..0000000 --- a/python/test/test_design.py +++ /dev/null @@ -1,97 +0,0 @@ -from source.json import to_json -from source.design import * -import unittest -import sys -from pathlib import Path -sys.path.append(str(Path('__file__').resolve().parent)) - - -class TestDesign(unittest.TestCase): - """test class of design.py - """ - - def test_KeyColor(self): - """test method for KeyColor - """ - actual = json.dumps(KeyColor.normal) - self.assertEqual("\"normal\"", actual) - - actual = json.dumps(KeyColor.special) - self.assertEqual("\"special\"", actual) - - actual = json.dumps(KeyColor.selected) - self.assertEqual("\"selected\"", actual) - - actual = json.dumps(KeyColor.unimportant) - self.assertEqual("\"unimportant\"", actual) - - def test_TextLabel(self): - """test method for TextLabel - """ - label = TextLabel("hogefugapiyo") - expected_json = { - "text": "hogefugapiyo", - } - self.assertEqual(expected_json, to_json(label)) - - def test_SystemImageLabel(self): - """test method for SystemImageLabel - """ - label = SystemImageLabel("azooKey") - expected_json = { - "system_image": "azooKey", - } - self.assertEqual(expected_json, to_json(label)) - - def test_MainAndSubLabel(self): - """test method for SystemImageLabel - """ - label = MainAndSubLabel(main="A", sub="BC") - expected_json = { - "type": "main_and_sub", - "main": "A", - "sub": "BC" - } - self.assertEqual(expected_json, to_json(label)) - - def test_KeyDesign(self): - """test method for KeyDesign - """ - label = SystemImageLabel("azooKey") - color = KeyColor.special - key_design = KeyDesign(label, color) - expected_json = { - "label": to_json(label), - "color": color - } - self.assertEqual(expected_json, to_json(key_design)) - - label = TextLabel("😭😭😭") - color = KeyColor.selected - key_design = KeyDesign(label, color) - expected_json = { - "label": to_json(label), - "color": color - } - self.assertEqual(expected_json, to_json(key_design)) - - def test_VariationDesign(self): - """test method for KeyDesign - """ - label = SystemImageLabel("azooKey") - design = VariationDesign(label) - expected_json = { - "label": to_json(label), - } - self.assertEqual(expected_json, to_json(design)) - - label = TextLabel("😭😭😭") - design = VariationDesign(label) - expected_json = { - "label": to_json(label), - } - self.assertEqual(expected_json, to_json(design)) - - -if __name__ == "__main__": - unittest.main() diff --git a/python/test/test_json.py b/python/test/test_json.py deleted file mode 100644 index 9953234..0000000 --- a/python/test/test_json.py +++ /dev/null @@ -1,71 +0,0 @@ -import unittest -import sys -from enum import unique, Enum -from pathlib import Path -sys.path.append(str(Path('__file__').resolve().parent)) -from source.json import * - - -class TestJSON(unittest.TestCase): - """test class of json.py - """ - - def test_to_json(self): - self.assertEqual(10, to_json(10)) - self.assertEqual(1.2, to_json(1.2)) - self.assertEqual("hoge", to_json("hoge")) - self.assertEqual(True, to_json(True)) - class SomeJSONableChild: - def __init__(self): - self.a = 100 - self.b = "hoge" - class SomeJSONable: - def __init__(self): - self.child = SomeJSONableChild() - self.a = True - self.b = [100, "foo", False, { "a": "b" }] - def fuga(): pass - - actual = to_json(SomeJSONable()) - expected_json = { - "child": { - "a": 100, - "b": "hoge" - }, - "a": True, - "b": [100, "foo", False, { "a": "b" }] - } - self.assertEqual(expected_json, actual) - - @unique - class SomeJSONableEnum(Enum): - foo = "foo" - bar = "bar" - self.assertEqual(SomeJSONableEnum.foo, to_json(SomeJSONableEnum.foo)) - - class SomeJSONableWithProperties: - def __init__(self, uniqueId): - self.uniqueId = uniqueId - - @property - def twice(self): return self.uniqueId * 2 - - @ignore_json - @property - def half(self): return self.uniqueId / 2 - - @rename_json("1/4") - @property - def quarter(self): return self.uniqueId / 4 - - actual = to_json(SomeJSONableWithProperties(12)) - expected_json = { - "uniqueId": 12, - "twice": 24, - "1/4": 3 - } - - self.assertEqual(actual, expected_json) - -if __name__ == "__main__": - unittest.main() diff --git a/python/test/test_keys.py b/python/test/test_keys.py deleted file mode 100644 index e93e367..0000000 --- a/python/test/test_keys.py +++ /dev/null @@ -1,248 +0,0 @@ -from source.json import to_json -from source.keys import * -import unittest -import sys -from pathlib import Path -sys.path.append(str(Path('__file__').resolve().parent)) - - -class TestKeys(unittest.TestCase): - """test class of keys.py - """ - - def test_GridFitSpecifier(self): - """test method for GridFitSpecifier - """ - specifier = GridFitSpecifier(3, 4) - expected_json = { - "x": 3, - "y": 4, - "width": 1, - "height": 1 - } - self.assertEqual(expected_json, to_json(specifier)) - - specifier = GridFitSpecifier(5, 9, 2, 2) - expected_json = { - "x": 5, - "y": 9, - "width": 2, - "height": 2 - } - self.assertEqual(expected_json, to_json(specifier)) - - def test_GridScrollSpecifier(self): - """test method for GridScrollSpecifier - """ - - specifier = GridScrollSpecifier(42) - expected_json = { - "index": 42 - } - self.assertEqual(expected_json, to_json(specifier)) - - def test_CustomKey(self): - """test method for CustomKey - """ - design = KeyDesign(TextLabel("ティッシュ"), KeyColor.selected) - press_actions = [ - MoveCursorAction(4), - InputAction("虫眼鏡型麻酔銃") - ] - key = CustomKey( - design=design, - press_actions=press_actions, - ) - expected_json = { - "design": to_json(design), - "press_actions": to_json(press_actions), - "longpress_actions": to_json(LongpressAction()), - "variations": [], - } - self.assertEqual(expected_json, to_json(key)) - - design = KeyDesign(TextLabel("花粉症"), KeyColor.selected) - press_actions = [ - MoveTabAction(tab_type=TabType.custom, - text="superstrongkeyboard"), - ] - variation_design = VariationDesign(TextLabel("アレジオン")) - variation = Variation(variation_design, [], LongpressAction()) - - key = CustomKey( - design=design, - press_actions=press_actions, - longpress_actions=LongpressAction(), - variations=[variation] - ) - expected_json = { - "design": to_json(design), - "press_actions": to_json(press_actions), - "longpress_actions": to_json(LongpressAction()), - "variations": [to_json(variation)], - } - self.assertEqual(expected_json, to_json(key)) - - def test_SystemKeyType(self): - """test method for SystemKeyType - """ - actual = json.dumps(SystemKeyType.change_keyboard) - self.assertEqual("\"change_keyboard\"", actual) - - actual = json.dumps(SystemKeyType.flick_kogaki) - self.assertEqual("\"flick_kogaki\"", actual) - - actual = json.dumps(SystemKeyType.flick_kutoten) - self.assertEqual("\"flick_kutoten\"", actual) - - actual = json.dumps(SystemKeyType.flick_abc_tab) - self.assertEqual("\"flick_abc_tab\"", actual) - - actual = json.dumps(SystemKeyType.flick_hira_tab) - self.assertEqual("\"flick_hira_tab\"", actual) - - actual = json.dumps(SystemKeyType.flick_star123_tab) - self.assertEqual("\"flick_star123_tab\"", actual) - - actual = json.dumps(SystemKeyType.enter) - self.assertEqual("\"enter\"", actual) - - def test_SystemKey(self): - """test method for SystemKey - """ - - key = SystemKey(SystemKeyType.flick_kogaki) - expected_json = { - "type": SystemKeyType.flick_kogaki - } - self.assertEqual(expected_json, to_json(key)) - - def test_KeyData(self): - """test method for KeyData - """ - specifier = GridScrollSpecifier(3) - key = SystemKey(SystemKeyType.flick_kogaki) - key_data = KeyData(specifier, key) - expected_json = { - "specifier_type": specifier.type, - "specifier": to_json(specifier), - "key_type": key.type, - "key": to_json(key) - } - self.assertEqual(expected_json, to_json(key_data)) - - specifier = GridFitSpecifier(1, 2, 3, 4) - key = CustomKey( - KeyDesign(SystemImageLabel("sun"), KeyColor.selected), []) - key_data = KeyData(specifier, key) - expected_json = { - "specifier_type": specifier.type, - "specifier": to_json(specifier), - "key_type": key.type, - "key": to_json(key) - } - self.assertEqual(expected_json, to_json(key_data)) - - def test_StaticKeys(self): - """test method for flickSpace and flickDelete - """ - flickSpace = CustomKey.flickSpace() - self.assertEqual(flickSpace.design.label.text, "空白") - self.assertEqual(flickSpace.design.color, KeyColor.special) - self.assertEqual(to_json(flickSpace.press_actions), - [to_json(InputAction(" "))]) - self.assertEqual(to_json(flickSpace.longpress_actions.start), [ - to_json(ToggleCursorBarAction())]) - self.assertEqual(flickSpace.longpress_actions.repeat, []) - self.assertEqual(len(flickSpace.variations), 3) - - flickDelete = CustomKey.flickDelete() - self.assertEqual(flickDelete.design.label.system_image, "delete.left") - self.assertEqual(flickDelete.design.color, KeyColor.special) - self.assertEqual(to_json(flickDelete.press_actions), - [to_json(DeleteAction(1))]) - self.assertEqual(flickDelete.longpress_actions.start, []) - self.assertEqual(to_json(flickDelete.longpress_actions.repeat), [ - to_json(DeleteAction(1))]) - self.assertEqual(len(flickDelete.variations), 1) - - def test_FlickSimpleInputs(self): - """test method for flickSimpleInputs - """ - inputs = CustomKey.flickSimpleInputs("裁判", subs=["冤罪", "贖罪", "脅迫罪"]) - self.assertEqual(inputs.design.label.text, "裁判") - self.assertEqual(inputs.design.color, KeyColor.normal) - self.assertEqual(to_json(inputs.press_actions), - [to_json(InputAction("裁判"))]) - self.assertEqual(inputs.longpress_actions.start, []) - self.assertEqual(inputs.longpress_actions.repeat, []) - - self.assertEqual(len(inputs.variations), 3) - - self.assertEqual(inputs.variations[0].direction, FlickDirection.left) - self.assertEqual(inputs.variations[0].key.design.label.text, "冤罪") - self.assertEqual(to_json(inputs.variations[0].key.press_actions), [ - to_json(InputAction("冤罪"))]) - - self.assertEqual(inputs.variations[0].key.longpress_actions.start, []) - self.assertEqual(inputs.variations[0].key.longpress_actions.repeat, []) - - self.assertEqual(inputs.variations[1].direction, FlickDirection.top) - self.assertEqual(inputs.variations[1].key.design.label.text, "贖罪") - self.assertEqual(to_json(inputs.variations[1].key.press_actions), [ - to_json(InputAction("贖罪"))]) - self.assertEqual(inputs.variations[1].key.longpress_actions.start, []) - self.assertEqual(inputs.variations[1].key.longpress_actions.repeat, []) - - self.assertEqual(inputs.variations[2].direction, FlickDirection.right) - self.assertEqual(inputs.variations[2].key.design.label.text, "脅迫罪") - self.assertEqual(to_json(inputs.variations[2].key.press_actions), [ - to_json(InputAction("脅迫罪"))]) - - self.assertEqual(inputs.variations[2].key.longpress_actions.start, []) - self.assertEqual(inputs.variations[2].key.longpress_actions.repeat, []) - - inputs = CustomKey.flickSimpleInputs( - "iOS", subs=["Android", "macOS", "Windows", "chromeOS"], centerLabel="OS") - self.assertEqual(inputs.design.label.text, "OS") - self.assertEqual(to_json(inputs.press_actions), - [to_json(InputAction("iOS"))]) - - inputs = CustomKey.flickSimpleInputAndLabels( - center=("やゆよ", "や"), - top="ゆ", - right=("え", "𛀁"), - bottom="よ" - ) - self.assertEqual(inputs.design.label.text, "やゆよ") - self.assertEqual(to_json(inputs.press_actions), - [to_json(InputAction("や"))]) - self.assertEqual(inputs.longpress_actions.start, []) - self.assertEqual(inputs.longpress_actions.repeat, []) - - self.assertEqual(len(inputs.variations), 3) - - self.assertEqual(inputs.variations[0].direction, FlickDirection.top) - self.assertEqual(inputs.variations[0].key.design.label.text, "ゆ") - self.assertEqual(to_json(inputs.variations[0].key.press_actions), [ - to_json(InputAction("ゆ"))]) - self.assertEqual(inputs.variations[0].key.longpress_actions.start, []) - self.assertEqual(inputs.variations[0].key.longpress_actions.repeat, []) - - self.assertEqual(inputs.variations[1].direction, FlickDirection.right) - self.assertEqual(inputs.variations[1].key.design.label.text, "え") - self.assertEqual(to_json(inputs.variations[1].key.press_actions), [ - to_json(InputAction("𛀁"))]) - self.assertEqual(inputs.variations[1].key.longpress_actions.start, []) - self.assertEqual(inputs.variations[1].key.longpress_actions.repeat, []) - - self.assertEqual(inputs.variations[2].direction, FlickDirection.bottom) - self.assertEqual(inputs.variations[2].key.design.label.text, "よ") - self.assertEqual(to_json(inputs.variations[2].key.press_actions), [ - to_json(InputAction("よ"))]) - self.assertEqual(inputs.variations[2].key.longpress_actions.start, []) - self.assertEqual(inputs.variations[2].key.longpress_actions.repeat, []) - - -if __name__ == "__main__": - unittest.main() diff --git a/python/test/test_layout.py b/python/test/test_layout.py deleted file mode 100644 index e814fcd..0000000 --- a/python/test/test_layout.py +++ /dev/null @@ -1,48 +0,0 @@ -import unittest -import sys -from pathlib import Path -sys.path.append(str(Path('__file__').resolve().parent)) -from source.layout import * -from source.json import to_json - - -class TestLayout(unittest.TestCase): - """test class of layout.py - """ - - def test_GridFitLayout(self): - """test method for GridFitLayout - """ - layout = GridFitLayout(0, 1) - expected_json = { - "type": "grid_fit", - "row_count": 0, - "column_count": 1 - } - self.assertEqual(expected_json, to_json(layout)) - - def test_GridScrollLayout(self): - """test method for GridScrollLayout - """ - layout = GridScrollLayout( - ScrollDirection.vertical, row_count=8, column_count=4.2) - expected_json = { - "type": "grid_scroll", - "direction": ScrollDirection.vertical, - "row_count": 8, - "column_count": 4.2 - } - self.assertEqual(expected_json, to_json(layout)) - - def test_ScrollDirection(self): - """test method for ScrollDirection - """ - actual = json.dumps(ScrollDirection.horizontal) - self.assertEqual("\"horizontal\"", actual) - - actual = json.dumps(ScrollDirection.vertical) - self.assertEqual("\"vertical\"", actual) - - -if __name__ == "__main__": - unittest.main() diff --git a/python/test/test_variations.py b/python/test/test_variations.py deleted file mode 100644 index 9132734..0000000 --- a/python/test/test_variations.py +++ /dev/null @@ -1,85 +0,0 @@ -import unittest -import sys -from pathlib import Path -sys.path.append(str(Path('__file__').resolve().parent)) -from source.variations import * -from source.json import to_json - - -class TestVariations(unittest.TestCase): - """test class of variations.py - """ - design = VariationDesign(SystemImageLabel("azooKey")) - press_actions = [ - ToggleCapsLockStateAction(), - MoveCursorAction(-4), - MoveTabAction(TabType.custom, "flick_greek") - ] - start = [ - InputAction("¡™£"), - ReplaceLastCharactersAction( - {"クレヨンしんちゃん": "ドラえもん", "妖怪ウォッチ": "ポケモン"}), - ] - repeat = [ - EnableResizingModeAction(), - SmartDeleteDefaultAction(), - ] - - def test_Variation(self): - """test method for Variation - """ - longpress_actions = LongpressAction(self.start, self.repeat) - variation = Variation( - self.design, self.press_actions, longpress_actions) - expected_json = { - "design": to_json(self.design), - "press_actions": to_json(self.press_actions), - "longpress_actions": to_json(longpress_actions), - } - self.assertEqual(expected_json, to_json(variation)) - - def test_FlickDirection(self): - """test method for FlickDirection - """ - actual = json.dumps(FlickDirection.left) - self.assertEqual("\"left\"", actual) - - actual = json.dumps(FlickDirection.top) - self.assertEqual("\"top\"", actual) - - actual = json.dumps(FlickDirection.bottom) - self.assertEqual("\"bottom\"", actual) - - actual = json.dumps(FlickDirection.right) - self.assertEqual("\"right\"", actual) - - def test_FlickVariationData(self): - """test method for FlickVariationData - """ - longpress_actions = LongpressAction(self.start, self.repeat) - variation = Variation( - self.design, self.press_actions, longpress_actions) - data = FlickVariationData(FlickDirection.bottom, variation) - expected_json = { - "type": "flick_variation", - "direction": FlickDirection.bottom, - "key": to_json(variation) - } - self.assertEqual(expected_json, to_json(data)) - - def test_LongpressVariationData(self): - """test method for LongpressVariationData - """ - longpress_actions = LongpressAction(self.start, self.repeat) - variation = Variation( - self.design, self.press_actions, longpress_actions) - data = LongpressVariationData(variation) - expected_json = { - "type": "longpress_variation", - "key": to_json(variation) - } - self.assertEqual(expected_json, to_json(data)) - - -if __name__ == "__main__": - unittest.main()