From 6880bc99ff55f3a91fce8aef8fe462ee9a0b741d Mon Sep 17 00:00:00 2001 From: Michael Davidson Date: Sun, 28 Jan 2024 16:35:46 +1100 Subject: [PATCH] Introduce ParagraphBreakTextRun. Forcefully causes new paragraphs --- .../components/graphical_layout/text_run_panel.cpp | 4 +++- .../components/graphical_layout/text_run_panel.h | 12 ++++++++++++ .../components/graphical_layout/text_run_panel.py | 14 ++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/esphome/components/graphical_layout/text_run_panel.cpp b/esphome/components/graphical_layout/text_run_panel.cpp index 88c8fda9bd..e584865c8f 100644 --- a/esphome/components/graphical_layout/text_run_panel.cpp +++ b/esphome/components/graphical_layout/text_run_panel.cpp @@ -97,7 +97,9 @@ std::vector> TextRunPanel::split_runs_into_wo can_wrap_at_args.offset = i; prop.can_wrap = this->can_wrap_at_character_.value(can_wrap_at_args); - if ((current_text_run == nullptr) || (!current_text_run->run_properties.is_equivalent(prop))) { + // New lines always trigger a new run regardless of equivalency with prior runs + if ((current_text_run == nullptr) || (!current_text_run->run_properties.is_equivalent(prop)) || + (prop.causes_new_line)) { current_text_run = std::make_shared(run, prop); runs.push_back(current_text_run); } diff --git a/esphome/components/graphical_layout/text_run_panel.h b/esphome/components/graphical_layout/text_run_panel.h index 4c296bc873..fbd6e446d6 100644 --- a/esphome/components/graphical_layout/text_run_panel.h +++ b/esphome/components/graphical_layout/text_run_panel.h @@ -71,6 +71,18 @@ class TextRun : public TextRunBase, public FormattableTextRun { TemplatableValue text_{}; }; +class ParagraphBreakTextRun : public TextRunBase { + public: + ParagraphBreakTextRun(size_t breaks, display::BaseFont *font) : TextRunBase(font) { + this->text_.append(breaks, '\n'); + } + + std::string get_text() override { return this->text_; } + + protected: + std::string text_{""}; +}; + class SensorTextRun : public TextRunBase, public FormattableTextRun { public: SensorTextRun(sensor::Sensor *sensor, display::BaseFont *font) : TextRunBase(font) { this->sensor_ = sensor; } diff --git a/esphome/components/graphical_layout/text_run_panel.py b/esphome/components/graphical_layout/text_run_panel.py index 6857a75251..2295b92138 100644 --- a/esphome/components/graphical_layout/text_run_panel.py +++ b/esphome/components/graphical_layout/text_run_panel.py @@ -18,6 +18,7 @@ TextRun = graphical_layout_ns.class_("TextRun", TextRunBase) SensorTextRun = graphical_layout_ns.class_("SensorTextRun", TextRunBase) TextSensorTextRun = graphical_layout_ns.class_("TextSensorTextRun", TextRunBase) TimeTextRun = graphical_layout_ns.class_("TimeTextRun", TextRunBase) +ParagraphBreakTextRun = graphical_layout_ns.class_("ParagraphBreakTextRun", TextRunBase) CanWrapAtCharacterArguments = graphical_layout_ns.struct("CanWrapAtCharacterArguments") CanWrapAtCharacterArgumentsConstRef = CanWrapAtCharacterArguments.operator( "const" @@ -37,6 +38,7 @@ CONF_TEXT_FORMATTER = "text_formatter" CONF_TIME_FORMAT = "time_format" CONF_USE_UTC_TIME = "use_utc_time" CONF_DRAW_PARTIAL_LINES = "draw_partial_lines" +CONF_PARAGRAPH_BREAK = "paragraph_break" TEXT_ALIGN = { "TOP_LEFT": TextAlign.TOP_LEFT, @@ -95,11 +97,19 @@ TIME_TEXT_RUN_SCHEMA = BASE_RUN_SCHEMA.extend( } ) +PARAGRAPH_BREAK_TEXT_RUN_SCHEMA = BASE_RUN_SCHEMA.extend( + { + cv.GenerateID(): cv.declare_id(ParagraphBreakTextRun), + cv.Optional(CONF_PARAGRAPH_BREAK, default=1): cv.int_range(min=1), + } +) + RUN_SCHEMA = cv.Any( SENSOR_TEXT_RUN_SCHEMA, TEXT_RUN_SCHEMA, TEXT_SENSOR_TEXT_RUN_SCHEMA, TIME_TEXT_RUN_SCHEMA, + PARAGRAPH_BREAK_TEXT_RUN_SCHEMA, ) @@ -165,6 +175,10 @@ async def config_to_layout_item(pvariable_builder, item_config, child_item_build run = cg.new_Pvariable( run_config[CONF_ID], time_sens, time_format, use_utc_time, run_font ) + elif paragraph_break_config := run_config.get(CONF_PARAGRAPH_BREAK): + run = cg.new_Pvariable( + run_config[CONF_ID], paragraph_break_config, run_font + ) else: run_text = await cg.templatable( run_config[CONF_TEXT], args=[], output_type=cg.std_string