Fl_Sys_Menu_Bar: make it strict equivalent of Fl_Menu_Bar outside macOS

This commit is contained in:
ManoloFLTK 2020-02-28 16:47:44 +01:00
parent e18de6ff03
commit 87c994e2f8
4 changed files with 65 additions and 37 deletions

View File

@ -29,15 +29,20 @@
class Fl_Sys_Menu_Bar_Driver;
/**
A class to create and modify menus that appear on Mac OS X in the menu bar at the top of the screen.
To use this class, just replace Fl_Menu_Bar with Fl_Sys_Menu_Bar, and on the Mac platform
A class to create and modify menus that appear on macOS in the menu bar at the top of the screen.
On other than macOS platforms, Fl_Sys_Menu_Bar is a synonym of class Fl_Menu_Bar.
On the macOS platform, replace Fl_Menu_Bar with Fl_Sys_Menu_Bar, and
a system menu at the top of the screen will be available. This menu will match an array
of Fl_Menu_Item's exactly as in all other FLTK menus (except for the submenu with the
application's own name; see below).
application's own name and the 'Window' menu; see below). There is, though, an important difference between
an Fl_Sys_Menu_Bar object under macOS and under other platforms: only a single object
from this class can be created, because macOS uses a single system menu bar. Therefore,
porting to macOS an app that creates, on other platforms, several Fl_Menu_Bar objects, one for each of several windows,
is more complex that just replacing Fl_Menu_Bar by Fl_Sys_Menu_Bar.
On other than Mac OS X platforms, Fl_Sys_Menu_Bar is a synonym of class Fl_Menu_Bar.
On the MacOS platform, the system menu bar of any FLTK app begins with the Application
On the macOS platform, the system menu bar of any FLTK app begins with the Application
menu which the FLTK library automatically constructs. Functions
Fl_Mac_App_Menu::custom_application_menu_items() and Fl_Sys_Menu_Bar::about() can be used to further customize
the Application menu. The FLTK library also automatically constructs and handles a Window menu which can be
@ -50,7 +55,7 @@ class Fl_Sys_Menu_Bar_Driver;
Changes to the menu state are immediately visible in the menubar when they are made
using member functions of the Fl_Sys_Menu_Bar class. Other changes (e.g., by a call to
Fl_Menu_Item::set()) should be followed by a call to update() to be
visible in the menubar across all platforms. Global variable \ref fl_sys_menu_bar points to
visible in the menubar across all platforms. macOS global variable \ref fl_sys_menu_bar points to
the unique, current system menu bar.
A few FLTK menu features are not supported by the Mac System menu:
@ -90,6 +95,7 @@ class Fl_Sys_Menu_Bar_Driver;
*/
class FL_EXPORT Fl_Sys_Menu_Bar : public Fl_Menu_Bar {
static Fl_Sys_Menu_Bar_Driver *driver();
protected:
virtual void draw();
public:
@ -102,7 +108,6 @@ public:
} window_menu_style_enum;
Fl_Sys_Menu_Bar(int x,int y,int w,int h,const char *l=0);
virtual ~Fl_Sys_Menu_Bar();
static Fl_Sys_Menu_Bar_Driver *driver();
/** Return the system menu's array of Fl_Menu_Item's
*/
const Fl_Menu_Item *menu() const {return Fl_Menu_::menu();}

View File

