/*********************************************************************** * FXRuby -- the Ruby language bindings for the FOX GUI toolkit. * Copyright (c) 2001-2009 by Lyle Johnson. All Rights Reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * For further information please contact the author by e-mail * at "lyle@lylejohnson.name". ***********************************************************************/ // Forward declarations class FXWindow; class FXIcon; class FXBitmap; class FXCursor; class FXRootWindow; class FXMainWindow; class FXPopup; class FXFont; class FXDC; class FXDCWindow; class FXVisual; class FXGLVisual; class FXGLContext; /// File input modes for addInput enum FXInputMode { INPUT_NONE = 0, /// Inactive INPUT_READ = 1, /// Read input fd INPUT_WRITE = 2, /// Write input fd INPUT_EXCEPT = 4 /// Except input fd }; /// All ways of being modal enum FXModality { MODAL_FOR_NONE, /// Non modal event loop (dispatch normally) MODAL_FOR_WINDOW, /// Modal dialog (beep if outside of modal dialog) MODAL_FOR_POPUP /// Modal for popup (always dispatch to popup) }; /// Default cursors provided by the application enum FXDefaultCursor { DEF_ARROW_CURSOR, /// Arrow cursor DEF_RARROW_CURSOR, /// Reverse arrow cursor DEF_TEXT_CURSOR, /// Text cursor DEF_HSPLIT_CURSOR, /// Horizontal split cursor DEF_VSPLIT_CURSOR, /// Vertical split cursor DEF_XSPLIT_CURSOR, /// Cross split cursor DEF_SWATCH_CURSOR, /// Color swatch drag cursor DEF_MOVE_CURSOR, /// Move cursor DEF_DRAGH_CURSOR, /// Resize horizontal edge DEF_DRAGV_CURSOR, /// Resize vertical edge DEF_DRAGTL_CURSOR, /// Resize upper-leftcorner DEF_DRAGBR_CURSOR=DEF_DRAGTL_CURSOR, /// Resize bottom-right corner DEF_DRAGTR_CURSOR, /// Resize upper-right corner DEF_DRAGBL_CURSOR=DEF_DRAGTR_CURSOR, /// Resize bottom-left corner DEF_DNDSTOP_CURSOR, /// Drag and drop stop DEF_DNDCOPY_CURSOR, /// Drag and drop copy DEF_DNDMOVE_CURSOR, /// Drag and drop move DEF_DNDLINK_CURSOR, /// Drag and drop link DEF_CROSSHAIR_CURSOR, /// Cross hair cursor DEF_CORNERNE_CURSOR, /// North-east cursor DEF_CORNERNW_CURSOR, /// North-west cursor DEF_CORNERSE_CURSOR, /// South-east cursor DEF_CORNERSW_CURSOR, /// South-west cursor DEF_HELP_CURSOR, /// Help arrow cursor DEF_HAND_CURSOR, /// Hand cursor DEF_ROTATE_CURSOR, /// Rotate cursor DEF_WAIT_CURSOR /// Wait cursor }; /// FOX Event struct FXEvent { FXEvent(); FXuint type; /// Event type FXuint time; /// Time of last event FXint win_x; /// Window-relative x-coord FXint win_y; /// Window-relative y-coord FXint root_x; /// Root x-coord FXint root_y; /// Root y-coord FXint state; /// Keyboard/Modifier state FXint code; /// Button, Keysym, or mode; DDE Source FXString text; /// Text of keyboard event FXint last_x; /// Window-relative x-coord of previous mouse location FXint last_y; /// Window-relative y-coord of previous mouse location FXint click_x; /// Window-relative x-coord of mouse press FXint click_y; /// Window-relative y-coord of mouse press FXint rootclick_x; /// Root-relative x-coord of mouse press FXint rootclick_y; /// Root-relative y-coord of mouse press FXuint click_time; /// Time of mouse button press FXuint click_button; /// Mouse button pressed FXint click_count; /// Click-count FXbool moved; /// Moved cursor since press FXRectangle rect; /// Rectangle FXbool synthetic; /// True if synthetic expose event FXDragType target; /// Target drag type being requested ~FXEvent(); }; // FXChore is an opaque struct for FOX; this is just a declaration for SWIG struct FXChore { }; // FXTimer is an opaque struct for FOX; this is just a declaration for SWIG struct FXTimer { }; %rename("hasInputMethod?") FXApp::hasInputMethod() const; %rename("hasChore?") FXApp::hasChore(FXObject *tgt,FXSelector sel) const; %rename("hasTimeout?") FXApp::hasTimeout(FXObject *tgt,FXSelector sel) const; %rename("focusWindow") FXApp::getFocusWindow() const; %rename("activeWindow") FXApp::getActiveWindow() const; %rename("scrollBarSize") FXApp::getScrollBarSize() const; %rename("scrollBarSize=") FXApp::setScrollBarSize(FXint); /// Application Object class FXApp : public FXObject { protected: /// Return TRUE when new raw event is available virtual bool getNextEvent(FXRawEvent& ev,FXbool blocking=TRUE); /// Dispatch raw event virtual bool dispatchEvent(FXRawEvent& ev); public: long onCmdQuit(FXObject*,FXSelector,void* PTR_IGNORE); long onCmdDump(FXObject*,FXSelector,void* PTR_IGNORE); long onCmdHover(FXObject*,FXSelector,void* PTR_IGNORE); public: // Messages applications understand enum { ID_QUIT=1, /// Terminate the application normally ID_DUMP, /// Dump the current widget tree ID_HOVER, ID_LAST }; public: %extend { // Copyright notice for library static VALUE copyright() { return to_ruby(FXApp::copyright); } } public: %extend { /** * Construct application object; the name and vendor strings are used * as keys into the registry database for this application's settings */ FXApp(const FXchar* name="Application",const FXchar* vendor="FoxDefault"){ if(FXApp::instance()){ rb_raise(rb_eRuntimeError,"attempted to create more than one FXApp instance"); return 0; } else{ return FXRbApp::constructAndInit(name,vendor); } } } /// Get application name const FXString& getAppName() const; /// Get vendor name const FXString& getVendorName() const; /// Connection to display; this is called by init() bool openDisplay(const FXchar* dpyname=NULL); /// Close connection to the display bool closeDisplay(); %extend { /// Return pointer to display unsigned long getDisplay() const { return reinterpret_cast(self->getDisplay()); } } /// Is application initialized bool isInitialized() const; /// Get argument count FXint getArgc() const; /// Get argument vector const FXchar *const *getArgv() const; // FIXME /// Return true if input method support bool hasInputMethod() const; /// Get default visual FXVisual* getDefaultVisual() const; %extend { /// Change default visual void setDefaultVisual(FXVisual* vis){ FXASSERT(vis); if(vis->isMemberOf(FXMETACLASS(FXRbVisual))){ dynamic_cast(vis)->ownedByApp=TRUE; } else if(vis->isMemberOf(FXMETACLASS(FXRbGLVisual))){ dynamic_cast(vis)->ownedByApp=TRUE; } self->setDefaultVisual(vis); } } /// Get monochrome visual FXVisual* getMonoVisual() const; /// Get root Window FXRootWindow* getRootWindow() const; /// Set root Window void setRootWindow(FXRootWindow* rt); /// Return window at the end of the focus chain FXWindow *getFocusWindow() const; /// Get the window under the cursor, if any FXWindow *getCursorWindow() const; /// Get the active toplevel window, if any FXWindow *getActiveWindow() const; /// Get current popup window, if any FXPopup* getPopupWindow() const; /// Find window from id FXWindow* findWindowWithId(FXID xid) const; /// Find window from root x,y, starting from given window FXWindow* findWindowAt(FXint rx,FXint ry,FXID window=0) const; /** * Add timeout message to be sent to target object in ms milliseconds; * the timer fires only once after the interval expires. The void* ptr * is user data which will be passed into the void* ptr of the message * handler. If a timer with the same target and message already exists, * it will be rescheduled. */ void addTimeout(FXObject* tgt,FXSelector sel,FXuint ms=1000,void* ptr=NULL); /** * Remove timeout identified by tgt and sel. */ void removeTimeout(FXObject* tgt,FXSelector sel); /** * Return TRUE if given timeout has been set */ bool hasTimeout(FXObject *tgt,FXSelector sel) const; /** * Return, in ms, the time remaining until the given timer fires. * If the timer is past due, 0 is returned. If there is no such * timer, infinity (UINT_MAX) is returned. */ FXuint remainingTimeout(FXObject *tgt,FXSelector sel); /** * Process any timeouts due at this time. */ void handleTimeouts(); /** * Add a idle processing message to be sent to target object when * the system becomes idle, i.e. there are no events to be processed. * The void* ptr is user data which will be passed into the void* ptr * of the message handler. If a chore with the same target and message * already exists, it will be rescheduled. */ void addChore(FXObject* tgt,FXSelector sel,void *ptr=NULL); /** * Remove idle processing message(s) identified by tgt and sel. */ void removeChore(FXObject* tgt,FXSelector sel); /** * Return TRUE if given chore has been set */ bool hasChore(FXObject *tgt,FXSelector sel) const; %extend { /** * Add signal processing message to be sent to target object when * the signal sig is raised; flags are to be set as per POSIX definitions. * When immediate is TRUE, the message will be sent to the target right away; * this should be used with extreme care as the application is interrupted * at an unknown point in its execution. */ void addSignal(VALUE sigObj,FXObject* tgt,FXSelector sel,FXbool immediate=FALSE,FXuint flags=0){ const char *s; FXint sig; switch(TYPE(sigObj)){ case T_STRING: s=StringValuePtr(sigObj); sig=FXRbSignalNameToNumber(s); if(sig==0) rb_raise(rb_eArgError,"unrecognized signal name `%s'",s); break; case T_FIXNUM: sig=(FXint)NUM2INT(sigObj); break; default: rb_raise(rb_eArgError,"bad signal type %s",rb_class2name(CLASS_OF(sigObj))); break; } self->addSignal(sig,tgt,sel,immediate,flags); } /// Remove signal message for signal sig void removeSignal(VALUE sigObj){ const char *s; FXint sig; switch(TYPE(sigObj)){ case T_STRING: s=StringValuePtr(sigObj); sig=FXRbSignalNameToNumber(s); if(sig==0) rb_raise(rb_eArgError,"unrecognized signal name `%s'",s); break; case T_FIXNUM: sig=(FXint)NUM2INT(sigObj); break; default: rb_raise(rb_eArgError,"bad signal type %s",rb_class2name(CLASS_OF(sigObj))); break; } self->removeSignal(sig); } } %extend { /** * Add a file descriptor fd to be watched for activity as determined * by mode, where mode is a bitwise OR (INPUT_READ, INPUT_WRITE, INPUT_EXCEPT). * A message of type SEL_IO_READ, SEL_IO_WRITE, or SEL_IO_EXCEPT will be sent * to the target when the specified activity is detected on the file descriptor. */ bool addInput(VALUE obj,FXuint mode,FXObject *tgt,FXSelector sel){ FXInputHandle fd; FXuint m; if(mode&INPUT_READ){ m=INPUT_READ; if(mode&INPUT_EXCEPT) m|=INPUT_EXCEPT; fd=FXRbGetReadFileHandle(obj); self->addInput(fd,m,tgt,sel); } if(mode&INPUT_WRITE){ m=INPUT_WRITE; if(mode&INPUT_EXCEPT) m|=INPUT_EXCEPT; fd=FXRbGetWriteFileHandle(obj); self->addInput(fd,m,tgt,sel); } return true; } /** * Remove input message and target object for the specified file descriptor * and mode, which is a bitwise OR of (INPUT_READ, INPUT_WRITE, INPUT_EXCEPT). */ bool removeInput(VALUE obj,FXuint mode){ FXInputHandle fd; FXuint m; if(mode&INPUT_READ){ m=INPUT_READ; if(mode&INPUT_EXCEPT) m|=INPUT_EXCEPT; fd=FXRbGetReadFileHandle(obj); self->removeInput(fd,m); } if(mode&INPUT_WRITE){ m=INPUT_WRITE; if(mode&INPUT_EXCEPT) m|=INPUT_EXCEPT; fd=FXRbGetWriteFileHandle(obj); self->removeInput(fd,m); } return true; } } /// Return key state bool getKeyState(FXuint keysym) const; /// Peek to determine if there's an event bool peekEvent(); /// Perform one event dispatch; return true if event was dispatched bool runOneEvent(bool blocking=true); /** * Run the main application event loop until stop() is called, * and return the exit code passed as argument to stop(). */ FXint run(); /** * Run an event loop till some flag becomes non-zero, and * then return. */ FXint runUntil(FXuint& condition); // FIXME /** * Run event loop while events are available, non-modally. * Return when no more events, timers, or chores are outstanding. */ FXint runWhileEvents(); /** * Run event loop while there are events are available in the queue. * Returns 1 when all events in the queue have been handled, and 0 when * the event loop was terminated due to stop() or stopModal(). * Except for the modal window and its children, user input to all windows * is blocked; if the modal window is NULL, all user input is blocked. */ FXint runModalWhileEvents(FXWindow* window=NULL); /** * Run modal event loop, blocking keyboard and mouse events to all windows * until stopModal is called. */ FXint runModal(); /** * Run a modal event loop for the given window, until stop() or stopModal() is * called. Except for the modal window and its children, user input to all * windows is blocked; if the modal window is NULL all user input is blocked. */ FXint runModalFor(FXWindow* window); /** * Run modal while window is shown, or until stop() or stopModal() is called. * Except for the modal window and its children, user input to all windows * is blocked; if the modal window is NULL all user input is blocked. */ FXint runModalWhileShown(FXWindow* window); /** * Run popup menu while shown, until stop() or stopModal() is called. * Also returns when entering previous cascading popup menu. */ FXint runPopup(FXWindow* owner); /// True if the window is modal bool isModal(FXWindow* window) const; /// Return window of current modal loop FXWindow* getModalWindow() const; /// Return mode of current modal loop FXModality getModality() const; /** * Terminate the outermost event loop, and all inner modal loops; * All more deeper nested event loops will be terminated with code equal * to 0, while the outermost event loop will return code equal to value. */ void stop(FXint value=0); /** * Break out of the matching modal loop, returning code equal to value. * All deeper nested event loops are terminated with code equal to 0. */ void stopModal(FXWindow* window,FXint value=0); /** * Break out of the innermost modal loop, returning code equal to value. */ void stopModal(FXint value=0); /// Force GUI refresh void forceRefresh(); /// Schedule a refresh void refresh(); /// Flush pending repaints void flush(bool sync=false); /** * Paint all windows marked for repainting. * On return all the applications windows have been painted. */ void repaint(); /** * Return a reference to the registry. The registry keeps * settings and configuration information for an application, * which are automatically loaded when the application starts * up, and saved when the application terminates. */ FXRegistry& reg(); /// Register new DND type FXDragType registerDragType(const FXString& name) const; /// Get drag type name FXString getDragTypeName(FXDragType type) const; /// Return drag window if a drag operation is in progress FXWindow* getDragWindow() const; /// Beep void beep(); /// Return application instance static inline FXApp* instance(); %extend { /// Change default font void setNormalFont(FXFont* font){ FXASSERT(font); if(font->isMemberOf(FXMETACLASS(FXRbFont))){ dynamic_cast(font)->ownedByApp=TRUE; } self->setNormalFont(font); } } /// Return default font FXFont* getNormalFont() const; /// Begin of wait-cursor block; wait-cursor blocks may be nested. void beginWaitCursor(); /// End of wait-cursor block void endWaitCursor(); %extend { /// Change to a new wait cursor void setWaitCursor(FXCursor *cur){ FXASSERT(cur); if(cur->isMemberOf(FXMETACLASS(FXRbCursor))){ dynamic_cast(cur)->ownedByApp=TRUE; } else if(cur->isMemberOf(FXMETACLASS(FXRbCURCursor))){ dynamic_cast(cur)->ownedByApp=TRUE; } else if(cur->isMemberOf(FXMETACLASS(FXRbGIFCursor))){ dynamic_cast(cur)->ownedByApp=TRUE; } self->setWaitCursor(cur); } } /// Return current wait cursor FXCursor* getWaitCursor() const; /// Obtain a default cursor FXCursor* getDefaultCursor(FXDefaultCursor which) const; %extend { /// Change default cursor void setDefaultCursor(FXDefaultCursor which,FXCursor* cur){ FXASSERT(cur); if(cur->isMemberOf(FXMETACLASS(FXRbCursor))){ dynamic_cast(cur)->ownedByApp=TRUE; } else if(cur->isMemberOf(FXMETACLASS(FXRbCURCursor))){ dynamic_cast(cur)->ownedByApp=TRUE; } else if(cur->isMemberOf(FXMETACLASS(FXRbGIFCursor))){ dynamic_cast(cur)->ownedByApp=TRUE; } self->setDefaultCursor(which,cur); } } /** * Write a window and its children, and all resources reachable from this * window, into the stream store. */ FXbool writeWindow(FXStream& store,FXWindow *window); %extend { /** * Read a window and its children from the stream store, and append * it under father; note it is initially not created yet. */ FXWindow* readWindow(FXStream& store,FXWindow*& window,FXWindow* father,FXWindow* owner){ window=0; self->readWindow(store,window,father,owner); return window; } } /** * Return a reference to the application-wide mutex. * Normally, the main user interface thread holds this mutex, * insuring that no other threads are modifying data during the * processing of user interface messages. However, whenever the * main user interface thread blocks for messages, it releases * this mutex, to allow other threads to modify the same data. * When a new message becomes available, the main user interface * thread regains the mutex prior to dispatching the message. * Other threads should hold this mutex only for short durations, * so as to not starve the main user interface thread. */ FXMutex& mutex(); /** * Change message translator. * The new translator will be owned by FXApp. */ void setTranslator(FXTranslator* trans); /// Return message translator FXTranslator* getTranslator() const; /// Obtain application-wide settings FXuint getTypingSpeed() const; FXuint getClickSpeed() const; FXuint getScrollSpeed() const; FXuint getScrollDelay() const; FXuint getBlinkSpeed() const; FXuint getAnimSpeed() const; FXuint getMenuPause() const; FXuint getTooltipPause() const; FXuint getTooltipTime() const; FXint getDragDelta() const; FXint getWheelLines() const; FXint getScrollBarSize() const; /// Change application-wide settings void setTypingSpeed(FXuint speed); void setClickSpeed(FXuint speed); void setScrollSpeed(FXuint speed); void setScrollDelay(FXuint delay); void setBlinkSpeed(FXuint speed); void setAnimSpeed(FXuint speed); void setMenuPause(FXuint pause); void setTooltipPause(FXuint pause); void setTooltipTime(FXuint time); void setDragDelta(FXint delta); void setWheelLines(FXint lines); void setScrollBarSize(FXint size); /// Obtain default colors FXColor getBorderColor() const; FXColor getBaseColor() const; FXColor getHiliteColor() const; FXColor getShadowColor() const; FXColor getBackColor() const; FXColor getForeColor() const; FXColor getSelforeColor() const; FXColor getSelbackColor() const; FXColor getTipforeColor() const; FXColor getTipbackColor() const; FXColor getSelMenuTextColor() const; FXColor getSelMenuBackColor() const; /// Change default colors void setBorderColor(FXColor color); void setBaseColor(FXColor color); void setHiliteColor(FXColor color); void setShadowColor(FXColor color); void setBackColor(FXColor color); void setForeColor(FXColor color); void setSelforeColor(FXColor color); void setSelbackColor(FXColor color); void setTipforeColor(FXColor color); void setTipbackColor(FXColor color); void setSelMenuTextColor(FXColor color); void setSelMenuBackColor(FXColor color); /// Dump widget information void dumpWidgets() const; /// Get number of existing windows FXuint getWindowCount() const; /// Destroy the application and all reachable resources virtual ~FXApp(); }; DECLARE_FXOBJECT_VIRTUALS(FXApp) DECLARE_FXAPP_VIRTUALS(FXApp) #ifdef SWIGRUBY %rename("threadsEnabled=") FXApp::setThreadsEnabled(FXbool); %rename("threadsEnabled?") FXApp::threadsEnabled() const; %extend FXApp { // Enable (or disable) support for multithreaded applications void setThreadsEnabled(FXbool enabled){ FXASSERT(self->isMemberOf(FXMETACLASS(FXRbApp))); dynamic_cast(self)->setThreadsEnabled(enabled); } // Are threads enabled? FXbool threadsEnabled() const { FXASSERT(self->isMemberOf(FXMETACLASS(FXRbApp))); return dynamic_cast(self)->threadsEnabled(); } // Set the amount of time to sleep void setSleepTime(FXuint sleepTime){ FXASSERT(self->isMemberOf(FXMETACLASS(FXRbApp))); dynamic_cast(self)->setSleepTime(sleepTime); } // Get the amount of time to sleep FXuint getSleepTime() const { FXASSERT(self->isMemberOf(FXMETACLASS(FXRbApp))); return dynamic_cast(self)->getSleepTime(); } } #endif