2017-11-04 07:03:53 +01:00
|
|
|
/***********************************************************************
|
|
|
|
* fmenuitem.cpp - Widget FMenuItem *
|
|
|
|
* *
|
|
|
|
* This file is part of the Final Cut widget toolkit *
|
|
|
|
* *
|
2018-02-22 01:15:57 +01:00
|
|
|
* Copyright 2015-2018 Markus Gans *
|
2017-11-04 07:03:53 +01:00
|
|
|
* *
|
|
|
|
* The Final Cut 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. *
|
|
|
|
* *
|
|
|
|
* The Final Cut 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 *
|
|
|
|
* <http://www.gnu.org/licenses/>. *
|
|
|
|
***********************************************************************/
|
2015-08-09 23:47:08 +02:00
|
|
|
|
2017-09-17 21:32:46 +02:00
|
|
|
#include "final/fapplication.h"
|
|
|
|
#include "final/fdialog.h"
|
|
|
|
#include "final/fmenu.h"
|
|
|
|
#include "final/fmenubar.h"
|
|
|
|
#include "final/fmenulist.h"
|
|
|
|
#include "final/fmenuitem.h"
|
|
|
|
#include "final/fstatusbar.h"
|
|
|
|
|
2018-09-20 23:59:01 +02:00
|
|
|
namespace finalcut
|
|
|
|
{
|
2015-08-09 23:47:08 +02:00
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// class FMenuItem
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
// constructor and destructor
|
|
|
|
//----------------------------------------------------------------------
|
2015-09-22 04:18:20 +02:00
|
|
|
FMenuItem::FMenuItem (FWidget* parent)
|
|
|
|
: FWidget(parent)
|
2015-08-09 23:47:08 +02:00
|
|
|
{
|
|
|
|
init (parent);
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
2017-03-17 22:59:06 +01:00
|
|
|
FMenuItem::FMenuItem (const FString& txt, FWidget* parent)
|
2015-09-22 04:18:20 +02:00
|
|
|
: FWidget(parent)
|
|
|
|
, text(txt)
|
2015-08-09 23:47:08 +02:00
|
|
|
{
|
|
|
|
init (parent);
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
2018-11-21 20:07:08 +01:00
|
|
|
FMenuItem::FMenuItem (FKey k, const FString& txt, FWidget* parent)
|
2015-11-12 01:33:16 +01:00
|
|
|
: FWidget(parent)
|
|
|
|
, text(txt)
|
|
|
|
, accel_key(k)
|
|
|
|
{
|
|
|
|
init (parent);
|
|
|
|
}
|
2015-11-15 19:46:33 +01:00
|
|
|
|
2015-08-09 23:47:08 +02:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
FMenuItem::~FMenuItem() // destructor
|
2015-11-12 23:14:12 +01:00
|
|
|
{
|
2018-10-03 22:21:30 +02:00
|
|
|
if ( super_menu && (isMenu(super_menu) || isMenuBar(super_menu)) )
|
|
|
|
{
|
2018-10-13 00:32:14 +02:00
|
|
|
FMenuList* menu_list = getFMenuList(*super_menu);
|
2018-10-03 22:21:30 +02:00
|
|
|
|
|
|
|
if ( menu_list )
|
|
|
|
menu_list->remove(this);
|
|
|
|
}
|
|
|
|
|
2015-11-12 23:14:12 +01:00
|
|
|
delAccelerator();
|
2016-07-30 23:00:37 +02:00
|
|
|
|
|
|
|
// remove dialog list item callback from the dialog
|
|
|
|
if ( associated_window )
|
|
|
|
associated_window->delCallback(this);
|
2015-11-12 23:14:12 +01:00
|
|
|
}
|
2015-08-09 23:47:08 +02:00
|
|
|
|
|
|
|
|
2016-11-02 00:37:58 +01:00
|
|
|
// public methods of FMenuItem
|
2015-08-09 23:47:08 +02:00
|
|
|
//----------------------------------------------------------------------
|
2016-11-02 00:37:58 +01:00
|
|
|
bool FMenuItem::setEnable (bool on)
|
2015-08-09 23:47:08 +02:00
|
|
|
{
|
2016-11-02 00:37:58 +01:00
|
|
|
FWidget::setEnable(on);
|
|
|
|
FWidget* super = getSuperMenu();
|
2015-08-09 23:47:08 +02:00
|
|
|
|
2016-11-02 00:37:58 +01:00
|
|
|
if ( on )
|
2015-08-09 23:47:08 +02:00
|
|
|
{
|
2016-11-02 00:37:58 +01:00
|
|
|
if ( super && isMenuBar(super) )
|
2015-09-15 23:07:24 +02:00
|
|
|
{
|
2016-11-02 00:37:58 +01:00
|
|
|
// Meta + hotkey
|
2018-11-21 20:07:08 +01:00
|
|
|
super->addAccelerator ( fc::Fmkey_meta + FKey(std::tolower(hotkey))
|
|
|
|
, this );
|
2015-09-15 23:07:24 +02:00
|
|
|
}
|
2015-08-09 23:47:08 +02:00
|
|
|
}
|
2016-11-02 00:37:58 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( super && isMenuBar(super) )
|
|
|
|
super->delAccelerator (this);
|
|
|
|
}
|
2015-10-29 21:10:50 +01:00
|
|
|
|
2016-11-02 00:37:58 +01:00
|
|
|
return on;
|
2015-08-09 23:47:08 +02:00
|
|
|
}
|
|
|
|
|
2015-08-16 20:05:39 +02:00
|
|
|
//----------------------------------------------------------------------
|
2016-11-02 00:37:58 +01:00
|
|
|
bool FMenuItem::setFocus (bool on)
|
2015-08-16 20:05:39 +02:00
|
|
|
{
|
2016-11-02 00:37:58 +01:00
|
|
|
FWidget::setFocus(on);
|
2015-08-16 20:05:39 +02:00
|
|
|
|
2016-11-02 00:37:58 +01:00
|
|
|
if ( on )
|
2015-09-30 22:39:02 +02:00
|
|
|
{
|
2016-11-02 00:37:58 +01:00
|
|
|
if ( isEnabled() )
|
2015-09-30 22:39:02 +02:00
|
|
|
{
|
2016-11-02 00:37:58 +01:00
|
|
|
if ( ! selected )
|
|
|
|
{
|
2018-10-13 00:32:14 +02:00
|
|
|
FMenuList* menu_list = getFMenuList(*getSuperMenu());
|
2016-11-02 00:37:58 +01:00
|
|
|
setSelected();
|
2016-07-09 00:01:59 +02:00
|
|
|
|
2016-11-02 00:37:58 +01:00
|
|
|
if ( menu_list )
|
|
|
|
{
|
|
|
|
menu_list->unselectItem();
|
|
|
|
menu_list->setSelectedItem(this);
|
|
|
|
}
|
2015-08-16 20:05:39 +02:00
|
|
|
|
2016-11-02 00:37:58 +01:00
|
|
|
if ( getStatusBar() )
|
|
|
|
getStatusBar()->drawMessage();
|
2015-08-09 23:47:08 +02:00
|
|
|
|
2016-11-02 00:37:58 +01:00
|
|
|
FWidget* parent = getSuperMenu();
|
2015-09-15 23:07:24 +02:00
|
|
|
|
2016-11-02 00:37:58 +01:00
|
|
|
if ( isMenuBar(parent) )
|
|
|
|
{
|
2017-09-11 03:06:02 +02:00
|
|
|
FMenuBar* menubar_ptr = static_cast<FMenuBar*>(parent);
|
2016-07-03 20:08:39 +02:00
|
|
|
|
2016-11-02 00:37:58 +01:00
|
|
|
if ( menubar_ptr )
|
|
|
|
menubar_ptr->redraw();
|
|
|
|
}
|
|
|
|
else if ( isMenu(parent) )
|
|
|
|
{
|
2017-09-11 03:06:02 +02:00
|
|
|
FMenu* menu_ptr = static_cast<FMenu*>(parent);
|
2016-07-03 20:08:39 +02:00
|
|
|
|
2016-11-02 00:37:58 +01:00
|
|
|
if ( menu_ptr )
|
|
|
|
menu_ptr->redraw();
|
|
|
|
}
|
|
|
|
}
|
2016-07-16 20:39:38 +02:00
|
|
|
|
2016-11-02 00:37:58 +01:00
|
|
|
if ( getStatusBar() )
|
2016-07-03 20:08:39 +02:00
|
|
|
{
|
2017-03-26 20:40:04 +02:00
|
|
|
const FString& msg = getStatusbarMessage();
|
|
|
|
const FString& curMsg = getStatusBar()->getMessage();
|
2016-07-31 20:25:25 +02:00
|
|
|
|
2016-11-02 00:37:58 +01:00
|
|
|
if ( curMsg != msg )
|
|
|
|
getStatusBar()->setMessage(msg);
|
2016-07-03 20:08:39 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-11-02 00:37:58 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( isEnabled() && getStatusBar() )
|
|
|
|
getStatusBar()->clearMessage();
|
|
|
|
}
|
|
|
|
|
|
|
|
return on;
|
2016-07-03 20:08:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
2016-11-02 00:37:58 +01:00
|
|
|
void FMenuItem::setSelected()
|
2016-07-03 20:08:39 +02:00
|
|
|
{
|
2016-11-02 00:37:58 +01:00
|
|
|
if ( isEnabled() )
|
2016-07-03 20:08:39 +02:00
|
|
|
{
|
2016-11-02 00:37:58 +01:00
|
|
|
selected = true;
|
|
|
|
processActivate();
|
2016-07-03 20:08:39 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-24 20:18:23 +02:00
|
|
|
//----------------------------------------------------------------------
|
2016-11-02 00:37:58 +01:00
|
|
|
void FMenuItem::unsetSelected()
|
2016-07-24 20:18:23 +02:00
|
|
|
{
|
2016-11-02 00:37:58 +01:00
|
|
|
selected = false;
|
2016-11-12 22:59:48 +01:00
|
|
|
unsetCursorPos();
|
2016-11-02 00:37:58 +01:00
|
|
|
processDeactivate();
|
2016-07-24 20:18:23 +02:00
|
|
|
}
|
|
|
|
|
2015-08-09 23:47:08 +02:00
|
|
|
//----------------------------------------------------------------------
|
2017-03-17 22:59:06 +01:00
|
|
|
void FMenuItem::setText (const FString& txt)
|
2015-08-09 23:47:08 +02:00
|
|
|
{
|
2016-11-02 00:37:58 +01:00
|
|
|
text = txt;
|
|
|
|
text_length = text.getLength();
|
|
|
|
hotkey = hotKey();
|
2015-08-09 23:47:08 +02:00
|
|
|
|
2016-11-02 00:37:58 +01:00
|
|
|
if ( hotkey )
|
|
|
|
text_length--;
|
2015-11-15 19:46:33 +01:00
|
|
|
|
2018-10-14 06:25:33 +02:00
|
|
|
setWidth(text_length);
|
2016-06-12 23:06:58 +02:00
|
|
|
}
|
|
|
|
|
2015-11-12 01:33:16 +01:00
|
|
|
//----------------------------------------------------------------------
|
2018-11-21 20:07:08 +01:00
|
|
|
void FMenuItem::addAccelerator (FKey key, FWidget* obj)
|
2015-11-12 01:33:16 +01:00
|
|
|
{
|
2016-07-14 00:12:16 +02:00
|
|
|
FWidget* root = getRootWidget();
|
|
|
|
accelerator accel = { key, obj };
|
2015-11-12 01:33:16 +01:00
|
|
|
|
2016-07-14 00:12:16 +02:00
|
|
|
if ( root && root->accelerator_list )
|
2015-11-12 01:33:16 +01:00
|
|
|
{
|
2016-07-14 00:12:16 +02:00
|
|
|
accel_key = key;
|
|
|
|
root->accelerator_list->push_back(accel);
|
2015-11-12 23:14:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if ( isMenu(super_menu) )
|
|
|
|
{
|
2017-09-11 03:06:02 +02:00
|
|
|
FMenu* menu_ptr = static_cast<FMenu*>(super_menu);
|
2016-07-09 00:01:59 +02:00
|
|
|
|
2015-11-12 23:14:12 +01:00
|
|
|
if ( menu_ptr )
|
2016-09-27 00:46:05 +02:00
|
|
|
menu_ptr->calculateDimensions();
|
2015-11-12 01:33:16 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void FMenuItem::delAccelerator (FWidget* obj)
|
|
|
|
{
|
2016-07-14 00:12:16 +02:00
|
|
|
FWidget* root = getRootWidget();
|
2016-07-09 00:01:59 +02:00
|
|
|
|
2016-12-18 23:34:11 +01:00
|
|
|
if ( root
|
2017-11-26 22:37:18 +01:00
|
|
|
&& root->accelerator_list
|
|
|
|
&& ! root->accelerator_list->empty() )
|
2015-11-12 01:33:16 +01:00
|
|
|
{
|
2016-07-14 00:12:16 +02:00
|
|
|
FWidget::Accelerators::iterator iter;
|
|
|
|
iter = root->accelerator_list->begin();
|
2015-11-12 01:33:16 +01:00
|
|
|
|
2016-07-14 00:12:16 +02:00
|
|
|
while ( iter != root->accelerator_list->end() )
|
2015-11-12 01:33:16 +01:00
|
|
|
{
|
2016-07-14 00:12:16 +02:00
|
|
|
if ( iter->object == obj )
|
2015-11-12 01:33:16 +01:00
|
|
|
{
|
2016-07-14 00:12:16 +02:00
|
|
|
accel_key = 0;
|
|
|
|
iter = root->accelerator_list->erase(iter);
|
2015-11-12 01:33:16 +01:00
|
|
|
}
|
2016-07-14 00:12:16 +02:00
|
|
|
else
|
|
|
|
++iter;
|
2015-11-12 01:33:16 +01:00
|
|
|
}
|
|
|
|
}
|
2015-11-12 23:14:12 +01:00
|
|
|
|
|
|
|
if ( isMenu(super_menu) )
|
|
|
|
{
|
2017-09-11 03:06:02 +02:00
|
|
|
FMenu* menu_ptr = static_cast<FMenu*>(super_menu);
|
2016-07-09 00:01:59 +02:00
|
|
|
|
2015-11-12 23:14:12 +01:00
|
|
|
if ( menu_ptr )
|
2016-09-27 00:46:05 +02:00
|
|
|
menu_ptr->calculateDimensions();
|
2015-11-12 23:14:12 +01:00
|
|
|
}
|
2015-11-12 01:33:16 +01:00
|
|
|
}
|
|
|
|
|
2016-11-02 00:37:58 +01:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void FMenuItem::openMenu()
|
|
|
|
{
|
|
|
|
if ( ! hasMenu() )
|
|
|
|
return;
|
|
|
|
|
2018-12-01 21:28:25 +01:00
|
|
|
FMenu* dd_menu = getMenu(); // Drop-down menu
|
2016-11-02 00:37:58 +01:00
|
|
|
|
|
|
|
if ( dd_menu->isVisible() )
|
|
|
|
return;
|
|
|
|
|
2018-12-01 21:28:25 +01:00
|
|
|
FMenu* openmenu = static_cast<FMenu*>(getOpenMenu());
|
2016-11-02 00:37:58 +01:00
|
|
|
|
2018-12-01 21:28:25 +01:00
|
|
|
if ( openmenu && openmenu != dd_menu )
|
2016-11-02 00:37:58 +01:00
|
|
|
{
|
2018-12-01 21:28:25 +01:00
|
|
|
openmenu->hide();
|
|
|
|
openmenu->hideSubMenus();
|
2016-11-02 00:37:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if ( dialog_index )
|
|
|
|
createDialogList (dd_menu);
|
|
|
|
|
|
|
|
setOpenMenu(dd_menu);
|
|
|
|
dd_menu->setVisible();
|
|
|
|
dd_menu->show();
|
2017-08-12 20:10:27 +02:00
|
|
|
dd_menu->raiseWindow();
|
2016-11-02 00:37:58 +01:00
|
|
|
dd_menu->redraw();
|
|
|
|
updateTerminal();
|
|
|
|
flush_out();
|
|
|
|
}
|
|
|
|
|
2015-08-09 23:47:08 +02:00
|
|
|
//----------------------------------------------------------------------
|
2015-10-29 21:10:50 +01:00
|
|
|
void FMenuItem::onKeyPress (FKeyEvent* ev)
|
2015-08-09 23:47:08 +02:00
|
|
|
{
|
2016-10-17 08:44:38 +02:00
|
|
|
if ( ! super_menu )
|
|
|
|
return;
|
|
|
|
|
|
|
|
if ( isMenu(super_menu) )
|
2015-08-09 23:47:08 +02:00
|
|
|
{
|
2017-09-11 03:06:02 +02:00
|
|
|
FMenu* smenu = static_cast<FMenu*>(super_menu);
|
2017-09-19 06:18:03 +02:00
|
|
|
smenu->onKeyPress(ev);
|
2016-10-17 08:44:38 +02:00
|
|
|
}
|
2015-10-29 21:10:50 +01:00
|
|
|
|
2016-10-17 08:44:38 +02:00
|
|
|
if ( isMenuBar(super_menu) )
|
|
|
|
{
|
2017-09-11 03:06:02 +02:00
|
|
|
FMenuBar* mbar = static_cast<FMenuBar*>(super_menu);
|
2016-07-09 00:01:59 +02:00
|
|
|
|
2016-10-17 08:44:38 +02:00
|
|
|
if ( mbar )
|
|
|
|
{
|
|
|
|
if ( mbar->hotkeyMenu(ev) )
|
|
|
|
return;
|
2016-07-09 00:01:59 +02:00
|
|
|
|
2016-10-17 08:44:38 +02:00
|
|
|
mbar->onKeyPress(ev);
|
2015-10-23 00:24:20 +02:00
|
|
|
}
|
2015-08-09 23:47:08 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-12 23:06:58 +02:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void FMenuItem::onMouseDoubleClick (FMouseEvent* ev)
|
|
|
|
{
|
2016-10-17 08:44:38 +02:00
|
|
|
if ( ! super_menu )
|
|
|
|
return;
|
|
|
|
|
|
|
|
if ( isMenu(super_menu) )
|
2016-06-12 23:06:58 +02:00
|
|
|
{
|
2017-09-11 03:06:02 +02:00
|
|
|
FMenu* smenu = static_cast<FMenu*>(super_menu);
|
2018-02-22 01:15:57 +01:00
|
|
|
passMouseEvent (smenu, ev, fc::MouseDoubleClick_Event);
|
2016-10-17 08:44:38 +02:00
|
|
|
}
|
2016-06-12 23:06:58 +02:00
|
|
|
|
2016-10-17 08:44:38 +02:00
|
|
|
if ( isMenuBar(super_menu) )
|
|
|
|
{
|
2017-09-11 03:06:02 +02:00
|
|
|
FMenuBar* mbar = static_cast<FMenuBar*>(super_menu);
|
2018-02-22 01:15:57 +01:00
|
|
|
passMouseEvent (mbar, ev, fc::MouseDoubleClick_Event);
|
2016-10-17 08:44:38 +02:00
|
|
|
}
|
2016-06-12 23:06:58 +02:00
|
|
|
|
2016-10-17 08:44:38 +02:00
|
|
|
if ( isWindowsMenu(super_menu) )
|
|
|
|
{
|
2017-09-11 03:06:02 +02:00
|
|
|
FDialog* dgl = static_cast<FDialog*>(super_menu);
|
2018-02-22 01:15:57 +01:00
|
|
|
passMouseEvent (dgl, ev, fc::MouseDoubleClick_Event);
|
2016-06-12 23:06:58 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-28 04:31:29 +02:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void FMenuItem::onMouseDown (FMouseEvent* ev)
|
|
|
|
{
|
2016-10-17 08:44:38 +02:00
|
|
|
if ( ! super_menu )
|
|
|
|
return;
|
|
|
|
|
|
|
|
if ( isMenu(super_menu) )
|
2015-09-30 22:39:02 +02:00
|
|
|
{
|
2017-09-11 03:06:02 +02:00
|
|
|
FMenu* smenu = static_cast<FMenu*>(super_menu);
|
2018-02-22 01:15:57 +01:00
|
|
|
passMouseEvent (smenu, ev, fc::MouseDown_Event);
|
2016-10-17 08:44:38 +02:00
|
|
|
}
|
2015-10-01 03:48:58 +02:00
|
|
|
|
2016-10-17 08:44:38 +02:00
|
|
|
if ( isMenuBar(super_menu) )
|
|
|
|
{
|
2017-09-11 03:06:02 +02:00
|
|
|
FMenuBar* mbar = static_cast<FMenuBar*>(super_menu);
|
2018-02-22 01:15:57 +01:00
|
|
|
passMouseEvent (mbar, ev, fc::MouseDown_Event);
|
2016-10-17 08:44:38 +02:00
|
|
|
}
|
2016-06-12 23:06:58 +02:00
|
|
|
|
2016-10-17 08:44:38 +02:00
|
|
|
if ( isWindowsMenu(super_menu) )
|
|
|
|
{
|
2017-09-11 03:06:02 +02:00
|
|
|
FDialog* dgl = static_cast<FDialog*>(super_menu);
|
2018-02-22 01:15:57 +01:00
|
|
|
passMouseEvent (dgl, ev, fc::MouseDown_Event);
|
2015-10-10 03:14:14 +02:00
|
|
|
}
|
2015-09-28 04:31:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void FMenuItem::onMouseUp (FMouseEvent* ev)
|
|
|
|
{
|
2016-10-17 08:44:38 +02:00
|
|
|
if ( ! super_menu )
|
|
|
|
return;
|
|
|
|
|
|
|
|
if ( isMenu(super_menu) )
|
2015-09-30 22:39:02 +02:00
|
|
|
{
|
2017-09-11 03:06:02 +02:00
|
|
|
FMenu* smenu = static_cast<FMenu*>(super_menu);
|
2018-02-22 01:15:57 +01:00
|
|
|
passMouseEvent (smenu, ev, fc::MouseUp_Event);
|
2016-10-17 08:44:38 +02:00
|
|
|
}
|
2015-10-01 03:48:58 +02:00
|
|
|
|
2016-10-17 08:44:38 +02:00
|
|
|
if ( isMenuBar(super_menu) )
|
|
|
|
{
|
2017-09-11 03:06:02 +02:00
|
|
|
FMenuBar* mbar = static_cast<FMenuBar*>(super_menu);
|
2018-02-22 01:15:57 +01:00
|
|
|
passMouseEvent (mbar, ev, fc::MouseUp_Event);
|
2016-10-17 08:44:38 +02:00
|
|
|
}
|
2016-06-12 23:06:58 +02:00
|
|
|
|
2016-10-17 08:44:38 +02:00
|
|
|
if ( isWindowsMenu(super_menu) )
|
|
|
|
{
|
2017-09-11 03:06:02 +02:00
|
|
|
FDialog* dgl = static_cast<FDialog*>(super_menu);
|
2018-02-22 01:15:57 +01:00
|
|
|
passMouseEvent (dgl, ev, fc::MouseUp_Event);
|
2015-10-10 03:14:14 +02:00
|
|
|
}
|
2015-09-28 04:31:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void FMenuItem::onMouseMove (FMouseEvent* ev)
|
|
|
|
{
|
2016-10-17 08:44:38 +02:00
|
|
|
if ( ! super_menu )
|
|
|
|
return;
|
|
|
|
|
|
|
|
if ( isMenu(super_menu) )
|
2015-09-30 22:39:02 +02:00
|
|
|
{
|
2017-09-11 03:06:02 +02:00
|
|
|
FMenu* smenu = static_cast<FMenu*>(super_menu);
|
2018-02-22 01:15:57 +01:00
|
|
|
passMouseEvent (smenu, ev, fc::MouseMove_Event);
|
2016-10-17 08:44:38 +02:00
|
|
|
}
|
2015-10-01 03:48:58 +02:00
|
|
|
|
2016-10-17 08:44:38 +02:00
|
|
|
if ( isMenuBar(super_menu) )
|
|
|
|
{
|
2017-09-11 03:06:02 +02:00
|
|
|
FMenuBar* mbar = static_cast<FMenuBar*>(super_menu);
|
2018-02-22 01:15:57 +01:00
|
|
|
passMouseEvent (mbar, ev, fc::MouseMove_Event);
|
2016-10-17 08:44:38 +02:00
|
|
|
}
|
2015-09-28 04:31:29 +02:00
|
|
|
|
2016-10-17 08:44:38 +02:00
|
|
|
if ( isWindowsMenu(super_menu) )
|
|
|
|
{
|
2017-09-11 03:06:02 +02:00
|
|
|
FDialog* dgl = static_cast<FDialog*>(super_menu);
|
2018-02-22 01:15:57 +01:00
|
|
|
passMouseEvent (dgl, ev, fc::MouseMove_Event);
|
2015-10-10 03:14:14 +02:00
|
|
|
}
|
2015-09-28 04:31:29 +02:00
|
|
|
}
|
|
|
|
|
2015-10-29 21:10:50 +01:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void FMenuItem::onAccel (FAccelEvent* ev)
|
|
|
|
{
|
2016-10-17 08:44:38 +02:00
|
|
|
if ( ! isEnabled() || isSelected() )
|
|
|
|
return;
|
|
|
|
|
|
|
|
if ( ! super_menu || ! isMenuBar(super_menu) )
|
2015-10-29 21:10:50 +01:00
|
|
|
{
|
2016-10-17 08:44:38 +02:00
|
|
|
processClicked();
|
|
|
|
return;
|
|
|
|
}
|
2016-07-09 00:01:59 +02:00
|
|
|
|
2017-09-11 03:06:02 +02:00
|
|
|
FMenuBar* mbar = static_cast<FMenuBar*>(super_menu);
|
2016-10-17 08:44:38 +02:00
|
|
|
|
|
|
|
if ( menu )
|
|
|
|
{
|
|
|
|
FWidget* focused_widget;
|
|
|
|
|
|
|
|
if ( mbar->getSelectedItem() )
|
|
|
|
mbar->getSelectedItem()->unsetSelected();
|
|
|
|
|
|
|
|
setSelected();
|
|
|
|
mbar->selected_item = this;
|
|
|
|
openMenu();
|
|
|
|
|
|
|
|
focused_widget = static_cast<FWidget*>(ev->focusedWidget());
|
|
|
|
|
2017-06-14 01:23:10 +02:00
|
|
|
if ( focused_widget && focused_widget->isWidget() )
|
2017-06-11 17:47:50 +02:00
|
|
|
{
|
|
|
|
FFocusEvent out (fc::FocusOut_Event);
|
|
|
|
FApplication::queueEvent(focused_widget, &out);
|
2017-08-24 22:58:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
menu->unselectItem();
|
|
|
|
menu->selectFirstItem();
|
2016-10-17 08:44:38 +02:00
|
|
|
|
2017-08-24 22:58:34 +02:00
|
|
|
if ( menu->getSelectedItem() )
|
|
|
|
menu->getSelectedItem()->setFocus();
|
2016-10-17 08:44:38 +02:00
|
|
|
|
2017-08-24 22:58:34 +02:00
|
|
|
if ( focused_widget && focused_widget->isWidget() )
|
2017-06-14 01:23:10 +02:00
|
|
|
focused_widget->redraw();
|
2016-10-17 08:44:38 +02:00
|
|
|
|
2017-08-24 22:58:34 +02:00
|
|
|
menu->redraw();
|
2017-06-11 17:47:50 +02:00
|
|
|
|
2017-08-24 22:58:34 +02:00
|
|
|
if ( getStatusBar() )
|
|
|
|
getStatusBar()->drawMessage();
|
|
|
|
|
|
|
|
mbar->redraw();
|
|
|
|
mbar->drop_down = true;
|
2016-10-17 08:44:38 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
unsetSelected();
|
2018-12-10 01:48:26 +01:00
|
|
|
mbar->selected_item = nullptr;
|
2016-10-17 08:44:38 +02:00
|
|
|
mbar->redraw();
|
|
|
|
processClicked();
|
|
|
|
mbar->drop_down = false;
|
2015-10-29 21:10:50 +01:00
|
|
|
}
|
2017-09-19 06:18:03 +02:00
|
|
|
|
2016-10-17 08:44:38 +02:00
|
|
|
ev->accept();
|
2015-10-29 21:10:50 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void FMenuItem::onFocusIn (FFocusEvent*)
|
|
|
|
{
|
2016-11-02 00:37:58 +01:00
|
|
|
if ( getStatusBar() )
|
|
|
|
getStatusBar()->drawMessage();
|
2015-10-29 21:10:50 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void FMenuItem::onFocusOut (FFocusEvent*)
|
|
|
|
{
|
2015-11-05 23:25:21 +01:00
|
|
|
unsetSelected();
|
2016-07-09 00:01:59 +02:00
|
|
|
|
2015-11-05 23:25:21 +01:00
|
|
|
if ( super_menu && isMenuBar(super_menu) )
|
|
|
|
{
|
2017-09-11 03:06:02 +02:00
|
|
|
FMenuBar* mbar = static_cast<FMenuBar*>(super_menu);
|
2017-09-19 06:18:03 +02:00
|
|
|
mbar->redraw();
|
2015-11-05 23:25:21 +01:00
|
|
|
}
|
2016-07-09 00:01:59 +02:00
|
|
|
|
2016-11-02 00:37:58 +01:00
|
|
|
if ( getStatusBar() )
|
2015-10-29 21:10:50 +01:00
|
|
|
{
|
2016-11-02 00:37:58 +01:00
|
|
|
getStatusBar()->clearMessage();
|
|
|
|
getStatusBar()->drawMessage();
|
2015-10-29 21:10:50 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-02 00:37:58 +01:00
|
|
|
|
|
|
|
// protected methods of FMenuItem
|
2015-10-29 21:10:50 +01:00
|
|
|
//----------------------------------------------------------------------
|
2016-11-02 00:37:58 +01:00
|
|
|
bool FMenuItem::isWindowsMenu (FWidget* w) const
|
2015-10-29 21:10:50 +01:00
|
|
|
{
|
2017-07-23 01:19:59 +02:00
|
|
|
return ( w ) ? w->isDialogWidget() : false;
|
2016-11-02 00:37:58 +01:00
|
|
|
}
|
2015-10-29 21:10:50 +01:00
|
|
|
|
2016-11-02 00:37:58 +01:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
bool FMenuItem::isMenuBar (FWidget* w) const
|
|
|
|
{
|
2017-07-23 01:19:59 +02:00
|
|
|
return ( w ) ? w->isInstanceOf("FMenuBar") : false;
|
2016-11-02 00:37:58 +01:00
|
|
|
}
|
2015-10-29 21:10:50 +01:00
|
|
|
|
2016-11-02 00:37:58 +01:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
bool FMenuItem::isMenu (FWidget* w) const
|
|
|
|
{
|
|
|
|
if ( ! w )
|
|
|
|
return false;
|
2016-07-09 00:01:59 +02:00
|
|
|
|
2017-07-23 01:19:59 +02:00
|
|
|
bool m1 = w->isInstanceOf("FMenu");
|
|
|
|
bool m2 = w->isInstanceOf("FDialogListMenu");
|
2016-11-02 00:37:58 +01:00
|
|
|
return bool( m1 || m2 );
|
2015-10-29 21:10:50 +01:00
|
|
|
}
|
|
|
|
|
2016-11-02 00:37:58 +01:00
|
|
|
|
|
|
|
// private methods of FMenuItem
|
2018-10-13 00:32:14 +02:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
FMenuList* FMenuItem::getFMenuList (FWidget& widget)
|
|
|
|
{
|
|
|
|
FMenuList* menu_list;
|
|
|
|
|
|
|
|
if ( isMenu(&widget) )
|
|
|
|
{
|
2018-10-14 06:25:33 +02:00
|
|
|
FMenu* Menu = static_cast<FMenu*>(&widget);
|
|
|
|
menu_list = static_cast<FMenuList*>(Menu);
|
2018-10-13 00:32:14 +02:00
|
|
|
}
|
|
|
|
else if ( isMenuBar(&widget) )
|
|
|
|
{
|
2018-10-14 06:25:33 +02:00
|
|
|
FMenuBar* Menubar = static_cast<FMenuBar*>(&widget);
|
|
|
|
menu_list = static_cast<FMenuList*>(Menubar);
|
2018-10-13 00:32:14 +02:00
|
|
|
}
|
|
|
|
else
|
2018-12-10 01:48:26 +01:00
|
|
|
menu_list = nullptr;
|
2018-10-13 00:32:14 +02:00
|
|
|
|
|
|
|
return menu_list;
|
|
|
|
}
|
|
|
|
|
2015-10-29 21:10:50 +01:00
|
|
|
//----------------------------------------------------------------------
|
2016-11-02 00:37:58 +01:00
|
|
|
void FMenuItem::init (FWidget* parent)
|
2015-10-29 21:10:50 +01:00
|
|
|
{
|
2016-11-02 00:37:58 +01:00
|
|
|
text_length = text.getLength();
|
|
|
|
hotkey = hotKey();
|
2015-10-29 21:10:50 +01:00
|
|
|
|
2016-11-02 00:37:58 +01:00
|
|
|
if ( hotkey )
|
|
|
|
text_length--;
|
2016-07-09 00:01:59 +02:00
|
|
|
|
2018-10-14 06:25:33 +02:00
|
|
|
setGeometry (1, 1, text_length + 2, 1, false);
|
2015-11-07 23:16:09 +01:00
|
|
|
|
2017-09-19 06:18:03 +02:00
|
|
|
if ( ! parent )
|
|
|
|
return;
|
2016-07-09 00:01:59 +02:00
|
|
|
|
2017-09-19 06:18:03 +02:00
|
|
|
setSuperMenu (parent);
|
2016-07-09 00:01:59 +02:00
|
|
|
|
2018-11-21 20:07:08 +01:00
|
|
|
if ( accel_key )
|
2017-09-19 06:18:03 +02:00
|
|
|
addAccelerator (accel_key);
|
2016-07-09 00:01:59 +02:00
|
|
|
|
2018-10-13 00:32:14 +02:00
|
|
|
FMenuList* menu_list = getFMenuList(*parent);
|
2015-11-12 23:14:12 +01:00
|
|
|
|
2017-09-19 06:18:03 +02:00
|
|
|
if ( menu_list )
|
|
|
|
menu_list->insert(this);
|
2016-07-09 00:01:59 +02:00
|
|
|
|
2017-09-19 06:18:03 +02:00
|
|
|
if ( isMenuBar(parent) ) // Parent is menubar
|
|
|
|
{
|
|
|
|
FMenuBar* menubar_ptr = static_cast<FMenuBar*>(parent);
|
|
|
|
menubar_ptr->calculateDimensions();
|
2016-11-02 00:37:58 +01:00
|
|
|
|
2017-09-19 06:18:03 +02:00
|
|
|
if ( hotkey ) // Meta + hotkey
|
2018-11-21 20:07:08 +01:00
|
|
|
menubar_ptr->addAccelerator ( fc::Fmkey_meta + FKey(std::tolower(hotkey))
|
2017-09-19 06:18:03 +02:00
|
|
|
, this );
|
2015-10-29 21:10:50 +01:00
|
|
|
|
2017-09-19 06:18:03 +02:00
|
|
|
addCallback // for this element
|
|
|
|
(
|
|
|
|
"deactivate",
|
|
|
|
F_METHOD_CALLBACK (parent, &FMenuBar::cb_item_deactivated)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
else if ( isMenu(parent) ) // Parent is menu
|
|
|
|
{
|
|
|
|
FMenu* menu_ptr = static_cast<FMenu*>(parent);
|
|
|
|
menu_ptr->calculateDimensions();
|
2015-10-29 21:10:50 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-08-09 23:47:08 +02:00
|
|
|
//----------------------------------------------------------------------
|
2016-11-02 00:37:58 +01:00
|
|
|
uChar FMenuItem::hotKey()
|
2015-08-09 23:47:08 +02:00
|
|
|
{
|
2018-10-14 06:25:33 +02:00
|
|
|
std::size_t length;
|
2016-11-02 00:37:58 +01:00
|
|
|
|
|
|
|
if ( text.isEmpty() )
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
length = text.getLength();
|
|
|
|
|
2018-10-14 06:25:33 +02:00
|
|
|
for (std::size_t i = 0; i < length; i++)
|
2015-08-22 18:53:52 +02:00
|
|
|
{
|
2016-11-02 00:37:58 +01:00
|
|
|
try
|
|
|
|
{
|
2017-08-27 09:50:30 +02:00
|
|
|
if ( i + 1 < length && text[i] == '&' )
|
2016-11-02 00:37:58 +01:00
|
|
|
return uChar(text[++i]);
|
|
|
|
}
|
|
|
|
catch (const std::out_of_range&)
|
|
|
|
{
|
2017-08-27 09:50:30 +02:00
|
|
|
return 0;
|
2016-11-02 00:37:58 +01:00
|
|
|
}
|
2015-08-22 18:53:52 +02:00
|
|
|
}
|
2016-11-02 00:37:58 +01:00
|
|
|
|
|
|
|
return 0;
|
2015-08-09 23:47:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
2016-11-02 00:37:58 +01:00
|
|
|
void FMenuItem::processActivate()
|
2015-09-30 22:39:02 +02:00
|
|
|
{
|
2016-11-02 00:37:58 +01:00
|
|
|
emitCallback("activate");
|
2015-09-30 22:39:02 +02:00
|
|
|
}
|
|
|
|
|
2015-11-05 23:25:21 +01:00
|
|
|
//----------------------------------------------------------------------
|
2016-11-02 00:37:58 +01:00
|
|
|
void FMenuItem::processDeactivate()
|
2015-11-05 23:25:21 +01:00
|
|
|
{
|
2016-11-02 00:37:58 +01:00
|
|
|
emitCallback("deactivate");
|
|
|
|
}
|
2015-11-05 23:25:21 +01:00
|
|
|
|
2016-11-02 00:37:58 +01:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void FMenuItem::createDialogList (FMenu* winmenu)
|
|
|
|
{
|
|
|
|
winmenu->clear();
|
2015-11-12 23:14:12 +01:00
|
|
|
|
2016-11-02 00:37:58 +01:00
|
|
|
if ( dialog_list && ! dialog_list->empty() )
|
|
|
|
{
|
2017-09-17 01:50:41 +02:00
|
|
|
widgetList::const_iterator iter, first;
|
|
|
|
iter = first = dialog_list->begin();
|
2016-07-09 00:01:59 +02:00
|
|
|
|
2016-11-02 00:37:58 +01:00
|
|
|
while ( iter != dialog_list->end() && *iter )
|
|
|
|
{
|
2017-09-11 03:06:02 +02:00
|
|
|
FDialog* win = static_cast<FDialog*>(*iter);
|
2016-07-09 00:01:59 +02:00
|
|
|
|
2016-11-02 00:37:58 +01:00
|
|
|
if ( win )
|
|
|
|
{
|
2017-08-12 22:55:29 +02:00
|
|
|
FMenuItem* win_item;
|
2018-11-21 20:07:08 +01:00
|
|
|
uInt32 n = uInt32(std::distance(first, iter));
|
2016-11-02 00:37:58 +01:00
|
|
|
// get the dialog title
|
2017-03-26 20:40:04 +02:00
|
|
|
const FString& name = win->getText();
|
2017-08-12 22:55:29 +02:00
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
// create a new dialog list item
|
|
|
|
win_item = new FMenuItem (name, winmenu);
|
|
|
|
}
|
|
|
|
catch (const std::bad_alloc& ex)
|
|
|
|
{
|
2018-11-22 21:51:32 +01:00
|
|
|
std::cerr << bad_alloc_str << ex.what() << std::endl;
|
2017-08-12 23:11:21 +02:00
|
|
|
return;
|
2017-08-12 22:55:29 +02:00
|
|
|
}
|
2015-11-24 23:40:41 +01:00
|
|
|
|
2016-11-02 00:37:58 +01:00
|
|
|
if ( n < 9 )
|
2017-09-11 03:06:02 +02:00
|
|
|
win_item->addAccelerator (fc::Fmkey_1 + n); // Meta + 1..9
|
2016-10-11 04:57:36 +02:00
|
|
|
|
2016-11-02 00:37:58 +01:00
|
|
|
win_item->addCallback
|
|
|
|
(
|
|
|
|
"clicked",
|
2017-04-09 20:08:53 +02:00
|
|
|
F_METHOD_CALLBACK (win_item, &FMenuItem::cb_switchToDialog),
|
2017-09-11 03:06:02 +02:00
|
|
|
static_cast<FWidget::data_ptr>(win)
|
2016-11-02 00:37:58 +01:00
|
|
|
);
|
2016-10-11 04:57:36 +02:00
|
|
|
|
2016-11-02 00:37:58 +01:00
|
|
|
win->addCallback
|
|
|
|
(
|
|
|
|
"destroy",
|
2017-04-09 20:08:53 +02:00
|
|
|
F_METHOD_CALLBACK (win_item, &FMenuItem::cb_destroyDialog)
|
2016-11-02 00:37:58 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
win_item->associated_window = win;
|
|
|
|
}
|
|
|
|
|
|
|
|
++iter;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
winmenu->calculateDimensions();
|
2015-11-05 23:25:21 +01:00
|
|
|
}
|
|
|
|
|
2018-02-22 01:15:57 +01:00
|
|
|
//----------------------------------------------------------------------
|
2018-10-20 22:50:35 +02:00
|
|
|
template <typename T>
|
2018-02-22 01:15:57 +01:00
|
|
|
void FMenuItem::passMouseEvent ( T widget, FMouseEvent* ev
|
|
|
|
, fc::events ev_type )
|
|
|
|
{
|
|
|
|
if ( ! widget )
|
|
|
|
return;
|
|
|
|
|
|
|
|
FMouseEvent* _ev;
|
|
|
|
const FPoint& t = ev->getTermPos();
|
|
|
|
const FPoint& p2 = widget->termToWidgetPos(t);
|
|
|
|
int b = ev->getButton();
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
_ev = new FMouseEvent (ev_type, p2, t, b);
|
|
|
|
}
|
|
|
|
catch (const std::bad_alloc& ex)
|
|
|
|
{
|
2018-11-22 21:51:32 +01:00
|
|
|
std::cerr << bad_alloc_str << ex.what() << std::endl;
|
2018-02-22 01:15:57 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch ( int(ev_type) )
|
|
|
|
{
|
|
|
|
case fc::MouseDoubleClick_Event:
|
|
|
|
widget->onMouseDoubleClick(_ev);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case fc::MouseDown_Event:
|
|
|
|
widget->onMouseDown(_ev);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case fc::MouseUp_Event:
|
|
|
|
widget->onMouseUp(_ev);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case fc::MouseMove_Event:
|
|
|
|
widget->onMouseMove(_ev);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
delete _ev;
|
|
|
|
}
|
|
|
|
|
2015-09-30 22:39:02 +02:00
|
|
|
//----------------------------------------------------------------------
|
2017-02-24 00:30:07 +01:00
|
|
|
void FMenuItem::cb_switchToDialog (FWidget*, data_ptr data)
|
2015-08-09 23:47:08 +02:00
|
|
|
{
|
2017-02-24 00:30:07 +01:00
|
|
|
FDialog* win = static_cast<FDialog*>(data);
|
2016-07-09 00:01:59 +02:00
|
|
|
|
2016-11-02 00:37:58 +01:00
|
|
|
if ( win )
|
|
|
|
{
|
2018-12-01 21:28:25 +01:00
|
|
|
FWidget* focus = getFocusWidget();
|
|
|
|
FAccelEvent a_ev (fc::Accelerator_Event, focus);
|
2016-11-02 00:37:58 +01:00
|
|
|
FApplication::sendEvent (win, &a_ev);
|
|
|
|
}
|
2015-08-09 23:47:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
2017-02-24 00:30:07 +01:00
|
|
|
void FMenuItem::cb_destroyDialog (FWidget* widget, data_ptr)
|
2015-08-09 23:47:08 +02:00
|
|
|
{
|
2016-11-02 00:37:58 +01:00
|
|
|
FDialog* win = static_cast<FDialog*>(widget);
|
|
|
|
FApplication* fapp = static_cast<FApplication*>(getRootWidget());
|
|
|
|
|
|
|
|
if ( win && fapp )
|
|
|
|
{
|
|
|
|
delAccelerator(win);
|
|
|
|
delCallback(win);
|
2018-12-10 01:48:26 +01:00
|
|
|
associated_window = nullptr;
|
2016-11-02 00:37:58 +01:00
|
|
|
}
|
2015-08-16 20:05:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
2016-11-02 00:37:58 +01:00
|
|
|
void FMenuItem::processClicked()
|
2015-08-16 20:05:39 +02:00
|
|
|
{
|
2016-11-02 00:37:58 +01:00
|
|
|
emitCallback("clicked");
|
2015-08-09 23:47:08 +02:00
|
|
|
}
|
2018-09-20 23:59:01 +02:00
|
|
|
|
|
|
|
} // namespace finalcut
|