/******************************************************************************** * * * M u l t i p l e D o c u m e n t C l i e n t W i n d o w * * * ********************************************************************************* * Copyright (C) 1998,2024 by Jeroen van der Zijp. 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 3 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 program. If not, see * ********************************************************************************/ #ifndef FXMDICLIENT_H #define FXMDICLIENT_H #ifndef FXCOMPOSITE_H #include "FXComposite.h" #endif namespace FX { class FXMDIChild; /** * The MDI client window manages a number of MDI child windows in a multiple-document * interface (MDI) application. MDI child windows usually receive messages from the GUI controls * by delegation via the MDI client. This is accomplished by making the MDI client window * the target for most GUI controls. The MDI client filters out messages intented for itself, * and delegates the remaining messages to its currently active MDI child, if any. * If you use the auto-gray or auto-hide feature available in some GUI controls, these * controls can be automatically grayed out or hidden when there is no active MDI child. * When delegating messages via MDI client to MDI child windows of different types, care * should be taken that message ID's do not overlap, so that all message ID's only map to * the intented handlers no matter which MDI child window type is active. * The MDI client sends a SEL_CHANGED message to its target when the active MDI child is * switched, with the void* pointer refering to the new MDI child. * A MDI Window selection dialog can be brought up through the ID_MDI_OVER_X messages; * a menu button connected to the MDI client with the ID_MDI_OVER_X message will be * automatically grayed out if there are less than X MDI child windows. * The ID_MDI_ANY may be connected to a menu separator to cause automatic hiding of the * menu separator when no MDI child windows are present. */ class FXAPI FXMDIClient : public FXComposite { FXDECLARE(FXMDIClient) friend class FXMDIChild; protected: FXMDIChild *active; // Active child FXImage *backImage; // Optional background image FXint cascadex; // Cascade offset X FXint cascadey; // Cascade offset Y protected: FXMDIClient(); private: FXMDIClient(const FXMDIClient&); FXMDIClient &operator=(const FXMDIClient&); public: long onPaint(FXObject*,FXSelector,void*); long onCmdActivateNext(FXObject*,FXSelector,void*); long onCmdActivatePrev(FXObject*,FXSelector,void*); long onCmdTileHorizontal(FXObject*,FXSelector,void*); long onCmdTileVertical(FXObject*,FXSelector,void*); long onCmdCascade(FXObject*,FXSelector,void*); long onUpdActivateNext(FXObject*,FXSelector,void*); long onUpdActivatePrev(FXObject*,FXSelector,void*); long onUpdTileVertical(FXObject*,FXSelector,void*); long onUpdTileHorizontal(FXObject*,FXSelector,void*); long onUpdCascade(FXObject*,FXSelector,void*); long onUpdClose(FXObject*,FXSelector,void*); long onUpdMenuClose(FXObject*,FXSelector,void*); long onUpdRestore(FXObject*,FXSelector,void*); long onUpdMenuRestore(FXObject*,FXSelector,void*); long onUpdMinimize(FXObject*,FXSelector,void*); long onUpdMenuMinimize(FXObject*,FXSelector,void*); long onUpdMaximize(FXObject*,FXSelector,void*); long onUpdMenuWindow(FXObject*,FXSelector,void*); long onCmdWindowSelect(FXObject*,FXSelector,void*); long onUpdWindowSelect(FXObject*,FXSelector,void*); long onCmdOthersWindows(FXObject*,FXSelector,void*); long onUpdOthersWindows(FXObject*,FXSelector,void*); long onUpdAnyWindows(FXObject*,FXSelector,void*); virtual long onDefault(FXObject*,FXSelector,void*); public: enum { ID_MDI_ANY=65400, ID_MDI_1, // Select MDI child 1 ID_MDI_2, ID_MDI_3, ID_MDI_4, ID_MDI_5, ID_MDI_6, ID_MDI_7, ID_MDI_8, ID_MDI_9, ID_MDI_10, ID_MDI_OVER_1, // Sensitize MDI menu when 1 or more children ID_MDI_OVER_2, ID_MDI_OVER_3, ID_MDI_OVER_4, ID_MDI_OVER_5, ID_MDI_OVER_6, ID_MDI_OVER_7, ID_MDI_OVER_8, ID_MDI_OVER_9, ID_MDI_OVER_10, ID_LAST }; public: /// Construct MDI Client window FXMDIClient(FXComposite* p,FXuint opts=0,FXint x=0,FXint y=0,FXint w=0,FXint h=0); /// Create window virtual void create(); /// Return default width virtual FXint getDefaultWidth(); /// Return default height virtual FXint getDefaultHeight(); /// Perform layout virtual void layout(); /** * Pass message to all MDI windows, stopping when one of * the MDI windows fails to handle the message. */ long forallWindows(FXObject* sender,FXSelector sel,void* ptr); /** * Pass message once to all MDI windows with the same document, * stopping when one of the MDI windows fails to handle the message. */ long forallDocuments(FXObject* sender,FXSelector sel,void* ptr); /** * Pass message to all MDI Child windows whose target is document, * stopping when one of the MDI windows fails to handle the message. */ long forallDocWindows(FXObject* document,FXObject* sender,FXSelector sel,void* ptr); /// Set active MDI Child virtual FXbool setActiveChild(FXMDIChild* child=nullptr,FXbool notify=true); /// Get current active child; may be NULL! FXMDIChild* getActiveChild() const { return active; } /// Get active document; this is the target of the active MDI Child, if any FXObject* getActiveDocument() const; /// Change background image void setBackImage(FXImage* img); /// Return background image FXImage* getBackImage() const { return backImage; } /// Cascade windows virtual void cascade(FXbool notify=false); /// Layout horizontally virtual void horizontal(FXbool notify=false); /// Layout vertically virtual void vertical(FXbool notify=false); /// Change cascade offset X void setCascadeX(FXint off){ cascadex=off; } /// Change cascade offset Y void setCascadeY(FXint off){ cascadey=off; } /// Get cascade offset X FXint getCascadeX() const { return cascadex; } /// Get cascade offset Y FXint getCascadeY() const { return cascadey; } /// Save object to a stream virtual void save(FXStream& store) const; /// Load object from a stream virtual void load(FXStream& store); /// Destructor virtual ~FXMDIClient(); }; } #endif