@ -43,6 +43,10 @@ static void move_tab_cb(Fl_Widget *, void *data);
static void merge_all_windows_cb(Fl_Widget *, void *data);
#endif
Fl_Sys_Menu_Bar_Driver *Fl_Sys_Menu_Bar::driver() {
return Fl_MacOS_Sys_Menu_Bar_Driver::driver();
}
void Fl_MacOS_Sys_Menu_Bar_Driver::draw() {
bar->deactivate(); // prevent Fl_Sys_Menu_Bar object from receiving events

View File

@ -17,6 +17,7 @@
//
#include "config_lib.h"
#include "Fl_Sys_Menu_Bar_Driver.H"
#include <FL/platform.H>
@ -30,20 +31,24 @@ Fl_Sys_Menu_Bar *fl_sys_menu_bar = 0;
Fl_Sys_Menu_Bar::Fl_Sys_Menu_Bar(int x,int y,int w,int h,const char *l)
: Fl_Menu_Bar(x,y,w,h,l)
{
if (fl_sys_menu_bar) delete fl_sys_menu_bar;
fl_sys_menu_bar = this;
driver()->bar = this;
if (driver()) {
if (fl_sys_menu_bar) delete fl_sys_menu_bar;
fl_sys_menu_bar = this;
driver()->bar = this;
}
}
/** The destructor */
Fl_Sys_Menu_Bar::~Fl_Sys_Menu_Bar()
{
fl_sys_menu_bar = 0;
clear();
if (driver()) {
fl_sys_menu_bar = 0;
clear();
}
}
void Fl_Sys_Menu_Bar::update() {
driver()->update();
if (driver()) driver()->update();
}
/**
@ -55,24 +60,29 @@ void Fl_Sys_Menu_Bar::update() {
*/
void Fl_Sys_Menu_Bar::menu(const Fl_Menu_Item *m)
{
driver()->menu(m);
if (driver()) driver()->menu(m);
else Fl_Menu_Bar::menu(m);
}
/** Changes the shortcut of item i to n.
*/
void Fl_Sys_Menu_Bar::shortcut (int i, int s) {
driver()->shortcut(i, s);
if (driver()) driver()->shortcut(i, s);
else Fl_Menu_Bar::shortcut(i, s);
}
/** Turns the radio item "on" for the menu item and turns "off" adjacent radio items of the same group.*/
void Fl_Sys_Menu_Bar::setonly (Fl_Menu_Item *item) {
driver()->setonly(item);
if (driver()) driver()->setonly(item);
else Fl_Menu_Bar::setonly(item);
}
/** Sets the flags of item i
\see Fl_Menu_::mode(int i, int fl) */
void Fl_Sys_Menu_Bar::mode (int i, int fl) {
driver()->mode(i, fl);
if (driver()) driver()->mode(i, fl);
else Fl_Menu_Bar::mode(i, fl);
}
/**
@ -93,7 +103,8 @@ void Fl_Sys_Menu_Bar::mode (int i, int fl) {
*/
int Fl_Sys_Menu_Bar::add(const char* label, int shortcut, Fl_Callback *cb, void *user_data, int flags)
{
return driver()->add(label, shortcut, cb, user_data, flags);
if (driver()) return driver()->add(label, shortcut, cb, user_data, flags);
else return Fl_Menu_Bar::add(label, shortcut, cb, user_data, flags);
}
/**
@ -104,7 +115,7 @@ int Fl_Sys_Menu_Bar::add(const char* label, int shortcut, Fl_Callback *cb, void
*/
int Fl_Sys_Menu_Bar::add(const char* str)
{
return driver()->add(str);
return driver() ? driver()->add(str) : Fl_Menu_Bar::add(str);
}
/**
@ -118,7 +129,8 @@ int Fl_Sys_Menu_Bar::add(const char* str)
*/
int Fl_Sys_Menu_Bar::insert(int index, const char* label, int shortcut, Fl_Callback *cb, void *user_data, int flags)
{
return driver()->insert(index, label, shortcut, cb, user_data, flags);
return driver() ? driver()->insert(index, label, shortcut, cb, user_data, flags) :
Fl_Menu_Bar::insert(index, label, shortcut, cb, user_data, flags);
}
/** Set the Fl_Menu_Item array pointer to null, indicating a zero-length menu.
@ -126,7 +138,8 @@ int Fl_Sys_Menu_Bar::insert(int index, const char* label, int shortcut, Fl_Callb
*/
void Fl_Sys_Menu_Bar::clear()
{
driver()->clear();
if (driver()) driver()->clear();
else Fl_Menu_Bar::clear();
}
/** Clears the specified submenu pointed to by index of all menu items.
@ -134,7 +147,7 @@ void Fl_Sys_Menu_Bar::clear()
*/
int Fl_Sys_Menu_Bar::clear_submenu(int index)
{
return driver()->clear_submenu(index);
return driver() ? driver()->clear_submenu(index) : Fl_Menu_Bar::clear_submenu(index);
}
/**
@ -144,7 +157,8 @@ int Fl_Sys_Menu_Bar::clear_submenu(int index)
*/
void Fl_Sys_Menu_Bar::remove(int index)
{
driver()->remove(index);
if (driver()) driver()->remove(index);
else Fl_Menu_Bar::remove(index);
}
/**
@ -155,7 +169,8 @@ void Fl_Sys_Menu_Bar::remove(int index)
*/
void Fl_Sys_Menu_Bar::replace(int index, const char *name)
{
driver()->replace(index, name);
if (driver()) driver()->replace(index, name);
else Fl_Menu_Bar::replace(index, name);
}
/**
@ -166,19 +181,22 @@ void Fl_Sys_Menu_Bar::replace(int index, const char *name)
\param data a pointer transmitted as 2nd argument to the callback.
*/
void Fl_Sys_Menu_Bar::about(Fl_Callback *cb, void *data) {
fl_open_display(); // create the system menu, if needed
driver()->about(cb, data);
if (driver()) {
fl_open_display(); // create the system menu, if needed
driver()->about(cb, data);
}
}
void Fl_Sys_Menu_Bar::draw() {
driver()->draw();
if (driver()) driver()->draw();
else Fl_Menu_Bar::draw();
}
/** Get the style of the Window menu in the system menu bar */
Fl_Sys_Menu_Bar::window_menu_style_enum Fl_Sys_Menu_Bar::window_menu_style() {
return Fl_Sys_Menu_Bar_Driver::window_menu_style();
return driver() ? Fl_Sys_Menu_Bar_Driver::window_menu_style() : no_window_menu;
}
/** Set the desired style of the Window menu in the system menu bar.
@ -199,7 +217,7 @@ Fl_Sys_Menu_Bar::window_menu_style_enum Fl_Sys_Menu_Bar::window_menu_style() {
\version 1.4
*/
void Fl_Sys_Menu_Bar::window_menu_style(Fl_Sys_Menu_Bar::window_menu_style_enum style) {
Fl_Sys_Menu_Bar_Driver::window_menu_style(style);
if (driver()) Fl_Sys_Menu_Bar_Driver::window_menu_style(style);
}
/** Adds a Window menu, to the end of the system menu bar.
@ -215,17 +233,18 @@ void Fl_Sys_Menu_Bar::window_menu_style(Fl_Sys_Menu_Bar::window_menu_style_enum
\version 1.4
*/
void Fl_Sys_Menu_Bar::create_window_menu() {
fl_open_display();
driver()->create_window_menu();
if (driver()) {
fl_open_display();
fl_sys_menu_bar->driver()->create_window_menu();
}
}
#if !defined(FL_DOXYGEN)
#if ! defined(FL_CFG_WIN_COCOA)
Fl_Sys_Menu_Bar_Driver *Fl_Sys_Menu_Bar::driver() {
if (!Fl_Sys_Menu_Bar_Driver::driver_) { // initialize this static variable if it was not initialized previously
Fl_Sys_Menu_Bar_Driver::driver_ = new Fl_Sys_Menu_Bar_Driver();
}
return Fl_Sys_Menu_Bar_Driver::driver_;
return NULL;
}
#endif // !FL_CFG_WIN_COCOA
Fl_Sys_Menu_Bar_Driver *Fl_Sys_Menu_Bar_Driver::driver_ = 0;

View File

@ -2930,7 +2930,7 @@ Fl_X* Fl_Cocoa_Window_Driver::makeWindow()
fl_open_display();
NSInteger winlevel = NSNormalWindowLevel;
NSUInteger winstyle;
Fl_Sys_Menu_Bar::driver()->create_window_menu(); // effective once at most
Fl_Sys_Menu_Bar::create_window_menu(); // effective once at most
Fl_Window* w = pWindow;
if (w->parent()) {
w->border(0);