00001 00002 // MathGUI = 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 // // 00030 00031 00032 00033 #ifndef MATHBOX_H 00034 #define MATHBOX_H 00035 00036 // includes 00037 #include "mc/Element.h" 00038 #include "mc/Text.h" 00039 #include "mc/MathLine.h" 00040 #include "mc/MathOrSystem.h" 00041 #include <wx/caret.h> 00042 00043 // required because mgMathBox uses a WX extension written by Markus Greither 00044 #include "wx/resizec.h" 00045 #include "wx/keybinder.h" 00046 00047 00048 // optimization for GCC compiler 00049 #ifdef __GNUG__ 00050 #pragma interface "MathBox.h" 00051 #endif 00052 00053 00054 00057 00059 #define mgMATHBOX_CONTEXTMENU_BASEID mgMATHBOX_BASEID 00060 00062 #define mgMATHBOX_CONTEXTMENU_MATHCMD_BASEID mgMATHBOX_CONTEXTMENU_BASEID+20 00063 00065 #define mgMATHBOX_CONTEXTMENU_FINALID mgMATHBOX_CONTEXTMENU_BASEID+32 00066 00068 00069 00070 00071 // the mgMathBox class is able to send to the wxEvtHandler attached through 00072 // the mgMathBox::SetClientHandler, some specific events: 00073 BEGIN_DECLARE_EVENT_TYPES() 00074 DECLARE_EVENT_TYPE( mgEVT_ACTIVE_ELEM_CHANGED, mgMATHBOX_EVENTS_BASEID ) 00075 END_DECLARE_EVENT_TYPES() 00076 00077 00082 #define EVT_ACTIVE_ELEM_CHANGED(winid, fn) \ 00083 DECLARE_EVENT_TABLE_ENTRY( mgEVT_ACTIVE_ELEM_CHANGED, winid, \ 00084 wxID_ANY, (wxObjectEventFunction) (wxEventFunction) \ 00085 wxStaticCastEvent( wxCommandEventFunction, & fn ), \ 00086 (wxObject *) NULL ), 00087 00088 00089 00092 class mgCaret : public wxCaret 00093 { 00094 public: 00095 mgCaret(wxWindow *window, int w, int h) 00096 : wxCaret(window, w, h) {} 00097 00103 void ForceShow() { DoShow(); m_countVisible=1; } 00104 00106 void ForceHide() { DoHide(); m_countVisible=0; } 00107 }; 00108 00109 00110 00113 enum mgMathBoxCmdID { 00114 00115 // standard edit commands 00116 mgMBC_CUT = 0, 00117 mgMBC_COPY_ASPLAIN, 00118 mgMBC_COPY_ASMATHML, 00119 mgMBC_PASTE, 00120 mgMBC_SELECTALL, 00121 00122 mgMBC_CREATENEW_ANDLINE, 00123 mgMBC_CREATENEW_ORLINE, 00124 mgMBC_SIMPLEEND, 00125 00126 // advanced edit commands 00127 mgMBC_EMBED_NUMFRACTION, 00128 mgMBC_EMBED_DENFRACTION, 00129 mgMBC_EMBED_RADICAL, 00130 mgMBC_EMBED_BRACKET, 00131 mgMBC_ADVEND, 00132 00133 #ifdef __MGDEBUG__ 00134 mgMBC_DEBUG, 00135 #endif 00136 00137 mgMBC_LAST 00138 }; 00139 00141 struct mgMathBoxCmd { 00142 mgMathBoxCmdID m_nID; 00143 const wxChar *m_strDescription; 00144 }; 00145 00146 00147 00148 00160 class mgMathBox : public wxWindow 00161 { 00162 protected: // member variables 00163 00165 mcMathOrSystem m_mathContent; 00166 00168 wxPoint m_ptPos; 00169 00176 //wxCursor *m_pCursor; 00177 00179 wxRect m_rcSelection; 00180 00182 mcElement m_eSelection; 00183 00185 //mcMathMngCmdID m_nCmdID[mgMATHBOX_MAXMENU_ITEMS]; 00186 00189 wxEvtHandler *m_pClient; 00190 00191 00192 protected: 00193 00197 bool m_bProcSpecialChar; 00198 00201 bool m_bAutoExpand; 00202 00203 00207 bool m_bInputEnabled; 00208 00211 bool m_bSelectionEnabled; 00212 00217 bool m_bContextMenuEnabled; 00218 00219 // This enables/disables preprocessing of 00220 bool m_bPreProcessingEnabled; 00221 00222 00223 protected: // internal utilities 00224 00226 void Init(); 00227 00228 #ifdef __WXMSW__ // WXMSG is not defined in all ports 00229 00230 // In the wxMSW port, this function determines if the messages 00231 // should be preprocessed (by acceleration tables, for example) or 00232 // they should just be sent to the the event handler of this window 00233 // "as is": by default, wxWindow::MSWShouldPreProcessMessage returns 00234 // TRUE but mgMathBox and 00235 virtual bool MSWShouldPreProcessMessage(WXMSG* pMsg) { 00236 return m_bPreProcessingEnabled; 00237 } 00238 00239 #endif 00240 00242 mgCaret *GetCaret() const { return (mgCaret *)wxWindow::GetCaret(); } 00243 00244 public: // customizable variables 00245 00247 static int nSpaceAround; 00248 00250 static int nCursorWidth; 00251 00258 static bool bUseNativeNewLines; 00259 00265 static mgMathBoxCmd cmd[mgMBC_LAST+1]; 00266 00267 public: 00268 00270 mgMathBox(wxWindow *parent, 00271 wxWindowID id = -1, 00272 const wxPoint &pos = wxDefaultPosition, 00273 const wxSize &size = wxDefaultSize, 00274 long style = wxSUNKEN_BORDER 00275 | wxNO_FULL_REPAINT_ON_RESIZE, 00276 const wxString &name = wxT("mgMathBox")) 00277 : wxWindow(parent, id, pos, size, style, name) { 00278 Init(); 00279 } 00280 00284 mgMathBox(const mgMathBox &tocopy) { DeepCopy(tocopy); } 00285 00288 virtual ~mgMathBox() { 00289 // the SetCaret() function will delete the caret, if it exists... 00290 SetCaret(NULL); 00291 } 00292 00293 00294 public: 00295 00299 00303 void DeepCopy(const mgMathBox &); 00304 00306 mcMathOrSystem &GetMathObj() { return m_mathContent; } 00307 const mcMathOrSystem &GetMathObj() const { return m_mathContent; } 00308 00310 void EnableInput(bool bEnable = TRUE); 00311 00313 void EnableSelection(bool bEnable = TRUE) { 00314 m_bSelectionEnabled = bEnable; 00315 } 00316 00318 void EnableContextMenu(bool bEnable = TRUE) { 00319 m_bContextMenuEnabled = bEnable; 00320 } 00321 00323 void EnablePreProcessing(bool bEnable = TRUE) { 00324 m_bPreProcessingEnabled = bEnable; 00325 } 00326 00327 void DisableInput() { EnableInput(FALSE); } 00328 void DisableSelection() { EnableSelection(FALSE); } 00329 void DisableContextMenu() { EnableContextMenu(FALSE); } 00330 void DisablePreProcessing() { EnablePreProcessing(FALSE); } 00331 00338 void SetClientEvtHandler(wxEvtHandler *p) { 00339 m_pClient = p; 00340 } 00341 00344 mcElement GetActiveElem(const wxPoint &pos, const wxPoint &pt) const { 00345 return m_mathContent.gui_GetActiveElem(pos.x, pos.y, pt); 00346 } 00347 00350 mcElement GetElemFromID(int id) const { 00351 return m_mathContent.data_GetElemFromID(id); 00352 } 00353 00355 wxString GetDebug() const; 00356 00358 00359 00360 00365 00368 void FitContents(); 00369 00373 void SetSizeHintsToFitContents(); 00374 00377 wxSize GetContentSize() const; 00378 00381 void Clean(); 00382 00384 int GetXPos() const { return m_ptPos.x; } 00385 00387 int GetYPos() const { return m_ptPos.y; } 00388 00390 wxRect GetRectOfContents() 00391 { return wxRect(wxPoint(GetXPos(), GetYPos()), GetContentSize()); } 00392 00394 00395 00396 00400 00410 int UpdateMathBmp(long flags, const wxPoint &p = wxDefaultPosition); 00411 00414 void UpdateContentPos(); 00415 00419 void UpdateCaretPos(); 00420 00422 void UpdateCaret(); 00423 00426 void UpdateMathBmpWithCurrentPos(); 00427 00430 void ForceBmpUpdate(); 00431 00433 00434 00435 00436 00440 00448 void RedrawMath(wxDC &dc, int x, int y); 00449 00452 void GetContextMenu(wxMenu &, const mcElement &selected) const; 00453 00457 void CheckReturnFlag(int res); 00458 00460 void ResetGUI(); 00461 00463 bool isSelecting() const 00464 { return m_rcSelection.width != -1; } 00465 00467 void ResetSelectionRect() { 00468 m_rcSelection.x = m_rcSelection.y = -1; 00469 m_rcSelection.width = m_rcSelection.height = -1; 00470 } 00471 00473 void DeSelect() 00474 { m_mathContent.gui_DeSelect(); } 00475 00477 void SetStyleArray(mcStyleArray *p) { 00478 m_mathContent.gui_SetStyleArray(p); 00479 m_mathContent.gui_DeepRecalcSize(); 00480 ResetGUI(); 00481 } 00482 00484 00485 00486 00487 00493 00494 void InsertFraction(); 00495 void InsertRadical(); 00496 void InsertFunction(); 00497 void EditExponent(); 00498 void EditSubscript(); 00499 00500 void Cut(const mcElement &sel = mcEmptyElement); 00501 void CopyAsPlainText(const mcElement &sel = mcEmptyElement); 00502 void CopyAsMathML(const mcElement &sel = mcEmptyElement); 00503 void Paste(const mcElement &sel = mcEmptyElement); 00504 00505 void EmbedAsFractionNum(const mcElement &sel = mcEmptyElement); 00506 void EmbedAsFractionDen(const mcElement &sel = mcEmptyElement); 00507 void EmbedAsRadical(const mcElement &sel = mcEmptyElement); 00508 00510 00511 00512 00513 00517 00518 void OnSetFocus(wxFocusEvent &); // focus events 00519 void OnFocusLost(wxFocusEvent &); 00520 00521 void OnTimer(wxTimerEvent &); // miscellaneous events 00522 void OnPaint(wxPaintEvent &); 00523 void OnSize(wxSizeEvent &); 00524 00525 void OnLDown(wxMouseEvent &); // mouse events 00526 void OnLUp(wxMouseEvent &); 00527 void OnRUp(wxMouseEvent &); 00528 void OnMouseMove(wxMouseEvent &); 00529 void OnSetCursor(wxSetCursorEvent &); 00530 void OnLeaveWindow(wxMouseEvent &); 00531 00532 void OnCtxMenuItem(wxCommandEvent &); // menu events 00533 00534 void OnChar(wxKeyEvent &); // keyboard events 00535 void OnSpecialChar(wxKeyEvent &); 00536 00538 00539 00540 00541 00545 00546 /* //! Adds one "line" to the mcMathOrSystem contained. 00549 void AddLine(bool bCopyLast); 00550 00552 void DeleteLine(int n); 00553 00555 void SelectLine(int n) { m_mathContent.gui_SelectLine(n); } 00556 00558 int GetSelLineId();*/ 00559 00560 void AppendEditCommands(wxMenu &); 00561 00563 00564 00565 00566 00570 00600 bool Export(bool bXHTML, const wxString &filename, const wxString &title, 00601 bool bUpperTag = FALSE, bool bMPSupp = FALSE, bool bUseNS = FALSE, 00602 const wxString &ns = wxEmptyString, const wxString &href = wxEmptyString, 00603 int indstep = 2) const; 00604 00608 bool Export(bool bXHTML, wxOutputStream &str, const wxString &title, 00609 bool bUpperTag = FALSE, bool bMPSupp = FALSE, bool bUseNS = FALSE, 00610 const wxString &ns = wxEmptyString, const wxString &href = wxEmptyString, 00611 int indstep = 2) const; 00612 00615 wxString GetExportPreview(bool bXHTML, const wxString &title, 00616 bool bUpperTag = FALSE, bool bMathPlayerSupport = FALSE, 00617 bool bUseNS = FALSE, const wxString &ns = wxEmptyString, 00618 const wxString &href = wxEmptyString, int indentstep = 2) const; 00619 00622 wxXml2Node GetMathML(bool bGetPresentation) const { 00623 return m_mathContent.io_GetMathML(bGetPresentation); 00624 } 00625 00627 wxString GetInlinedExpr() const { 00628 return m_mathContent.io_GetInlinedExpr(); 00629 } 00630 00632 bool Import(int type, const wxString &filename, wxString *pDesc = NULL); 00633 00636 bool ImportMathML(wxXml2Node pDoc, wxString *pErr) { 00637 return m_mathContent.io_ImportPresentationMathML(pDoc, *pErr); 00638 } 00639 00641 bool ImportInlinedExpr(const wxString &str); 00642 00646 wxString ConvertString(const wxString &str) const; 00647 00649 00650 00651 private: 00652 DECLARE_CLASS(mgMathBox) 00653 DECLARE_EVENT_TABLE() 00654 }; 00655 00656 00657 00658 00659 #if 1 00660 00670 class mgResizeableBox : public wxResizeableControl 00671 { 00672 protected: 00673 00675 int m_nMinBorder; 00676 00677 //bool m_bFocus, m_bChildFocus; 00678 00679 public: 00682 mgResizeableBox(wxWindow *parent, 00683 wxWindowID id = -1, 00684 const wxPoint &pos = wxDefaultPosition, 00685 const wxSize &size = wxDefaultSize); 00686 00690 mgResizeableBox() { 00691 m_nMinBorder = 0; 00692 } 00693 00696 mgResizeableBox(const mgResizeableBox &tocopy); 00697 00699 virtual ~mgResizeableBox() { 00700 //GetParent()->GetParent()->SetFocus(); 00701 } 00702 00704 void DeepCopy(const mgResizeableBox &); 00705 00710 void SetMinBorder(int n); 00711 00715 int GetBorder(); 00716 00717 //void SetFocus(); 00718 //void Refresh(bool eraseBackground = TRUE, const wxRect* rect = NULL); 00719 00721 virtual wxString GetDebug(); 00722 00723 00728 00729 virtual wxWindow *GetChild() { return NULL; } 00730 00732 00733 // event handlers 00734 virtual void OnSize(wxSizeEvent &); 00735 virtual void OnSetFocus(wxFocusEvent &); 00736 virtual void OnKillFocus(wxFocusEvent &); 00737 virtual void OnSetCursor(wxSetCursorEvent &ev); 00738 virtual void OnPaint(wxPaintEvent &ev); 00739 virtual void OnMove(wxMoveEvent &ev); 00740 00741 virtual void OnChildKillFocus(wxCommandEvent &); 00742 virtual void OnChildSetFocus(wxCommandEvent &); 00743 virtual void OnChildResize(wxCommandEvent &); 00744 00745 00746 private: 00747 DECLARE_CLASS(mgResizeableBox) 00748 DECLARE_EVENT_TABLE() 00749 }; 00750 /* 00751 class mgResizeableBox2 : public wxResizeableHub 00752 { 00753 protected: 00754 00756 int m_nMinBorder; 00757 00758 //bool m_bFocus, m_bChildFocus; 00759 00760 public: 00763 mgResizeableBox(wxWindow *parent, 00764 wxWindowID id = -1, 00765 const wxPoint &pos = wxDefaultPosition, 00766 const wxSize &size = wxDefaultSize); 00767 00771 mgResizeableBox(); { 00772 m_nMinBorder = 0; 00773 } 00774 00777 mgResizeableBox(const mgResizeableBox &tocopy); 00778 00780 virtual ~mgResizeableBox() { 00781 //GetParent()->GetParent()->SetFocus(); 00782 } 00783 00785 void DeepCopy(const mgResizeableBox &); 00786 00791 void SetMinBorder(int n); 00792 00796 int GetBorder(); 00797 00798 void SetFocus(); 00799 //void Refresh(bool eraseBackground = TRUE, const wxRect* rect = NULL); 00800 00802 virtual wxString GetDebug(); 00803 00804 00809 00810 virtual wxWindow *GetChild() { return NULL; } 00811 00813 00814 // event handlers 00815 virtual void OnSize(wxSizeEvent &); 00816 virtual void OnSetFocus(wxFocusEvent &); 00817 virtual void OnKillFocus(wxFocusEvent &); 00818 virtual void OnSetCursor(wxSetCursorEvent &ev); 00819 virtual void OnPaint(wxPaintEvent &ev); 00820 00821 virtual void OnChildKillFocus(wxCommandEvent &); 00822 virtual void OnChildSetFocus(wxCommandEvent &); 00823 virtual void OnChildResize(wxCommandEvent &); 00824 00825 00826 private: 00827 DECLARE_CLASS(mgResizeableBox2) 00828 DECLARE_EVENT_TABLE() 00829 }; 00830 */ 00842 class mgResizeableMathBox : public mgResizeableBox 00843 { 00844 protected: 00845 00847 mgMathBox *m_pMathBox;//m_mathBox; 00848 00849 public: 00852 mgResizeableMathBox(wxWindow *parent, 00853 wxWindowID id = -1, 00854 const wxPoint &pos = wxDefaultPosition, 00855 const wxSize &size = wxDefaultSize); 00856 00860 mgResizeableMathBox() {};// : m_mathBox() {} 00861 00864 mgResizeableMathBox(const mgResizeableMathBox &tocopy); 00865 00867 virtual ~mgResizeableMathBox() { 00868 if (m_pMathBox) delete m_pMathBox; 00869 } 00870 00872 void DeepCopy(const mgResizeableMathBox &); 00873 00875 wxString GetDebug(); 00876 00879 virtual wxXml2Node GetMathML(bool bGetPresentation) { 00880 return m_pMathBox->GetMathML(bGetPresentation); 00881 } 00882 00884 virtual bool ImportMathML(wxXml2Node pDoc, wxString *pErr) { 00885 return m_pMathBox->ImportMathML(pDoc, pErr); 00886 } 00887 00888 00889 wxWindow *GetChild() { return m_pMathBox; }//&m_mathBox; } 00890 00893 /* void DeleteLine(int n) { m_pMathBox->DeleteLine(n); } 00894 void SelectLine(int n) { m_pMathBox->SelectLine(n); } 00895 void AddLine(bool bCopyLast) { m_pMathBox->AddLine(bCopyLast); } 00896 int GetSelLineId() { return m_pMathBox->GetSelLineId(); }*/ 00898 00899 // event handlers 00900 //virtual void OnSize(wxSizeEvent &); 00901 00902 private: 00903 DECLARE_CLASS(mgResizeableMathBox) 00904 DECLARE_EVENT_TABLE() 00905 }; 00906 00907 00908 00912 class mgResizeableTextBox : public /*wxTextCtrl, public*/ mgResizeableBox 00913 { 00914 protected: 00915 00917 wxTextCtrl *m_pTextCtrl; 00918 //mcText m_text; 00919 00920 public: 00923 mgResizeableTextBox(wxWindow *parent, 00924 wxWindowID id = -1, 00925 const wxPoint &pos = wxDefaultPosition, 00926 const wxSize &size = wxDefaultSize); 00927 00931 //mgResizeableTextBox() : m_pTextCtrl(NULL) {} 00932 00935 //mgResizeableTextBox(const mgResizeableTextBox &tocopy); 00936 00938 virtual ~mgResizeableTextBox() { 00939 //if (m_pTextCtrl) delete m_pTextCtrl; 00940 } 00941 00943 //void DeepCopy(const mgResizeableTextBox &); 00944 00946 wxString GetDebug(); 00947 00948 00949 wxWindow *GetChild() { return m_pTextCtrl; } 00950 00951 // event handlers 00952 /*void OnSize(wxSizeEvent &); 00953 void OnSetFocus(wxFocusEvent &); 00954 void OnSetCursor(wxSetCursorEvent &ev); 00955 void OnChildResize(wxCommandEvent &); 00956 void OnPaint(wxPaintEvent &ev);*/ 00957 00958 private: 00959 DECLARE_CLASS(mgResizeableTextBox) 00960 DECLARE_EVENT_TABLE() 00961 }; 00962 00963 #endif 00964 #endif // MATHBOX_H 00965
[ Top ] |