mirror of
https://github.com/esphome/esphome.git
synced 2024-12-13 08:54:54 +01:00
Add first implementation of a DisplayRenderingPanel
Makes use of a standard display_writer_t style Lambda so users can use arbitrary APIs from the Display Rendering Engine within the layout engine
This commit is contained in:
parent
5c2c8935ce
commit
00caf53dc4
4 changed files with 95 additions and 0 deletions
|
@ -5,6 +5,7 @@ from esphome.const import CONF_ID
|
||||||
from . import horizontal_stack
|
from . import horizontal_stack
|
||||||
from . import vertical_stack
|
from . import vertical_stack
|
||||||
from . import text_panel
|
from . import text_panel
|
||||||
|
from . import display_rendering_panel
|
||||||
|
|
||||||
graphical_layout_ns = cg.esphome_ns.namespace("graphical_layout")
|
graphical_layout_ns = cg.esphome_ns.namespace("graphical_layout")
|
||||||
RootLayoutComponent = graphical_layout_ns.class_("RootLayoutComponent", cg.Component)
|
RootLayoutComponent = graphical_layout_ns.class_("RootLayoutComponent", cg.Component)
|
||||||
|
@ -68,6 +69,14 @@ ITEM_TYPE_SCHEMA = cv.typed_schema(
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
display_rendering_panel.CONF_TYPE: BASE_ITEM_SCHEMA.extend(
|
||||||
|
{
|
||||||
|
cv.GenerateID(): cv.declare_id(display_rendering_panel.DisplayRenderingPanel),
|
||||||
|
cv.Required(display_rendering_panel.CONF_WIDTH): cv.templatable(cv.int_range(min=1)),
|
||||||
|
cv.Required(display_rendering_panel.CONF_HEIGHT): cv.templatable(cv.int_range(min=1)),
|
||||||
|
cv.Required(display_rendering_panel.CONF_LAMBDA): cv.lambda_,
|
||||||
|
}
|
||||||
|
),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -75,6 +84,7 @@ CODE_GENERATORS = {
|
||||||
text_panel.CONF_TYPE: text_panel.config_to_layout_item,
|
text_panel.CONF_TYPE: text_panel.config_to_layout_item,
|
||||||
horizontal_stack.CONF_TYPE: horizontal_stack.config_to_layout_item,
|
horizontal_stack.CONF_TYPE: horizontal_stack.config_to_layout_item,
|
||||||
vertical_stack.CONF_TYPE: vertical_stack.config_to_layout_item,
|
vertical_stack.CONF_TYPE: vertical_stack.config_to_layout_item,
|
||||||
|
display_rendering_panel.CONF_TYPE: display_rendering_panel.config_to_layout_item,
|
||||||
}
|
}
|
||||||
|
|
||||||
CONFIG_SCHEMA = cv.Schema(
|
CONFIG_SCHEMA = cv.Schema(
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
#include "display_rendering_panel.h"
|
||||||
|
|
||||||
|
#include "esphome/components/display/display.h"
|
||||||
|
#include "esphome/components/display/rect.h"
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace graphical_layout {
|
||||||
|
|
||||||
|
static const char *const TAG = "displayrenderingpanel";
|
||||||
|
|
||||||
|
void DisplayRenderingPanel::dump_config(int indent_depth, int additional_level_depth) {
|
||||||
|
ESP_LOGCONFIG(TAG, "%*sDimensions: %ix%i", indent_depth, "", this->width_, this->height_);
|
||||||
|
ESP_LOGCONFIG(TAG, "%*sHas drawing lambda: %s", indent_depth, "", YESNO(this->lambda_ != nullptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
const display::Rect DisplayRenderingPanel::measure_item(display::Display *display) {
|
||||||
|
return display::Rect(0, 0, this->width_, this->width_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayRenderingPanel::render(display::Display *display, display::Rect bounds) {
|
||||||
|
this->lambda_(*display);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace graphical_layout
|
||||||
|
} // namespace esphome
|
|
@ -0,0 +1,32 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/components/graphical_layout/graphical_layout.h"
|
||||||
|
#include "esphome/components/font/font.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace graphical_layout {
|
||||||
|
|
||||||
|
/* See display.h for original declaration */
|
||||||
|
using display_writer_t = std::function<void(display::Display &)>;
|
||||||
|
|
||||||
|
/** The DisplayRenderingPanel is a UI item that renders a custom lambda to the display whilst
|
||||||
|
* participating in the layout process
|
||||||
|
*/
|
||||||
|
class DisplayRenderingPanel : public LayoutItem {
|
||||||
|
public:
|
||||||
|
const display::Rect measure_item(display::Display *display);
|
||||||
|
void render(display::Display *display, display::Rect bounds);
|
||||||
|
void dump_config(int indent_depth, int additional_level_depth);
|
||||||
|
|
||||||
|
void set_width(int width) { this->width_ = width; };
|
||||||
|
void set_height(int height) { this->height_ = height; };
|
||||||
|
void set_lambda(display_writer_t lambda) { this->lambda_ = lambda; };
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int width_{0};
|
||||||
|
int height_{0};
|
||||||
|
display_writer_t lambda_{nullptr};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace graphical_layout
|
||||||
|
} // namespace esphome
|
|
@ -0,0 +1,27 @@
|
||||||
|
import esphome.codegen as cg
|
||||||
|
from esphome.const import CONF_ID
|
||||||
|
from esphome.components.display import DisplayRef
|
||||||
|
|
||||||
|
graphical_layout_ns = cg.esphome_ns.namespace("graphical_layout")
|
||||||
|
DisplayRenderingPanel = graphical_layout_ns.class_("DisplayRenderingPanel")
|
||||||
|
|
||||||
|
CONF_TYPE = "display_rendering_panel"
|
||||||
|
CONF_HEIGHT = "height"
|
||||||
|
CONF_WIDTH = "width"
|
||||||
|
CONF_LAMBDA = "lambda"
|
||||||
|
|
||||||
|
async def config_to_layout_item(item_config, child_item_builder):
|
||||||
|
var = cg.new_Pvariable(item_config[CONF_ID])
|
||||||
|
|
||||||
|
width = await cg.templatable(item_config[CONF_WIDTH], args=[], output_type=int)
|
||||||
|
cg.add(var.set_width(width))
|
||||||
|
|
||||||
|
height = await cg.templatable(item_config[CONF_HEIGHT], args=[], output_type=int)
|
||||||
|
cg.add(var.set_height(height))
|
||||||
|
|
||||||
|
lambda_ = await cg.process_lambda(
|
||||||
|
item_config[CONF_LAMBDA], [(DisplayRef, "it")], return_type=cg.void
|
||||||
|
)
|
||||||
|
cg.add(var.set_lambda(lambda_))
|
||||||
|
|
||||||
|
return var
|
Loading…
Reference in a new issue