//------------------------------------------------------------------------------
// emWindow.h
//
// Copyright (C) 2005-2010,2016-2018,2022 Oliver Hamann.
//
// Homepage: http://eaglemode.sourceforge.net/
//
// This program is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License version 3 as published by the
// Free Software Foundation.
//
// This program 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 General Public License version 3 for
// more details.
//
// You should have received a copy of the GNU General Public License version 3
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//------------------------------------------------------------------------------
#ifndef emWindow_h
#define emWindow_h
#ifndef emScreen_h
#include <emCore/emScreen.h>
#endif
#ifndef emView_h
#include <emCore/emView.h>
#endif
class emWindowPort;
//==============================================================================
//================================== emWindow ==================================
//==============================================================================
class emWindow : public emView {
public:
// An emWindow is an emView which is shown as a window on a screen. See
// also class emScreen. Such a screen interface has to be installed in a
// context before windows can be constructed. This should be done at
// program start, maybe with the help of an emGUIFramework.
typedef int WindowFlags;
// Data type for the feature flags of a window. Possible flags
// are:
enum {
WF_MODAL = (1<<0),
// Ancestor windows of same screen cannot get input
// events or close signal. This flag has no effect if
// the are no such ancestors.
WF_UNDECORATED = (1<<1),
// The window has no border and not title bar.
WF_POPUP = (1<<2),
// Like WF_UNDECORATED, but the close signal is
// generated as soon as the focus is lost.
WF_MAXIMIZED = (1<<3),
// The window covers the whole work area of the desktop.
// This flag may have no effect when combined with
// WF_UNDECORATED, WF_POPUP or WF_FULLSCREEN.
WF_FULLSCREEN = (1<<4),
// The window covers the whole screen. This flag may
// have no effect when combined with WF_UNDECORATED or
// WF_POPUP.
WF_AUTO_DELETE = (1<<5)
// The window deletes itself automatically three time
// slices after the close signal is signaled.
};
emWindow(
emContext & parentContext,
ViewFlags viewFlags=0,
WindowFlags windowFlags=0,
const emString & wmResName="emWindow"
);
// Construct a window. If the parent context or a higher
// ancestor context is a window (without another emScreen in
// between), this new window will be a slave of that ancestor
// window ("Transient Window" in X11 speaking, "Owned Window" in
// Windows speaking). The new window is not shown before the end
// of the current time slice (by typical emWindowPort
// derivatives). This gives a chance to prepare things like the
// size and position of the window without any flicker on the
// screen. If the position or size is not set before the window
// is shown, a default is invented at the moment of showing the
// window (the default depends on the emWindowPort derivative,
// which may even forward the job to the window manager).
// Arguments:
// parentContext - Parent context for this new context.
// viewFlags - Initial view features.
// windowFlags - Initial window features.
// wmResName - A resource name for the window. This is
// reported to the window manager.
virtual ~emWindow();
// Destructor.
void LinkCrossPtr(emCrossPtrPrivate & crossPtr);
// This means emCrossPtr<emWindow> is possible.
emScreen & GetScreen() const;
// Get the screen where this window is shown.
WindowFlags GetWindowFlags() const;
void SetWindowFlags(WindowFlags windowFlags);
// Get or set the features of this window.
// CAUTION: Changing WF_MODAL, WF_UNDECORATED or WF_POPUP may
// reset position and size of the window. Any call to
// SetViewPosSize(..), SetWinPosSize(..) or companions should be
// made AFTER setting the window flags.
const emSignal & GetWindowFlagsSignal() const;
// This signal is signaled when the features of this window have
// changed.
const emString & GetWMResName() const;
// Get the resource name of this window.
emWindowPort & GetWindowPort() const;
// Get the window port of this window.
const emSignal & GetCloseSignal() const;
// Get the close signal. It is signaled when the window should
// be deleted.
void SignalClosing();
// Signal the close signal.
void SetViewPos(double x, double y);
void SetViewSize(double w, double h);
void SetViewPosSize(double x, double y, double w, double h);
// Set position and size of this window by the coordinates of
// the view port. This sets the coordinates you can get with
// GetHomeX, GetHomeY, GetHomeWidth and GetHomeHeight from the
// base class. On X11, the position may not be exact.
void SetWinPos(double x, double y);
void SetWinSize(double w, double h);
void SetWinPosSize(double x, double y, double w, double h);
// Set position and size of this window by the coordinates of
// the whole window rectangle including the borders. On X11, the
// size may not be exact.
void SetWinPosViewSize(double x, double y, double w, double h);
// Like SetWinPos and SetViewSize.
bool SetWinPosViewSize(const char * geometry);
// Like SetWinPosViewSize, but parse a typical X11 geometry
// option string (e.g. "800x600+100-100"). As expected, the
// position or size is not set if it is not specified (e.g.
// "320x200" sets the size only). On parse error, false is
// returned.
void GetBorderSizes(double * pL, double * pT, double * pR,
double * pB) const;
// Get the best known size (thickness) of the left, top, right
// and bottom edges of the window border.
int GetMonitorIndex() const;
// Get the index of the display monitor on which this window is.
const emImage & GetWindowIcon() const;
void SetWindowIcon(const emImage & windowIcon);
// Get or set the icon to be shown for this window. The default
// is to inherit the icon from an ancestor window at
// construction. But if there is no ancestor window, the default
// is an empty image which means to have no specific icon.
void Raise();
// Bring this window to the top of the stacking order. The
// window is even restored from any iconified state.
void InhibitScreensaver();
void AllowScreensaver();
// Inhibit or re-allow the screensaver. This should implement an
// internal counter for calls to InhibitScreensaver() which have
// not yet been taken back by calls to AllowScreensaver().
// Inhibiting only works while the window is shown quite large
// and not iconified.
protected:
virtual void InvalidateTitle();
// The title of the view is taken for the title of the window.
// This method has been overloaded just to update the window
// title.
private:
friend class emWindowPort;
class AutoDeleteEngineClass : public emEngine {
public:
AutoDeleteEngineClass(emWindow * window);
protected:
virtual bool Cycle();
private:
emWindow * Window;
int CountDown;
};
emRef<emScreen> Screen;
emCrossPtrList CrossPtrList;
WindowFlags WFlags;
emString WMResName;
emImage WindowIcon;
emWindowPort * WindowPort;
emSignal WindowFlagsSignal;
emSignal CloseSignal;
AutoDeleteEngineClass AutoDeleteEngine;
};
//==============================================================================
//================================ emWindowPort ================================
//==============================================================================
class emWindowPort : public emViewPort {
public:
// Abstract base class for the connection between an emWindow and the
// operating system or the hardware or whatever. When an emWindow is
// constructed, its constructor creates an emWindowPort by calling
// CreateWindowPort on the emScreen.
emWindowPort(emWindow & window);
// Only to be called through overloaded versions of
// emScreen::CreateWindowPort.
virtual ~emWindowPort();
emWindow & GetWindow() const;
protected:
emWindow::WindowFlags GetWindowFlags() const;
const emString & GetWMResName() const;
emString GetWindowTitle() const;
const emImage & GetWindowIcon() const;
virtual void WindowFlagsChanged() = 0;
enum PosSizeArgSpec {
PSAS_IGNORE,
PSAS_VIEW,
PSAS_WINDOW
};
virtual void SetPosSize(
double x, double y, PosSizeArgSpec posSpec,
double w, double h, PosSizeArgSpec sizeSpec
) = 0;
// Should call SetViewGeometry(...) immediately with appropriate
// values.
virtual void GetBorderSizes(
double * pL, double * pT, double * pR, double * pB
) const = 0;
virtual void Raise() = 0;
virtual void InhibitScreensaver() = 0;
virtual void AllowScreensaver() = 0;
virtual void InvalidateTitle() = 0;
virtual void InvalidateIcon() = 0;
void SignalWindowClosing();
private:
friend class emWindow;
emWindow & Window;
};
//==============================================================================
//============================== Implementations ===============================
//==============================================================================
//---------------------------------- emWindow ----------------------------------
inline void emWindow::LinkCrossPtr(emCrossPtrPrivate & crossPtr)
{
CrossPtrList.LinkCrossPtr(crossPtr);
}
inline emScreen & emWindow::GetScreen() const
{
return *(Screen.Get());
}
inline emWindow::WindowFlags emWindow::GetWindowFlags() const
{
return WFlags;
}
inline const emString & emWindow::GetWMResName() const
{
return WMResName;
}
inline emWindowPort & emWindow::GetWindowPort() const
{
return *WindowPort;
}
inline const emSignal & emWindow::GetCloseSignal() const
{
return CloseSignal;
}
inline void emWindow::SignalClosing()
{
Signal(CloseSignal);
}
inline void emWindow::SetViewPos(double x, double y)
{
WindowPort->SetPosSize(
x,y,emWindowPort::PSAS_VIEW,
0,0,emWindowPort::PSAS_IGNORE
);
}
inline void emWindow::SetViewSize(double w, double h)
{
WindowPort->SetPosSize(
0,0,emWindowPort::PSAS_IGNORE,
w,h,emWindowPort::PSAS_VIEW
);
}
inline void emWindow::SetViewPosSize(double x, double y, double w, double h)
{
WindowPort->SetPosSize(
x,y,emWindowPort::PSAS_VIEW,
w,h,emWindowPort::PSAS_VIEW
);
}
inline void emWindow::SetWinPos(double x, double y)
{
WindowPort->SetPosSize(
x,y,emWindowPort::PSAS_WINDOW,
0,0,emWindowPort::PSAS_IGNORE
);
}
inline void emWindow::SetWinSize(double w, double h)
{
WindowPort->SetPosSize(
0,0,emWindowPort::PSAS_IGNORE,
w,h,emWindowPort::PSAS_WINDOW
);
}
inline void emWindow::SetWinPosSize(double x, double y, double w, double h)
{
WindowPort->SetPosSize(
x,y,emWindowPort::PSAS_WINDOW,
w,h,emWindowPort::PSAS_WINDOW
);
}
inline void emWindow::SetWinPosViewSize(double x, double y, double w, double h)
{
WindowPort->SetPosSize(
x,y,emWindowPort::PSAS_WINDOW,
w,h,emWindowPort::PSAS_VIEW
);
}
inline void emWindow::GetBorderSizes(
double * pL, double * pT, double * pR, double * pB
) const
{
WindowPort->GetBorderSizes(pL,pT,pR,pB);
}
inline const emImage & emWindow::GetWindowIcon() const
{
return WindowIcon;
}
inline void emWindow::Raise()
{
WindowPort->Raise();
}
inline void emWindow::InhibitScreensaver()
{
WindowPort->InhibitScreensaver();
}
inline void emWindow::AllowScreensaver()
{
WindowPort->AllowScreensaver();
}
//-------------------------------- emWindowPort --------------------------------
inline emWindow & emWindowPort::GetWindow() const
{
return Window;
}
inline emWindow::WindowFlags emWindowPort::GetWindowFlags() const
{
return Window.GetWindowFlags();
}
inline const emSignal & emWindow::GetWindowFlagsSignal() const
{
return WindowFlagsSignal;
}
inline const emString & emWindowPort::GetWMResName() const
{
return Window.GetWMResName();
}
inline emString emWindowPort::GetWindowTitle() const
{
return Window.GetTitle();
}
inline const emImage & emWindowPort::GetWindowIcon() const
{
return Window.GetWindowIcon();
}
inline void emWindowPort::SignalWindowClosing()
{
Window.SignalClosing();
}
#endif