From abfe047cb80335f348eb5163a55cb8aef9e3c101 Mon Sep 17 00:00:00 2001 From: John Till Date: Fri, 8 Nov 2024 22:06:24 +0000 Subject: [PATCH] Highlight construct groupings Matrix and binomial constructs have highlighted groupings --- src/forscape_symbol_lexical_pass.cpp | 4 +- src/typeset_construct.cpp | 4 ++ src/typeset_construct.h | 1 + src/typeset_constructs/typeset_big_integral.h | 3 ++ src/typeset_constructs/typeset_binomial.h | 5 ++ src/typeset_constructs/typeset_matrix.h | 15 ++++++ src/typeset_model.cpp | 7 +++ src/typeset_painter.h | 4 ++ src/typeset_painter_qt.cpp | 47 +++++++++++++++++-- 9 files changed, 85 insertions(+), 5 deletions(-) diff --git a/src/forscape_symbol_lexical_pass.cpp b/src/forscape_symbol_lexical_pass.cpp index baa0f48..a586216 100644 --- a/src/forscape_symbol_lexical_pass.cpp +++ b/src/forscape_symbol_lexical_pass.cpp @@ -201,15 +201,15 @@ void SymbolLexicalPass::resolveAssignment(ParseNode pn) alloc_except { break; case OP_IDENTIFIER: - resolveExpr(rhs); resolveAssignmentId(pn); + resolveExpr(rhs); break; case OP_SUBSCRIPT_ACCESS: if(lexical_map.find(parse_tree.getSelection(lhs)) != lexical_map.end()){ resolvePotentialIdSub(lhs); - resolveExpr(rhs); resolveAssignmentId(pn); + resolveExpr(rhs); }else{ parse_tree.setOp(pn, OP_REASSIGN); resolveAssignmentSubscript(pn, lhs, rhs); diff --git a/src/typeset_construct.cpp b/src/typeset_construct.cpp index a7e7deb..1b9cd43 100644 --- a/src/typeset_construct.cpp +++ b/src/typeset_construct.cpp @@ -186,6 +186,10 @@ void Construct::paint(Painter& painter) const { for(Subphrase* arg : args) arg->paint(painter); } +void Construct::paintGrouping(Painter&) const { + // DO NOTHING +} + double Construct::height() const noexcept { return above_center + under_center; } diff --git a/src/typeset_construct.h b/src/typeset_construct.h index 2b0613f..9450b56 100644 --- a/src/typeset_construct.h +++ b/src/typeset_construct.h @@ -79,6 +79,7 @@ class Construct { virtual void updateSizeFromChildSizes() noexcept = 0; void updateLayout() noexcept; void paint(Painter& painter) const; + virtual void paintGrouping(Painter& painter) const; double height() const noexcept; double width DEBUG_INIT_STALE; double above_center DEBUG_INIT_STALE; diff --git a/src/typeset_constructs/typeset_big_integral.h b/src/typeset_constructs/typeset_big_integral.h index 25c43e9..113e60d 100644 --- a/src/typeset_constructs/typeset_big_integral.h +++ b/src/typeset_constructs/typeset_big_integral.h @@ -66,6 +66,9 @@ class BigIntegralSuper0 final : public Construct { painter.drawSymbol(x, y, getBigIntegralString(type)); } + // EVENTUALLY: it would be nice to highlight groupings for integrals, e.g. in ∫ x ⅆx + // treat the '∫' like an opening symbol and ⅆx like a closing one. + static void modifyFirstScript(Construct* con, Controller& c, Subphrase*); static const std::vector actions; diff --git a/src/typeset_constructs/typeset_binomial.h b/src/typeset_constructs/typeset_binomial.h index 333792f..e28551c 100644 --- a/src/typeset_constructs/typeset_binomial.h +++ b/src/typeset_constructs/typeset_binomial.h @@ -63,6 +63,11 @@ class Binomial final : public Construct { painter.drawSymbol(')', x + width - paren_width, y, paren_width, height()); } + virtual void paintGrouping(Painter& painter) const override { + painter.drawHighlightedGrouping(x, y, paren_width, height(), "("); + painter.drawHighlightedGrouping(x + width - paren_width, y, paren_width, height(), ")"); + } + virtual bool increasesScriptDepth(uint8_t) const noexcept override{ return !parent->isLine(); } diff --git a/src/typeset_constructs/typeset_matrix.h b/src/typeset_constructs/typeset_matrix.h index d889c5f..72d41d8 100644 --- a/src/typeset_constructs/typeset_matrix.h +++ b/src/typeset_constructs/typeset_matrix.h @@ -149,6 +149,21 @@ class Matrix final : public Construct { painter.drawLine(x+width-BRACKET_WIDTH-MATRIX_RPADDING, y+BRACKET_VSHIFT+h, BRACKET_WIDTH, 0); } + virtual void paintGrouping(Painter& painter) const override { + double h = height(); + constexpr double m = 2.0; // margin + painter.drawHighlightBox(x+MATRIX_LPADDING-m, y+BRACKET_VSHIFT-m, BRACKET_WIDTH+m, h+2*m); + painter.drawHighlightBox(x+width-BRACKET_WIDTH-MATRIX_RPADDING, y+BRACKET_VSHIFT-m, BRACKET_WIDTH+m, h+2*m); + + painter.drawHighlightLine(x+MATRIX_LPADDING, y+BRACKET_VSHIFT, BRACKET_WIDTH, 0); + painter.drawHighlightLine(x+MATRIX_LPADDING, y+BRACKET_VSHIFT, 0, h); + painter.drawHighlightLine(x+MATRIX_LPADDING, y+BRACKET_VSHIFT+h, BRACKET_WIDTH, 0); + + painter.drawHighlightLine(x+width-BRACKET_WIDTH-MATRIX_RPADDING, y+BRACKET_VSHIFT, BRACKET_WIDTH, 0); + painter.drawHighlightLine(x+width-MATRIX_RPADDING, y+BRACKET_VSHIFT, 0, h); + painter.drawHighlightLine(x+width-BRACKET_WIDTH-MATRIX_RPADDING, y+BRACKET_VSHIFT+h, BRACKET_WIDTH, 0); + } + static std::vector actions; virtual const std::vector& getContextActions(Subphrase* child) const noexcept override { diff --git a/src/typeset_model.cpp b/src/typeset_model.cpp index 8086c85..28baee8 100644 --- a/src/typeset_model.cpp +++ b/src/typeset_model.cpp @@ -575,6 +575,13 @@ void Model::paintGroupings(Painter& painter, const Marker& loc) const { Typeset::Marker left = close_lookup->second; left.text->paintGrouping(painter, left.index); } + + if(loc.atTextEnd()) + if(Construct* con = loc.text->nextConstructInPhrase()) + con->paintGrouping(painter); + if(loc.atTextStart()) + if(Construct* con = loc.text->prevConstructInPhrase()) + con->paintGrouping(painter); } void Model::paintNumberCommas(Painter& painter, double xL, double yT, double xR, double yB, const Selection& sel) const { diff --git a/src/typeset_painter.h b/src/typeset_painter.h index ab911d4..fa6884a 100644 --- a/src/typeset_painter.h +++ b/src/typeset_painter.h @@ -62,7 +62,11 @@ class Painter { void setScriptLevel(uint8_t depth); void setOffset(double x, double y); void drawText(double x, double y, std::string_view text); + void drawHighlightBox(double x, double y, double w, double h); + void drawHighlightLine(double x, double y, double w, double h); + void drawHighlightText(double x, double y, double w, double h, std::string_view text); void drawHighlightedGrouping(double x, double y, double w, std::string_view text); + void drawHighlightedGrouping(double x, double y, double w, double h, std::string_view text); void drawSymbol(double x, double y, std::string_view text); void drawLine(double x, double y, double w, double h); void drawDashedLine(double x, double y, double w, double h); diff --git a/src/typeset_painter_qt.cpp b/src/typeset_painter_qt.cpp index cc745db..28259af 100644 --- a/src/typeset_painter_qt.cpp +++ b/src/typeset_painter_qt.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #ifndef NDEBUG #include @@ -142,14 +143,33 @@ void Painter::drawText(double x, double y, std::string_view text){ painter.drawText(QPointF(x, y), q_str); } -void Painter::drawHighlightedGrouping(double x, double y, double w, std::string_view text){ - if(x >= xR || y >= yB || (y + CAPHEIGHT[depth]) <= yT || x + CHARACTER_WIDTHS[depth] < xL) return; +void Painter::drawHighlightBox(double x, double y, double w, double h) { + if(x >= xR || y >= yB || (y + h) <= yT || x + w < xL) return; x += x_offset; painter.setPen(getColour(COLOUR_GROUPINGBACKGROUND)); painter.setBrush(getColour(COLOUR_GROUPINGBACKGROUND)); - painter.drawRect(x, y, w, ASCENT[depth]); + painter.drawRect(x, y, w, h); + + painter.setPen(getColour(COLOUR_CURSOR)); + painter.setBrush(getColour(COLOUR_CURSOR)); +} + +void Painter::drawHighlightLine(double x, double y, double w, double h) { + if(x >= xR || y >= yB || (y + h) <= yT || x + w < xL) return; + + painter.setPen(getColour(COLOUR_GROUPINGHIGHLIGHT)); + drawLine(x, y, w, h); + painter.setPen(getColour(COLOUR_CURSOR)); + painter.setBrush(getColour(COLOUR_CURSOR)); +} + +void Painter::drawHighlightedGrouping(double x, double y, double w, std::string_view text){ + if(x >= xR || y >= yB || (y + CAPHEIGHT[depth]) <= yT || x + CHARACTER_WIDTHS[depth] < xL) return; + drawHighlightBox(x, y, w, ASCENT[depth]); + + x += x_offset; painter.setPen(getColour(COLOUR_GROUPINGHIGHLIGHT)); y += CAPHEIGHT[depth]; @@ -159,6 +179,27 @@ void Painter::drawHighlightedGrouping(double x, double y, double w, std::string_ painter.setBrush(getColour(COLOUR_CURSOR)); } +void Painter::drawHighlightedGrouping(double x, double y, double w, double h, std::string_view text) { + if(x >= xR || y >= yB || (y + h) <= yT || x + w < xL) return; + drawHighlightBox(x, y, w, h * (1 + static_cast(DESCENT[depth])/ASCENT[depth])); + + x += x_offset; + painter.setPen(getColour(COLOUR_GROUPINGHIGHLIGHT)); + + double scale_x = w / CHARACTER_WIDTHS[depth]; + double scale_y = h / ASCENT[depth]; + x /= scale_x; + y = (y + h - DESCENT[depth]) / scale_y; + + QTransform transform = painter.transform(); + painter.scale(scale_x, scale_y); + painter.drawText(QPointF(x, y), toQString(text)); + painter.setTransform(transform); + + painter.setPen(getColour(COLOUR_CURSOR)); + painter.setBrush(getColour(COLOUR_CURSOR)); +} + void Painter::drawSymbol(double x, double y, std::string_view text){ if(x >= xR || y >= yB ||