Add a title bar menu to close dialogs
This commit is contained in:
parent
29dfeafa87
commit
b576b8dcad
|
@ -1,3 +1,6 @@
|
|||
2016-06-12 Markus Gans <guru.mail@muenster.de>
|
||||
* Add a title bar menu to close dialogs
|
||||
|
||||
2016-05-24 Markus Gans <guru.mail@muenster.de>
|
||||
* Use nl_langinfo to determine the numeric thousands separator
|
||||
for Fstring::setFormatedNumber as default parameter
|
||||
|
|
2
doc/TODO
2
doc/TODO
|
@ -20,8 +20,6 @@ Missing Features
|
|||
└──► tmp
|
||||
---------------------------------------
|
||||
|
||||
- A single click on the FDialog title button [-] should open
|
||||
a FMenu with a closing item
|
||||
- FDialog title button [▲] and [▼] should maximized or restore
|
||||
the window size on a resizeable dialog
|
||||
- A possibility to change the window size dynamically with the mouse
|
||||
|
|
|
@ -969,7 +969,7 @@ void FApplication::processMouseEvent()
|
|||
}
|
||||
}
|
||||
|
||||
// close open menu
|
||||
// close the open menu
|
||||
if ( open_menu && ! b_state.mouse_moved )
|
||||
{
|
||||
FMenu* menu = static_cast<FMenu*>(open_menu);
|
||||
|
@ -980,8 +980,6 @@ void FApplication::processMouseEvent()
|
|||
menu->hide();
|
||||
menu->hideSubMenus();
|
||||
menu->hideSuperMenus();
|
||||
if ( statusBar() )
|
||||
statusBar()->clearMessage();
|
||||
|
||||
// No widget was been clicked
|
||||
if ( ! clicked_widget )
|
||||
|
@ -1375,7 +1373,9 @@ bool FApplication::sendEvent(FObject* receiver, FEvent* event)
|
|||
window = FWindow::getWindowWidget(widget);
|
||||
|
||||
// block events for widgets in non modal windows
|
||||
if ( window && (window->getFlags() & fc::modal) == 0 )
|
||||
if ( window
|
||||
&& (window->getFlags() & fc::modal) == 0
|
||||
&& ! window->isMenu() )
|
||||
{
|
||||
switch ( event->type() )
|
||||
{
|
||||
|
|
170
src/fdialog.cpp
170
src/fdialog.cpp
|
@ -20,6 +20,8 @@ FDialog::FDialog(FWidget* parent)
|
|||
, TitleBarClickPos()
|
||||
, oldGeometry()
|
||||
, focus_widget(0)
|
||||
, dialog_menu()
|
||||
, dgl_menuitem()
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
@ -33,6 +35,8 @@ FDialog::FDialog (const FString& txt, FWidget* parent)
|
|||
, TitleBarClickPos()
|
||||
, oldGeometry()
|
||||
, focus_widget(0)
|
||||
, dialog_menu()
|
||||
, dgl_menuitem()
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
@ -88,12 +92,13 @@ FDialog::~FDialog() // destructor
|
|||
//----------------------------------------------------------------------
|
||||
void FDialog::init()
|
||||
{
|
||||
FWidget* rootObj = getRootWidget();
|
||||
xmin = 1 + rootObj->getLeftPadding();
|
||||
ymin = 1 + rootObj->getTopPadding();
|
||||
xmax = rootObj->getWidth();
|
||||
ymax = rootObj->getHeight();
|
||||
width = 10;
|
||||
height = 10;
|
||||
xmin = 1;
|
||||
ymin = 1;
|
||||
xmax = width;
|
||||
ymax = height;
|
||||
client_xmin = 1;
|
||||
client_ymin = 1;
|
||||
client_xmax = width;
|
||||
|
@ -106,6 +111,7 @@ void FDialog::init()
|
|||
setGeometry (1, 1, 10, 10, false); // initialize geometry values
|
||||
ignore_padding = true;
|
||||
window_object = true;
|
||||
dialog_object = true;
|
||||
addWindow(this);
|
||||
setActiveWindow(this);
|
||||
|
||||
|
@ -124,6 +130,25 @@ void FDialog::init()
|
|||
old_focus->redraw();
|
||||
}
|
||||
accelerator_list = new Accelerators();
|
||||
|
||||
dialog_menu = new FMenu ("-", this);
|
||||
dialog_menu->move (xpos, ypos+1);
|
||||
|
||||
dgl_menuitem = dialog_menu->getItem();
|
||||
if ( dgl_menuitem )
|
||||
{
|
||||
dgl_menuitem->ignorePadding();
|
||||
dgl_menuitem->unsetFocusable();
|
||||
}
|
||||
|
||||
FMenuItem* close_item = new FMenuItem ("&Close", dialog_menu);
|
||||
close_item->setStatusbarMessage ("Close window");
|
||||
|
||||
close_item->addCallback
|
||||
(
|
||||
"clicked",
|
||||
_METHOD_CALLBACK (this, &FDialog::cb_close)
|
||||
);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -214,14 +239,28 @@ void FDialog::drawTitleBar()
|
|||
print (fc::NF_rev_menu_button3);
|
||||
}
|
||||
else if ( isMonochron() )
|
||||
print ("[-]");
|
||||
{
|
||||
print ('[');
|
||||
if ( dgl_menuitem )
|
||||
print (dgl_menuitem->getText());
|
||||
else
|
||||
print ('-');
|
||||
print (']');
|
||||
}
|
||||
else
|
||||
print (" - ");
|
||||
{
|
||||
print (' ');
|
||||
if ( dgl_menuitem )
|
||||
print (dgl_menuitem->getText());
|
||||
else
|
||||
print ('-');
|
||||
print (' ');
|
||||
}
|
||||
|
||||
// fill with spaces (left of the title)
|
||||
if ( getMaxColor() < 16 )
|
||||
setBold();
|
||||
if ( isActiveWindow() )
|
||||
if ( isActiveWindow() || dialog_menu->isVisible() )
|
||||
setColor (wc.titlebar_active_fg, wc.titlebar_active_bg);
|
||||
else
|
||||
setColor (wc.titlebar_inactive_fg, wc.titlebar_inactive_bg);
|
||||
|
@ -251,6 +290,17 @@ void FDialog::drawTitleBar()
|
|||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FDialog::cb_close (FWidget*, void*)
|
||||
{
|
||||
dialog_menu->unselectItem();
|
||||
dialog_menu->hide();
|
||||
setClickedWidget(0);
|
||||
drawTitleBar();
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
// protected methods of FDialog
|
||||
//----------------------------------------------------------------------
|
||||
void FDialog::done(int result)
|
||||
|
@ -475,6 +525,47 @@ void FDialog::onMouseDown (FMouseEvent* ev)
|
|||
}
|
||||
if ( has_raised )
|
||||
redraw();
|
||||
|
||||
// click on titlebar menu button
|
||||
if ( mouse_x < 4 && mouse_y == 1 )
|
||||
{
|
||||
if ( dialog_menu->isVisible() )
|
||||
{
|
||||
dialog_menu->unselectItem();
|
||||
dialog_menu->hide();
|
||||
activateWindow();
|
||||
raiseWindow();
|
||||
getFocusWidget()->setFocus();
|
||||
redraw();
|
||||
if ( statusBar() )
|
||||
statusBar()->drawMessage();
|
||||
}
|
||||
else
|
||||
{
|
||||
setOpenMenu(dialog_menu);
|
||||
dialog_menu->move (xpos, ypos+1);
|
||||
dialog_menu->setVisible();
|
||||
dialog_menu->show();
|
||||
dialog_menu->raiseWindow(dialog_menu);
|
||||
dialog_menu->redraw();
|
||||
}
|
||||
}
|
||||
}
|
||||
else // ev->getButton() != fc::LeftButton
|
||||
{
|
||||
// click on titlebar menu button
|
||||
if ( mouse_x < 4 && mouse_y == 1 && dialog_menu->isVisible() )
|
||||
{
|
||||
// close menu
|
||||
dialog_menu->unselectItem();
|
||||
dialog_menu->hide();
|
||||
activateWindow();
|
||||
raiseWindow();
|
||||
getFocusWidget()->setFocus();
|
||||
redraw();
|
||||
if ( statusBar() )
|
||||
statusBar()->drawMessage();
|
||||
}
|
||||
}
|
||||
|
||||
if ( ev->getButton() == fc::RightButton )
|
||||
|
@ -537,6 +628,9 @@ void FDialog::onMouseUp (FMouseEvent* ev)
|
|||
|
||||
if ( ev->getButton() == fc::LeftButton )
|
||||
{
|
||||
int mouse_x = ev->getX();
|
||||
int mouse_y = ev->getY();
|
||||
|
||||
if ( ! TitleBarClickPos.isNull()
|
||||
&& titlebar_x > xpos+xmin+2
|
||||
&& titlebar_x < xpos+xmin+width
|
||||
|
@ -547,6 +641,24 @@ void FDialog::onMouseUp (FMouseEvent* ev)
|
|||
move (currentPos + deltaPos);
|
||||
TitleBarClickPos = ev->getGlobalPos();
|
||||
}
|
||||
|
||||
// click on titlebar menu button
|
||||
if ( mouse_x < 4
|
||||
&& mouse_y == 1
|
||||
&& dialog_menu->isVisible()
|
||||
&& ! dialog_menu->hasSelectedItem() )
|
||||
{
|
||||
FMenuItem* first_item;
|
||||
dialog_menu->selectFirstItem();
|
||||
first_item = dialog_menu->getSelectedItem();
|
||||
if ( first_item )
|
||||
first_item->setFocus();
|
||||
dialog_menu->redraw();
|
||||
if ( statusBar() )
|
||||
statusBar()->drawMessage();
|
||||
updateTerminal();
|
||||
flush_out();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -562,6 +674,25 @@ void FDialog::onMouseMove (FMouseEvent* ev)
|
|||
move (currentPos + deltaPos);
|
||||
TitleBarClickPos = ev->getGlobalPos();
|
||||
}
|
||||
|
||||
if ( dialog_menu->isVisible() && dialog_menu->isShown() )
|
||||
{
|
||||
// Mouse event handover to the menu
|
||||
const FRect& menu_geometry = dialog_menu->getGeometryGlobal();
|
||||
|
||||
if ( dialog_menu->count() > 0
|
||||
&& menu_geometry.contains(ev->getGlobalPos()) )
|
||||
{
|
||||
const FPoint& g = ev->getGlobalPos();
|
||||
const FPoint& p = dialog_menu->globalToLocalPos(g);
|
||||
int b = ev->getButton();
|
||||
FMouseEvent* _ev = new FMouseEvent (fc::MouseMove_Event, p, g, b);
|
||||
dialog_menu->mouse_down = true;
|
||||
setClickedWidget(dialog_menu);
|
||||
dialog_menu->onMouseMove(_ev);
|
||||
delete _ev;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -580,8 +711,14 @@ void FDialog::onMouseDoubleClick (FMouseEvent* ev)
|
|||
FPoint gPos = ev->getGlobalPos();
|
||||
if ( title_button.contains(gPos) )
|
||||
{
|
||||
dialog_menu->unselectItem();
|
||||
dialog_menu->hide();
|
||||
setClickedWidget(0);
|
||||
close();
|
||||
|
||||
if ( isModal() )
|
||||
done(FDialog::Reject);
|
||||
else
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -591,18 +728,15 @@ void FDialog::onWindowActive (FEvent*)
|
|||
if ( isVisible() && isShown() )
|
||||
drawTitleBar();
|
||||
|
||||
if ( ! FWidget::getFocusWidget() )
|
||||
if ( focus_widget && focus_widget->isVisible() && focus_widget->isShown() )
|
||||
{
|
||||
if ( focus_widget && focus_widget->isVisible() && focus_widget->isShown() )
|
||||
{
|
||||
focus_widget->setFocus();
|
||||
focus_widget->redraw();
|
||||
if ( statusBar() )
|
||||
statusBar()->drawMessage();
|
||||
}
|
||||
else
|
||||
focusFirstChild();
|
||||
focus_widget->setFocus();
|
||||
focus_widget->redraw();
|
||||
if ( statusBar() )
|
||||
statusBar()->drawMessage();
|
||||
}
|
||||
else
|
||||
focusFirstChild();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
#ifndef _FDIALOG_H
|
||||
#define _FDIALOG_H
|
||||
|
||||
#include "fmenu.h"
|
||||
#include "fmenuitem.h"
|
||||
#include "fwindow.h"
|
||||
|
||||
|
||||
|
@ -48,12 +50,14 @@ class FDialog : public FWindow
|
|||
};
|
||||
|
||||
private:
|
||||
FString tb_text; // title bar text
|
||||
int result_code;
|
||||
bool maximized;
|
||||
FPoint TitleBarClickPos;
|
||||
FRect oldGeometry; // required by move()
|
||||
FWidget* focus_widget;
|
||||
FString tb_text; // title bar text
|
||||
int result_code;
|
||||
bool maximized;
|
||||
FPoint TitleBarClickPos;
|
||||
FRect oldGeometry; // required by move()
|
||||
FWidget* focus_widget;
|
||||
FMenu* dialog_menu;
|
||||
FMenuItem* dgl_menuitem;
|
||||
|
||||
private:
|
||||
FDialog (const FDialog&);
|
||||
|
@ -61,6 +65,7 @@ class FDialog : public FWindow
|
|||
void init();
|
||||
void drawBorder();
|
||||
void drawTitleBar();
|
||||
void cb_close (FWidget*, void*);
|
||||
|
||||
protected:
|
||||
virtual void done (int);
|
||||
|
|
|
@ -130,6 +130,7 @@ class FMenu : public FWindow, public FMenuList
|
|||
private:
|
||||
friend class FApplication;
|
||||
friend class FCheckMenuItem;
|
||||
friend class FDialog;
|
||||
friend class FMenuBar;
|
||||
friend class FMenuItem;
|
||||
friend class FRadioMenuItem;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// Provides: class FMenuItem
|
||||
|
||||
#include "fapp.h"
|
||||
#include "fdialog.h"
|
||||
#include "fmenu.h"
|
||||
#include "fmenubar.h"
|
||||
#include "fmenulist.h"
|
||||
|
@ -246,6 +247,12 @@ void FMenuItem::processClicked()
|
|||
|
||||
|
||||
// protected methods of FMenuItem
|
||||
//----------------------------------------------------------------------
|
||||
bool FMenuItem::isWindowsMenu (FWidget* w) const
|
||||
{
|
||||
return w->isDialog();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
bool FMenuItem::isMenuBar (FWidget* w) const
|
||||
{
|
||||
|
@ -369,6 +376,52 @@ void FMenuItem::onKeyPress (FKeyEvent* ev)
|
|||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FMenuItem::onMouseDoubleClick (FMouseEvent* ev)
|
||||
{
|
||||
if ( super_menu )
|
||||
{
|
||||
const FPoint& g = ev->getGlobalPos();
|
||||
int b = ev->getButton();
|
||||
|
||||
if ( isMenu(super_menu) )
|
||||
{
|
||||
FMenu* smenu = dynamic_cast<FMenu*>(super_menu);
|
||||
if ( smenu )
|
||||
{
|
||||
const FPoint& p2 = smenu->globalToLocalPos(g);
|
||||
FMouseEvent* _ev = new FMouseEvent (fc::MouseDoubleClick_Event, p2, g, b);
|
||||
smenu->onMouseDoubleClick(_ev);
|
||||
delete _ev;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isMenuBar(super_menu) )
|
||||
{
|
||||
FMenuBar* mbar = dynamic_cast<FMenuBar*>(super_menu);
|
||||
if ( mbar )
|
||||
{
|
||||
const FPoint& p2 = mbar->globalToLocalPos(g);
|
||||
FMouseEvent* _ev = new FMouseEvent (fc::MouseDoubleClick_Event, p2, g, b);
|
||||
mbar->onMouseDoubleClick(_ev);
|
||||
delete _ev;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isWindowsMenu(super_menu) )
|
||||
{
|
||||
FDialog* dgl = dynamic_cast<FDialog*>(super_menu);
|
||||
if ( dgl )
|
||||
{
|
||||
const FPoint& p2 = dgl->globalToLocalPos(g);
|
||||
FMouseEvent* _ev = new FMouseEvent (fc::MouseDoubleClick_Event, p2, g, b);
|
||||
dgl->onMouseDoubleClick(_ev);
|
||||
delete _ev;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FMenuItem::onMouseDown (FMouseEvent* ev)
|
||||
{
|
||||
|
@ -400,6 +453,18 @@ void FMenuItem::onMouseDown (FMouseEvent* ev)
|
|||
delete _ev;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isWindowsMenu(super_menu) )
|
||||
{
|
||||
FDialog* dgl = dynamic_cast<FDialog*>(super_menu);
|
||||
if ( dgl )
|
||||
{
|
||||
const FPoint& p2 = dgl->globalToLocalPos(g);
|
||||
FMouseEvent* _ev = new FMouseEvent (fc::MouseDown_Event, p2, g, b);
|
||||
dgl->onMouseDown(_ev);
|
||||
delete _ev;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -434,6 +499,18 @@ void FMenuItem::onMouseUp (FMouseEvent* ev)
|
|||
delete _ev;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isWindowsMenu(super_menu) )
|
||||
{
|
||||
FDialog* dgl = dynamic_cast<FDialog*>(super_menu);
|
||||
if ( dgl )
|
||||
{
|
||||
const FPoint& p2 = dgl->globalToLocalPos(g);
|
||||
FMouseEvent* _ev = new FMouseEvent (fc::MouseUp_Event, p2, g, b);
|
||||
dgl->onMouseUp(_ev);
|
||||
delete _ev;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -469,6 +546,17 @@ void FMenuItem::onMouseMove (FMouseEvent* ev)
|
|||
}
|
||||
}
|
||||
|
||||
if ( isWindowsMenu(super_menu) )
|
||||
{
|
||||
FDialog* dgl = dynamic_cast<FDialog*>(super_menu);
|
||||
if ( dgl )
|
||||
{
|
||||
const FPoint& p2 = dgl->globalToLocalPos(g);
|
||||
FMouseEvent* _ev = new FMouseEvent (fc::MouseMove_Event, p2, g, b);
|
||||
dgl->onMouseMove(_ev);
|
||||
delete _ev;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -65,6 +65,7 @@ class FMenuItem : public FWidget
|
|||
virtual void processClicked();
|
||||
|
||||
protected:
|
||||
bool isWindowsMenu (FWidget*) const;
|
||||
bool isMenuBar (FWidget*) const;
|
||||
bool isMenu (FWidget*) const;
|
||||
FWidget* getSuperMenu() const;
|
||||
|
@ -88,6 +89,7 @@ class FMenuItem : public FWidget
|
|||
using FWidget::delAccelerator;
|
||||
void delAccelerator (FWidget*);
|
||||
void onKeyPress (FKeyEvent*);
|
||||
void onMouseDoubleClick (FMouseEvent*);
|
||||
void onMouseDown (FMouseEvent*);
|
||||
void onMouseUp (FMouseEvent*);
|
||||
void onMouseMove (FMouseEvent*);
|
||||
|
|
|
@ -54,6 +54,7 @@ FWidget::FWidget (FWidget* parent)
|
|||
, adjustWidgetSizeGlobalShadow()
|
||||
, ignore_padding(false)
|
||||
, window_object(false)
|
||||
, dialog_object(false)
|
||||
, menu_object(false)
|
||||
, flags(0)
|
||||
, foregroundColor()
|
||||
|
|
|
@ -246,6 +246,7 @@ class FWidget : public FObject, public FTerm
|
|||
FRect adjustWidgetSizeGlobalShadow;
|
||||
bool ignore_padding;
|
||||
bool window_object;
|
||||
bool dialog_object;
|
||||
bool menu_object;
|
||||
int flags;
|
||||
short foregroundColor;
|
||||
|
@ -331,6 +332,7 @@ class FWidget : public FObject, public FTerm
|
|||
FWidget* parentWidget() const;
|
||||
bool isRootWidget() const;
|
||||
bool isWindow() const;
|
||||
bool isDialog() const;
|
||||
bool isMenu() const;
|
||||
virtual bool close();
|
||||
|
||||
|
@ -580,6 +582,10 @@ inline bool FWidget::isShown() const
|
|||
inline bool FWidget::isWindow() const
|
||||
{ return window_object; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FWidget::isDialog() const
|
||||
{ return dialog_object; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FWidget::isMenu() const
|
||||
{ return menu_object; }
|
||||
|
|
Loading…
Reference in New Issue