Switch to using shared_ptr for Text Runs being added to the TextRunPanel

This commit is contained in:
Michael Davidson 2024-02-25 21:30:45 +11:00
parent bae83021ed
commit c2d72b08f3
No known key found for this signature in database
GPG key ID: B8D1A99712B8B0EB
3 changed files with 45 additions and 13 deletions

View file

@ -21,7 +21,7 @@ void TextRunPanel::dump_config(int indent_depth, int additional_level_depth) {
LOG_STR_ARG(display::text_align_to_string(this->text_align_))); LOG_STR_ARG(display::text_align_to_string(this->text_align_)));
ESP_LOGCONFIG(TAG, "%*sDraw Partial Lines: %s", indent_depth, "", YESNO(this->draw_partial_lines_)); ESP_LOGCONFIG(TAG, "%*sDraw Partial Lines: %s", indent_depth, "", YESNO(this->draw_partial_lines_));
ESP_LOGCONFIG(TAG, "%*sText Runs: %i", indent_depth, "", this->text_runs_.size()); ESP_LOGCONFIG(TAG, "%*sText Runs: %i", indent_depth, "", this->text_runs_.size());
for (TextRunBase *run : this->text_runs_) { for (const auto &run : this->text_runs_) {
std::string text = run->get_text(); std::string text = run->get_text();
ESP_LOGCONFIG(TAG, "%*sText: %s", indent_depth + additional_level_depth, "", text.c_str()); ESP_LOGCONFIG(TAG, "%*sText: %s", indent_depth + additional_level_depth, "", text.c_str());
} }
@ -85,7 +85,7 @@ void TextRunPanel::render_internal(display::Display *display, display::Rect boun
std::vector<std::shared_ptr<CalculatedTextRun>> TextRunPanel::split_runs_into_words_() { std::vector<std::shared_ptr<CalculatedTextRun>> TextRunPanel::split_runs_into_words_() {
std::vector<std::shared_ptr<CalculatedTextRun>> runs; std::vector<std::shared_ptr<CalculatedTextRun>> runs;
for (TextRunBase *run : this->text_runs_) { for (const auto &run : this->text_runs_) {
std::string text = run->get_text(); std::string text = run->get_text();
CanWrapAtCharacterArguments can_wrap_at_args(this, 0, text, ' '); CanWrapAtCharacterArguments can_wrap_at_args(this, 0, text, ' ');

View file

@ -174,7 +174,7 @@ struct RunProperties {
class CalculatedTextRun { class CalculatedTextRun {
public: public:
CalculatedTextRun(TextRunBase *run, RunProperties run_properties) { CalculatedTextRun(std::shared_ptr<TextRunBase> run, RunProperties run_properties) {
this->run = run; this->run = run;
this->run_properties = run_properties; this->run_properties = run_properties;
} }
@ -193,7 +193,7 @@ class CalculatedTextRun {
std::string text{}; std::string text{};
display::Rect bounds{}; display::Rect bounds{};
TextRunBase *run{nullptr}; std::shared_ptr<TextRunBase> run{};
int16_t baseline{0}; int16_t baseline{0};
RunProperties run_properties{}; RunProperties run_properties{};
}; };
@ -258,7 +258,7 @@ class TextRunPanel : public LayoutItem {
this->can_wrap_at_character_ = can_wrap_at_character; this->can_wrap_at_character_ = can_wrap_at_character;
}; };
void add_text_run(TextRunBase *text_run) { this->text_runs_.push_back(text_run); }; void add_text_run(std::shared_ptr<TextRunBase> text_run) { this->text_runs_.push_back(text_run); };
void set_text_align(display::TextAlign text_align) { this->text_align_ = text_align; }; void set_text_align(display::TextAlign text_align) { this->text_align_ = text_align; };
void set_min_width(int min_width) { this->min_width_ = min_width; }; void set_min_width(int min_width) { this->min_width_ = min_width; };
void set_max_width(int max_width) { this->max_width_ = max_width; }; void set_max_width(int max_width) { this->max_width_ = max_width; };
@ -274,7 +274,7 @@ class TextRunPanel : public LayoutItem {
void apply_alignment_to_lines_(std::vector<std::shared_ptr<LineInfo>> &lines, display::TextAlign alignment); void apply_alignment_to_lines_(std::vector<std::shared_ptr<LineInfo>> &lines, display::TextAlign alignment);
CharacterProperties get_character_properties_(char character); CharacterProperties get_character_properties_(char character);
std::vector<TextRunBase *> text_runs_; std::vector<std::shared_ptr<TextRunBase>> text_runs_;
display::TextAlign text_align_{display::TextAlign::TOP_LEFT}; display::TextAlign text_align_{display::TextAlign::TOP_LEFT};
int min_width_{0}; int min_width_{0};
int max_width_{0}; int max_width_{0};

View file

@ -1,4 +1,6 @@
import esphome.codegen as cg import esphome.codegen as cg
from esphome.cpp_generator import CallExpression, MockObjClass, MockObj
from esphome.core import ID
import esphome.config_validation as cv import esphome.config_validation as cv
from esphome.components import font, color, sensor, text_sensor, time from esphome.components import font, color, sensor, text_sensor, time
from esphome.components.display import display_ns from esphome.components.display import display_ns
@ -10,6 +12,8 @@ from esphome.const import (
CONF_TIME_ID, CONF_TIME_ID,
) )
SharedPtr = cg.std_ns.class_("shared_ptr")
graphical_layout_ns = cg.esphome_ns.namespace("graphical_layout") graphical_layout_ns = cg.esphome_ns.namespace("graphical_layout")
TextRunPanel = graphical_layout_ns.class_("TextRunPanel") TextRunPanel = graphical_layout_ns.class_("TextRunPanel")
TextAlign = display_ns.enum("TextAlign", is_class=True) TextAlign = display_ns.enum("TextAlign", is_class=True)
@ -130,6 +134,20 @@ def get_config_schema(base_item_schema, item_type_schema):
) )
def build_text_run_base_shared_ptr(
id_: ID, type: MockObjClass, *make_shared_args
) -> MockObj:
make_shared = CallExpression(
cg.RawExpression("std::make_shared"),
cg.TemplateArguments(type),
*make_shared_args,
)
shared_ptr = cg.new_variable(id_, make_shared, SharedPtr.template(type))
shared_ptr.op = "->"
return shared_ptr
async def config_to_layout_item(pvariable_builder, item_config, child_item_builder): async def config_to_layout_item(pvariable_builder, item_config, child_item_builder):
var = await pvariable_builder(item_config) var = await pvariable_builder(item_config)
@ -162,28 +180,42 @@ async def config_to_layout_item(pvariable_builder, item_config, child_item_build
run_font = await cg.get_variable(run_config[CONF_FONT]) run_font = await cg.get_variable(run_config[CONF_FONT])
if run_sensor_config := run_config.get(CONF_SENSOR): if run_sensor_config := run_config.get(CONF_SENSOR):
sens = await cg.get_variable(run_sensor_config) sens = await cg.get_variable(run_sensor_config)
run = cg.new_Pvariable(run_config[CONF_ID], sens, run_font) run = build_text_run_base_shared_ptr(
run_config[CONF_ID], SensorTextRun, sens, run_font
)
elif run_text_sensor_config := run_config.get(CONF_TEXT_SENSOR): elif run_text_sensor_config := run_config.get(CONF_TEXT_SENSOR):
text_sens = await cg.get_variable(run_text_sensor_config) text_sens = await cg.get_variable(run_text_sensor_config)
run = cg.new_Pvariable(run_config[CONF_ID], text_sens, run_font) run = build_text_run_base_shared_ptr(
run_config[CONF_ID], TextSensorTextRun, text_sens, run_font
)
elif run_time_id_config := run_config.get(CONF_TIME_ID): elif run_time_id_config := run_config.get(CONF_TIME_ID):
time_sens = await cg.get_variable(run_time_id_config) time_sens = await cg.get_variable(run_time_id_config)
time_format = await cg.templatable( time_format = await cg.templatable(
run_config[CONF_TIME_FORMAT], args=[], output_type=cg.std_string run_config[CONF_TIME_FORMAT], args=[], output_type=cg.std_string
) )
use_utc_time = run_config[CONF_USE_UTC_TIME] use_utc_time = run_config[CONF_USE_UTC_TIME]
run = cg.new_Pvariable( run = build_text_run_base_shared_ptr(
run_config[CONF_ID], time_sens, time_format, use_utc_time, run_font run_config[CONF_ID],
TimeTextRun,
time_sens,
time_format,
use_utc_time,
run_font,
) )
elif paragraph_break_config := run_config.get(CONF_PARAGRAPH_BREAK): elif paragraph_break_config := run_config.get(CONF_PARAGRAPH_BREAK):
run = cg.new_Pvariable( run = build_text_run_base_shared_ptr(
run_config[CONF_ID], paragraph_break_config, run_font run_config[CONF_ID],
ParagraphBreakTextRun,
paragraph_break_config,
run_font,
) )
else: else:
run_text = await cg.templatable( run_text = await cg.templatable(
run_config[CONF_TEXT], args=[], output_type=cg.std_string run_config[CONF_TEXT], args=[], output_type=cg.std_string
) )
run = cg.new_Pvariable(run_config[CONF_ID], run_text, run_font) run = build_text_run_base_shared_ptr(
run_config[CONF_ID], TextRun, run_text, run_font
)
if run_text_formatter_config := run_config.get(CONF_TEXT_FORMATTER): if run_text_formatter_config := run_config.get(CONF_TEXT_FORMATTER):
run_text_formatter = await cg.process_lambda( run_text_formatter = await cg.process_lambda(