Automatizálások
A .clinkplugin fájl opcionális automation objektuma eseményeket, állapotot, beállításokat, parancsokat, kész szabályokat és parancsikonhelyeket deklarál. Minden elemnek stabil azonosítója, pontos sémaverziója és lokalizált címe van. A gazda hozza létre a plugin/<plugin-id>/<kind>/<id> neveket. Egy bővítmény nem használhat rendszerbeli vagy másik bővítményhez tartozó névteret.
Automatizálások ›Hogyan működnek a bővítmények
A panel a billentyűket váltja fel, a művelet pedig egyszer fut le egy szövegrészen. A bővítménynek nincs saját képernyője a billentyűzeten. A Clink meghatározott pillanatokban hívja a függvényeit, például amikor megnyílik a billentyűzet, vagy amikor befejezel egy szót, a bővítmény pedig frissítheti a szóközt vagy a saját mentett állapotát. A beállításai az appban jelennek meg, ugyanazokkal az építőelemekkel, amelyeket a panelek is használnak. A lenti WPM Spacebar egy teljes bővítmény.
def initial():
return {"on": False}
def settings(state):
return section("keys.spacebar", [
toggle("Show typing speed", state["on"], action="toggle"),
], title="WPM Spacebar")
def on_action(action, value, state):
state["on"] = value
if value:
claim("spacebar.text")
else:
release("spacebar.text")
space_text(None)
return state
def on_word(word, state):
if state["on"]:
space_text(f"{stats()['wpm']} wpm")
return stateA bővítményekhez Clink Pro szükséges. Mielőtt tárolóból telepítenél egyet, a Clink megkérdezi, engedélyezed-e az abból a tárolóból származó kódot, ugyanúgy, mint a paneleknél és a műveleteknél.
Az on_key és az on_word megkapja, amit gépelsz, egy szószámláló is így működik. A PyMini nem fér hozzá a hálózathoz és a fájlokhoz, ezért a bővítmény nem tudja elküldeni az interneten, amit gépelsz, amit pedig elment, az a Clinknél marad a készülékeden.
Az első bővítményed
A leggyorsabb út az indító szkript, amelyet az app ír meg neked. Egy kapcsolót tesz a Billentyűk > Szóköz alá, és amíg a kapcsoló be van kapcsolva, szavakat számol a szóközön. Öt lépés, letöltés nélkül.
- Nyisd meg a Bővítmények lapot, kapcsold be a bővítményeket felül, és koppints a + jelre egy új bővítményhez.
- A szerkesztő az indító szkripttel nyílik meg. Olvasd végig egyszer: initial(), settings(), on_action(), on_open() és on_word() az egész.
- Válts az Előnézetre. Kapcsold át a kapcsolót, majd koppints néhányszor az on_open és on_word gombokra, és figyeld a szóköz makettjét és a konzolt.
- Mentés. A bővítmény be van kapcsolva a listában, és a kapcsolója most már a Billentyűk > Szóköz alatt is ott van.
- Nyisd meg a billentyűzetet bárhol, és gépelj. A szóköz számol veled.
def initial():
return {"on": False, "words": 0}
def settings(state):
return section("keys.spacebar", [
toggle("Count words on the space bar", state["on"], action="toggle"),
], title="Word count")
def on_action(action, value, state):
if action == "toggle":
state["on"] = value
if value:
claim("spacebar.text")
else:
release("spacebar.text")
space_text(None)
return state
def on_open(state):
state["words"] = 0
if state["on"]:
space_text("0 words")
return state
def on_word(word, state):
state["words"] += 1
if state["on"]:
space_text(f"{state['words']} words")
return stateHorogpontok
Definiáld a 33 függvény bármelyikét, a feleslegeseket pedig hagyd ki. Mindegyik utolsó argumentumként megkapja a state értéket. Amelyek valamire reagálnak, visszaadják a state értéket, akár módosították, akár nem. Amelyek egy kérdésre felelnek (elements, draw, effects, a megjelenési horogpontok, haptics, hitboxes, suggestions és correct), a válaszukat adják vissza, és közben helyben is módosíthatják a state értéket.
| Horogpont | Mikor fut |
|---|---|
on_automation(command, args, state) | Az on_automation(command, args, state) egy jóváhagyott helyi parancsot futtat a meglévő elkülönített környezetben. Frissítheti a szóköz feliratát, közzétehet deklarált állapotot vagy kibocsáthat deklarált eseményt. Ez a hook nem szúrhat be szöveget, nem férhet hozzá a vágólaphoz, nem módosíthat tartós beállítást, és nem indíthat külső kérést. |
initial() | Egyszer, mielőtt bármilyen mentett állapot létezne. Adj vissza egy dict értéket bármivel, amit a JSON tárolni tud. |
settings(state) | Amikor a bővítmény beállításai megjelennek az appban. Add vissza a vezérlőit csomópontfaként. A billentyűzetben soha nem fut le. |
on_action(action, value, state) | Amikor a bővítmény valamelyik vezérlőjét használják. Az on_action(action, state) alak, value nélkül, szintén működik. |
on_open(state) | Amikor megjelenik a billentyűzet. Jó hely a stats() kiolvasására vagy a szóköz beállítására. |
on_close(state) | Amikor a billentyűzet bezárul. Az állapot közvetlenül ezután mentődik. |
on_key(key, state) | Minden alkalommal, amikor egy billentyű beír valamit. Minden leütésnél lefut, ezért legyen gyors. |
on_word(word, state) | Amikor egy szó elkészül, akár szóközzel, javaslattal vagy csúsztatással. |
on_backspace(state) | Amikor a törlés billentyűt lenyomják. Szöveget nem kap, csak az állapotot. |
on_suggestion(word, state) | Amikor egy javaslatra koppintanak. A word az, amelyikre koppintottak. |
on_language(code, state) | Amikor a gépelés nyelve megváltozik. A code az új nyelv, például en vagy de. |
on_field(kind, state) | Amikor a billentyűzet egy mezőhöz kapcsolódik. A kind értéke default, email, url, number, phone, password vagy search. |
on_tick(state) | Másodpercenként egyszer, amíg a billentyűzet látszik, akár gépelsz, akár nem. Ez a horogpont mindenhez, aminek magától kell változnia: óra, visszaszámlálás, vagy sebesség, amelynek nullára kell esnie, ha abbahagyod. |
on_swipe(direction, state) | Egy betűbillentyűn kezdődő legyintés: "left", "right", "up", "up_left" vagy "up_right". Csak akkor érzékeli, ha a húzásos gépelés ki van kapcsolva. Ha a horogpont nem kér semmit, a legyintés sima billentyűleütés marad; ha kér, előbb visszavonja azt a betűt, amelyen kezdődött. |
elements(state) | Amit ez a bővítmény egy egyéni kiosztásnak kínál. Adj vissza element(id, name, icon=, width=) bejegyzéseket, vagy hagyd ki a horogpontot. |
draw(id, state) | Egy elem arca, csomópontfaként. Nagyjából másodpercenként egyszer fut, amíg a billentyűzet látszik. |
effects(state) | Fényeffektek, amelyeket ez a bővítmény a Hatások oldalnak kínál. Adj vissza light_effect(...) bejegyzéseket, vagy hagyd ki a horogpontot. |
key_styles(state) | Billentyűstílusok a témaszerkesztőnek. Adj vissza key_style(...) bejegyzéseket; lásd lent a Megjelenések részt. |
themes(state) | Teljes témák a témaszerkesztő Bővítmények lapjára. Adj vissza theme(...) bejegyzéseket. |
popups(state) | Billentyű-előugró stílusok. Adj vissza popup_style(...) bejegyzéseket. |
animations(state) | Animációk: entrance(...), press_animation(...), letter_animation(...) és transition(...) tetszőleges keveréke. |
backgrounds(state) | Animált hátterek. Adj vissza particles(...) rétegekből álló background(...) bejegyzéseket. |
layouts(state) | Billentyűzetkiosztások. Adj vissza layout(...) bejegyzéseket. |
trails(state) | Húzási csíkok, amelyeket ez a bővítmény a csíkválasztónak kínál. Adj vissza trail(...) bejegyzéseket; lásd lentebb a Megjelenéseket. |
haptics(state) | Billentyűnként egy haptikus visszajelzés, billentyűnevekből érzetekre mutató dict formájában. A billentyűzet megnyitásakor, majd nagyjából másodpercenként olvasódik be. |
hitboxes(state) | Billentyűnként egy érintési terület, billentyűnevekből hitbox(...) értékekre mutató dict formájában. Ugyanabban az ütemben olvasódik be, mint a haptics. |
on_touch(key, x, y, state) | Minden koppintás után: melyik billentyűhöz került, és azon a billentyűn hol ért le az ujj. Az x és az y -0.5 és 0.5 között mozog, középen 0. |
suggestions(word, state) | Szavak a javaslatsávba, amíg a word gépelése folyik. Akkor fut, amikor a sáv megnyugszik, nem minden billentyűnél. |
correct(word, fix, state) | A szóköz épp lezárta a word szót. Adj vissza egy szót, amely helyette kerül be, False értéket, hogy maradjon úgy, ahogy begépelték, vagy None értéket, hogy a billentyűzet saját javítása érvényesüljön. |
bar_items(state) | Gombok és tárcsák, amelyeket ez a bővítmény a felső sávnak kínál. Adj vissza bar_button(...) és bar_knob(...) bejegyzéseket, vagy hagyd ki a hookot. |
key_art(state) | A billentyűkre festendő grafika, billentyűnevekből alakzatokra mutató dict formájában. Minden esemény után újra beolvasódik, amit a bővítmény hall, így a hookban módosított állapot megjelenik a billentyűkön. |
events(state) | Az eseménynevek, amelyeket az on_event hallani akar, a bővítmény betöltésekor egyszer beolvasva. Enélkül a bővítmény mindent hall a sűrű események kivételével. |
on_event(name, info, state) | Egyetlen hook mindenre, ami történik: open, close, word, backspace, suggestion, language, field, shift és plane, továbbá a sűrű key, key_down, key_up, predictions és tick, amelyeket névre szólóan kell kérni az events(state)-ben. |
def on_key(key, state):
if key == " " and setting("language") == "en":
state["spaces"] = state.get("spaces", 0) + 1
return state
def on_close(state):
haptic("light")
return stateAz app és a billentyűzet az állapot egyetlen példányán osztozik. Ha az appban bekapcsolsz egy kapcsolót, a billentyűzet következő megnyitásakor be lesz kapcsolva. Amit a billentyűzet számol, az ott lesz, amikor legközelebb megnyitod a bővítmény beállításait. A billentyűzet bezáráskor menti az állapotot, nem minden billentyű után.
Aktuális javaslat a szóközbillentyűn
A fő megjelenített javaslatot a context()["suggestion"] értékéből olvashatod ki. Iratkozz fel a predictions eseményre, hogy a változásokat az info["suggestion"] mezőben kapd meg. Mindkettőhöz hozzáférés kell a gépelési adatokhoz. Az on_suggestion egy javaslat elfogadásakor fut le, nem a javaslatok változásakor. A space_text(value or None) beállítja a feliratot, vagy visszaállítja, ha nincs javaslat. A szóközbillentyű működése nem változik.
def initial():
return {}
def events(state):
return ["predictions"]
def on_open(state):
space_text(context()["suggestion"] or None)
return state
def on_event(name, info, state):
if name == "predictions":
space_text(info["suggestion"] or None)
return state
def on_close(state):
space_text(None)
return stateÁllapot
Az állapot egyetlen dict. Az initial() építi fel először; utána minden horogpont ugyanazt a dict-et kapja, módosítja és visszaadja. Bármit tárol, amit a JSON tud: számokat, sztringeket, listákat, egymásba ágyazott dict-eket. Az app minden használt vezérlő után menti, a billentyűzet bezáráskor, és mindkettő ugyanazt a fájlt olvassa, így sosem térnek el sokáig.
def initial():
return {"session": 0, "total": 0, "longest": ""}
def on_open(state):
state["session"] = 0 # starts over each time the keyboard opens
return state
def on_word(word, state):
state["session"] += 1
state["total"] += 1 # survives, it is saved when the keyboard closes
if len(word) > len(state["longest"]):
state["longest"] = word
return state
def settings(state):
return vstack([
text(f"{state['total']:,} words so far"),
text(f"Longest: {state['longest'] or '...'}", size=13, color="gray"),
button("Start over", "reset", style="destructive"),
])
def on_action(action, value, state):
if action == "reset":
return initial()
return stateAz állapot visszaadása jó szokás, de nem kötelező: a dict referencia, ezért a helyben módosítás is működik. Adj vissza egy másik dict-et, mint fent az initial(), és az lesz az állapot.
Beállítások és szakaszok
A settings(state) a panelépítőkkel készült csomópontfát ad vissza: text, toggle, slider, stepper, segmented, button, row, field és az elrendezések. Ez a bővítmény oldalán jelenik meg a Bővítmények lapon. Ha egy részét section(anchor, children, title) hívásba csomagolod, az a rész a Clink egyik saját beállításképernyőjén is megjelenik, amellett a beállítás mellett, amelyhez kapcsolódik.
def settings(state):
return vstack([
text("Counts words as you type.", size=13),
section("keys.spacebar", [
toggle("Count on the space bar", state["on"], action="toggle"),
stepper(state["goal"], min=10, max=500, step=10, label="Goal", key="goal"),
], title="Word count"),
])A vezérlők, amelyekre egy bővítménynek a leggyakrabban szüksége van. Mindegyik vagy a key alá írja az új értékét az állapotba, vagy megnevez egy action-t az on_action számára, vagy mindkettőt. A teljes építőlista, az elrendezésekkel együtt, a panelek oldalán van.
| Építőelem | Mit rajzol |
|---|---|
toggle(label, on=False, key="", action="") | Kapcsoló. A key True vagy False értéket ír az adott állapotkulcsba. |
slider(value, min=0, max=100, step=1, label="", key="", action="") | Csúszka min és max között. A key az állást írja az adott állapotkulcsba. |
stepper(value, min=0, max=100, step=1, label="", key="", action="") | Egy érték − és + gombbal, min és max között. |
segmented(options, value=None, key="", action="") | Egy választás egy listából. A key a kiválasztott elemet írja az állapotkulcsba. |
field(key, placeholder="", action="", submit="") | Szövegdoboz, amely a state[key] kulcshoz kötődik. Megérintve a billentyűk abba a kulcsba írnak; a submit nevezi meg az Enterre futó kezelőt. |
button(label, action="", value=None, insert="", set=None, style="plain", icon="", enabled=True) | Egy gomb. Az insert beírja a szövegét oda, ahol éppen írsz, a set kulcsokat olvaszt az állapotba, az action pedig kezelőt nevez meg az on_action számára. A style lehet plain, primary, tinted, quiet vagy destructive. |
row(title, subtitle="", detail="", icon="", action="", value=None, insert="") | Megérinthető sor: cím, második sor, ikon és jobbra egy részlet. |
text(s, size=17, weight="regular", color="", align="leading", lines=0, mono=False) | Egy szövegsor. A weight lehet regular, medium, semibold, bold, heavy, light vagy thin; az align lehet leading, center vagy trailing; a lines korlátozza a tördelt sorok számát; a color színnevet vagy #RRGGBB értéket vesz. |
Hová kerülnek a szakaszok
A horgony egy kártya azonosítója a Clink saját beállítási képernyőinek egyikén. Nevezd meg a section() hívásban, és a bővítmény vezérlői közvetlenül az alá a kártya alá rajzolódnak, fölöttük a bővítmény nevével. A legegyszerűbb megtalálni: az appban nyisd meg a Továbbiak > Fejlesztő menüt, és kapcsold be az Azonosítók megjelenítését. Minden kártya kap egy kis infójelvényt, amely megnevezi az azonosítóját és koppintásra másolja; az oldalak a címsorban mutatják a sajátjukat.
Minden horgony, amelyet egy szakasz megnevezhet
analytics.heatmapanalytics.privacyanalytics.trendsanalytics.typing-testautomations.rulesgestures.accentsgestures.cursorgestures.deletegestures.generalgestures.suggestionsgestures.swipehaptics.feelkeys.adaptivekeys.faceskeys.hitboxeskeys.hitmapkeys.long-presskeys.numberrowkeys.onehandedkeys.roundnesskeys.sizekeys.spacebarkeys.spacingkeys.splitlanguages.applanguages.customlanguages.managelanguages.packslanguages.switchlanguages.typinglayout.arrangelayout.arrangementlayout.buildlayout.longpresslayout.presetslayout.topbarmotion.deletemotion.entrancemotion.glowmotion.key-pressmotion.key-responsemotion.lettersmotion.space-responsemotion.transitionpopups.stylesound.keysoundstext.automationtext.contenttext.correctionstext.historytext.punctuationtext.speedtext.suggestionstext.symbolsthemes.backgroundthemes.canvasthemes.theme
A keys.spacebar saját helyet kap, magán a Szóköz képernyőn. Egy szakasz olyan horgonnyal, amely nincs ebben a listában, továbbra is megjelenik a bővítmény oldalán, így egy elgépelés egy kártyába kerül, nem a bővítménybe.
Átvételek
Amikor egy bővítmény a Clink saját beállításainak egyikét vezérli, az embernek látnia kell ezt, és a kettő nem harcolhat egymással. A claim(control) kimondja, hogy a bővítményé: az app a beállítás kártyáján kiírja a bővítmény nevét, a szóköz szövegmezője pedig zárolva van, amíg a bővítmény tartja. A release(control) visszaadja. Az átvétel abban az on_action-ben legyen, amely bekapcsolja a funkciódat, az elengedés abban, amely kikapcsolja, és ugyanakkor állítsd vissza az értéket None-ra vagy a régi értékére. A listában kikapcsolt bővítmény mindent elenged, amit tartott.
def on_action(action, value, state):
if action == "toggle":
state["on"] = value
if value:
claim("spacebar.text")
space_text("...")
else:
release("spacebar.text")
space_text(None) # hand the person's own text back
return stateKét bővítmény is átveheti ugyanazt a vezérlőt; az app azt nevezi meg, amelyik utoljára vette át. Az átvételeket az app jegyzi fel, ezért az on_action-ből vedd át, amely ott fut. A billentyűzeten belül tett átvétel nem marad meg.
Parancsok és olvasások
A bővítmények minden panelparancsot használhatnak, ezen felül van hat saját parancsuk és két olvasásuk. A parancsok sorba kerülnek, és azután hajtódnak végre, hogy a függvényed visszatért, így a billentyűzeten semmi sem változik egy hívás közepén. Az olvasások a közvetlenül a hívás előtti értékeket adják vissza.
| Hívás | Mit csinál |
|---|---|
space_text(text) | Feliratot jelenít meg a szóközön, legfeljebb 32 karakterben. None értéket átadva visszaáll a felhasználó saját szóközszövege. |
space_language_text(text) | Felülírja a szóköz sarkában lévő nyelvjelzőt, önmagában, akkor is, ha a beépített jelző ki van kapcsolva. Egy sor, legfeljebb 12 karakter; a "" elrejti, a None pedig visszaadja a beépített szöveget. |
space_language_flag(language) | Zászlót tesz erre a jelzőre egy nyelvazonosító, például en_GB alapján, a mellékelt zászlógrafikából. A None visszaadja a beépített viselkedést. |
space_language_emoji(language) | Ugyanaz a jelző, a régió zászlóemodzsijaként. A három jelzőparancs egyetlen helyen osztozik, így az egyik jelzőbővítmény bekapcsolása kikapcsolja a többit. |
set_setting(name, value) | Név alapján módosítja a Clink egy beállítását megfelelő fajtájú értékre: logikai érték, a tartományon belüli szám, a választási lehetőségek egyike vagy szöveg. Ismeretlen név KeyError hibát dob. A rossz fajtájú vagy tartományon kívüli érték nem lép érvénybe, és a szerkesztő konzolja megmondja, mit vár a beállítás. |
claim(control) | Átvesz egyet a Clink saját beállításai közül. A kártyája az appban megnevezi a bővítményt, amelyik tartja. |
release(control) | Visszaadja a beállítást. Egy bővítmény kikapcsolásakor minden felszabadul, amit átvett. |
suggest(words) | Legfeljebb tíz saját szót tesz a javaslatsáv elejére. Addig maradnak, amíg valaki rá nem koppint egyre, meg nem nyomja a törlést, vagy a mező nem változik; a suggest([]) hamarabb eltünteti őket. Koppintásra begépeli a szót. |
banner(text) | Rövid üzenetet mutat a billentyűzeten egy pillanatra. Egy jelzésre való, nem beszélgetésre. |
press(key) | Lenyomja a billentyűzet egyik saját gombját, mintha megérintették volna: "space" vagy "delete". Bármely más név ValueError hibát dob. |
pick_suggestion(slot) | A sáv "left", "center" vagy "right" részében lévő javaslatot választja, pont úgy, mint egy koppintás. Görgetett sávnál az számít, ami a képernyőn látszik. Az on_swipe hookon belül abból a sávból választ, amilyen az ujj érintésekor volt. |
stats() | Egy dict értéket ad vissza wpm, peak_wpm, keystrokes, words és streak mezőkkel. A wpm élőben frissül, amíg a bővítmények be vannak kapcsolva. Az összesítések az Elemzésből jönnek, és nem frissülnek tovább, ha az Elemzés ki van kapcsolva. |
setting(name) | Név szerint kiolvassa az alább felsorolt beállítások egyikét. Bármilyen más név KeyError hibát vált ki. |
context() | Ugyanaz a pillanatkép, amit egy panel is olvas, bővítménynél kiegészülve a suggestion, shift (off, on vagy locked) és plane kulcsokkal. A dokumentumkulcsokat a gépelési adatokhoz való hozzáférés tölti fel; a shift enélkül is olvasható. |
| Kulcs | Mit tartalmaz |
|---|---|
stats()["wpm"] | Szó per perc az utolsó néhány másodpercből, a mezőbe érkező karakterek alapján. A szám egy-két másodperccel az indulás után jelenik meg, szünet alatt csökken, és nullára ér, ha abbahagyod. A törlés sosem növeli. |
stats()["peak_wpm"] | A Statisztika által valaha rögzített legjobb sebesség. |
stats()["keystrokes"] | Összes leütés, ahogy a Statisztika számolja. |
stats()["words"] | Véglegesített szavak összesen. |
stats()["streak"] | Egymást követő gépelős napok, a mai nappal bezárólag. |
A setting(name) és a set_setting(name, value) egyetlen névlistán osztozik, és a claim(control) is bármelyiket elfogadja. A logikai értékek True vagy False formában olvashatók, a számok számként, a választások az azonosítójukkal. A lista szándékosan hosszú: egy bővítmény szinte mindenre reagálhat, vagy majdnem mindent vezérelhet, amit egy személy az appban beállíthat.
A setting() által elfogadott nevek
analyticsemoji.skin_toneemoji.trailing_spacegestures.cursorgestures.cursor_stylegestures.highlight_shiftgestures.plane_slidegestures.predictive_flickgestures.quick_accentgestures.swipegestures.swipe_deletegestures.swipe_multi_wordgestures.swipe_space_commitgestures.swipe_two_thumbgestures.trailgestures.trail_stylegestures.trail_widthhaptics.enabledhaptics.intensityhaptics.sharpnesskeys.accentskeys.glyph_scalekeys.heightkeys.long_press_hintkeys.popup_stylekeys.popupskeys.radiuskeys.row_spacingkeys.spacingkeys.uppercasekeys.widthlanguagelanguage.bar_keylanguage.bar_key_stylelanguage.modelayoutlayout.dismiss_shortcutlayout.number_rowlayout.number_row_scalelayout.one_handedlayout.one_handed_shortcutlayout.one_handed_sidelayout.one_handed_widthlayout.splitlayout.split_gaplayout.split_number_rowlayout.split_shortcutlayout.split_space_barpet.cornerpet.enabledpet.speciessettings.accentHoldDelaysettings.accentMoveCancelsettings.activateWithIconsettings.adaptiveGrowsettings.adaptiveHitboxessettings.adaptivePredictAtWordStartsettings.adaptivePredictionWeightsettings.adaptiveShrinksettings.adaptiveSpacesettings.aiAutocorrectsettings.aiCompletionssettings.aiExtensionEnabledsettings.aiSearchsettings.aiToolsColorOverridessettings.aiToolsDiffStylesettings.aiToolsDisabledsettings.aiToolsLayoutStylesettings.aiToolsOrdersettings.aiToolsPromptOverridessettings.aiTranslatesettings.alternatingSplitsettings.arabicIndicNumeralssettings.backgroundEffectOverridesettings.clipboardCloseOnPastesettings.clipboardDeleteOnPastesettings.clipboardIgnoreImagessettings.clipboardIgnorePinsOnDeletesettings.clipboardStylesettings.cursorActivationHapticsettings.cursorLineStridesettings.cursorStepHapticsettings.customPanelsStandalonesettings.customPetIDsettings.deleteWordSwipeEngagesettings.deleteWordSwipeStridesettings.dictationAssistsettings.dictationAssistCustomsettings.dictationAssistLevelsettings.dictationColorSchemesettings.dictationGlassCapsulesettings.dictationSmartActionssettings.dictationStylesettings.dictationVisualStylesettings.dragUpThresholdsettings.emojiCategoryOrdersettings.emojiCellSpacingsettings.emojiColumnCountsettings.emojiCrossAxisSwitchesTabsettings.emojiCustomSetssettings.emojiGlyphScalesettings.emojiHiddenCategoriessettings.emojiHiddenFromPanelssettings.emojiRecentsCapsettings.emojiRecentsSortsettings.emojiRememberCategorysettings.emojiRowCountsettings.emojiScrollDirectionsettings.emojiSearchSlotsettings.emojiShowABCKeysettings.emojiShowBackspaceKeysettings.emojiStartCategoryIDsettings.emojiTabBarSlotsettings.emojiTabIconStylesettings.emojiToneHoldDelaysettings.extensionOrdersettings.extraTopBarssettings.formFreeCornerssettings.formLayoutEnabledsettings.gifShareAsLinksettings.glassPerRowMergesettings.glassReleaseResponsesettings.gridSwitchAnimationsettings.gridSwitchDurationsettings.handwritingInkColorsettings.handwritingInkGlowsettings.handwritingInkStylesettings.handwritingInkWidthsettings.hitboxScalesettings.iconPickerStylesettings.keyBloomScalesettings.keyLightingsettings.keyPressGlowsettings.keyPressInstantsettings.keyPressLingersettings.keySpringDampingsettings.keySpringResponsesettings.keyboardBottomPaddingsettings.keyboardLanguagessettings.keyboardTopPaddingsettings.longPressGlyphScalesettings.minPressVisiblesettings.notepadBrowseStylesettings.notepadModesettings.numberRowFontSizesettings.numberRowLeadingKeyssettings.numberRowTrailingKeyssettings.oneHandedCustomKeyssettings.oneHandedExtraKeyssettings.panelButtonHitboxScalesettings.persistentLeadingKeyssettings.persistentTrailingKeyssettings.petIdleMotionsettings.petScalesettings.pinyinFuzzyEnabledsettings.pluginLookssettings.popupSpringDampingsettings.popupSpringResponsesettings.predictiveFlickSuggestionPositionsettings.predictiveFlickSuggestionsSeparatesettings.reduceEffectsOnLowPowersettings.repeatAccelStepsettings.repeatHoldDelaysettings.repeatInitialIntervalsettings.repeatMinIntervalsettings.replacementsLayoutsettings.rowInsetssettings.secondaryNeuralModelsEnabledsettings.separateActivationsettings.separateLanguageLayoutssettings.showCaptureOverlaysettings.showCorrectionFieldsettings.showHitboxOverlaysettings.showIconsBeforeTypingsettings.showRecentEmojisettings.showTouchHeatmapsettings.showTouchSurfaceBoundssettings.showTouchTelemetryOverlaysettings.slideUpPickerStylesettings.solidPopupOpacitysettings.soundVoicesettings.spaceBloomScalesettings.spaceCursorActivationDelaysettings.spaceCursorDragScalesettings.spaceCursorStridesettings.spaceLeanMultipliersettings.spaceSpringDampingsettings.spaceSpringResponsesettings.spatialBiasEnabledsettings.spatialBiasGainsettings.splitIndicessettings.splitOtherPlanessettings.stickerGridSnapsettings.stickerPlacementssettings.suggestionDebounceDelaysettings.suggestionHitboxScalesettings.suggestionSegmentLiquidGlasssettings.suggestionSegmentStylesettings.suggestionSegmentsFollowThemesettings.suggestionSeparatorColorsettings.suggestionSeparatorStylesettings.suggestionTopPaddingsettings.swipeKeyMorphsettings.swipeMorphRadiussettings.swipeMorphStrengthsettings.swipeTrailEndWidthsettings.swipeTrailMaxLengthsettings.swipeTrailStartWidthsettings.swipeTrailTrimsettings.toolsButtonStylesettings.toolsHiddenFromPanelssettings.topBarItemssettings.topBarOrdersettings.translateLanguageOrdersettings.translateLanguagesDisabledsettings.translateStylesettings.translateTonesettings.vietnameseInputMethodsound.enabledsound.packsound.volumespacebar.cornerspacebar.language_codespacebar.sizespacebar.textstickers.enabledtext.arithmetictext.auto_capitalizetext.auto_punctuationtext.autocorrecttext.autocorrect_everywheretext.contactstext.conversionstext.double_space_periodtext.learningtext.punctuation_spacingtext.return_to_letterstext.revert_on_deletetext.smart_quotestext.suggestionstext.suggestions_animationtext.suggestions_heighttext.suggestions_scrolltext.suggestions_stylethemetheme.backgroundtheme.darktheme.delete_glyphtheme.entrancetheme.glyph_presstheme.lighttheme.match_systemtheme.press_styletheme.reactive_backgroundtools.calculatortools.clingtools.clipboardtools.conversiontools.dictationtools.dictionarytools.emojitools.giftools.handwritingtools.layout_switchertools.notepadtools.plugin_switchertools.profilestools.replacementstools.textfxtools.theme_switchertools.translate
Parancsok
insert()backspace()delete_word()replace()move_cursor()copy()close()haptic()toast()
Ahogy egy panel view() függvénye, a settings() is csak vezérlőket írjon le. Az onnan hívott parancsok nem hajtódnak végre, csak bekerülnek a konzolnaplóba.
Példák
Öt kis bővítmény, mindegyik teljes. Illessz be egyet egy új bővítménybe, mentsd el, és fut.
def initial():
return {"on": True}
def settings(state):
return section("keys.spacebar", [
toggle("Language on the space bar", state["on"], action="toggle"),
], title="Language badge")
def on_action(action, value, state):
if action != "toggle":
return state
state["on"] = value
if value:
claim("spacebar.text")
space_text(setting("language").upper())
else:
release("spacebar.text")
space_text(None)
return state
def on_open(state):
if state["on"]:
space_text(setting("language").upper())
return state
def on_language(code, state):
if state["on"]:
space_text(code.upper())
return stateSHORTCUTS = {"omw": "on my way", "brb": "be right back", "ty": "thank you"}
def on_key(key, state):
if key != " ":
return state
words = context()["before"].split()
if words and words[-1] in SHORTCUTS:
# the space is already in the text, so it goes too and comes back after
replace(len(words[-1]) + 1, SHORTCUTS[words[-1]] + " ")
return statedef initial():
return {"goal": 200, "count": 0}
def settings(state):
return vstack([
stepper(state["goal"], min=50, max=2000, step=50, label="Words per session", key="goal"),
progress(state["count"], total=state["goal"], label=f"{state['count']} of {state['goal']}"),
])
def on_open(state):
state["count"] = 0
return state
def on_word(word, state):
state["count"] += 1
if state["count"] == state["goal"]:
haptic("medium")
banner("Goal reached")
return statedef initial():
return {"muted": False, "was_on": True}
def on_field(kind, state):
# a password or a number field is not a place for key sounds
quiet = kind in ("password", "number", "phone")
if quiet and not state["muted"]:
state["was_on"] = setting("sound.enabled")
state["muted"] = True
set_setting("sound.enabled", False)
elif not quiet and state["muted"]:
state["muted"] = False
if state["was_on"]:
set_setting("sound.enabled", True)
return stateNAMES = ["sam", "ana", "team"]
def on_key(key, state):
typing = context()["before"].split(" ")[-1]
if typing.startswith("@"):
start = typing[1:].lower()
suggest([n for n in NAMES if n.startswith(start)])
state["showing"] = True
elif state.get("showing"):
suggest([]) # the mention is over, give the bar back
state["showing"] = False
return statedef on_swipe(direction, state):
if direction == "left":
delete_word()
elif direction == "right":
press("space") # the space bar's own path, so it autocorrects
elif direction == "up":
pick_suggestion("center")
elif direction == "up_left":
pick_suggestion("left")
elif direction == "up_right":
pick_suggestion("right")
return stateElemek egy kiosztásban
Egy egyéni kiosztás billentyűkből és elemekből áll: egy sáv a legutóbbi emojikkal, egy számsor, egy kurzorpad. Egy bővítmény hozzáadhatja a sajátjait. Az elements(state) megmondja, mit kínál, a draw(id, state) pedig megrajzol egyet, így egy billentyű bármit mutathat, amit a bővítmény ki tud számolni: gépelési sebességet, órát, visszaszámlálást vagy saját töltöttségjelzőt.
Két horogpont épít egyet. Az elements(state) felsorolja, mit kínálsz, elemenként egy bejegyzést, és az app ebből tölti fel a kiosztásszerkesztő palettáját. A draw(id, state) megkapja az egyik azonosítót, és visszaadja, mit kell rajzolni. Egy bővítmény többet is kínálhat; a draw mindegyikre külön kérdez rá.
| Hívás | Mit csinál |
|---|---|
element(id, name, icon="", width=2) | Egy felkínált elem. A width billentyűszélességben mér, ahogy egy kiosztás számolja, az icon pedig az az SF Symbol, amit a szerkesztő a palettáján mutat. |
sparkline(values, min=None, max=None, fill=False) | Vonal egy számsoron át, kitöltve a kapott helyet. Ha kihagyod a min és max értéket, a saját adataihoz igazodik. Csak bővítmény rajzolhatja, és billentyűre készült. |
POINTS = 30
def initial():
return {"history": []}
def elements(state):
return [element("sparkline", "WPM sparkline", icon="waveform.path.ecg", width=3)]
def on_tick(state):
history = state["history"]
history.append(stats()["wpm"])
state["history"] = history[-POINTS:]
return state
def draw(id, state):
rate = state["history"][-1] if state["history"] else 0
return hstack([
sparkline(state["history"], min=0, max=max(60, max(state["history"] or [0])), fill=True),
text(f"{rate}", size=12, weight="semibold"),
], spacing=5, align="center")Az arc egy csomópontfa, mint egy beállítási oldal, de a billentyű nem beállítási oldal: csak a rajzoló csomópontok számítanak, minden koppintható kimarad. A billentyű már a kiosztásé, így nincs benne hely egy gombnak.
AMIT EGY ARC RAJZOLHAT
sparklinetextbadgeiconprogresshstackvstackspacerdivider
Billentyűméretre tervezd. A width billentyűszélességben mér: 1 egy betű, 3 nagyjából egy sor harmada, és utólag át lehet méretezni. A szöveg egy sort kap, és összehúzódik, hogy elférjen; a színek alapból a billentyű saját szövegszínét követik, így az elem illik a körülötte lévő billentyűkhöz, hacsak mást nem kérsz. Egy sparkline az utolsó 120 pontját tartja meg, többet, mint amennyit egy billentyű megmutathat.
import time
def elements(state):
return [element("clock", "Clock", icon="clock", width=2)]
def draw(id, state):
return text(time.format("HH:mm"), size=15, weight="semibold")GOAL = 200
def initial():
return {"words": 0}
def elements(state):
return [element("goal", "Word goal", icon="target", width=2)]
def on_open(state):
state["words"] = 0
return state
def on_word(word, state):
state["words"] += 1
return state
def draw(id, state):
return vstack([
text(f"{state['words']}/{GOAL}", size=11),
progress(state["words"], total=GOAL),
], spacing=2)Az elemek egyéni kiosztásokban élnek, tehát előbb kiosztást kell építeni. Az előre elkészítettek nem tudnak elemet tartani: az első, amit a szerkesztő felajánl, hogy másold sajátoddá.
- Telepítsd a bővítményt és kapcsold be. Az elemei azonnal megjelennek.
- Nyisd meg a Kiosztást, hozz létre vagy másolj egy egyéni kiosztást, és lépj az Elrendezésre.
- Koppints az Elem gombra, válaszd ki a bővítmény elemét a sávból, és állítsd be a szélességét.
A szerkesztő Előnézete minden elemet kirajzol, amit a szkript kínál, nagyjából akkorában, mint a billentyű, amelyre kerül, a szóköz makettje alatt. Mentsd el, tedd ki egyszer, és a billentyűzet ugyanazt rajzolja.
Egy elem csak azt mutatja, amit a bővítmény rajzol: a koppintás nem csinál semmit, mert a billentyű már a kiosztásé. A kiosztás akkor is megtartja az elemet, ha a bővítménye ki van kapcsolva vagy eltávolították, és a billentyű újra megtelik, amint visszakerül.
Gombok és tárcsák a felső sávon
A billentyűk fölötti sávot a Kiosztás > Felső sáv alatt lehet összerakni, és egy bővítmény saját vezérlőket kínálhat bele. A bar_items(state) adja vissza őket: a bar_button(...) koppintásra való, a bar_knob(...) tekerésre. A lista a billentyűzet megnyitásakor és minden koppintás után újra beolvasódik, így egy elem a bővítmény állapotával jöhet és mehet.
| Hívás | Mit csinál |
|---|---|
bar_items(state) | Minden, amit ez a bővítmény a sávnak kínál, listaként. Az id-nek csak a bővítményen belül kell egyedinek lennie; a sáv a bővítmény saját azonosítója mellé teszi el. Ismétlődő id esetén az első marad, és amit a hook már nem ad vissza, az nem rajzolódik ki. |
bar_button(id, name, icon="", title="") | Egy gomb. A name az, amit a szerkesztő kilistáz, és amit a VoiceOver felolvas. Az icon egy SF Symbol, a title pedig legfeljebb 12 karakternyi felirat mellette: ikonnal és title nélkül az ikon áll magában, ikon nélkül a szöveg. A gombnak nincs értéke és nincs tartománya. Egy koppintás az on_action(id, None, state) hívást jelenti, és minden, amit a gomb csinál, ott történik. |
bar_knob(id, name, icon="", min=0, max=1, step=0, value=0, setting=None, art=None, rotor=None) | Egy tárcsa. A min és a max a tartománya, a step nullánál nagyobb értéknél fokozatokra osztja, a value pedig a kiindulópont. A setting= ehelyett az app egyik saját számvezérlőjéhez köti, és onnan jön a tartomány és az állás is. Az art= és a rotor= rajzolja meg Pythonban. |
def initial():
return {"width": 2.0}
def bar_items(state):
return [
bar_button("sig", "Sign off", icon="signature", title="Sign off"),
bar_knob("volume", "Key volume", icon="speaker.wave.2", setting="sound.volume"),
bar_knob("width", "Trail width", icon="scribble", min=1, max=6, step=0.5, value=state["width"]),
]
def on_action(action, value, state):
if action == "sig":
insert(" sent from Clink")
elif action == "width":
state["width"] = value
return stateMindkettő az on_action(action, value, state) hookon jön vissza, az elem id-je alapján, így a bővítmény sávelemei és a beállításvezérlői ugyanazt a hookot használják. Egy koppintás None-t küld. A tárcsa minden kattanásnál elküldi az értékét, amíg az ujj lent van, és még egyszer elengedéskor, így a bővítmény követheti a húzást, vagy megvárhatja az utolsó értéket.
A setting= paraméterrel ellátott tárcsa olyan beállítást tekeri, ami az appban már megvan, a fenti Parancsok és olvasások listájából, például sound.volume vagy haptics.intensity. Olyan név, amit az app nem ismer, KeyError a konzolon. A tartomány és a kiindulási állás ebből a vezérlőből jön, a billentyűzet saját másolata már húzás közben változik, így a következő leütés már az új szinten szól, az érték pedig elengedéskor mentődik. A nulláról felhúzott hangerő- vagy rezgéstárcsa a húzás idejére vissza is kapcsolja a hangot vagy a rezgést, hogy a kattanások felfelé menet hallatszódjanak és érezhetők legyenek; ezt a kapcsolót a bővítmény menti el, a saját set_setting hívásával az on_action-ben.
A tárcsa Pythonban is megrajzolható. Az art= az, ami a helyén marad, a foglalat vagy a test, a rotor= pedig a forgó lap, a minimumnál -135 fok, a maximumnál +135 fok. Mindkettő ugyanazokat az alakzatokat, festéseket, színátmeneteket és árnyékokat fogadja, mint a billentyűgrafika, egyenként legfeljebb tizenhat alakzatot, az unit="key" pedig a négyzetes számlapra méretezi a koordinátákat, ahol a negatív y-nál lévő mutató felfelé néz. A rajz megkapja a sáv szövegszínét "text" néven és a téma kiemelőszínét "accent" néven. Ha mindkettőt kihagyod, a tárcsa egy gyűrű az ikonnal a közepén; a szerkesztőben a sávba tett tárcsára bármelyik beépített kidolgozás rátehető.
A sávba magától nem kerül semmi. Az elemet kézzel kell odatenni, ugyanúgy, mint a menüt és a javaslatokat.
- Telepítsd a bővítményt és kapcsold be. A sávelemei rögtön megjelennek.
- Nyisd meg a Kiosztás > Felső sáv menüpontot.
- Add hozzá a bővítmény gombját vagy tárcsáját, és húzd a helyére. A tárcsához ezen felül kidolgozást is lehet választani.
Az építők szó nélkül átlépnek egy kulcsszót, amit nem ismernek. A setting=, min=, max=, step=, value=, art= és rotor= csak a bar_knob sajátja, így a bar_button ettől még egyszerű gombként épül fel, és nem szól semmi: a gomb munkája az on_action-be való. Fordítva a title= a gombé, a tárcsa pedig átlépi.
Fényeffektek
Egy bővítmény saját billentyűvilágítást is adhat. Az effects(state) light_effect(...) bejegyzéseket ad vissza, és mindegyik megjelenik az appban a Hatások > Bővítményekből részben, a beépített stílusok és a felhasználók saját effektjei mellett. Az effekt adat, nem rajz: rétegek halmaza, amelyet a billentyűzet maga animál. A szkriptben tehát semmi sem fut képkockánként, és a billentyűfelületek, a betűk, a ragyogás, a leütéskori felvillanás és az alvó mód ugyanúgy működik, mint a beépített stílusoknál.
| Hívás | Mit csinál |
|---|---|
light_effect(id, name, layers=[...], colors=[], icon="") | Egy effekt. Az id-nek csak a bővítményen belül kell egyedinek lennie. A layers light_layer(...) elemek listája, fentről lefelé alkalmazva. A colors legfeljebb nyolc "#rrggbb" karakterlánc, amelyeken a szín körbejár; ha elhagyod, az effekt a felhasználó Szín beállítását követi. |
light_layer(pattern, ...) | Egy réteg: egy minta az alábbi listából. Minden kulcsszó elhagyható. |
COLORS = ["#00e5ff", "#7c4dff", "#ff4081"]
def effects(state):
return [
light_effect("tide", "Tide", colors=COLORS, layers=[
light_layer("solid", low=0.2, high=0.2),
light_layer("wave", moves="both", speed=0.8, size=1.5,
direction="up"),
]),
]Minták
solidpulsewavegradienttwinklesweeprainflickerchecker
| Kulcs | Mit csinál |
|---|---|
moves="light" | Mit változtat a minta: "light" a fényerőt, "color" vagy "both". |
mix="add" | Hogyan találkozik a fényereje a fölötte lévő rétegekkel: "add", "max" a fényesebbet tartja meg, "multiply" pedig maszkként elsötétíti őket. |
shape="smooth" | A pulse, a wave és a gradient emelkedése és esése: "smooth", "ramp", "step" vagy "spike". |
direction="right" | Merre halad a wave, a gradient, a sweep és a rain: "right", "left", "down", "up", vagy "out" a középről kifelé. |
speed=1 | 0 és 4 között. 0-nál a minta áll. |
size=1 | 0,25 és 4 között: hányszor ismétlődik a minta a billentyűzeten. A twinkle-nél azt adja meg, hány billentyű világít, a sweep-nél a csóva hosszát. |
low=0, high=1 | A fényerő, amely között a minta mozog, mindkettő 0 és 1 között. Ha a low magasabb, mint a high, a minta megfordul. |
color_span=1, color_offset=0 | Mennyit halad a minta a színeken, és honnan indul, mindkettő 0 és 1 között. |
def effects(state):
return [
light_effect("scanner", "Scanner", layers=[
light_layer("wave", moves="color", speed=0.3),
light_layer("sweep", mix="multiply", speed=1.2, size=1.5),
]),
]Egy effekt kiválasztása bemásolja azt a felhasználó beállításaiba, így kikapcsolt bővítménnyel is működik tovább. Amíg a bővítmény be van kapcsolva és valamelyik effektje fut, a billentyűzet megnyitáskor, majd nagyjából másodpercenként újra beolvassa az effects(state) eredményét, és átveszi, ami változott. Így követheti az effekt az állapotot, az időt vagy a stats() értékeit.
def effects(state):
# Rounded, so the effect only changes when the pace really does.
tempo = round(0.3 + min(stats()["wpm"], 120) / 40, 1)
return [
light_effect("tempo", "Tempo", colors=["#ff3d7f", "#ffb000"], layers=[
light_layer("wave", moves="both", speed=tempo, low=0.15),
]),
]A szerkesztő effects gombja kilistázza, mit kínál a szkript. Ha mozgásban akarod látni, mentsd a bővítményt, válaszd ki az effektet a Hatások > Bővítményekből részben, és figyeld a képernyő tetején lévő billentyűzetet.
Kerekíts mindent, ami ugrál, például a gépelési sebességet. Egy effekt, amely minden másodpercben másképp érkezik vissza, minden másodpercben feleslegesen cserélődik. Ismeretlen minta vagy kulcsszó ValueError a szerkesztő konzoljában, a rétegek nélküli effekt pedig kimarad.
Megjelenések
Hét horogpont kínál választanivalót az appnak: key_styles, themes, popups, animations, backgrounds, trails és layouts. Mindegyik az alábbi hívásokkal épített bejegyzéseket ad vissza, és ezek a Bővítményekből alatt jelennek meg a beépített lehetőségek mellett. Kivételt a témák jelentenek: ezek saját Bővítmények lapot kapnak a témaszerkesztőben. Egy megjelenés számokból és szavakból áll, nem rajzoló kódból, így a szkriptben semmi sem fut képkockánként. A kiválasztás bemásolja a felhasználó beállításaiba, így kikapcsolt bővítménnyel is működik tovább, egy beépített lehetőség későbbi kiválasztása pedig félreteszi.
| Hívás | Mit csinál |
|---|---|
key_style(id, name, material=, variant=, shape=, shadow=, cap=cap(...)) | Billentyűstílus, amely a témaszerkesztőben épp megnyitott témára kerül a Stílus kártyáról. Csak a megnevezett mezők változnak: material, variant, shape, glass, fan, a mechanikus inner_radius, face_inset, edges, raised és light_angle, shadow (a 0 lapos) és outline. A színek a témáé maradnak. |
cap(outline="round", corner=None, travel=2, layers=[cap_layer(...)]) | Festett billentyűfelület egy billentyűstílushoz, cap_layer(...) bejegyzésekből rétegezve. Az outline round vagy rect, a corner felülírja a lekerekítést, a travel pedig azt mondja meg, milyen mélyre süllyed a billentyű lenyomáskor. |
cap_layer(kind, paint, inset=0, x=0, y=0, blur=0, fade=None, when=[...]) | Egy festett billentyűfelület egy rétege. A kind fill, stroke vagy inner, a paint a billentyűszín-nyelvtant, egy color(...)-t vagy egy gradient(...)-et fogad, a when pedig a pale, dark, pressed, resting és highlighted állapotokra szűkíti a réteget. A moves=False a helyén tartja a réteget, miközben a billentyű süllyed. |
theme(id, name, background=, keys=, key_text=, style=key_style(...), ...) | Teljes téma a témaszerkesztő Bővítmények lapján. A background, keys és key_text kötelező "#rrggbb" színek; a special, special_text, accent, background_bottom (átmenet lefelé), dark, font és weight elhagyható. A style=key_style(...) adja a felület kidolgozását. Kiválasztva egyéni témaként települ. |
popup_style(id, name, shape="tile", width=48, height=56, lift=30, ...) | A lenyomott billentyű fölötti buborék, a Megjelenés > Előugró ablakok alatt. A shape értéke "tile", "round" vagy "balloon"; a width, height, lift és font_size pontban értendő, a response és a damping a rugót állítja. |
entrance(id, name, opacity=0, x=0, y=0, scale=1, tilt=0, spin=0, ...) | Ahogyan a billentyűzet megérkezik, a Megjelenés > Megjelenés alatt. Az opacity, x, y, scale, tilt és spin a kiinduló állapot; a response és a damping szerinti rugóval áll nyugalomba. |
press_animation(id, name, scale=, x=0, y=0, rotation=0, ...) | A lenyomva tartott billentyű alakja, a Reakciók > Geometria alatt: a scale (vagy a scale_x és a scale_y), az x, az y és a rotation teljes lenyomásnál. |
letter_animation(id, name, scale=, x=0, y=0, rotation=0, anchor="center") | A rövid mozdulat, amelyet egy betű minden koppintáskor lejátszik, a Reakciók > Betűk alatt: ugyanazok a számok a csúcson, plusz az anchor. |
transition(id, name, x=0, y=0, scale=1, tilt=0, fade=True, duration=None) | A váltás a betűk, a 123 és a #+= között, a Megjelenés > Átmenet alatt. Az x és az y azt adja meg, mennyit mozdulnak a régi billentyűk a billentyűzet arányában, az újak pedig tükrözve érkeznek. A scale, a tilt, a fade és a duration is megadható. |
background(id, name, layers=[...], colors=[]) | Animált háttér, a Megjelenés > Háttér alatt: legfeljebb négy particles(...) réteg és legfeljebb nyolc "#rrggbb" szín. |
particles(shape="glow", count=40, size=4, speed=20, direction="none", ...) | Egy háttér egyik rétege. A shape értéke "dot", "glow", "streak", "ring" vagy "square"; a count, size, speed, direction, spread, gravity, wobble, life, twinkle és opacity alakítja a mozgást, a burst pedig részecskéket lő ki minden lenyomott billentyűből. |
layout(id, name, rows=[...], left=[], right=[]) | Kiosztás, az Elrendezés > Elrendezés alatt. Minden sor billentyűk listája: egy karakterlánc betű, minden más layout_key(...). A left és a right legfeljebb három billentyűt tesz a szóköz mellé. A kiválasztása egy közönséges egyéni kiosztást telepít. |
layout_key(glyph, action="insert", width=1) | Billentyű, amely nem egyszerű betű. Az action értéke insert, spacer, shift, delete, space, return, numbers, emoji, globe, tab, left, right, undo, redo vagy dismiss, a width pedig billentyűben értendő. |
trail(id, name, layers=[...], colors=[]) | Egy húzási csík. A layers trail_line, trail_stamps és trail_head bejegyzésekből áll, sorban kirajzolva, a colors pedig az a paletta, amire hivatkoznak. |
trail_line(width=1, tail_width=1, color=-1, glow=0, dash=0, gap=0, band=0, flow=0) | A húzás mentén futó vonal. A tail_width elvékonyítja a régi végét, a color=-1 az egész palettát elkeveri a vonal hosszában, a dash, gap, band és flow pedig feltördeli vagy mozgásba hozza. |
trail_stamps(shape="dot", size=1, spacing=14, scatter=0, spin=0, twinkle=0, color=-1) | A húzás mentén lehulló alakzatok: dot, ring, square, diamond, star, spark vagy heart. A spacing a köztük lévő távolság pontban, a scatter leszórja őket a vonalról, a spin forgatja, a twinkle pedig fel-le úsztatja őket. |
trail_head(shape="dot", size=1.5, pulse=0, opacity=1, color=-1, glow=0) | Az ujjhegynél lévő jel. A pulse lélegeztet rajta, a glow pedig fényt szór köré. |
def animations(state):
return [
entrance("swoop", "Swoop", y=90, scale=0.94, tilt=-20,
response=0.5, damping=0.72),
press_animation("dip", "Dip", scale=0.93, y=2),
letter_animation("bounce", "Bounce", y=-7, scale=1.12,
anchor="bottom"),
transition("glide", "Glide", x=0.3, scale=0.96),
]def backgrounds(state):
return [
background("snowfall", "Snowfall", colors=["#ffffff", "#cfe8ff"], layers=[
particles(shape="dot", count=70, size=2.2, speed=28,
direction="down", spread=12, wobble=10, life=9),
particles(shape="glow", count=0, size=3, life=1,
burst=8, burst_speed=90),
]),
]A trails(state) függvény trail csomópontokat adjon vissza. Minden nyomnak van colors színpalettája és rétegei, például trail_line. A color=-1 értékkel a vonal színei fokozatosan váltakoznak a húzás mentén. Kapcsold be a bővítményt, majd válaszd ki a nyomát a nyomválasztó Bővítményekből részében. A rajzelemek állapotban tárolása önmagában nem rajzol nyomot.
def trails(state):
return [trail("rainbow", "Rainbow", colors=["#ff0000", "#ff8800", "#ffff00", "#00cc44", "#0066ff", "#9900ff"],
layers=[trail_line(width=1.3, tail_width=0.2, color=-1)])]Egy megjelenés a kiválasztáskor másolódik, így a szkript későbbi módosítása nem változtatja meg a már használt megjelenést; újra ki kell választani. Egy elgépelt kulcsszó, a listáján kívüli szó vagy szám helyett szöveg hiba a szerkesztő konzoljában, a számok pedig az app saját vezérlőinek tartományaiban maradnak.
Rajz a billentyűkön
A key_art(state) billentyűnevekből rajzra mutató dictet ad vissza, a billentyűzet pedig a billentyű felületére festi. A billentyűnevek ugyanazok, mint a haptics-nál, a letters és keys tartalékokkal. A rajz lehet shape(...) lista, egyetlen alakzat, egy art([...]) réteg vagy rétegek listája, és minden réteg a saját órája szerint úszik át a következő rajzába, így egy billentyű két, eltérő sebességgel mozgó dolgot is hordozhat.
| Hívás | Mit csinál |
|---|---|
art(shapes, animate=0, curve="ease_out") | Egy animálódó réteg. Adj át új rajzot, és a réteg animate másodperc alatt úszik át rá a curve mentén: ease_out, linear, ease_in, ease_in_out vagy spring. Az egy billentyűn lévő több réteg mind külön animálódik. |
shape(kind, anchor="center", unit="pt", x=0, y=0, size=, width=, height=, fill=, stroke=, ...) | Egy megrajzolt dolog: circle, rect, capsule, line, path, text vagy icon. A billentyű anchor pontjától x és y távolságra ül, pontokban vagy unit="key" esetén a billentyű arányában. A fill és a stroke hexszínt, "text" vagy "accent" értéket, color(...)-t vagy gradient(...)-et fogad, és van még line_width, corner, trim_from, trim_to, rotation, opacity, blur és legfeljebb három árnyék. |
graph(values, min=None, max=None, width=0.8, height=0.25, stroke=, fill=) | Számsor közönséges alakzatokká kiterítve, hogy alakzatlistához fűzd vagy önmagában használd. A legfrissebb 60 véges minta marad meg, a határok egyébként magából a sorból jönnek, a fill pedig zárt alapvonalat tesz a vonal alá. |
color(value, opacity=1) | Egy festés: hexszín, vagy "text", illetve "accent", amit az alatta lévő billentyűhöz képest old fel, opacity átlátszósággal. |
gradient(kind, colors, stops=[], start=, end=, center=, radius=0.5) | Lineáris vagy sugaras színátmenet egy színlistán át. A stops helyezi el a színeket, a start és az end irányítja a lineárist, a center és a radius helyezi el a sugarasat. |
shadow(color, radius=4, x=0, y=0) | Árnyék egy alakzat alatt, legfeljebb három. A billentyűt kitöltő fátyol követi a billentyű sarkait ahelyett, hogy szögletesre vágná; a ragyogás viszont kiszökik a billentyűről. |
A rajz minden esemény után újra beolvasódik, amit a bővítmény hall, és ennyi az egész kör: állapotot módosítasz az on_event(name, info, state)-ben, és abból rajzolsz a key_art(state)-ben. Az events(state) nevezi meg a kívánt eseményeket, és a bővítmény betöltésekor olvasódik be egyszer. Enélkül a bővítmény mindent hall a key, key_down, key_up, predictions és tick kivételével, amelyek leütésenként vagy másodpercenként futtatnak szkriptet, ezért külön kell kérni őket. A shift és a sík változása akkor is újrarajzolja a rajzot, ha senki sem figyel, és a context()-be is eljut.
def initial():
return {"shift": "off"}
def events(state):
return ["shift"]
def on_event(name, info, state):
state["shift"] = info["state"]
return state
def key_art(state):
if state["shift"] != "locked":
return {}
lamp = shape("circle", anchor="top_right", x=-7, y=7, size=5,
fill="accent", shadow=shadow("accent", radius=4))
return {"shift": art([lamp], animate=0.12)}Alakzatok
circlerectcapsulelinepathtexticon
Billentyűnként tizenhat alakzat, az összes rétegét egybeszámolva, és útvonalanként 64 pont; ami ezen túl van, az kimarad. Az alakzat a saját width és height méretű dobozába rajzolódik, és a vastagság nélküli doboz semmit sem fest, ezért egy vízszintes vonalnak kell egy kis saját height, a pontjaival annak közepén (height=0.03, points=[[0, 0.5], [1, 0.5]]), különben szó nélkül nem jelenik meg.
Haptika, érintési területek és javítások
A haptics(state) és a hitboxes(state) billentyűnevekkel kulcsolt dicteket ad vissza: maga a betű, "space", "delete", "return", "shift" vagy "globe", aztán "letters" minden meg nem nevezett betűre és "keys" minden másra. A bővítmény által kihagyott billentyűk megtartják a felhasználó saját beállításait. Mindkét tábla a billentyűzet megnyitásakor, majd nagyjából másodpercenként olvasódik be, így miattuk semmi sem fut billentyűleütésenként.
| Hívás | Mit csinál |
|---|---|
feel(style=None, intensity=None, sharpness=None) | Haptikus visszajelzés: a style értéke "soft", "light", "medium", "heavy", "rigid" vagy "off", az intensity és a sharpness (0 és 1 között) pedig finomítja. Egy stílusszó önmagában is jó. |
hitbox(scale=1, x=0, y=0) | Érintési terület: az x és az y a billentyű célját a mérete ekkora hányadával tolja el, legfeljebb fél billentyűvel, a scale pedig nagyítja vagy kicsinyíti. Egy puszta szám scale-nek számít. |
def haptics(state):
return {
"space": "heavy",
"return": "rigid",
"delete": feel(intensity=0.45, sharpness=0.9),
}Az on_touch(key, x, y, state) minden koppintás után fut, miután a koppintás feldolgozása megtörtént, azzal, hogy hol ért le az ujj a billentyűn. A helyet a kirajzolt billentyűhöz mérjük, nem az eltolt célhoz, így egy bővítmény minden billentyűt arrafelé tolhat, ahol valójában megnyomják, anélkül hogy a saját eltolását kergetné.
def initial():
return {"keys": {}}
def on_touch(key, x, y, state):
if len(key) != 1:
return state
n, ax, ay = state["keys"].get(key, [0, 0.0, 0.0])
n = min(n + 1, 50)
ax += (x - ax) / n
ay += (y - ay) / n
state["keys"][key] = [n, ax, ay]
return state
def hitboxes(state):
boxes = {}
for key in state["keys"]:
n, x, y = state["keys"][key]
if n >= 12:
boxes[key] = hitbox(x=round(x * 0.6, 2), y=round(y * 0.6, 2))
return boxesA suggestions(word, state) szavakat tesz a sáv elejére, amíg egy szó gépelése folyik. A correct(word, fix, state) szavanként egyszer fut, amikor a szóköz lezárja a szót, a billentyűzet saját javításával vagy None értékkel, kikapcsolt automatikus javításnál is. Adj vissza egy szót, hogy bekerüljön, False értéket, hogy a szó úgy maradjon, ahogy begépelték, vagy None értéket, hogy a billentyűzet döntsön. Az első válaszoló bővítmény nyer, és a közvetlenül utána nyomott törlés visszavonja, mint bármely automatikus javítást.
SHORT = {"brb": "be right back", "omw": "on my way", "idk": "I don't know"}
def suggestions(word, state):
long = SHORT.get(word.lower())
return [long] if long else []
def correct(word, fix, state):
if len(word) > 1 and word.isupper():
return False
return NoneEgyik horogpont sem fut jelszómezőkben. A sáv javítási címkéje a billentyűzet saját javítását mutatja, nem azt, amit a correct visszaadna, és az on_touch-ban módosított tábla a következő ütemben jut el a billentyűzetig.
Tesztelés a szerkesztőben
A szerkesztő Előnézete egy helyettesítő billentyűzet. Élőben rajzolja a settings(state) függvényt, koppintásra bármely horogpontot elindít mintaszóval, billentyűvel vagy mezőtípussal, mutatja a szóközt úgy, ahogy a bővítmény hagyta, és felsorol mindent, amit a bővítmény a billentyűzettől kért. A stats() ott kitalált számokat ad vissza, így gépelés nélkül is megjelenik egy sebesség.
- Használd az előnézet vezérlőit. Mindegyik lefuttatja az on_action-t és újrarajzol.
- Koppints a horogpontgombokra abban a sorrendben, ahogy a billentyűzet tenné: on_open, aztán néhányszor on_word vagy on_key, majd on_close.
- Olvasd a konzolt. A parancsok úgy jelennek meg, ahogy írtad őket, alattuk a print() sorai, a hiba pedig megnevezi a sorát.
- Töltsd újra az állapot nullázásához. A szkript szerkesztése önmagában nem állítja vissza.
Az előnézetnek nincs dokumentuma, ezért az insert() és a replace() csak naplóz. Kipróbálásukhoz ments, és gépelj bármelyik mezőbe nyitott billentyűzettel.
Korlátok
Ha egy bővítmény fájlként vagy tárolóból érkezik, a Clink mentés előtt ellenőrzi. 64 000 bájtnál és 1600 sornál kisebbnek kell lennie, legalább egy horogpontot kell definiálnia, csak engedélyezett modulokat importálhat, és a következők egyikét sem tartalmazhatja:
Megosztott bővítményben nem megengedett
__exec(eval(open(compile(
Modulok, amelyeket egy megosztott bővítmény importálhat
jsonmathrandomresystime
Minden horogponthívás 2 000 000 értelmezőlépést kap, ugyanannyit, mint egy panel kirajzolása. Az on_key viszont minden leütésnél lefut, így az ott végzett nehéz munka jóval azelőtt lelassítja a gépelést, hogy elérné ezt a korlátot.
A fájl
A bővítmény egyetlen JSON-dokumentum. Az id frissítések között is állandó, a version szabad szöveg, amely a listában látszik, az icon egy SF Symbol neve, a source pedig a szkript escape-elt sortörésekkel. Oszd meg a szerkesztő ellenőrzőjéből, vagy importálj egyet a Bővítmények lap nyílgombjával.
{
"id": "word-count",
"name": "Word count",
"icon": "text.word.spacing",
"summary": "Counts words on the space bar",
"version": "1.0",
"author": "You",
"enabled": true,
"source": "def initial():\n return {\"on\": False}\n..."
}A bővítményeket .clinkplugin fájlként lehet megosztani, ez egy JSON-dokumentum, benne a szkripttel. Tárolón keresztül lehet közzétenni őket, ugyanúgy, mint a paneleket: egy mappa fájllal, egy manifeszttel és egy kiadással. A hivatalos tároló: anti-ltd/clink-plugins.
Tárházak ›Ha valami nem történik meg
Legtöbbször ezek egyike.
| Tünet | Mit érdemes ellenőrizni |
|---|---|
| Semmi sem történik | A bővítmények ki vannak kapcsolva a Bővítmények lap tetején, a bővítmény ki van kapcsolva a listában, vagy nincs Clink Pro tagság. Mindhárom esetben a billentyűzet egyetlen bővítményt sem futtat. |
| A szóköz szövege ki van szürkítve | Egy bővítmény átvette. A mező alatti sor megnevezi, melyik; kapcsold ki annak a bővítménynek a kapcsolóját, vagy magát a bővítményt, hogy visszakapd a mezőt. |
| Hiányzik a szakasz | A horgony el van gépelve. Vesd össze az app Azonosítók megjelenítése funkciójával, és ne feledd, hogy a szakasz továbbra is megjelenik a bővítmény saját oldalán, ahol először érdemes nézni. |
| Egy elem-billentyű üres | A mögötte lévő bővítmény ki van kapcsolva, el van távolítva, vagy a draw(id, state) hibát dobott. A kiosztás így is megtartja a billentyűt, tehát újra megtelik, amint a bővítmény bekapcsol. A hibát a szerkesztő konzolja mutatja. |
| Egy elem sosem változik | A draw továbbra is lefut, tehát a mögötte lévő állapot nem mozdul. Amit az arc mutat, azt horogpontból kell frissíteni: on_tick, ha magától változik, on_word vagy on_key, ha a gépelést követi. |
| A set_setting() nem csinált semmit | A fenti listában nem szereplő név KeyError hibát dob. A rossz fajtájú vagy tartományon kívüli érték kimarad, és a szerkesztő konzolja megmondja, mit vár a beállítás. Egy zárolt beállítás tagság nélkül vissza is ugrik. |
| A számláló lenullázódott | A billentyűzet bezáráskor menti az állapotot, nem minden billentyűnél. Egy, a rendszer által munkamenet közben leállított billentyűzet elveszíti, amit a bővítményei a megnyitás óta számoltak. Tartsd az összegeket az app oldali horogpontokban, ha ez számít. |
| Lassúnak érződik a gépelés | Valami nehéz fut az on_key-ben. Tedd át az on_word-be, csinálj belőle kevesebbet, vagy gyorsítótárazd az eredményt az állapotban. |
| Egy effekt hiányzik a Bővítményekből részből | A Bővítményeknek bekapcsolva, a bővítménynek engedélyezve kell lennie, és az effects(state) függvénynek legalább egy réteggel rendelkező light_effect-et kell visszaadnia. Koppints a szerkesztőben az effects gombra, hogy lásd, mi jött vissza, és keress ValueError-t a konzolban. |
| A felső sáv egyik eleme nem csinál semmit | A koppintás és az elengedett tárcsa is az on_action(action, value, state) hookba érkezik, az elem id-je és nem a neve alapján párosítva. A tárcsa csak akkor ír beállítást, ha a bar_knob megnevez egyet a setting=-ben; enélkül az érték a bővítményre marad, gomb pedig sosem ír beállítást. |