Open dogamak opened 7 years ago
I have come up with this design, which should be pretty flexible. It is quite a lot of stuff to implement for a simple component like components::Text
, but should allow for nice and easy abstractions.
trait ComponentConfig {
type State: ComponentState = Self;
}
trait ComponentState: Future<Item=Self::Update, Error=Self::Error> {
type Update;
type Error: Into<Error>;
type Config: ComponentConfig<State=Self> = Self;
fn create(config: Self::Config) -> Result<Self>;
fn get_size(self) -> u16;
fn update(&mut self, update: Update) -> Result<()>;
fn render(&mut self, surface: cairo::Surface) -> Result<()>;
}
This could be abstracted to resemble the current Component
trait with a blanket impl:
trait StringComponent {
type Stream: Stream<Item=String, Error=Self::Error>;
type Error: Error;
type Config: ComponentConfig<State=Self> = Self;
fn create(config: Self::Config) -> Result<Self>;
fn stream(self, handle: Handle) -> Self::Stream;
}
Requiring ComponentState
to implement Stream
was probably a mistake. Returning a stream is probably cleaner, simpler and more flexible.
Currently
Component
s are streams ofString
values at heart. This works nicely for simple components such as clock, but a good bar is more than just text.Ideally a component should be able to render whatever it wants on the part of the window reserved for it. This could be used to implement features like icons (#5) and progress bars (#10) and even more complicated componens.
However nobody wants to worry about individual pixels when all they want it to display a piece of text or an icon. Because of this we need higher level abstractions over the raw access to the drawing surface. Ideally components and abstractions would be chainable so that one could easily and without custom components implement things like "showing the content of file, truncated at 25 characters and refreshing every 5 seconds".
This issue is for the planning of such architecture.