00001 00002 // MathCore = a WYSIWYG equation editor + a powerful math engine // 00003 // Copyright (C) 2003 by Francesco Montorsi // 00004 // // 00005 // This library is free software; you can redistribute it and/or // 00006 // modify it under the terms of the GNU Lesser General Public // 00007 // License as published by the Free Software Foundation; either // 00008 // version 2.1 of the License, or (at your option) any later // 00009 // version. // 00010 // // 00011 // This library is distributed in the hope that it will be useful, // 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of // 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // 00014 // GNU Lesser General Public License for more details. // 00015 // // 00016 // You should have received a copy of the GNU Lesser General Public // 00017 // License along with this program; if not, write to the Free // 00018 // Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, // 00019 // MA 02111-1307, USA. // 00020 // // 00021 // For any comment, suggestion or feature request, please contact // 00022 // the administrator of the project at frm@users.sourceforge.net // 00023 // // 00031 00032 00033 00034 #ifndef mcFRACTION_H 00035 #define mcFRACTION_H 00036 00037 // optimization for GCC compiler 00038 #ifdef __GNUG__ 00039 #pragma interface "Fraction.h" 00040 #endif 00041 00042 // required includes 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: // DATA variables 00061 00063 mcPolynomial mdata_eNum; 00064 00066 mcPolynomial mdata_eDen; 00067 00068 #endif 00069 00070 00071 00072 #ifdef mcENABLE_GUI 00073 protected: // GUI variables 00074 00076 int mgui_nCursorPos; 00077 00078 // mgui_nCursorPos can assume the following values: 00079 #define mcFRACTION_LEFTMOST 1 00080 #define mcFRACTION_INSIDENUM 2 00081 #define mcFRACTION_INSIDEDEN 3 00082 #define mcFRACTION_RIGHTMOST 4 00083 00084 public: // customizable variables 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 // the num & den are *always* present because they are created 00130 // in mcFractionData contructor... 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 /* mcPolynomialHelpers *data_GetNumHlp() { return mdata_eNum.hlp(); } 00194 mcPolynomialHelpers *data_GetDenHlp() { return mdata_eDen.hlp(); } 00195 const mcPolynomialHelpers *data_GetNumHlp() const { return mdata_eNum.hlp(); } 00196 const mcPolynomialHelpers *data_GetDenHlp() const { return mdata_eDen.hlp(); } 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 // gui_DeSelect(), gui_SelectAll(), gui_isAllSelected() are implemented in mcElement 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 //bool hasSameContentOf(const mcElement &p) const; 00305 00306 mcRealValue math_Evaluate() const; 00307 void math_SetExp(const mcPolynomial &p); 00308 mcBasicOpRes math_RaiseTo(const mcPolynomial &p); 00309 00310 //mcPolynomial &&math_GetFactors() const; 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 // MATH ML export functions 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
[ Top ] |