On Wed, Feb 21, 2007 at 03:12:24PM +0100, Stefan Schimanski wrote:
> Hi all!
> 
> I wrote here recently about the sometimes hard to use math macros in  
> LyX:
> 
>   http://www.mail-archive.com/[email protected]/msg53740.html
> 
> Attached is an experimental patch against the 1.5 branch to make  
> inline editing of macros possible, i.e. _without_ jumping back and  
> forth between the LyX macro preview and the unfolded version with the  
> #1, #2, ... lines.
> 
> The main idea is the following: If a macro is expanded, the  
> MathMacroArguments are replaced by MathMacroArgumentValues. These  
> have pointers to the MathMacro cells to (only) pass through draw and  
> metric calls to the cell. Hence the MathMacroArgumentValues will  
> behave like the cell visually.
> 
> This works quite nice, even if arguments appear multiple times in the  
> macro definition. Also the cursor movement is acceptable. It just  
> follows the order of argument appearances in the macro template.
> 
> I am not entirely sure whether the memory management is correct. It  
> would help if somebody who knows this in LyX could take a look over  
> it. Especially I wonder if the cell pointers can become invalid by  
> deleting the cell, but keeping the MathMacroArgumentValue object,  
> hence leading to a segfault.
> 
> Waiting for some comments
>   Schimmi


Here we go.

> Index: InsetMathMacro.h
> ===================================================================
> --- InsetMathMacro.h  (Revision 17273)
> +++ InsetMathMacro.h  (Arbeitskopie)
> @@ -20,8 +20,25 @@
>  
>  
>  namespace lyx {
> -
> -
> +  
> +  /// This class is the value of a macro argument, technically 
> +  /// a wrapper of the cells of MathMacro.
> +  class MathMacroArgumentValue : public InsetMathDim {
> +  public:
> +    ///
> +    MathMacroArgumentValue( MathArray *value );
> +    ///
> +    MathMacroArgumentValue( const MathMacroArgumentValue & );
> +    ///
> +    bool metrics(MetricsInfo & mi, Dimension & dim) const;
> +    ///
> +    void draw(PainterInfo &, int x, int y) const;
> +    
> +  private:
> +    virtual std::auto_ptr<InsetBase> doClone() const;
> +    MathArray *value_;
> +  };

This is not needed outside InsetMathMacro.C. So move it there.

Note that we are very picky wrt to code formatting. Please have 
a look at the rest of the code and follow the unwritten rules there
strictly.

This would e.g. be
    MathMacroArgumentValue(MathArray * value);
    MathMacroArgumentValue(MathMacroArgumentValue const &);

I'll attach a changed version of your patch. We should start from there.

Andre'
 
Index: InsetMathMacro.C
===================================================================
--- InsetMathMacro.C	(revision 17284)
+++ InsetMathMacro.C	(working copy)
@@ -33,6 +33,56 @@
 using std::vector;
 
 
+/// This class is the value of a macro argument, technically 
+/// a wrapper of the cells of MathMacro.
+class MathMacroArgumentValue : public InsetMathDim {
+public:
+	///
+	MathMacroArgumentValue(MathArray * value) : value_(value) {}
+	///
+	MathMacroArgumentValue(MathMacroArgumentValue const &);
+	///
+	bool metrics(MetricsInfo & mi, Dimension & dim) const;
+	///
+	void draw(PainterInfo &, int x, int y) const;
+	
+private:
+	virtual std::auto_ptr<InsetBase> doClone() const;
+	MathArray *value_;
+};
+
+
+auto_ptr<InsetBase> MathMacroArgumentValue::doClone() const 
+{
+	return auto_ptr<InsetBase>(new MathMacroArgumentValue(*this));
+}
+
+
+MathMacroArgumentValue::MathMacroArgumentValue(MathMacroArgumentValue const & x)
+	: value_(x.value_)
+{
+}
+
+
+bool MathMacroArgumentValue::metrics(MetricsInfo & mi, Dimension & dim) const 
+{
+	value_->metrics(mi, dim);
+	metricsMarkers2(dim);
+	if (dim_ == dim)
+		return false;
+	dim_ = dim;
+	return true;
+}
+
+
+void MathMacroArgumentValue::draw(PainterInfo & pi, int x, int y) const 
+{
+	value_->draw(pi, x, y);
+}
+
+
+
+
 MathMacro::MathMacro(docstring const & name, int numargs)
 	: InsetMathNest(numargs), name_(name)
 {}
@@ -63,24 +113,14 @@
 {
 	if (!MacroTable::globalMacros().has(name())) {
 		mathed_string_dim(mi.base.font, "Unknown: " + name(), dim);
-	} else if (editing(mi.base.bv)) {
-		// FIXME UNICODE
-		asArray(MacroTable::globalMacros().get(name()).def(), tmpl_);
-		LyXFont font = mi.base.font;
-		augmentFont(font, from_ascii("lyxtex"));
-		tmpl_.metrics(mi, dim);
-		// FIXME UNICODE
-		dim.wid += mathed_string_width(font, name()) + 10;
-		// FIXME UNICODE
-		int ww = mathed_string_width(font, from_ascii("#1: "));
-		for (idx_type i = 0; i < nargs(); ++i) {
-			MathArray const & c = cell(i);
-			c.metrics(mi);
-			dim.wid  = max(dim.wid, c.width() + ww);
-			dim.des += c.height() + 10;
+	} else {
+		// create MathMacroArgumentValue object pointing to the cells of the macro
+		vector<MathArray> values(nargs());
+		for(size_t i = 0; i != nargs(); ++i) {
+			MathMacroArgumentValue value(const_cast<MathArray *>(&cells_[i]));
+			values[i].insert(0, MathAtom(value.clone().release()));
 		}
-	} else {
-		MacroTable::globalMacros().get(name()).expand(cells_, expanded_);
+		MacroTable::globalMacros().get(name()).expand(values, expanded_);
 		expanded_.metrics(mi, dim);
 	}
 	metricsMarkers2(dim);
@@ -96,26 +136,6 @@
 	if (!MacroTable::globalMacros().has(name())) {
 		// FIXME UNICODE
 		drawStrRed(pi, x, y, "Unknown: " + name());
-	} else if (editing(pi.base.bv)) {
-		LyXFont font = pi.base.font;
-		augmentFont(font, from_ascii("lyxtex"));
-		int h = y - dim_.ascent() + 2 + tmpl_.ascent();
-		pi.pain.text(x + 3, h, name(), font);
-		int const w = mathed_string_width(font, name());
-		tmpl_.draw(pi, x + w + 12, h);
-		h += tmpl_.descent();
-		Dimension ldim;
-		string t = "#1: ";
-		mathed_string_dim(font, name(), ldim);
-		for (idx_type i = 0; i < nargs(); ++i) {
-			MathArray const & c = cell(i);
-			h += max(c.ascent(), ldim.asc) + 5;
-			c.draw(pi, x + ldim.wid, h);
-			char_type str[] = { '#', '1', ':', '\0' };
-			str[1] += static_cast<char_type>(i);
-			pi.pain.text(x + 3, h, str, font);
-			h += max(c.descent(), ldim.des) + 5;
-		}
 	} else {
 		expanded_.draw(pi, x, y);
 	}
Index: InsetMathMacro.h
===================================================================
--- InsetMathMacro.h	(revision 17284)
+++ InsetMathMacro.h	(working copy)
@@ -20,8 +20,7 @@
 
 
 namespace lyx {
-
-
+  
 /// This class contains the data for a macro.
 class MathMacro : public InsetMathNest {
 public:

Reply via email to