pypercard.core¶
PyperCard is a simple HyperCard inspired framework for PyScript for building graphical apps in Python.
Based on original pre-COVID work by Nicholas H.Tollervey.
Copyright (c) 2023 Anaconda Inc.
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Module Contents¶
Classes¶
|
Represents a card in the application. A card defines what is presented to the user. |
|
Represents a card based application. |
API¶
- class pypercard.core.Card(name, template=None, on_show=None, on_hide=None, auto_advance=None, transition=None, sound=None, sound_loop=False, background=None, background_repeat=False)
Represents a card in the application. A card defines what is presented to the user.
The app ensures that only one card is ever displayed at once. Each card has a
nameand an HTMLtemplatethat defines how it looks on the page. If atemplateis not passed in on instantiation, theCardwill look for atemplateelement within the DOM with the sameidas the givennameto use as the template instead.Cards may also have optional
auto_advanceandtransitionattributes for transitioning to a target card after a given period of time.Cards are rendered from the
templatein theshowmethod. The first timeshowis called it creates apyper-cardHTML element for the app to insert into the DOM.Bespoke behaviour for rendering can be defined by the user. This should be passed in as the optional
on_showargument when initialising the card. It will be called, at the end of the card’sshowfunction, but before the element to insert into the DOM is returned to the app. Theon_showfunction is called with the same arguments as a transition function: a reference to the app and the current card.The
hidemethod hides card’s HTML element, but leaves it in the DOM.Card’s can optionally take some action each time a card is hidden using the
on_hidemethod. Theon_hidemethod is called with the same arguments as a transition function: a reference to the app and the current card.It’s also possible to use the
register_transitionmethod to register a user defined function to handle events dispatched by elements found in the card’s HTML. These contain application logic and transition the app to new cards by returning a string indicating the name of the next card to show.The convenience functions called
get_by_id,get_elementandget_elementsreturn individual or groups of matching HTML elements rendered by this card, given a valid id or CSS selector (comments attached to the functions explain the specific behaviours).Cards can optionally define the nature of their background, via the
backgroundandbackground_repeatattributes. Thebackgroundshould either be a valid CSScoloror a URL to an image. If thebackgroundis an image, thebackground_repeatflag will indicate if the image will fill the whole screen or repeat in a tiled fashion (the default is to fill the whole screen).Initialization
Initialise the card with a
nameunique within the application in which it is used.The following optional arguments are available to customize the card’s appearance and behaviour.
The string content of the
templateargument is used to render the card. If not given, the card will attempt to extract theinnerHTMLfrom atemplatetag with an id of the given name of the card. Otherwise, the card will raise aRuntimeError.The
on_showfunction is called every time the card is shown. It should takeappandcardarguments (just like transitions) and be used for customising the rendered card.The
on_hidefunction is called every time the card is hidden. It should takeappandcardarguments (just like transitions) and be used for stopping actions (sounds etc.).The
auto_advanceis the number of seconds, as afloatorint, to wait until thetransitionis evaluated to discern the next card to which to automatically transition.The
transitioncan be either a string containing the name of the card to which to automatically transition, or a transition function to call that returns a string containing the name of the next card.Either both
auto_advanceandtransitionneed to be given, or both need to beNone. Otherwise, the card will raise aValueError. If thetransitionis not a string or function or theauto_advanceis not an integer or float, aTypeErrorwill be raised.The optional
backgroundargument can either contain a valid CSScoloror a URL to an image to display as the background.The optional
background_repeatflag defines if thebackgroundimage fills the whole screen (the default) or repeats in a tiled fashion (if the flag is set toTrue).- register_app(app)
Add a reference to the hosting app, of which this card is a part.
- show()
Show the card to the user.
If this is the first time the card has been shown a
pyper-cardelement will be created for it and inserted into the DOM (as a child of the app’spyper-appelement).If the card has already been shown then we simply make it visible by setting the element’s
displayattribute toblock.Ensures the template is
.format-ed with theself.app.datastoredictionary (so named custom values can be inserted into the template).Rebinds any user defined transitions to the newly rendered elements created by the card.
- _add_dom_event_listeners()
Add DOM event listeners for any transitions added via “app.transition”.
- _start_auto_advance_timer()
Start the card’s auto-advance timer.
- hide()
Hide the card from the user.
This leaves the card in the DOM but just sets
displaytonone, and removes any DOM event listeners.
- _remove_dom_event_listeners()
Remove any DOM event listeners that were hooked up when the card was shown.
- register_transition(dom_event_name, element_id=None, query=None)
event_name- e.g. “click”element_id- the unique ID identifying the target element.query- a CSS selector identifying the target element(s).
- get_by_id(element_id)
Convenience function for getting a child element by id. Returns
Noneif no element is found.
- get_element(selector)
Convenience function for getting a child element that matches the passed in CSS selector. Returns
Noneif no element is found.
- get_elements(selector)
Convenience function for getting a Python list of child elements that match the passed in CSS selector. Returns an empty list if no elements are found.
- class pypercard.core.App(name=None, datastore=None, cards=None, sounds=None)
Represents a card based application.
This encapsulates the state (as a
DataStore), stack ofCardinstances, and registering transitions.Other app-wide functions (such as playing or pausing sounds) are methods of this class. To add your own app-wide functions, create a sub-class of this one.
TODO: It will be possible to dump and load a declarative
JSONrepresentation of the application, once the specification and capabilities of an app are finalised.If no default arguments given, the app will assume sensible defaults.
Initialization
Initialise a PyperCard app.
If no
nameis given, the page’stitlevalue is used, otherwise the givennamebecomes the pagetitle.The
datastoreis an optional pre-populatedDataStoreinstance.The
cardsare an optional list ofCardinstances with which to initialise the app. If no cards are given, the app will look in the DOM fortemplatetags to populate the card stack.The
soundsdict contains defaultname/urlpairs that define the initial sounds the app may need to play.- _new_id()
Gets a likely unique id to be attached to an element that doesn’t have one (but should).
Why not UUID? MicroPython.
- _harvest_cards_from_dom()
Harvest any cards defined in the DOM.
This queries the DOM for all ‘template’ tags. The contents and attributes of each template tag is used to configure a card in the app’s stack of cards.
Returns a (possibly empty) list of the Card instances.
- _resolve_card(card_reference)
Given a card reference, that could be either a string containing the card’s name, or a card object, returns the correct card instance if the card is in the app’s stack.
Otherwise, raises a
ValueError.
- show_card(card)
Show the referenced card into the DOM via
self.placeholder.TODO: enable different types of visual transition between cards (e.g. fade, slide etc…).
- hide_card(card)
Hide the specified card.
- add_card(card)
Add a card to the stack.
- get_next_card(card)
Get the next card sequentially in the card list.
Returns
Noneif ‘card’ is the last card.
- remove_card(card_reference)
Remove a card from the stack.
The reference to the card can be an instance of the card itself, or a string containing the card’s
name.
- add_sound(name, url)
Add a named Audio object to the application, to play the sound file found at the given URL.
NOTE The URL is NOT a reference to a file on the PyScript filesystem, but a file accessible to the browser via an HTTP request.
- get_sound(name)
Get the sound referenced by the given name.
If the name doesn’t reference a sound, a ValueError is raised.
- remove_sound(name)
Remove the Audio object referenced by the given name.
- play_sound(name, loop=False, multitrack=False, restart=False)
Play the sound, added to self with the given name. If the sound was paused with the
keep_placeflag set toTrue, the sound will resume playing from the place at which it was paused. Otherwise, the sound will play from the start.If
loopisTruethe sound will keep repeating until paused or removed from the application.If
multitrackisTruethen any currently playing sounds will continue to play. The default is false, so only one track will play at any given time (the most recet track to be played).If
restartisTruethen, if the sound is already playing when this function is called, it will be restarted from the beginning, otherwise the sound will be allowed to continue to play as is.
- pause_sound(name, keep_place=False)
If the sound, added to self with the given name, is playing, pause it. If
keep_placeisTruethe sound will pause at its current location. Otherwise, should the sound be played again, it will play from the start.
- register_transition(dom_event_name, element_id=None, selector=None)
event_name- e.g. “click”element_id- the unique ID identifying the target element.query- a CSS selector identifying the target element(s).
- set_background(background='')
Set the body tag’s background style attribute to the given value. If no value is given, resets it to blank.
- transition(from_card_name_or_list, dom_event_name, id=None, query=None)
A decorator to create transitions for DOM events within the specified card.
This just adds a transition to the app’s state machine.
The
from_card_name_or_listcan be either a string of the name of the target card, or a list of target card names. If the card name is “*” the transition applies to ALL cards in.The
dom_event_nameis the name of the event, as dispatched by the browser, e.g. “click”.The
idis the uniqueidattribute of the target element within the referenced card[s], that will dispatch the event.Finally,
queryis a way to provide a valid CSS query to match elements within the referenced card[s], that will dispatch the event.
- start(card_reference=None)
Start the app with the referenced card.
The reference to the card can be an instance of the card itself, or a string containing the card’s
name.If no
card_referenceis given, the app will start with the first card that was added to its stack.
- dump()
TODO: Dump a tree (JSON) representation of the app.
- load(tree)
TODO: Load a tree (JSON) representation of the app.
- _create_auto_advance_transition(from_card)
Create a transition that accepts a timeout and advances to another card.
- _create_dom_event_transition(from_card_name, transition_fn_or_card_name, dom_event_name, element_id=None, selector=None)
Create a transition that is triggered by a DOM event.
- _create_card_state(card)
Create a state machine state for the specified card.
Returns a
tuplein the form (State, [Transition])
- _get_name_of_card_to_transition_to(from_card, transition_fn_or_card_name, input_)
Get the name of the card to transition to.