diff --git a/docs/guide/devtools.md b/docs/guide/devtools.md index 487700c8e..63f515af0 100644 --- a/docs/guide/devtools.md +++ b/docs/guide/devtools.md @@ -30,13 +30,13 @@ textual run my_app.py:alternative_app When running any terminal application, you can no longer use `print` when debugging (or log to the console). This is because anything you write to standard output would overwrite application content, making it unreadable. Fortunately Textual supplies a debug console of its own which has some super helpful features. -To use the console, open up 2 terminal emulators. In the first one, run the following: +To use the console, open up 2 terminal emulators. Run the following in one of the terminals: ```bash textual console ``` -This should look something like the following: +You should see the Textual devtools welcome message: ```{.textual title="textual console" path="docs/examples/getting_started/console.py", press="_,_"} ``` @@ -47,5 +47,16 @@ In the other console, run your application using `textual run` and the `--dev` s textual run --dev my_app.py ``` -Anything you `print` from your application will be displayed in the console window. You can also call the [`log()`][textual.message_pump.MessagePump.log] method on App and Widget objects for advanced formatting. Try it with `self.log(self.tree)`. +Anything you `print` from your application will be displayed in the console window. + +### Textual log + +In addition to printing strings, Textual console supports more advanced formatting in logs. To write advanced logs import `log` from `textual` as follows: + +```python +from textual import log +``` + +You can logs strings, other Python data types which will be pretty printed in the console. You can also log [Rich renderables](https://rich.readthedocs.io/en/stable/protocol.html). + diff --git a/docs/guide/layout.md b/docs/guide/layout.md index e69de29bb..6f10cf228 100644 --- a/docs/guide/layout.md +++ b/docs/guide/layout.md @@ -0,0 +1,56 @@ +# Layout + +TODO: Explanation of layout + +## Vertical layout + +
+--8<-- "docs/images/layout_vertical.excalidraw.svg" +
+ + +TODO: Explanation of vertical layout + + +## Horizontal layout + +
+--8<-- "docs/images/layout_horizontal.excalidraw.svg" +
+ + +TODO: Explantion of horizontal layout + +## Center layout + +
+--8<-- "docs/images/layout_center.excalidraw.svg" +
+ + +TODO: Explanation of center layout + +## Table layout + + +
+--8<-- "docs/images/layout_table.excalidraw.svg" +
+ + +TODO: Explanation of table layout + + +## Dock + +TODO: Diagram +TODO: Explanation of dock + +## Offsets + +TODO: Diagram +TODO: Offsets + +## Box Model + +TBC diff --git a/docs/how-to/animation.md b/docs/how-to/animation.md new file mode 100644 index 000000000..4709f033e --- /dev/null +++ b/docs/how-to/animation.md @@ -0,0 +1 @@ +# Animation diff --git a/docs/how-to/mouse-and-keyboard.md b/docs/how-to/mouse-and-keyboard.md new file mode 100644 index 000000000..1707580e4 --- /dev/null +++ b/docs/how-to/mouse-and-keyboard.md @@ -0,0 +1 @@ +# Mouse and Keyboard diff --git a/docs/how-to/scroll.md b/docs/how-to/scroll.md new file mode 100644 index 000000000..a12cc92b4 --- /dev/null +++ b/docs/how-to/scroll.md @@ -0,0 +1 @@ +# Scroll diff --git a/docs/images/layout_align.excalidraw.svg b/docs/images/layout_align.excalidraw.svg new file mode 100644 index 000000000..fd2f8e94f --- /dev/null +++ b/docs/images/layout_align.excalidraw.svg @@ -0,0 +1,16 @@ + + + eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nN2ZW1PbOFx1MDAxNMff+Vx1MDAxNJn0tXGtozszOzuUy5altEOBXHUwMDAy2d1hXHUwMDE0W0nU+FbbIUCH776yk8FJSCBAmmY3XHUwMDBmmVhcdTAwMTfrSOd3pP9RfmzUavX8JtH1zVpdX3sqMH6qXHUwMDA29bdF+ZVOM1x1MDAxM0e2XG7K5yzup17ZspvnSbb57l2o0p7Ok0B52rkyWV9cdTAwMDVZ3vdN7Hhx+M7kOsx+L74/qVD/lsShn6dONUhD+yaP0+FYOtChjvLMvv0v+1xcq/0ov8esS7WXq6hcdTAwMTPoskNZVVx1MDAxOYhcdTAwMTibLv1cdTAwMTRHpbHAXHUwMDEwYEJcdTAwMTm9b2CyXHUwMDFkO1xcrn1b27Ym66qmKKpnW1x1MDAwM6EvTz5cdTAwMWOdnr3fa1x1MDAxZJxkUVx1MDAwMnvVqG1cdTAwMTNcdTAwMDTH+U1QWuWlcZY1uir3ulWLLE/jnj4zft4tbJsqv++bxXYhql5p3O90I51lXHUwMDEzfeJEeSa/KcpcXPe+dLhcdTAwMTCbtark2j41sHQkRoy4XGaq6Vx1MDAxNn1cdTAwMDGowySarFx1MDAxOJqzXHUwMDFkXHUwMDA31lx01pw3bvmpXGZqKa/XsVZF/n2bPFVRlqjUuqpqN1x1MDAxOE2USOZgLuTEIF1tOt3c1mJcdTAwMTCOIJiPja9LXHUwMDE3MExBuEJWXHUwMDFlLFx1MDAwNk32/Vx1MDAxMoZ/plevq9JktEr1rHhcdTAwMTgzuLB1d4ykqnM/8dXQ41x1MDAxNlx1MDAxNVx1MDAwMClcdEOYVMtcdTAwMWOYqGcro35cdTAwMTBUZbHXqyApS+/evlx1MDAwME6MYVx1MDAxZZyYcNc67Fx1MDAxOXBcdTAwMWX+eXmjm4KdXFxsN1x1MDAwZre/tHZC+s28XHUwMDFjTlghnMJhhJFJXHUwMDA2hnBcdTAwMTKHulj+ZDiJM4dMYFx1MDAwZVx1MDAwMuTKXHUwMDE5bFwiXHUwMDBltKhcdTAwMDOyOjixnafgiMGy4NRBYJJsJpqA5Dw0keQu48DIwmgmX1x1MDAwN9ffZPiRXFxk/T3VXHUwMDEwaciO8jloTuH1y3ZMwFx1MDAwZZZAuUDTOyZGzit5fNNWXHUwMDE0KDxkXHUwMDExgVx1MDAwM2gqXHUwMDEw7mlEyCFcdTAwMTSPmzNiXHUwMDExXHUwMDEzbMstXHUwMDFiq9wnhSDUXHUwMDA1vFxuXHUwMDE0OZ6LXCJcdTAwMDEhXHUwMDAwU1xuXHUwMDBis8j7/n7nNHa1Pr+J6EHe3PrgrzmLyEHUKpVcdTAwMDe7I3ZcdTAwMWSKXHUwMDEwR4K/lsaW69Jl0YiElVx1MDAxOcSVzP1/4oiBz8NRWlx1MDAxMjlnXHUwMDBis9jS+GBcdTAwMDBR0NKn6UHb97RcdTAwMWY1d9abRXskMjnp9+FJbVx1MDAwNSbikr2WRVx1MDAwNC0h2NJYtFwiym7g7D+9NT6e31x1MDAxMHdcdTAwMWWN4Fwiq53AJXhhIHezXXLFaf/w6svOIblIzPlutrXeQDaAO5Iz+iCxYfZcdTAwMDCniD52VHtcdTAwMTJcdTAwMTSol0tHJMlDXHUwMDE4XHUwMDA1OLTQ7kDk8PNcdTAwMDBKZOWmRDbtWT6Uo4qKolx0knJ9Xc1izO2oXHUwMDFm7feDi+/87PiA9D73veOji9v6fbu70a9HkyZhsV9cdPEwllx1MDAxM00nTcz6m3G+MO9KZb3P9HTPoEP5/Xa7Sa9JStebd4RsUsJcXPRcdTAwMDB4zMB5Qlxm2L1VYb1q3u1cdTAwMGVk5YCF/iekSi/jPaTNVFxydHT058fuye5547ZcdTAwMWSe9Z7HOyfAV8Q7XHUwMDEy83hHYNeWXG54XHUwMDA28a7ZYrHMzVx1MDAwMf/jsnnph3nnrIPWm3hcdTAwMGKWQ9hkXHUwMDE2XvS0M3eeuFx1MDAxYii0qGr9XHUwMDAy4IFTzsZud34x8OeXn8yHILyNzuLUfFx1MDAxZPS6unlknlx0vMDAllx1MDAwNfyEnVx1MDAxM1x1MDAxN2JzpbWk3Eo5gVx1MDAxNiZ99qG21qQ3XHUwMDAwZmtcdTAwMTkuXHUwMDFkhtnjm/tcdTAwMDJi5k273Z5cdTAwMDG5mFx1MDAwMTl1p6lGrnCxxf5nbOPLVFx1MDAxNpWH4yg/NrdDKTxRuqdCXHUwMDEz3Ey4qSSyUFx1MDAwNIHpRI2uXHKTW9tQXHUwMDA1m7W/o0C38/F1zbS1onjtmLIu+m9cdTAwMTV9i5d4dl46nVx1MDAwMDw3nlxu7lx1MDAxYoTG98d3e69cdTAwMTjLvjPdX0SGW+M6JlLByVxcm0uLX1x1MDAxNoFzxVWhOFx1MDAwMGOQi4fg7HN2rUNcdTAwMTBcdTAwMDGaI6+4sElmue+/SmC9Klx1MDAwNjHh5Z3zSq9Wni92llx1MDAxZoLTXHUwMDExtYIgfFwiN3g6XGJHXHUwMDA2vCxcZtG8MFx1MDAxNFx1MDAwMPYkJGLxpH724b/WUVxilMyWfJw4jE9dyr9A9L3uILRWMcQpXvH/ks9VYMuPwrRcXJNVXHUwMDA24Vx1MDAxM+nK00E4NHlcdTAwMTiDXHUwMDFiI4VbV0lynNvVtV2GXHUwMDExaVx1MDAxZGj80Vx1MDAxMlUrWr8yevB+Nj1cdTAwMDVAXHUwMDFio7guQkhcdTAwMTfu+3G3cfcvaFx1MDAxZGxTIn0= + + + + align-horizontal: leftalign-horizontal: centeralign-horizontal: right \ No newline at end of file diff --git a/docs/images/layout_center.excalidraw.svg b/docs/images/layout_center.excalidraw.svg new file mode 100644 index 000000000..b9e15e7a9 --- /dev/null +++ b/docs/images/layout_center.excalidraw.svg @@ -0,0 +1,16 @@ + + + eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nNWXW2/bNlx1MDAxNMff+ylcZve1UXhcdTAwMTdcdTAwMTlgXHUwMDE4nHRZ0mxuV6fpsmFcdTAwMThcdTAwMTiJllx0U5eJtHNDvvsoObUsx1x1MDAwZbzUMDI9XGLQ4eVcdTAwMWPy/Pg/4v2bTqfrblx1MDAwYtU96HTVTSSNjkt53X1X2aeqtDrPfFx1MDAxM6q/bT4po7rnyLnCXHUwMDFl7O+nslx1MDAxYytXXHUwMDE4XHUwMDE5qWCq7URcdTAwMWHrJrHOgyhP97VTqf2xevdlqn4o8jR2ZdA42VOxdnk586WMSlXmrJ/9T//d6dzX74XoSlx1MDAxNTmZJUbVXHUwMDAz6qaFXHUwMDAwXHUwMDAxW7b286xcdTAwMGWWUoxpXGJDMO+g7XvvzqnYt1x1MDAwZX3IqmmpTN2Pn0+MMlx1MDAxZk4tXHUwMDFj9tXPXHUwMDE3VCfclo3XoTZm4G5NXHUwMDFkVVTm1u6NpItGTVx1MDAwZuvKfKy+6tiNfFx1MDAxZrhkn4+1ud+IZlSZT5JRpqxtjclcdTAwMGJcdTAwMTlpd1vZQLOE2UZcdTAwMWN0XHUwMDFhy43/wkBcdTAwMDRIIMF4SOdcctVQRFnAXHUwMDA1oiGHiC6Fc5RcdTAwMWKfXHUwMDA0XHUwMDFmzltQP01AVzJcdTAwMWEnPqosnvdxpcxsIUufqqbf9eNCiWBcdTAwMDFcdTAwMGW5XHUwMDAwbMHJSOlk5KrgXHUwMDEwXHUwMDBmOMFcdTAwMGKRWVWnQISQYoZ5s5bKaXFcdTAwMWHXMPy1vHsjWVx1MDAxNo+71LXVx0LAVaw/LZDUXGaeXHUwMDE0sZxlXHUwMDFjMoaQXHUwMDEwzHuFeN5udDb2jdnEmMaWR+NcdTAwMDaS2vrw7lx1MDAwNXBCLtbBiYDgXHUwMDA0YkrJxnT+dszkP72LL/BzL75y4PBTf7CWziXC2lxcop1yXHUwMDE5glx1MDAxMOBF+r5xXHShgKSFzPa5JMFcdTAwMWEokfePIFx1MDAxMCuwRJwwgVx1MDAwNWW7w1x1MDAxMvtlUlx1MDAxNHK0LSyVMbqwq6Gk4VooXHUwMDExXHUwMDAxXGJ7IdmYSWhcXFx1MDAxNNvxydHFuexHe1NzqT9+eFx0kzvUSlx1MDAwNFx1MDAwMr/h5KlWMuphpeC7tfLtUFJE0VNcdTAwMWUhXG5cdTAwMTAkbS2cXHUwMDEzXHRhQGjroDzyXHUwMDE4+lPCXHUwMDE5RWR3PFwiwSmFLNyaTD7DI4JwXHUwMDFkj1x1MDAxMFx1MDAxMVx1MDAwZVx1MDAxOSB0cyBvpoOz+DzLit4vJ1x0j/hcdTAwMTFOXHUwMDBm81dcdTAwMGUkIUFcdTAwMThS3FaqXHUwMDE5kSSgXHUwMDAyhu26/jJcIq+8wmyLSFx1MDAwMlx1MDAwMWV0p1xuuVNcIlx1MDAxOV1LJIWCXHUwMDAyXHUwMDA0Nq/al45cXJP4MFx1MDAxMX+MP/V+7+9l788y/sqBXGZBgCHHtFVcdTAwMWRnQOJAXGK+JJ4vXHUwMDAxXHUwMDEyoivO2baAhIRcdTAwMDJIOcbof0zks7+SbKEoLzPJIeC+ZjG2MZQ4Oc56N3eEqPIqncqvf5dwcLZcdTAwMDbKkYxGk1K9XHUwMDAyLFx1MDAxOVx1MDAwYsBcbpXEOFxmQkp5XHUwMDFi15fXbbZcdTAwMDJL7zb45qKeiK2gk/tb0PLReOSTcsaxXHUwMDFmvlPF9GXD/83RbfHp1I1bhWbI15HJWMh8XHKHm5dvfX7X+7KX0PjXy/MzejhMU927fe1g+ppcdTAwMTCQZakkSFx1MDAwNP5g0u+WymdvOIw85XCFPFwi4C+9XHUwMDAy7PSi/d/VsUlznrmBvpvdk1vWY5lqc9vKVI2lj9TnPVFucSut8j5nXG7Z6t0zOqnA7Vx1MDAxYTVsXHUwMDEz7XQkzbzZ5Vx1MDAwYiuPvHfppytP4+VV5KVOdCbNeTuS2WHy73qPurIoXHUwMDA2zu+Q7zE7Wj5cdDp+XFxmM193qtX14Spxqp9q1vqAVmdBVSm4f3jz8C/DXFz9NyJ9 + + + + Widget \ No newline at end of file diff --git a/docs/images/layout_horizontal.excalidraw.svg b/docs/images/layout_horizontal.excalidraw.svg new file mode 100644 index 000000000..25ce496f2 --- /dev/null +++ b/docs/images/layout_horizontal.excalidraw.svg @@ -0,0 +1,16 @@ + + + eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nO2aa0/bSFx1MDAxNIa/8ytQ+rVM536ptFpcdTAwMTEuLTQtlNAtdFVVjj1JZnFsYztcdGnFf9+xQ+PE2GxcYlHKatdCSTzX45nnXHUwMDFjvzPDj63t7UY6iXTj9XZD37iOb7zYXHUwMDE5N15m6SNcdTAwMWQnJlxmbFx1MDAxNs7vk3BcdTAwMTi7ecl+mkbJ61evXHUwMDA2Tnyl08h3XFxcckYmXHUwMDE5On6SXHUwMDBlPVx1MDAxM1x1MDAwMjdcdTAwMWO8MqlcdTAwMWUkv2efXHUwMDFmnIH+LVxuXHUwMDA3Xlx1MDAxYYOik1x1MDAxZO2ZNIynfWlfXHUwMDBmdJAmtvU/7f329o/8c866WLupXHUwMDEz9HydV8izXG5cdTAwMDNcdTAwMTFH5dRcdTAwMGZhkFx1MDAxYitcdTAwMDRnTFBOZ1x1MDAwNUyyb7tLtWdzu9ZkXeRkSY1wrHY6o1x1MDAxMbuiTv8vfja8uWw3o6LXrvH9djrxc6vcOEySnb6Tuv2iRJLG4ZX+bLy0n9lWSp/VTUI7XHUwMDEwRa04XHUwMDFj9vqBTpKFOmHkuCadZGlcdTAwMTDOUqdcdTAwMDPxertIubF3XHUwMDFjXHUwMDAxXHUwMDA0XHUwMDEx45jNkvOKXHUwMDA0XHUwMDAyXHUwMDBlXHUwMDA1xUhcblYyZi/07Vx1MDAxNFhjXsD8KszpOO5Vz9pcdTAwMTR4szJp7Fx1MDAwNEnkxHaiinLju8ekilx1MDAwM1wipILz3fe16fVTm0uwXHUwMDA0kpL5/nU+XHUwMDAxXGJhXHUwMDAyle2ZzHKyXqMjL2fha3nw+k5cdTAwMWPdXHJSI8lu5izOjD2YXHUwMDAzqag8jDxnOuGIc4yVXCJcbjNajJ5vgiubXHUwMDE5XGZ9v0hcdTAwMGLdq4KRPPX25SpsXHUwMDEyXsemopxcdTAwMGKO4fJs9odB29//LryTZvzHXHUwMDA1jpLjT+ZdXHKbJb5cdTAwMTapxJukktPFuc8rYlx1MDAwNVx1MDAwNJSqRMXaqaSgXHUwMDA2ScxcdTAwMDHCXGKqKii55Vx1MDAxMVNcdTAwMDHR5qAkXHUwMDEwYiigQOuCUvu+iZJqJFx1MDAxMalDkiNCqP1cdTAwMTNLI/lpsPd2ctChqOd8eXt4zVvHcFx1MDAxZq2C5OZcdTAwMDKlwFx1MDAwMImFaDiNk1xuMIZcdTAwMDV5KpEvulx1MDAwZcNcZt+nXHUwMDExYYBRyVx1MDAxN2Y8XCJcdTAwMDQoI1xi36NcdTAwMTFbw1xiUYJvNERaKyGkXHUwMDFioZGLOlx1MDAxYe1gXHREkIBqaVx1MDAxY9E5vWmpTtg62lx1MDAxOUYnh63v3eB493njaN+cwlx1MDAwZYLi94mUgFx1MDAxMlXGYiVcIjtcdTAwMTCytVx1MDAxMVx0MWFIWiY3TyTeXHUwMDAwkVx1MDAxONfKSeuLUmJCKVmayPeuuL5pXlx1MDAxY6TiYHzcla0v+/1o/3lcdTAwMTOJsOWC2ZBTISaFXHUwMDE1ckzAJyOJcEdKvi4kXHUwMDExQlx1MDAxMCumXHUwMDE4+1x1MDAxNyP5oI7k9WtcdTAwMWOroZVgXG7hpZmM3r9PzpvDvdZxcn74RSr+5qzztobJvuP2h7H+9VRcblx1MDAwMaxywVx1MDAxMpWZXHUwMDE0XGYwWKZ19Vx1MDAxNzevopJZuShcdFOVWGIuXHUwMDAxrMKSWIVPIedqk1QqSlx1MDAxMCNiXVSm+iatVpGyXHUwMDE2SIVskGRKLS8jj1x1MDAwZttJ2mpCdlx1MDAxMnjJ8FrH74KLi+dO5DROksVcdTAwMTVGVlx1MDAxNUtcYlxixvjJSD64upnb1ChQrFjNWFxirYhcIlx1MDAxYlxczWShUVwiwsgjICzmOlxm0rb5rnOlsZB66FxmjD9ZmK6cTmupnfyeTufHMtG2z5xGuVB61ze9jN+Gr7uLYKfGdfxZdlx1MDAxYc49uWt7d2xz8ZFXfoowNj1cdTAwMTM4/vmiJatHeilonWNcdFx1MDAxYuelJIIv7Ve4NWiN+67eXHUwMDFm6dbHyWRMh2ejo+fuV5gxUN5cdTAwMWGYRnr7XG6AVns+OdJP1UdlpIdcdTAwMWPYt7pYeM3MRXpcdTAwMDZ4aZPtp59Jqz6gIHijXHUwMDEyRFFcdTAwMWJq4WP8bHUwXHUwMDE1YnVgXCJMoWBYLs3ldde9hEcn15+Cvve5N1x1MDAxYZs2Pfz23Lkkklx1MDAwMJS90O8pXHUwMDEwXHUwMDA0eFmarIIlxrKjq7HkXHUwMDE4SJ53QVV2iSo4XHUwMDE1kFx1MDAwNFcqXHUwMDExpCRWVJBccitcdTAwMTEsXHUwMDA15OuCs1aJqHouKYNcdTAwMWOJR+xnnYs3x6NT7/SjY051e6/3wfF26/aznlxymFhIIGBpVTZcdTAwMTVcIlx1MDAxMqh1bCGsQYhQqlxis4vHTetcdTAwMTAqXHUwMDFmJYb/Szqk1qPkXHUwMDAzXHUwMDEyhNs4w+dm8Vx1MDAxZlx1MDAwZtQ+XHUwMDFmOJff6NklvDa9sVaBOPlr8tw9imJcdTAwMDHKbvPToaDgpf3jX6TsieJ2sUfxpj0qO7T636Oyr3tcdTAwMWXlxHE4rnQpWOtSdrVoXHUwMDAzOH/EnuK3uHnK946uXHUwMDA35uDj8I1vlHmz667mUlx1MDAxYjxcdJSA4vu73FxmXCLwkCtJ0WWdp1x1MDAxY1x1MDAwMTJA+KK7XHUwMDE2+4mAK1U6XHUwMDE4v/MtaHOs4EUr7HHn1q3mW1xmMkVcdTAwMWVz6jJnh1x1MDAxM6dNXHUwMDEzeCbolavowKvJ8Z0k3Vx1MDAwYlx1MDAwN1x1MDAwM5NaM05DXHUwMDEzpOVcdTAwMTJ5u7tcdTAwMTnVfe3cc1x1MDAxMdvyfF5cdTAwMTn/KGux+K+O7Cp+bVx1MDAxN3zkN7PfX19Wlq6Yyewq5rBoYGv++3brrsmGXHUwMDEzRe3UXHUwMDBluDVo6rh2To13XHUwMDE3kYrnaoyMXHUwMDFlN6v2XHUwMDA38ytcdTAwMGJcdTAwMDC5+2d+prOn+3G7dfs38GbaXHUwMDA3In0= + + + + WidgetWidgetWidget \ No newline at end of file diff --git a/docs/images/layout_table.excalidraw.svg b/docs/images/layout_table.excalidraw.svg new file mode 100644 index 000000000..b1c03573d --- /dev/null +++ b/docs/images/layout_table.excalidraw.svg @@ -0,0 +1,16 @@ + + + eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nN2ZW0/bWFx1MDAxMMff+ylQ+tq4Z+bcK61WNFxcWiCUkt1cdTAwMDK7WlWO41x1MDAxMINcdTAwMTNcdTAwMWLbIUDV775jhyU33KZpakXrXHUwMDA3Kz5zLmP7l5n/XHUwMDFjf3mxtVXL7mO/9mar5t95blx1MDAxOHRcdTAwMTJ3VHuVt9/6SVx1MDAxYURcdTAwMDMyYXGdRsPEK3r2sixO37x+3XeTaz+LQ9fzndsgXHUwMDFkumGaXHI7QeR4Uf91kPn99Pf8fOz2/d/iqN/JXHUwMDEyZ7JI3e9cdTAwMDRZlIzX8kO/71x1MDAwZrKUZv+brre2vlx1MDAxNOcp71x1MDAxMt/L3MFl6Fx1MDAxN1x1MDAwM1xu05SDTM23XHUwMDFlR4PCWVx1MDAwNOTaWG6fOlx1MDAwNOlcdTAwMGUtl/lcdTAwMWSydsllf2LJm2pcdTAwMTdcdTAwMDfN7bOP7frZyd1d4+P1kN1cdTAwMWPeXHUwMDFkTFbtXHUwMDA2YdjK7sPCKy+J0rTeczOvN+mRZkl07Z9cdTAwMDWdrEd9YK79aWxcdTAwMWHRg5iMSqLhZW/gp+nMmCh2vSC7z9tcdTAwMTh7alx1MDAxZD+IN1uTlruih3CEZchcdTAwMDXX8slSjFXGYahnXHJjd1x1MDAxYVFIL4HcecmKY+JQ2/WuL8mrQeepT5a4gzR2XHUwMDEzelWTfqPHXHUwMDFiXHUwMDE1Vjn5o2ZcbieL9PzgspeRlaNxzOz6fvFcblx1MDAwMFx1MDAxOFdWXHUwMDAzm1jyVeP3nYKGf+ZcdTAwMWZfz03ix8dUS/OLKY9zZ3enUJpcZlx1MDAxZcZcdTAwMWR3/MpBKURrpURE82RcdTAwMGaDwTVcdTAwMTlcdTAwMDfDMJy0Rd71hJKi9eurXHUwMDE16Fx1MDAwNFx1MDAwM2V0guBKaCNcdTAwMDCWxvNcYsxprD9fdi5cdTAwMWV6O63zXHUwMDA2unB+VYLnXHUwMDFjYrNgYqVgcqlcdTAwMDWCWVx1MDAwMFM7XHUwMDAytFXml4IpnFx1MDAxMipROYDA7HNcXGpjXHUwMDE0SKOhOi45Y2BcYk25Li79MFxm4vR5KqUujZkoKIqgxaWhvOrsXHUwMDFknkrVPd/fPYhakDWu9o6OVoGywmhcdMIxhlx1MDAxOWlcdTAwMTeipVaO1ajkNDIrQPmy60qUuFxiJKCDIGaj4Vx1MDAxM5JcdTAwMDCOkFx1MDAxY3BcdTAwMDFII1x1MDAwNCCNstXxiNYoxrTBXG54RCiPknTboJiQy1x1MDAwM3kxVKOjpOPtn7jhcFx1MDAwZmL3Pey3N1x1MDAxY0huXHUwMDFkgVKb6Xc/5lE6c5iuRmObMbkuXHUwMDFhuZVGXHUwMDE4i/p/SqOSpTRKsJIhXHUwMDEzS8PoS+1dnN6c3lxmP0Rvd0+McuuNvVxyh1FRzlRcdTAwMGLpmkhcXENcXFx1MDAwNGxTbl1cdTAwMTeJkKdpbqyqMFGvXHUwMDFkxW9cbkhrTVx1MDAxOYzSkuLnQsilYey6Ot1vXFy+P/N6fHR80N5pZp/LUnXP9XrDxN9cdTAwMDBcdTAwMWOBqlx1MDAwN2VBzMi4fCwyiprCzkrL1ZO1elx1MDAwNktkzGGP6rWYiC/SqfE/XHUwMDFkK2xxLJY5hkojToK30jJH0YpcYpVQXG6kmMsw5VxmhEa5fFx1MDAxMZ707el+eLB90k/f3orgoKWPd+NNp5RzokAzzfh8XG7PKdWG46xlvZhcdTAwMWHm6HGJP55cdTAwMDdWoVx1MDAxNCWn0GZs1ZRcbjS6XCJKVWndQ9U4ZVx1MDAxMSHN8tX4X432fnB1XHUwMDA28Knree+uXHUwMDFlLpvHO+6mcyqQ6nEln9koQkrBQuHcJs56OaVk7fBcXM4+MjjF2vKg0lx1MDAxZkqRXGJcdTAwMDNd7a6R4sZIUVxyqGxKXcyHU7p3kNOJ6HucNk+UVz+Fm/1MRkN5eNjubsNg0zlcdTAwMDXMNZ9kiyVcdTAwMTFn6Fx1MDAwMJvfUVpdi/66tE/AUEZQrFJxaiVJRlVR2kdRXrhcdTAwMDMgKVx1MDAxMMaXl6cgdlx1MDAwMqyLXHUwMDExXHUwMDBm7Fx1MDAwNV5cdTAwMWaMwtG7/t2mg8q5cJixZiGeckZllDVM/OxcdTAwMDbnNzhdT95XUkqOouK8XHUwMDBmjH5UgymXvFx1MDAxNFOhlFGag15cdTAwMWFTb7dxdXHYPKvzT6zVvv/ktnpRuOmYXG60jmTymS1Pzlx1MDAxNFnAyp/Wp+WcgrCOnT5WyftcdTAwMDCSdFx1MDAwYlx1MDAxM9XugloltGZr25X/TjyV5Vx1MDAxZjNcdTAwMTknSjmI5Vx1MDAwNWrrfK/ZxEHWYSzTf/x5XFw/yuKdTVx1MDAwNzVP/FZcdTAwMGLFXHUwMDE2QbXaoeQ2Z1lcdTAwMDVURNP2n0/8XHUwMDE2SFx1MDAxZetcdTAwMTlp8SOhNP9yXHUwMDA0lPaqJVx1MDAxNOn/W9H3TNI0paFcdTAwMTSlUcL+XGKhn/vx1Yc06D58XGa3e7fRUe9cdTAwMTQu2KZcdTAwMTOah1LEMkKZYXOidb2EUsJy7PhTgfiJXHUwMDEySoE1WHkopVxmJNRcdTAwMGaDSudi0ppcdTAwMWLHrYymJPNcdTAwMThb8jrotIJcdTAwMDd/ZprabeCP3j5XmFx1MDAxNkftxSP8OV9+7vOXry++/lx1MDAwYntetL4ifQ== + + + + \ No newline at end of file diff --git a/docs/images/layout_vertical.excalidraw.svg b/docs/images/layout_vertical.excalidraw.svg new file mode 100644 index 000000000..fff71ecf9 --- /dev/null +++ b/docs/images/layout_vertical.excalidraw.svg @@ -0,0 +1,16 @@ + + + eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nO2ZW2/aSFx1MDAxNIDf8ytcIvrauHO/VFqtXHUwMDAyTdrck9KkTVdVNLFcdTAwMDdwMLbXXHUwMDFlXHUwMDEyoOp/37FJMVx1MDAxOFx1MDAxY1FcdTAwMWFRtrt+MPjM7XjmO2fOXHUwMDE5f93a3q6ZYaxrr7dreuCqwPdcdTAwMTL1UHuZye91kvpRaItQ/pxG/cTNa3aMidPXr171VNLVJlx1MDAwZZSrnXs/7asgNX3Pj1x1MDAxYzfqvfKN7qV/ZvdT1dN/xFHPM4lTXGayoz3fRMl4LFx1MDAxZOieXHUwMDBlTWp7/8s+b29/ze9T2iXaNSpsXHUwMDA3Om+QXHUwMDE3XHUwMDE1XG5CLsrS0yjMlYVcdTAwMDJRxFx1MDAxMGZsUsNP39jxjPZsccvqrIuSTFS7rNdcdTAwMGbj+/6RSNBdfFF/84lcdTAwMGZIUlxm2/KDoGmGQa6Wm0RputNRxu1cdTAwMTQ1UpNEXf3R90wn06Akn7RNIztcdTAwMTNFqyTqtzuhTtOZNlGsXFzfXGYzXHUwMDE5XHUwMDAwXHUwMDEz6XgmXm9cdTAwMTeSQbZOQjqSUFxmXHUwMDExncjzloI6XHUwMDE4gVx1MDAxOflYl0ZcdTAwMTTYJbC6vFx1MDAwMPlVaHOr3G7bqlx1MDAxNHqTOiZRYVx1MDAxYavELlRR7+HxLYlkXHUwMDBl5kJcdTAwMDI2NUhH++2OsaVcdTAwMThcdEdcdTAwMTDMp8bX+fxD24ZcdTAwMGLBWVGSjVx1MDAxYVx1MDAxZng5XHUwMDBiX8pz11FJ/DhHtTR7mNI4U3ZvXG6konE/9tR4vSFjXGJJiVx1MDAwMVx1MDAxN6yYvMBcdTAwMGa7tjDsXHUwMDA3QSGL3G6BSC799nJcdTAwMTU2KapiU2AkhSRkeTRcdTAwMTk4XCJcdTAwMThGh+qm8/Gi07jY8y/gTVx1MDAwNZolvGahROuDUlx1MDAwModIXHUwMDA0XHUwMDA1L0NJXHUwMDFjgGd5eX4oiVNBJGJcdTAwMGVEXHUwMDEwyFx1MDAwNUxcIkgpwFx1MDAxOK5cdTAwMTFJXGZcdTAwMDCUjHD0XFxI6iDw43QxkKjSWVxujJl1XHUwMDE0kixccuS+PLl517x6f/k+uvp09Fx1MDAwZXXdYd1bXHUwMDA1yPV5SVxmoFx1MDAwMyBlZSdpWSmJV8DxRUtRu+HMo1xikYMgmfWBXHUwMDEzXHUwMDE4IXRKbvu7e+SIQYq5/Fx1MDAxN3vHp1BcdTAwMTSVvpFbs4VcdTAwMThRsDSKny/SgTm6eXu81/Aurlx1MDAxM91NSXC04ShcIupQXHUwMDA2KGFz3lFcIuu5XHUwMDEwnt0zV+LxXHUwMDE2XHUwMDAw+lxcPFwiwFx0XHUwMDAzkEn8e1x1MDAwMmnjxCogXHQj2DpqKZZcdTAwMDbyslx1MDAxZTY/XHUwMDFm3lx1MDAwNVx1MDAwZnz0rn/gN+7vXFx8sOFAUuhAYO9cdTAwMGLcI3IwXHUwMDEwVP4skFx1MDAxMN1cbsGeXHUwMDBiSMKJpIKJ3zZ8xE+kNvaShEO8PJLnXHUwMDFmklH3nDY8vvu3fHOTXHUwMDA0QI3OKpDsKLfTT/RcdTAwMDZAXHSBXHUwMDAz5YJcdTAwMTDSukeHlZBZfc+mXHUwMDBivCQhwsk8nlxcSCW1Sc04r1wiMrtcdTAwMDQr44lcdTAwMTBEmGNcdTAwMDLXiifN7Eg8XHUwMDE3nkZcdTAwMGbMQl9Z6SohQ4xhgsDyiVxybV2NTsO3g+udYDS63mVR86ZcdTAwMTFvOpg2S5jlkZKf4fDJVIaRef5cdTAwMTbEi1x1MDAxNkKbSeBcco9cdTAwMTeLdY1C0/RHOlx1MDAwZi1mpPuq51x1MDAwN8OZpclBtJrahW5rMz2VqbZjjk97ZmrvXHUwMDA2fjtDtVx1MDAxNujWLMPGd1UwKTbR1Ju7dnRlu0tcdTAwMGW88ltEid/2Q1x1MDAxNXyY1WR1705cdTAwMTCv9u6SXHUwMDAwIaRcXD5cdTAwMDKW51x1MDAxMFx1MDAxY1x1MDAwZY7htZa3rZM9fkz76d6mXHUwMDFiXHUwMDExXHUwMDA20mFcdTAwMDLPXHUwMDA2XHUwMDE2w9ztXHUwMDEzR1xiJH7y1OpcdTAwMDVcdTAwMDEuoJwtXGI5XGIlXHUwMDBlp7jihFx1MDAwMELqXGLISFaaXHUwMDBmXHUwMDAz56yNXCJJKON0vdFcdTAwMDdcdTAwMDXUboZriT4oJlV8YmRcdTAwMTM0xvnyeKrPO83hzd6nncuTw+O6XHUwMDFj+Gr/Q3Pj8bTBXHUwMDA3gVxczmVoWWhApSzFXHUwMDA2K1x1MDAwMeoy3aKLXHUwMDAxtUFxJaCEOyjXazzIPJ9cYoBcZm+I15utUWhDtWfjUyVJ9LD4XHUwMDFjqzpX43ZcdTAwMGKU8Fx1MDAwN+KP+5OUjc5cdTAwMGUur0x8XHUwMDE2JOfDs1x1MDAwN4YvVmNzfUerwsa/slx1MDAxY1x1MDAwMH8/yypHrWUybVx1MDAxYaawfprMqlxcXHI4nHO8OFXDXGI5XHUwMDA0US5cdTAwMTZcdTAwMWZnXHRcblxiWyFcdTAwMWPONVt3eJJcdTAwMWGVmLpcdTAwMWZ6ftguN9GhV1FcdTAwMTKo1DSiXs83Vo3zyFx1MDAwZk25Rt7vblx1MDAwNnZHq7kow/Y8XVa2gDjrsfhSll3Fv+1cdTAwMDKR/GHy/8vLxbXnVjK7ptew6GFr+vdHs1x1MDAwNVwiy8JJoGMxlVhQtLy1plx1MDAwN/qwvdc+xfuXcrA/knetNiSbvpNYN+0ghNjc0Vxutnnk/LeIX5M/XHUwMDAwTG3ehjb9POW/lEBUWZR84ps3QcKGrj/wzftYJo2O2b3bXHUwMDFk6uOr3TPVc+/ev918i+JcdTAwMGVcdTAwMTFg/vScWIviXGbymVx1MDAxM6NfZFFYXHUwMDEwXHS53aP/t6i1W9TW475XU3HcNHaGbI2xfdlF8L3H1yz6q937+qG+6IQwv7JecyvN7EFnS/D129a3f1x1MDAwMLFE1Vx1MDAwMCJ9 + + + + WidgetWidgetWidget \ No newline at end of file diff --git a/docs/index.md b/docs/index.md index a3fdfc8ea..dd59b082b 100644 --- a/docs/index.md +++ b/docs/index.md @@ -70,7 +70,5 @@ Textual is a framework for building applications that run within your terminal. === "Example 2" - ```{.textual path="docs/examples/introduction/timers.py"} - ``` diff --git a/mkdocs.yml b/mkdocs.yml index 1e84692a9..46367e352 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -7,9 +7,13 @@ nav: - "introduction.md" - Guide: - "guide/devtools.md" + - "guide/layout.md" - "guide/CSS.md" - "guide/events.md" - + - How to: + - "how-to/animation.md" + - "how-to/mouse-and-keyboard.md" + - "how-to/scroll.md" - "actions.md" - Events: - "events/blur.md" diff --git a/src/textual/_doc.py b/src/textual/_doc.py index 88770bd95..6a73696a6 100644 --- a/src/textual/_doc.py +++ b/src/textual/_doc.py @@ -1,5 +1,6 @@ from __future__ import annotations +import runpy import os from typing import cast, TYPE_CHECKING @@ -11,36 +12,36 @@ if TYPE_CHECKING: def format_svg(source, language, css_class, options, md, attrs, **kwargs) -> str: """A superfences formatter to insert a SVG screenshot.""" - path: str = attrs["path"] - _press = attrs.get("press", None) - press = [*_press.split(",")] if _press else ["_"] - title = attrs.get("title") - - os.environ["COLUMNS"] = attrs.get("columns", "80") - os.environ["LINES"] = attrs.get("lines", "24") - - print(f"screenshotting {path!r}") - - cwd = os.getcwd() - examples_path, filename = os.path.split(path) try: - os.chdir(examples_path) - with open(filename, "rt") as python_code: - source = python_code.read() - app_vars: dict[str, object] = {} - exec(source, app_vars) + path: str = attrs["path"] + _press = attrs.get("press", None) + press = [*_press.split(",")] if _press else ["_"] + title = attrs.get("title") - app: App = cast("App", app_vars["app"]) - app.run( - quit_after=5, - press=press or ["ctrl+c"], - headless=True, - screenshot=True, - screenshot_title=title, - ) - svg = app._screenshot - finally: - os.chdir(cwd) + os.environ["COLUMNS"] = attrs.get("columns", "80") + os.environ["LINES"] = attrs.get("lines", "24") - assert svg is not None - return svg + print(f"screenshotting {path!r}") + + cwd = os.getcwd() + try: + app_vars = runpy.run_path(path) + app: App = cast("App", app_vars["app"]) + app.run( + quit_after=5, + press=press or ["ctrl+c"], + headless=True, + screenshot=True, + screenshot_title=title, + ) + svg = app._screenshot + finally: + os.chdir(cwd) + + assert svg is not None + return svg + + except Exception as error: + import traceback + + traceback.print_exception(error) diff --git a/src/textual/message_pump.py b/src/textual/message_pump.py index 4700538d8..01cecabca 100644 --- a/src/textual/message_pump.py +++ b/src/textual/message_pump.py @@ -112,6 +112,11 @@ class MessagePump(metaclass=MessagePumpMeta): @property def log(self) -> Logger: + """Get a logger for this object. + + Returns: + Logger: A logger. + """ return self.app._logger def _attach(self, parent: MessagePump) -> None: