Create the Screenplay library, with a demo in the Kifu app #33

Merged
savanni merged 3 commits from savanni/screenplay into main 2023-03-22 15:08:00 +00:00
1 changed files with 31 additions and 1 deletions
Showing only changes of commit f23d7e9d7e - Show all commits

View File

@ -10,24 +10,49 @@ Screenplay is distributed in the hope that it will be useful, but WITHOUT ANY WA
You should have received a copy of the GNU General Public License along with Lumeto. If not, see <https://www.gnu.org/licenses/>. You should have received a copy of the GNU General Public License along with Lumeto. If not, see <https://www.gnu.org/licenses/>.
*/ */
/// Screenplay is a library that helps visualize GTK scenes. I got my inspiration from working with
/// Storybook and decided that I wanted a similar tool for GTK.
///
/// With this library, you can write an application that loads up a bunch of different user
/// interfaces, and the library will put them on separate pages. Each UI can have as much or as
/// little behavior as you want.
use gtk::prelude::*; use gtk::prelude::*;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum Action { enum Action {
SelectPage(usize), SelectPage(usize),
Deselect, Deselect,
} }
/// Unused. In the near future, this will contain useful errors.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Error; pub struct Error;
/// A definition of a single Screen. The screen can be as much or as little as you want, but must
/// contain a title (for the page selector) and a widget to show the screen.
#[derive(Clone)] #[derive(Clone)]
pub struct Screen { pub struct Screen {
/// Title of the screen. This will only be rendered in the page selector.
pub title: String, pub title: String,
/// The screen itself. This can be anything that implements the gtk::Widget interface, and it
/// will be rendered in the main area of the window.
pub widget: gtk::Widget, pub widget: gtk::Widget,
/// Unused today, however...
/// These will be rendered in an area of the window reserved for adjustments. They are meant to
/// be ways to provide variants to the current scene. You will need to attach behaviors.
pub adjustments: Vec<gtk::Widget>, pub adjustments: Vec<gtk::Widget>,
} }
/// Screenplay is an object that will render a gtk::ApplicationWindow.
///
/// That window contains a sidebar which lists the names of all of the Screens that have been
/// provided to it. Selecting one of those will cause the application to render that screen and all
/// of its adjustments.
///
/// It is highly likely that in the future this structure will be reformulated as a child of a GTK
/// ApplicationWindow.
#[derive(Clone)] #[derive(Clone)]
pub struct Screenplay { pub struct Screenplay {
frame: gtk::Frame, frame: gtk::Frame,
@ -35,6 +60,10 @@ pub struct Screenplay {
} }
impl Screenplay { impl Screenplay {
/// Construct a new Screenplay. This will construct and render the ApplicationWindow as the
/// primary child of the Application.
///
/// This function currently returns no errors, instead panicing if anything goes wrong.
pub fn new(gtk_app: &gtk::Application, screens: Vec<Screen>) -> Result<Self, Error> { pub fn new(gtk_app: &gtk::Application, screens: Vec<Screen>) -> Result<Self, Error> {
let window = gtk::ApplicationWindow::new(gtk_app); let window = gtk::ApplicationWindow::new(gtk_app);
window.show(); window.show();
@ -86,6 +115,7 @@ impl Screenplay {
Ok(storybook) Ok(storybook)
} }
/// Handle an application action. This generally means changing the current screen.
fn process_action(&mut self, message: Action) -> Continue { fn process_action(&mut self, message: Action) -> Continue {
let nothing: Option<&gtk::Widget> = None; let nothing: Option<&gtk::Widget> = None;
match message { match message {