Skip to content

Python library for making GUI applications on the ReMarkable tablet using "simple".

License

Notifications You must be signed in to change notification settings

granolaonicecream/Carta

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

42 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Carta

Python library for making GUI applications on the reMarkable tablet wrapped around the "simple" application

Simulating the ReMarkable device

It can be a pain having to transfer the script & run the script from the RM each time. Especially if you want to use the device for something else at the time. To help with this, I've made the option to manually set the command to a simple x64 binary that can be run on linux which will write to fb.pnm - This is the framebuffer file that you'll need to read from.

In the misc folder I've provided the binary and a basic script as an example. To use this, just initialize the ReMarkable object like so:

rm = ReMarkable(simple="path/to/simple/binay") 

Finally, checkout remarkable-sim for events (like button clicking) support

Using Carta

Carta's purpose is to function as a Python wrapper around sas - the simple app script for making apps on the reMarkable without need to compiling code. It's written in python and is designed to be as user-friendly and easy to use as possible.

To use it, you'll need to install a few things onto your reMarkable, in an SSH session:

  • toltec - an unofficial reMarkable-specific package manager See instructions on toltec's website.
  • simple opkg install simple
  • rM2 users need display opkg install display
  • pip - the package manager for python
    wget https://bootstrap.pypa.io/get-pip.py
    python get-pip.py
    
  • carta - this library pip install carta

After having installed all the prerequisites, you are ready to start developing. Make a python script on the rM and run chmod +x on the script to make it executable. You'll also need to add a shebang to the script (#!/opt/bin/python at the top) so that it knows what to run it with.

Here's an example script that you can copy:

#!/opt/bin/python 
from carta import ReMarkable, Widget 
rm = ReMarkable() 

my_button = Widget(id="but1", typ="button", value="Hello!", x="50%", y="50%")

rm.add(my_button)
rm.display()

Let's walk through it line by line,

from carta import ReMarkable, Widget 
rm = ReMarkable() 

This imports the necessary "parts" for the library to function. The ReMarkable class is the main "driver" code and handles everything from interacting with simple to display your app to managing the widgets themselves. The widget dataclass are the actual contents themselves and there are 6 core types;

  • Label
  • Paragraph
  • Button
  • TextInput
  • Text Area
  • Image

Please refer to the simple spec for more detailed information.

my_button = Widget(id="but1", type="button", value="Hello!", x="50%", y="50%")

Here we are making a new Widget which we have assigned to my_button. The following is a table outlining information about supported arguments which can be given.

Argument Required Use Supported inputs Notes
id Yes Used to uniquely identify a widget when being interacted with Any string that hasn't been used before Spaces will be converted to _
typ Yes Gives a widget specific properties so it knows what to be used as Any from the following: label, paragraph, burtton, textinput, textarea, image Range is a WIP
value Yes What will be displayed on the widget Any string (Image path for the image widget type) Be careful about using new lines
x Yes Used to calculate the rendering position of the widget A percentage, keyword or an integer Supported keywords are same (same value as previous item) and step (previous item's cord + previous items size)
y Yes Used to calculate the rendering position of the widget A percentage, keyword or an integer Supported keywords are same (same value as previous item) and step (previous item's cord + previous items size)
width No (Automatically calculated) The width of the widget Any integer You might have some trouble with getting the right value for this
height No (Automatically calculated) The height of the widget Any integer You might have some trouble with getting the right value for this
justify No (Optional for buttons) Where the text sits in a button Any string from the following: center, right, left

Finally, we want to add the widget to the actual screen.

rm.add(my_button)
rm.display()

I've made the decision to have widgets be manually added like this to make it easier to manage when making apps). We can do this easily with add(args*), where args* are any Widget types - For example,

rm.add(my_button, label1, logo)

And then display it to the rM! The display() function will take all the currently active Widgets and convert them into something that simple can understand and render. The active widgets are all stored in the screen list (in this case rm.screen) and you can easily access and modify any of the widgets in there at any time via the lookup function which will return the Widget object that has the corresponding ID

print(rm.lookup("<id>"))

To remove a Widget you can use the remove() function and either supply it an ID or Widget object like so

rm.remove("<id>")

rm.remove(my_button)

In case you want to fully clear the screen, you can use the eclear() function - however this does require the modified updated simple binary which okeh can provide for you!

rm.eclear()

Finally, there are two other options that the ReMarkable class has that we can modify.

  • Fontsize - Changes the fontsize of the text on the screen
  • Timeout - The time after simple quits if no input is given
    • In this case, carrying on the program after rm.display() has been run and no input has been given after a set time

For example, if we wanted to make the fontsize 24 and timeout the program after 30 seconds we would do

rm.timeout = 32
rm.fontsize = 24

When you run the display function, carta will wait on any input being given OR the timeout being reached. When it's done this, it will return a dict object with the input given.

clicked = rm.display()

print(clicked) # {"<id>": True}

If it's a button that has been pressed it will return True as the value, if anything else has been given it will use that specific input (for example, from the keyboard) as the value.

Hope this guide was helpful, feel free to ask if you need some help (Jayy#6024 on discord)

About

Python library for making GUI applications on the ReMarkable tablet using "simple".

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Python 100.0%