00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00031
00032
00033
00034 #ifndef mcFRACTION_H
00035 #define mcFRACTION_H
00036
00037
00038 #ifdef __GNUG__
00039 #pragma interface "Fraction.h"
00040 #endif
00041
00042
00043 #include "mc/Element.h"
00044 #include "mc/Polynomial.h"
00045
00046
00047 mcDEFINE_HELPER_CLASSES(mcFraction)
00048
00049
00050
00051
00052
00053
00054
00055 class mcFractionHelpers : public mcElementHelpers
00056 {
00057 mcDEFINE_REFERENCE_DATA(mcFraction, mcET_FRACTION);
00058
00059 #ifdef mcENABLE_DATA
00060 protected:
00061
00063 mcPolynomial mdata_eNum;
00064
00066 mcPolynomial mdata_eDen;
00067
00068 #endif
00069
00070
00071
00072 #ifdef mcENABLE_GUI
00073 protected:
00074
00076 int mgui_nCursorPos;
00077
00078
00079 #define mcFRACTION_LEFTMOST 1
00080 #define mcFRACTION_INSIDENUM 2
00081 #define mcFRACTION_INSIDEDEN 3
00082 #define mcFRACTION_RIGHTMOST 4
00083
00084 public:
00085
00087 static mcKey *sgui_pNewFraction;
00088
00090 static int sgui_nSpaceAboveBelow;
00091
00093 static int sgui_nSpaceBetween;
00094
00096 static int sgui_nAdditionalWidth;
00097
00100 static int sgui_nAdditionalSpace;
00101
00102 #endif // mcENABLE_GUI
00103
00104
00105
00106 public:
00107 mcFractionHelpers() { data_Init(); }
00108 virtual ~mcFractionHelpers() {}
00109
00110 protected:
00111
00112 void gui_Init() {
00113 mcElementHelpers::gui_Init();
00114 mgui_nCursorPos = mcFRACTION_INSIDENUM;
00115 }
00116
00117
00118
00119
00120 #ifdef mcENABLE_DATA
00121 public:
00122
00123 #ifdef __MCDEBUG__
00124 wxString data_Debug(long flags) const;
00125 void data_Check() const;
00126 #endif
00127
00128 int data_GetChildrenCount() const {
00129
00130
00131 return mcElementHelpers::data_GetChildrenCount()+2;
00132 }
00133
00134 const mcElement &data_GetConstChild(int n) const {
00135 mcRETURN_ELEMENT_CHILD(n, mcElementHelpers);
00136 if (n == 0)
00137 return data_GetNum();
00138 if (n == 1)
00139 return data_GetDen();
00140 return mcEmptyElement;
00141 }
00142
00143 void data_SetChild(int n, const mcElement &newchild) {
00144 mcSET_ELEMENT_CHILD(n, mcElementHelpers, newchild);
00145 mcASSERT(newchild.data_GetType() == mcET_POLYNOMIAL, wxT("Invalid new child"));
00146 mcPolynomial p(newchild);
00147
00148 if (n == 0) data_SetNum(p);
00149 if (n == 1) data_SetDen(p);
00150 }
00151
00152 void data_DeepCopy(const mcElementHelpers *p) {
00153 const mcFractionHelpers *f = (const mcFractionHelpers *)p;
00154 mdata_eNum.data_DeepCopy(f->mdata_eNum);
00155 mdata_eDen.data_DeepCopy(f->mdata_eDen);
00156 mgui_nCursorPos = f->mgui_nCursorPos;
00157 mcElementHelpers::data_DeepCopy(p);
00158 }
00159
00160 bool data_isSameAs(const mcElementHelpers *p) const {
00161 if (!mcElementHelpers::data_isSameAs(p))
00162 return FALSE;
00163
00164 const mcFractionHelpers *fd = (const mcFractionHelpers *)p;
00165 if (mdata_eNum != fd->mdata_eNum) return FALSE;
00166 if (mdata_eDen != fd->mdata_eDen) return FALSE;
00167 return TRUE;
00168 }
00169
00172 void data_SetDen(const mcPolynomial &p) {
00173 mdata_eDen = p;
00174 mdata_eDen.data_Check();
00175 }
00176
00179 void data_SetNum(const mcPolynomial &p) {
00180 mdata_eNum = p;
00181 mdata_eNum.data_Check();
00182 }
00183
00185 virtual void data_AddElements(bool bNum, mcElement *p, int num,
00186 int pos = -1, bool bOverwrite = FALSE, bool bForceCopy = FALSE);
00187
00188 mcPolynomial &data_GetNum() { return mdata_eNum; }
00189 mcPolynomial &data_GetDen() { return mdata_eDen; }
00190 const mcPolynomial &data_GetNum() const { return mdata_eNum; }
00191 const mcPolynomial &data_GetDen() const { return mdata_eDen; }
00192
00193
00194
00195
00196
00197
00198 #endif // mcENABLE_DATA
00199
00200
00201
00202
00203
00204 #ifdef mcENABLE_GUI
00205 public:
00206
00210
00211 wxPoint gui_GetNumPos() const;
00212 wxPoint gui_GetDenPos() const;
00213
00214 void gui_SetCursorOnDen(mcCursorPos cp = mcCP_END) {
00215 mgui_nCursorPos = mcFRACTION_INSIDEDEN;
00216 data_GetDen().gui_SetCursorPos(cp);
00217 }
00218
00219 void gui_SetCursorOnNum(mcCursorPos cp = mcCP_END) {
00220 mgui_nCursorPos = mcFRACTION_INSIDENUM;
00221 data_GetNum().gui_SetCursorPos(cp);
00222 }
00223
00225
00226
00227
00228
00232
00234 void gui_UpdateExpDepth() {
00235 data_GetNum().gui_SetAtSameLevelOf(this);
00236 data_GetDen().gui_SetAtSameLevelOf(this);
00237 mcElementHelpers::gui_UpdateExpDepth();
00238 }
00239
00240 bool gui_isBeginKey(const mcKey &ev) const;
00241 bool gui_isEndKey(const mcKey &ev) const;
00242
00243 mcInputRes gui_Input(const mcKey &ev, mcElement *newelem);
00244 mcInsertRes gui_Insert(const mcElement &, mcElement *);
00245 mcMoveCursorRes gui_MoveCursor(mcMoveCursorFlag flag, long modifiers);
00246 void gui_GetCursorPos(mcCursorPos &) const;
00247 int gui_MoveCursorUsingPoint(wxDC &dc, const wxPoint &p);
00248 int gui_Draw(wxDC &dc, int x, int y, long flags, const wxPoint &pt) const;
00249 int gui_GetRelCursorPos(wxDC &dc, wxPoint *pt) const;
00250 int gui_GetYAnchor() const;
00251
00252 void gui_SetCursorPos(const mcCursorPos &);
00253 void gui_OnSelect(wxDC &dc, wxRect &rc);
00254 void gui_DoRecalcSize();
00255
00256 mcElement gui_GetSelection() const;
00257 void gui_DeleteSelection();
00258
00259
00260
00262
00263 #endif // mcENABLE_GUI
00264
00265
00266
00267
00268
00269 #ifdef mcENABLE_MATH
00270 protected:
00271
00272 mcExpSimRes math_SimplifyFactors(long flags, mcElement *newelem);
00273
00274 public:
00275
00277 void math_Flip();
00278
00279
00280
00284
00285 bool math_CanBeMultWith(const mcElement &p) const;
00286 bool math_CanBeAddedWith(const mcElement &p) const;
00287 bool math_CanBeDivBy(const mcElement &p) const;
00288
00289 virtual mcBasicOpRes math_Add(const mcElement &, mcElement *p, bool add);
00290 virtual mcBasicOpRes math_MultiplyBy(const mcElement &, mcElement *p);
00291 virtual mcBasicOpRes math_DivideBy(const mcElement &, mcElement *p);
00292
00293 mcRealValue math_GetLenght() const { return 1.5; }
00294 int math_GetOrderPos() const { return 1; }
00295
00296 mcMathType math_GetMathType() const;
00297 mcBasicOpRes math_MakeReciprocal(mcElement *)
00298 { math_Flip(); return mcBOR_REMOVE_OPERAND; }
00299
00300 mcExpSimRes math_Simplify(long flags, mcElement *newelem);
00301 mcExpSimRes math_Expand(long flags, mcElement *newelem);
00302
00303 bool math_Compare(const mcElement &p, long flags) const;
00304
00305
00306 mcRealValue math_Evaluate() const;
00307 void math_SetExp(const mcPolynomial &p);
00308 mcBasicOpRes math_RaiseTo(const mcPolynomial &p);
00309
00310
00311 mcMonomial math_GetLCM(const mcElement &) const;
00312 mcMonomial math_GetGCD(const mcElement &) const;
00313
00315
00316 #endif // mcENABLE_MATH
00317
00318
00319
00320 #ifdef mcENABLE_IO
00321 public:
00322
00323 bool io_isBeginTag(const wxXml2Node &tag) const {
00324 if (tag.GetName() == wxT("mfrac"))
00325 return TRUE;
00326 return FALSE;
00327 }
00328
00329 bool io_isBeginChar(const wxString &str) const {
00330 return FALSE;
00331 }
00332
00333
00336 void io_Set(const wxString &num, const wxString &den) {
00337 io_SetNum(num);
00338 io_SetDen(den);
00339 }
00340
00341 void io_SetNum(const wxString &num);
00342 void io_SetDen(const wxString &den);
00343
00344
00345
00346 wxXml2Node io_GetMathML(bool bGetPresentation) const;
00347 wxString io_GetInlinedExpr() const;
00348
00349 bool io_CheckBracketNeed(const mcPolynomial &p, const wxString &exp) const;
00350 bool io_ImportPresentationMathML(wxXml2Node tag, wxString &pErr);
00351 bool io_ImportInlinedExpr(const wxString &str, int *count, wxString &pErr);
00352
00353 #endif // mcENABLE_IO
00354 };
00355
00356
00361 class mcFraction : public mcElement
00362 {
00363 mcDEFINE_MAIN_CLASS(Fraction, mcElement);
00364
00365 public:
00366
00367 mcFraction(const mcNumber &n, const mcNumber &d)
00368 { data_SetRefData(new mcFractionHelpers()); data_SetNum(mcPolynomial(n)); data_SetDen(mcPolynomial(d)); }
00369
00370 bool data_isValidContainerFor(mcElementType t) const
00371 { return t == mcET_FRACTION; }
00372
00373 mcWRAPPER void data_SetDen(const mcPolynomial &p)
00374 { hlp()->data_SetDen(p); }
00375 mcWRAPPER void data_SetNum(const mcPolynomial &p)
00376 { hlp()->data_SetNum(p); }
00377
00378 mcWRAPPER void data_AddElements(bool bNum, mcElement *p, int num,
00379 int pos = -1, bool bOverwrite = FALSE, bool bForceCopy = FALSE)
00380 { hlp()->data_AddElements(bNum, p, num, pos, bOverwrite, bForceCopy); }
00381
00382 mcWRAPPER mcPolynomial &data_GetNum() { return hlp()->data_GetNum(); }
00383 mcWRAPPER mcPolynomial &data_GetDen() { return hlp()->data_GetDen(); }
00384
00385
00386
00387 mcWRAPPER wxPoint gui_GetNumPos() const
00388 { return hlp()->gui_GetNumPos(); }
00389 mcWRAPPER wxPoint gui_GetDenPos() const
00390 { return hlp()->gui_GetDenPos(); }
00391
00392 mcWRAPPER void gui_SetCursorOnDen(mcCursorPos cp = mcCP_END)
00393 { hlp()->gui_SetCursorOnDen(cp); }
00394 mcWRAPPER void gui_SetCursorOnNum(mcCursorPos cp = mcCP_END)
00395 { hlp()->gui_SetCursorOnNum(cp); }
00396
00397
00398 mcWRAPPER void math_Flip()
00399 { hlp()->math_Flip(); }
00400 };
00401
00402
00403 #endif // mcFRACTION_H
00404