1999-09-27 18:44:28 +00:00
|
|
|
/*
|
|
|
|
* File: math_macro.C
|
|
|
|
* Purpose: Implementation of macro class for mathed
|
|
|
|
* Author: Alejandro Aguilar Sierra <asierra@servidor.unam.mx>
|
|
|
|
* Created: November 1996
|
|
|
|
* Description: WYSIWYG math macros
|
|
|
|
*
|
|
|
|
* Dependencies: Mathed
|
|
|
|
*
|
2000-03-09 03:36:48 +00:00
|
|
|
* Copyright: 1996, 1997 Alejandro Aguilar Sierra
|
1999-09-27 18:44:28 +00:00
|
|
|
*
|
|
|
|
* Version: 0.2, Mathed & Lyx project.
|
|
|
|
*
|
|
|
|
* This code is under the GNU General Public Licence version 2 or later.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
#ifdef __GNUG__
|
2001-02-13 13:28:32 +00:00
|
|
|
#pragma implementation
|
1999-09-27 18:44:28 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "math_macro.h"
|
2001-02-13 13:28:32 +00:00
|
|
|
#include "array.h"
|
1999-09-27 18:44:28 +00:00
|
|
|
#include "math_iter.h"
|
|
|
|
#include "math_inset.h"
|
2001-02-13 13:28:32 +00:00
|
|
|
#include "math_accentinset.h"
|
|
|
|
#include "math_deliminset.h"
|
|
|
|
#include "math_fracinset.h"
|
|
|
|
#include "math_rowst.h"
|
1999-10-02 16:21:10 +00:00
|
|
|
#include "support/lstrings.h"
|
1999-10-07 18:44:17 +00:00
|
|
|
#include "debug.h"
|
2001-02-13 17:08:51 +00:00
|
|
|
#include "mathed/support.h"
|
|
|
|
#include "math_macrotemplate.h"
|
|
|
|
#include "macro_support.h"
|
2001-04-24 16:13:38 +00:00
|
|
|
#include "Painter.h"
|
1999-09-27 18:44:28 +00:00
|
|
|
|
2001-04-24 16:13:38 +00:00
|
|
|
using namespace std;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
1999-10-07 18:44:17 +00:00
|
|
|
ostream & operator<<(ostream & o, MathedTextCodes mtc)
|
|
|
|
{
|
|
|
|
return o << int(mtc);
|
|
|
|
}
|
|
|
|
|
1999-09-27 18:44:28 +00:00
|
|
|
|
2001-04-24 16:13:38 +00:00
|
|
|
MathMacro::MathMacro(MathMacroTemplate const & t)
|
|
|
|
: MathParInset(LM_ST_TEXT, t.GetName(), LM_OT_MACRO),
|
|
|
|
tmplate_(const_cast<MathMacroTemplate *>(&t)),
|
|
|
|
args_(t.nargs()),
|
2001-04-25 15:43:57 +00:00
|
|
|
idx_(t.nargs() ? 0 : -1)
|
1999-09-27 18:44:28 +00:00
|
|
|
{
|
2001-04-24 16:13:38 +00:00
|
|
|
array = tmplate_->GetData();
|
|
|
|
for (int i = 0; i < nargs(); ++i)
|
|
|
|
args_[i].reset(new MathParInset);
|
1999-09-27 18:44:28 +00:00
|
|
|
}
|
|
|
|
|
1999-12-07 00:44:53 +00:00
|
|
|
|
1999-11-25 13:15:52 +00:00
|
|
|
MathedInset * MathMacro::Clone()
|
1999-09-27 18:44:28 +00:00
|
|
|
{
|
2001-02-28 11:56:36 +00:00
|
|
|
return new MathMacro(*this);
|
1999-09-27 18:44:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-04-24 16:13:38 +00:00
|
|
|
void MathMacro::expand()
|
|
|
|
{
|
|
|
|
expanded_.reset(static_cast<MathParInset *>(tmplate_->Clone()));
|
|
|
|
expanded_->substitute(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MathParInset const * MathMacro::arg(int i) const
|
|
|
|
{
|
|
|
|
if (i < 0 || i >= nargs()) {
|
|
|
|
lyxerr << "Illegal index " << i << " max: " << nargs() << endl;
|
|
|
|
lyx::Assert(0);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return i >= 0 ? args_[i].get() : static_cast<MathParInset const *>(this);
|
|
|
|
}
|
|
|
|
|
2001-04-25 15:43:57 +00:00
|
|
|
|
2001-04-24 16:13:38 +00:00
|
|
|
MathParInset * MathMacro::arg(int i)
|
|
|
|
{
|
|
|
|
if (i < 0 || i >= nargs()) {
|
|
|
|
lyxerr << "Illegal index " << i << " max: " << nargs() << endl;
|
|
|
|
lyx::Assert(0);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return i >= 0 ? args_[i].get() : static_cast<MathParInset *>(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
MathMacroTemplate * MathMacro::tmplate() const
|
|
|
|
{
|
|
|
|
return const_cast<MathMacroTemplate *>(tmplate_);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extern bool is_mathcursor_inside(MathParInset *);
|
|
|
|
|
1999-09-27 18:44:28 +00:00
|
|
|
void MathMacro::Metrics()
|
|
|
|
{
|
2001-04-24 16:13:38 +00:00
|
|
|
if (is_mathcursor_inside(this)) {
|
|
|
|
tmplate_->Metrics();
|
|
|
|
width = tmplate_->Width() + 4;
|
|
|
|
ascent = tmplate_->Ascent() + 2;
|
|
|
|
descent = tmplate_->Descent() + 2;
|
|
|
|
|
|
|
|
width += mathed_string_width(LM_TC_TEXTRM, size(), GetName()) + 10;
|
|
|
|
|
|
|
|
for (int i = 0; i < nargs(); ++i) {
|
|
|
|
MathParInset * p = arg(i);
|
|
|
|
p->Metrics();
|
|
|
|
if (p->Width() + 30 > width)
|
|
|
|
width = p->Width() + 30;
|
|
|
|
descent += p->Height() + 10;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
expand();
|
|
|
|
expanded_->Metrics();
|
2001-04-25 15:43:57 +00:00
|
|
|
width = expanded_->Width() + 6;
|
|
|
|
ascent = expanded_->Ascent() + 3;
|
|
|
|
descent = expanded_->Descent() + 3;
|
2001-04-24 16:13:38 +00:00
|
|
|
}
|
1999-09-27 18:44:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-02-10 17:53:36 +00:00
|
|
|
void MathMacro::draw(Painter & pain, int x, int y)
|
|
|
|
{
|
2001-04-24 16:13:38 +00:00
|
|
|
LColor::color col;
|
|
|
|
|
|
|
|
if (is_mathcursor_inside(this)) {
|
|
|
|
int h = y + Descent() - 2;
|
|
|
|
for (int i = nargs() - 1; i >= 0; --i) {
|
|
|
|
MathParInset * p = arg(i);
|
|
|
|
h -= p->Descent() + 5;
|
|
|
|
p->draw(pain, x + 30, h);
|
|
|
|
char str[] = "#1:";
|
|
|
|
str[1] += i;
|
2001-04-25 15:43:57 +00:00
|
|
|
drawStr(pain, LM_TC_TEX, size(), x + 3, h, str);
|
2001-04-24 16:13:38 +00:00
|
|
|
h -= p->Ascent() + 5;
|
|
|
|
}
|
|
|
|
|
|
|
|
h -= tmplate_->Descent();
|
|
|
|
int w = mathed_string_width(LM_TC_TEXTRM, size(), GetName());
|
2001-04-25 15:43:57 +00:00
|
|
|
drawStr(pain, LM_TC_TEXTRM, size(), x + 3, h, GetName());
|
2001-04-24 16:13:38 +00:00
|
|
|
tmplate_->draw(pain, x + w + 12, h);
|
|
|
|
|
|
|
|
col = LColor::red;
|
|
|
|
} else {
|
2001-04-25 15:43:57 +00:00
|
|
|
expanded_->draw(pain, x + 3, y);
|
2001-04-24 16:13:38 +00:00
|
|
|
col = LColor::black;
|
|
|
|
}
|
|
|
|
|
|
|
|
int w = Width();
|
|
|
|
int a = Ascent();
|
|
|
|
int h = Height();
|
2001-04-25 15:43:57 +00:00
|
|
|
pain.rectangle(x + 1, y - a + 1, w - 2, h - 2, col);
|
1999-09-27 18:44:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-02-13 17:08:51 +00:00
|
|
|
bool MathMacro::setArgumentIdx(int i)
|
1999-09-27 18:44:28 +00:00
|
|
|
{
|
2001-04-24 16:13:38 +00:00
|
|
|
if (i >= 0 && 0 < (nargs() - i)) {
|
2001-02-15 12:22:01 +00:00
|
|
|
idx_ = i;
|
2001-02-13 17:08:51 +00:00
|
|
|
return true;
|
|
|
|
} else
|
|
|
|
return false;
|
2001-04-24 16:13:38 +00:00
|
|
|
idx_ = i;
|
|
|
|
return true;
|
1999-09-27 18:44:28 +00:00
|
|
|
}
|
|
|
|
|
1999-12-07 00:44:53 +00:00
|
|
|
|
2001-02-13 17:08:51 +00:00
|
|
|
int MathMacro::getArgumentIdx() const
|
|
|
|
{
|
2001-04-24 16:13:38 +00:00
|
|
|
//lyxerr << "MathMacro::getArgumentIdx: res: " << idx_ << endl;
|
2001-02-15 12:22:01 +00:00
|
|
|
return idx_;
|
2000-02-10 17:53:36 +00:00
|
|
|
}
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
|
|
|
2001-02-13 17:08:51 +00:00
|
|
|
int MathMacro::getMaxArgumentIdx() const
|
|
|
|
{
|
2001-04-24 16:13:38 +00:00
|
|
|
return nargs() - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int MathMacro::nargs() const
|
|
|
|
{
|
|
|
|
return args_.size();
|
2001-02-13 17:08:51 +00:00
|
|
|
}
|
1999-12-07 00:44:53 +00:00
|
|
|
|
1999-09-27 18:44:28 +00:00
|
|
|
|
2001-02-20 16:00:22 +00:00
|
|
|
MathedArray & MathMacro::GetData()
|
2001-02-13 17:08:51 +00:00
|
|
|
{
|
2001-04-24 16:13:38 +00:00
|
|
|
//lyxerr << "MathMacro::GetData: " << *this << endl;
|
|
|
|
return idx_ >= 0 ? arg(idx_)->GetData() : MathParInset::GetData();
|
2001-02-13 17:08:51 +00:00
|
|
|
}
|
1999-12-07 00:44:53 +00:00
|
|
|
|
1999-09-27 18:44:28 +00:00
|
|
|
|
2001-02-28 17:21:16 +00:00
|
|
|
MathedArray const & MathMacro::GetData() const
|
|
|
|
{
|
2001-04-24 16:13:38 +00:00
|
|
|
//lyxerr << "MathMacro::GetData: " << *this << endl;
|
|
|
|
return idx_ >= 0 ? arg(idx_)->GetData() : MathParInset::GetData();
|
2001-02-28 17:21:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-02-13 17:08:51 +00:00
|
|
|
int MathMacro::GetColumns() const
|
1999-09-27 18:44:28 +00:00
|
|
|
{
|
2001-04-24 16:13:38 +00:00
|
|
|
return idx_ >= 0 ? arg(idx_)->GetColumns() : MathParInset::GetColumns();
|
1999-09-27 18:44:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-02-13 17:08:51 +00:00
|
|
|
void MathMacro::GetXY(int & x, int & y) const
|
1999-09-27 18:44:28 +00:00
|
|
|
{
|
2001-04-24 16:13:38 +00:00
|
|
|
if (idx_ >= 0)
|
|
|
|
arg(idx_)->GetXY(x, y);
|
|
|
|
else
|
|
|
|
MathParInset::GetXY(x, y);
|
1999-09-27 18:44:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-02-13 17:08:51 +00:00
|
|
|
bool MathMacro::Permit(short f) const
|
2000-02-10 17:53:36 +00:00
|
|
|
{
|
2001-04-24 16:13:38 +00:00
|
|
|
return idx_ >= 0 ? arg(idx_)->Permit(f) : MathParInset::Permit(f);
|
2000-02-10 17:53:36 +00:00
|
|
|
}
|
1999-09-27 18:44:28 +00:00
|
|
|
|
1999-12-07 00:44:53 +00:00
|
|
|
|
2001-02-13 17:08:51 +00:00
|
|
|
void MathMacro::SetFocus(int x, int y)
|
1999-09-27 18:44:28 +00:00
|
|
|
{
|
2001-04-24 16:13:38 +00:00
|
|
|
idx_ = -1;
|
|
|
|
for (int i = 0; i < nargs(); ++i) {
|
|
|
|
if (arg(i)->Inside(x, y)) {
|
|
|
|
idx_ = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MathMacro::setData(MathedArray const & a, int i)
|
|
|
|
{
|
|
|
|
arg(i)->setData(a);
|
1999-09-27 18:44:28 +00:00
|
|
|
}
|
|
|
|
|
1999-12-07 00:44:53 +00:00
|
|
|
|
2001-02-20 16:00:22 +00:00
|
|
|
void MathMacro::setData(MathedArray const & a)
|
1999-09-27 18:44:28 +00:00
|
|
|
{
|
2001-04-24 16:13:38 +00:00
|
|
|
if (idx_ >= 0)
|
|
|
|
arg(idx_)->setData(a);
|
|
|
|
else
|
|
|
|
array = a;
|
1999-09-27 18:44:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-02-13 17:08:51 +00:00
|
|
|
MathedTextCodes MathMacro::getTCode() const
|
1999-09-27 18:44:28 +00:00
|
|
|
{
|
2001-04-24 16:13:38 +00:00
|
|
|
return nargs() ? LM_TC_ACTIVE_INSET : LM_TC_INSET;
|
|
|
|
//return LM_TC_INSET;
|
1999-09-27 18:44:28 +00:00
|
|
|
}
|
2001-02-13 17:08:51 +00:00
|
|
|
|
2001-04-24 16:13:38 +00:00
|
|
|
void MathMacro::dump(ostream & os) const
|
|
|
|
{
|
|
|
|
os << "\n macro: '" << this << "'\n";
|
|
|
|
os << " name: '" << name << "'\n";
|
|
|
|
os << " idx: '" << idx_ << "'\n";
|
|
|
|
os << " data: '" << array << "'\n";
|
|
|
|
os << " nargs: '" << nargs() << "'\n";
|
|
|
|
for (int i = 0; i < nargs(); ++i)
|
|
|
|
os << " " << arg(i) << ": " << arg(i)->GetData() << endl;
|
|
|
|
os << endl;
|
|
|
|
}
|
1999-09-27 18:44:28 +00:00
|
|
|
|
2001-02-13 17:08:51 +00:00
|
|
|
void MathMacro::Write(ostream & os, bool fragile)
|
1999-09-27 18:44:28 +00:00
|
|
|
{
|
2001-03-01 14:07:43 +00:00
|
|
|
os << '\\' << name;
|
2001-04-24 16:13:38 +00:00
|
|
|
for (int i = 0; i < nargs(); ++i) {
|
2001-03-01 14:07:43 +00:00
|
|
|
os << '{';
|
2001-04-24 16:13:38 +00:00
|
|
|
arg(i)->Write(os, fragile);
|
2001-03-01 14:07:43 +00:00
|
|
|
os << '}';
|
2001-04-24 16:13:38 +00:00
|
|
|
}
|
|
|
|
if (nargs() == 0)
|
2001-03-01 14:07:43 +00:00
|
|
|
os << ' ';
|
1999-09-27 18:44:28 +00:00
|
|
|
}
|
2001-04-25 15:43:57 +00:00
|
|
|
|
|
|
|
|
|
|
|
void MathMacro::WriteNormal(ostream & os)
|
|
|
|
{
|
2001-04-27 12:35:55 +00:00
|
|
|
os << "[macro " << name << " ";
|
|
|
|
for (int i = 0; i < nargs(); ++i) {
|
2001-04-25 15:43:57 +00:00
|
|
|
arg(i)->WriteNormal(os);
|
2001-04-27 12:35:55 +00:00
|
|
|
os << ' ';
|
|
|
|
}
|
|
|
|
os << "] ";
|
2001-04-25 15:43:57 +00:00
|
|
|
}
|