diff --git a/doc/_sphinx/extensions/flutter_app.css b/doc/_sphinx/extensions/flutter_app.css index a54247966..54af42ca3 100644 --- a/doc/_sphinx/extensions/flutter_app.css +++ b/doc/_sphinx/extensions/flutter_app.css @@ -130,3 +130,30 @@ button.flutter-app-button:after { height: 350px; width: 100%; } + +.flutter-app-infobox { + background: #282828; + border: 1px solid #555555; + border-radius: 6px; + float: right; + margin-left: 6pt; + padding: 8px; + width: 280px; +} + +.flutter-app-infobox button.flutter-app-iframe { + height: 400px; +} + +.flutter-app-infobox button.flutter-app-button { + float: right; + font-size: 0.85em; + margin-bottom: 0; + margin-right: 0; + min-height: 14pt; + min-width: 50pt; +} + +.flutter-app-infobox p:last-child { + margin-bottom: 0; +} diff --git a/doc/_sphinx/extensions/flutter_app.py b/doc/_sphinx/extensions/flutter_app.py index 7c7e5eae2..bef8b948d 100644 --- a/doc/_sphinx/extensions/flutter_app.py +++ b/doc/_sphinx/extensions/flutter_app.py @@ -44,13 +44,16 @@ class FlutterAppDirective(SphinxDirective): with the matching name. :show: - a list of one or more run modes, which could include "widget", - "popup", and "code". Each of these modes produces a different output: + "popup", "code", and "infobox". Each of these modes produces a different + output: "widget" - an iframe shown directly inside the docs page; "popup" - a [Run] button which opens the app to (almost) fullscreen; "code" - a [Code] button which opens a popup with the code that was compiled. + "infobox" - the content will be displayed as an infobox floating on + the right-hand side of the page. """ - has_content = False + has_content = True required_arguments = 0 optional_arguments = 0 option_spec = { @@ -103,6 +106,11 @@ class FlutterAppDirective(SphinxDirective): classes=['flutter-app-button', 'code'], onclick=f'open_code_listings("{code_id}")', )) + if 'infobox' in self.modes: + self.state.nested_parse(self.content, 0, result) + result = [ + nodes.container('', *result, classes=['flutter-app-infobox']) + ] return result def _process_show_option(self): @@ -110,7 +118,7 @@ class FlutterAppDirective(SphinxDirective): if argument: values = argument.split() for value in values: - if value not in ['widget', 'popup', 'code']: + if value not in ['widget', 'popup', 'code', 'infobox']: raise self.error('Invalid :show: value ' + value) self.modes = values else: @@ -228,30 +236,23 @@ def _doc_root(): # ------------------------------------------------------------------------------ class IFrame(nodes.Element, nodes.General): - pass + def visit(self, node): + self.body.append( + self.starttag(node, 'iframe', src=node.attributes['src'])) - -def visit_iframe(self, node): - self.body.append(self.starttag(node, 'iframe', src=node.attributes['src'])) - - -def depart_iframe(self, _): - self.body.append('') + def depart(self, _): + self.body.append('') class Button(nodes.Element, nodes.General): - pass + def visit(self, node): + attrs = {} + if 'onclick' in node.attributes: + attrs['onclick'] = node.attributes['onclick'] + self.body.append(self.starttag(node, 'button', **attrs).strip()) - -def visit_button(self, node): - attrs = {} - if 'onclick' in node.attributes: - attrs['onclick'] = node.attributes['onclick'] - self.body.append(self.starttag(node, 'button', **attrs).strip()) - - -def depart_button(self, _): - self.body.append('') + def depart(self, _): + self.body.append('') # ------------------------------------------------------------------------------ @@ -265,8 +266,8 @@ def setup(app): shutil.copy(os.path.join(base_dir, 'flutter_app.js'), target_dir) shutil.copy(os.path.join(base_dir, 'flutter_app.css'), target_dir) - app.add_node(IFrame, html=(visit_iframe, depart_iframe)) - app.add_node(Button, html=(visit_button, depart_button)) + app.add_node(IFrame, html=(IFrame.visit, IFrame.depart)) + app.add_node(Button, html=(Button.visit, Button.depart)) app.add_directive('flutter-app', FlutterAppDirective) app.add_js_file('flutter_app.js') app.add_css_file('flutter_app.css') diff --git a/doc/_sphinx/theme/flames.css b/doc/_sphinx/theme/flames.css index 78d927b8a..499eb87ba 100644 --- a/doc/_sphinx/theme/flames.css +++ b/doc/_sphinx/theme/flames.css @@ -482,6 +482,12 @@ div.document { padding: var(--document-padding); } +div.document::after { /* clearfix */ + content: ''; + display: block; + clear: both; +} + div.copyright { font-size: 12px; margin-top: 3px; diff --git a/doc/development/documentation.md b/doc/development/documentation.md index 36532d25c..11b7e5381 100644 --- a/doc/development/documentation.md +++ b/doc/development/documentation.md @@ -109,11 +109,13 @@ Here's what the different options mean: When using this option, the `main.dart` file of the app should route the execution to the proper widget according to the `page` being passed. -- **show**: contains a subset of modes: `widget`, `code`, and `popup`. The `widget` mode creates an - iframe with the embedded example, directly within the page. The `code` mode will show a button - that allows the user to see the code that produced this example. The `popup` mode also shows a - button, which displays the example in an overlay window. This is more suitable for demoing larger - apps. Using both "widget" and "popup" modes at the same time is not recommended. +- **show**: contains a subset of modes: `widget`, `code`, `infobox`, and `popup`. The `widget` mode + creates an iframe with the embedded example, directly within the page. The `code` mode will show + a button that allows the user to see the code that produced this example. The `popup` mode also + shows a button, which displays the example in an overlay window. This is more suitable for + demoing larger apps. Using both "widget" and "popup" modes at the same time is not recommended. + Finally, the `infobox` mode will display the result in a floating window -- this mode is best + combined with `widget` and `code`. ```{flutter-app} :sources: ../flame/examples