mirror of
https://github.com/esphome/esphome.git
synced 2024-12-12 08:24:55 +01:00
Add ability for FixedDimensionPanel to operate in one of three modes; display dimension, child dimension, or fixed.
- Display dimensions use the width/height of the display (minus margin, border, and padding) for the dimension - Child dimensions fix the dimension to that of the child - Fixed dimension uses a specified pixel value (or lambda returning pixel value)
This commit is contained in:
parent
fed36a0af5
commit
cbd4515900
3 changed files with 78 additions and 22 deletions
|
@ -11,28 +11,53 @@ static const char *const TAG = "fixeddimensionpanel";
|
|||
|
||||
void FixedDimensionPanel::dump_config(int indent_depth, int additional_level_depth) {
|
||||
this->dump_config_base_properties(TAG, indent_depth);
|
||||
YESNO(this->width_.value() < 1));
|
||||
ESP_LOGCONFIG(TAG, "%*sHeight: %i (Will use display height: %s)", indent_depth, "", this->height_.value(),
|
||||
YESNO(this->height_.value() < 1));
|
||||
if (this->width_.value() < 0) {
|
||||
ESP_LOGCONFIG(TAG, "%*sWidth: UNSET (Will use %s's width)", indent_depth, "",
|
||||
this->unset_width_uses_display_width_ ? "DISPLAY" : "CHILD");
|
||||
} else {
|
||||
ESP_LOGCONFIG(TAG, "%*sWidth: %i", indent_depth, "", this->width_.value());
|
||||
}
|
||||
|
||||
if (this->height_.value() < 0) {
|
||||
ESP_LOGCONFIG(TAG, "%*sHeight: UNSET (Will use %s's height)", indent_depth, "",
|
||||
this->unset_height_uses_display_height_ ? "DISPLAY" : "CHILD");
|
||||
} else {
|
||||
ESP_LOGCONFIG(TAG, "%*sHeight: %i", indent_depth, "", this->height_.value());
|
||||
}
|
||||
|
||||
this->child_->dump_config(indent_depth + additional_level_depth, additional_level_depth);
|
||||
}
|
||||
|
||||
display::Rect FixedDimensionPanel::measure_item_internal(display::Display *display) {
|
||||
// Call measure_child so they can do any measurements
|
||||
display::Rect child_size = this->child_->measure_item(display);
|
||||
display::Rect rect(0, 0, this->width_.value(), this->height_.value());
|
||||
if (rect.w < 1) {
|
||||
rect.w = display->get_width();
|
||||
|
||||
if (rect.w < 0) {
|
||||
if (this->unset_width_uses_display_width_) {
|
||||
rect.w = display->get_width();
|
||||
// We need to account for our own padding + margin + border
|
||||
rect.w -= (this->margin_ + this->border_ + this->padding_) * 2;
|
||||
} else {
|
||||
rect.w = child_size.w;
|
||||
}
|
||||
}
|
||||
if (rect.h < 1) {
|
||||
rect.h = display->get_height();
|
||||
|
||||
if (rect.h < 0) {
|
||||
if (this->unset_height_uses_display_height_) {
|
||||
rect.h = display->get_height();
|
||||
// We need to account for our own padding + margin + border
|
||||
rect.h -= (this->margin_ + this->border_ + this->padding_) * 2;
|
||||
} else {
|
||||
rect.h = child_size.h;
|
||||
}
|
||||
}
|
||||
// Call measure_child just so they can do any measurements
|
||||
this->child_->measure_item(display);
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
void FixedDimensionPanel::render_internal(display::Display *display, display::Rect bounds) {
|
||||
this->child_->render_internal(display, bounds);
|
||||
this->child_->render(display, bounds);
|
||||
}
|
||||
|
||||
} // namespace graphical_layout
|
||||
|
|
|
@ -19,10 +19,19 @@ class FixedDimensionPanel : public LayoutItem {
|
|||
template<typename V> void set_width(V width) { this->width_ = width; };
|
||||
template<typename V> void set_height(V height) { this->height_ = height; }
|
||||
|
||||
void set_unset_width_uses_display_width(bool use_display) {
|
||||
this->unset_width_uses_display_width_ = use_display;
|
||||
}
|
||||
void set_unset_height_uses_display_height(bool use_display) {
|
||||
this->unset_height_uses_display_height_ = use_display;
|
||||
}
|
||||
|
||||
protected:
|
||||
LayoutItem *child_{nullptr};
|
||||
TemplatableValue<int> width_{0};
|
||||
TemplatableValue<int> height_{0};
|
||||
TemplatableValue<int> width_{-1};
|
||||
TemplatableValue<int> height_{-1};
|
||||
bool unset_width_uses_display_width_{false};
|
||||
bool unset_height_uses_display_height_{false};
|
||||
};
|
||||
|
||||
} // namespace graphical_layout
|
||||
|
|
|
@ -5,19 +5,25 @@ from esphome.const import CONF_TYPE, CONF_WIDTH, CONF_HEIGHT
|
|||
graphical_layout_ns = cg.esphome_ns.namespace("graphical_layout")
|
||||
FixedDimensionPanel = graphical_layout_ns.class_("FixedDimensionPanel")
|
||||
|
||||
CONF_ITEM_PADDING = "item_padding"
|
||||
CONF_FIXED_DIMENSION_PANEL = "fixed_dimension_panel"
|
||||
CONF_CHILD = "child"
|
||||
|
||||
UNSET_DIMENSION_MODE = ["CHILD", "DISPLAY"]
|
||||
|
||||
|
||||
def get_config_schema(base_item_schema, item_type_schema):
|
||||
return base_item_schema.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(FixedDimensionPanel),
|
||||
cv.Optional(CONF_ITEM_PADDING, default=0): cv.int_,
|
||||
cv.Required(CONF_CHILD): item_type_schema,
|
||||
cv.Optional(CONF_WIDTH, default=-1): cv.templatable(cv.int_range(min=-1)),
|
||||
cv.Optional(CONF_HEIGHT, default=-1): cv.templatable(cv.int_range(min=-1)),
|
||||
cv.Optional(CONF_WIDTH, default=-1): cv.Any(
|
||||
cv.one_of(*UNSET_DIMENSION_MODE, upper=True),
|
||||
cv.templatable(cv.int_range(min=-1)),
|
||||
),
|
||||
cv.Optional(CONF_HEIGHT, default=-1): cv.Any(
|
||||
cv.one_of(*UNSET_DIMENSION_MODE, upper=True),
|
||||
cv.templatable(cv.int_range(min=-1)),
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -25,13 +31,29 @@ def get_config_schema(base_item_schema, item_type_schema):
|
|||
async def config_to_layout_item(pvariable_builder, item_config, child_item_builder):
|
||||
var = await pvariable_builder(item_config)
|
||||
|
||||
width = await cg.templatable(item_config[CONF_WIDTH], args=[], output_type=cg.int_)
|
||||
cg.add(var.set_width(width))
|
||||
if width_config := item_config.get(CONF_WIDTH):
|
||||
if width_config in UNSET_DIMENSION_MODE:
|
||||
cg.add(
|
||||
var.set_unset_width_uses_display_width(
|
||||
width_config.upper() == "DISPLAY"
|
||||
)
|
||||
)
|
||||
else:
|
||||
width = await cg.templatable(width_config, args=[], output_type=cg.int_)
|
||||
cg.add(var.set_width(width))
|
||||
|
||||
height = await cg.templatable(
|
||||
item_config[CONF_HEIGHT], args=[], output_type=cg.int_
|
||||
)
|
||||
cg.add(var.set_height(height))
|
||||
if height_config := item_config.get(CONF_HEIGHT):
|
||||
if height_config in UNSET_DIMENSION_MODE:
|
||||
cg.add(
|
||||
var.set_unset_height_uses_display_height(
|
||||
height_config.upper() == "DISPLAY"
|
||||
)
|
||||
)
|
||||
else:
|
||||
height = await cg.templatable(
|
||||
item_config[CONF_HEIGHT], args=[], output_type=cg.int_
|
||||
)
|
||||
cg.add(var.set_height(height))
|
||||
|
||||
child_item_config = item_config[CONF_CHILD]
|
||||
child_item_type = child_item_config[CONF_TYPE]
|
||||
|
|
Loading…
Reference in a new issue