fltk_utils.hpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:14k
- /*
* ===========================================================================
* PRODUCTION $Log: fltk_utils.hpp,v $
* PRODUCTION Revision 1000.4 2004/06/01 19:51:09 gouriano
* PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.34
* PRODUCTION
* ===========================================================================
*/
#ifndef GUI_UTILS___FLTK_UTILS__HPP
#define GUI_UTILS___FLTK_UTILS__HPP
/* $Id: fltk_utils.hpp,v 1000.4 2004/06/01 19:51:09 gouriano Exp $
* ===========================================================================
*
* PUBLIC DOMAIN NOTICE
* National Center for Biotechnology Information
*
* This software/database is a "United States Government Work" under the
* terms of the United States Copyright Act. It was written as part of
* the author's official duties as a United States Government employee and
* thus cannot be copyrighted. This software/database is freely available
* to the public for use. The National Library of Medicine and the U.S.
* Government have not placed any restriction on its use or reproduction.
*
* Although all reasonable efforts have been taken to ensure the accuracy
* and reliability of the software and data, the NLM and the U.S.
* Government do not and cannot warrant the performance or results that
* may be obtained by using this software or data. The NLM and the U.S.
* Government disclaim all warranties, express or implied, including
* warranties of performance, merchantability or fitness for any particular
* purpose.
*
* Please cite the author in any work or product based on this material.
*
* ===========================================================================
*
* Authors: Mike DiCuccio
*
* File Description:
* Generic FLTK utilites.
*/
#include <corelib/ncbiobj.hpp>
#include <FL/Fl.H>
#include <FL/Fl_Menu_.H>
#include <map>
#include <vector>
#include <set>
#include <gui/utils/gui_event.hpp> // temp. for backward compatibility
BEGIN_NCBI_SCOPE
/** @addtogroup GUI_UTILS
*
* @{
*/
class NCBI_GUIUTILS_EXPORT CFltkUtils
{
public:
// enums for NCBI-specific box types
enum EBoxType {
eBox_RightEdge = FL_FREE_BOXTYPE
};
// perform all FLTK-specific initialization
static void Init(int argc, char** argv);
// wrappers for FLTK's thread locking mechanism. FLTK unfortunately
// doesn't include stub functions of Fl::lock() and Fl::unlock() in
// non-threaded compiles, so this is needed to work around this.
static void Lock(void);
// Unlock() takes an optional void* that will be made available to each
// thread after Fl::awake() is called.
static void Unlock(void* data = NULL);
// wrapper for setting the FLTK cursor. We need to do this because FLTK
// does not provide any way to retrieve what the current cursor is.
static void SetCursor(Fl_Cursor cursor);
static Fl_Cursor GetCursor(void);
// Escape fltk special characters: , @, &
static string EscapeSpecialChars(const string& src);
- private:
static Fl_Cursor m_CurrentCursor;
};
//
// class CFltkMenuMgrBase defines base class functionality for handling dynamic
// menus.
//
// GBENCH supports dynamically-loaded menus. These menus are designed so that
// a list of applicable plugins can be generated and iterated, with each plugin
// being added to the dynamic menu. We need a menu manager to maintain state
// and a few additional pieces of data associated with each menu item. FLTK
// provides one unique and one menu-common pieces of user-defined data. For
// our purposes, we need two unique pieces of data for each menu item. This
// class maintains pairs of unique items so that menu callbacks can be
// correctly followed.
//
// The requirement for this template is that class Object be a completely
// self-contained object that supports the function Object::Run()
//
template <class Object>
class CFltkMenuMgrBase
{
public:
CFltkMenuMgrBase(Fl_Menu_* menu)
: m_Menu(menu) { }
virtual ~CFltkMenuMgrBase();
// Set the base menu text. This is the fully-resolved name of the menu
// originating from the root menu. Submenus are distinguished via a '/'; a
// '&' can be placed before the letter of the menu shortcut.
void SetMenuBase(const string& base) { m_Base = base; }
protected:
// the FLTK menu itself
Fl_Menu_* m_Menu;
// The menu base item
string m_Base;
// Our list of callback data. The callback is passed the address of the
// object in question.
typedef vector< CRef<Object> > TCallbackData;
typedef void (*FCallbackFunc)(Fl_Widget*, void*);
TCallbackData m_Data;
// Our static menu callback function
static void x_StaticCB(Fl_Widget*, void* data);
// Add a menu item to the base.
virtual void x_AddItem(const string& item, Object* plugin,
FCallbackFunc = &x_StaticCB);
// Clear all items from the data array.
void x_ClearData();
// Add a NULL item to the menu. The item will be deactivated; the null
// item text is passed in.
void x_AddNullItem(const string& item);
// utility function to remove the children of a given fully-qualified
// submenu name. Submenus are indicated with a '/'
void x_RemoveSubitems(const string& menu);
};
//
// class CFltkGuard is a simple exception-safe guard wrapper for
// FLTK's GUI locking mechanism
//
class CFltkGuard
{
public:
CFltkGuard(Fl_Widget* w = NULL)
: m_Widget(w)
{
CFltkUtils::Lock();
}
~CFltkGuard()
{
CFltkUtils::Unlock(m_Widget);
}
private:
Fl_Widget* m_Widget;
CFltkGuard(const CFltkGuard&);
CFltkGuard& operator=(const CFltkGuard&);
};
//
// class CFltkCursorGuard implements a guard paradigm for changing
// and restoring the current cursor.
//
// Please note that this contains a CFltkGuard internally, so there is no
// need to use CFltkGuard in conjunction with this.
//
class NCBI_GUIUTILS_EXPORT CFltkCursorGuard
{
public:
CFltkCursorGuard(Fl_Cursor cursor = FL_CURSOR_WAIT);
~CFltkCursorGuard();
private:
CFltkGuard m_Guard;
// for restoring the cursor
Fl_Cursor m_OrigCursor;
Fl_Window* m_CursorWindow;
};
//////////////////////////////////////////////////////////////////////////
// Inline Methods
//////////////////////////////////////////////////////////////////////////
template <class Object>
inline
CFltkMenuMgrBase<Object>::~CFltkMenuMgrBase()
{
x_ClearData();
}
//
// x_AddItem()
// private function to add an item to a given menu
//
template <class Object>
inline
void CFltkMenuMgrBase<Object>::x_AddItem(const string& item,
Object* plugin,
FCallbackFunc callback)
{
if ( !m_Menu ) {
return;
}
// save our callback data
m_Data.push_back( CRef<Object> (plugin));
// create a new menu item
m_Menu->add(item.c_str(), (const char*) NULL,
(Fl_Callback*) callback,
reinterpret_cast<void*> (plugin));
}
//
// x_Clear()
// clear the contents of our menu base
//
template <class Object>
inline
void CFltkMenuMgrBase<Object>::x_ClearData(void)
{
// clear our callback data array
m_Data.clear();
}
//
// x_AddNullItem()
// add an emtpy (deactivated) entry to a menu
//
template <class Object>
inline
void CFltkMenuMgrBase<Object>::x_AddNullItem(const string& text)
{
if ( !m_Menu ) {
return;
}
m_Menu->add(text.c_str(), 0, NULL, NULL, FL_MENU_INACTIVE);
}
//
// x_RemoveItem()
// removes the children of a given submenu
//
template <class Object>
inline
void CFltkMenuMgrBase<Object>::x_RemoveSubitems(const string& menu)
{
string menu_stripped(menu);
SIZE_TYPE pos;
while ( (pos = menu_stripped.find_first_of("&")) != string::npos) {
menu_stripped.erase(pos, 1);
}
// exception: menu_stripped is empty; we just remove the whole thing
if (menu_stripped.empty()) {
m_Menu->clear();
return;
}
// scan through our menu to find our entry
string curr_menu;
for (int i = 0; i < m_Menu->size(); ++i) {
const char* p = m_Menu->text(i);
// NULL entry = go up one level in the menu
if ( !p ) {
SIZE_TYPE pos = curr_menu.find_last_of("/");
if (pos != string::npos) {
curr_menu.erase(pos);
} else {
curr_menu = "";
}
continue;
}
// non-null entry
// see if we're a submenu
const Fl_Menu_Item& item = m_Menu->menu()[i];
string s = p;
if ( !curr_menu.empty() ) {
s = curr_menu + "/" + s;
}
while ( (pos = s.find_first_of("&")) != string::npos) {
s.erase(pos, 1);
}
if (item.flags & FL_SUBMENU) {
curr_menu = s;
}
if (menu_stripped == s) {
// found it!
// here we just iterate until we count balanced NULLs
++i;
int submenu_size = m_Menu->menu()[i].size() - 1;
for (int j = 0; j < submenu_size; ++j) {
m_Menu->remove(i);
}
}
}
}
//
// x_StaticCB()
// this is the main menu callback function
//
template <class CallbackMgr>
inline
void CFltkMenuMgrBase<CallbackMgr>::x_StaticCB(Fl_Widget*, void* data)
{
if ( !data ) {
return;
}
// we hold a CRef<> here because Run() may trigger some untoward events,
// such as plug being deleted...
CRef<CallbackMgr> plug(reinterpret_cast<CallbackMgr*> (data));
plug->DoCallback();
}
END_NCBI_SCOPE
/* @} */
/*
* ===========================================================================
* $Log: fltk_utils.hpp,v $
* Revision 1000.4 2004/06/01 19:51:09 gouriano
* PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.34
*
* Revision 1.34 2004/05/25 17:05:35 dicuccio
* Added single point for FLTK initialization. Defined new box type (right edge
* vertical line)
*
* Revision 1.33 2004/05/18 11:32:56 friedman
* Added method to add escape char to FLTK special chars.
*
* Revision 1.32 2004/04/16 14:24:45 dicuccio
* Added doxygen module tag. Updated include guard to reflect real location
*
* Revision 1.31 2004/03/23 13:35:13 dicuccio
* Added GetCursor(), plus storage of current cursor. Fixed hanging wait cursors.
*
* Revision 1.30 2004/03/17 19:50:59 yazhuk
* Moved Event classes to gui_event.hpp
*
* Revision 1.29 2004/03/08 16:36:09 lebedev
* eInsZoomStateIn and eInsZoomStateOut states added
*
* Revision 1.28 2004/03/05 12:27:52 lebedev
* eLensZoomState added
*
* Revision 1.27 2004/01/30 17:12:34 dicuccio
* Added standard event types for cut/copy/paste/undo/redo
*
* Revision 1.26 2004/01/06 20:12:17 dicuccio
* Added CFltkCursorGuard
*
* Revision 1.25 2003/12/31 20:19:16 dicuccio
* Added CFltkUtils. Added Lock() / Unlock().
*
* Revision 1.24 2003/12/22 23:42:41 ucko
* Conditionalize use of FLTK locking on NCBI_THREADS, as single-threaded
* FLTK builds lack stub versions.
*
* Revision 1.23 2003/12/22 19:15:35 dicuccio
* Code reformatting
*
* Revision 1.22 2003/12/01 16:31:06 yazhuk
* Added CGUIEvent class
*
* Revision 1.21 2003/09/30 13:39:03 dicuccio
* Cleaned up erroneous comments. Changed template parameter name from Plugin to
* Object (clearer on its intent). Fixed bug in clearning menus when the menu
* base is an empty string
*
* Revision 1.20 2003/07/21 19:23:15 dicuccio
* Minor semantic change: changed name of template parameter to match its use
*
* Revision 1.19 2003/06/25 16:59:41 dicuccio
* Changed CPluginHandle into a pointer-to-implementation (the previous
* implementation is now the pointer held). Lots of #include file clean-ups.
*
* Revision 1.18 2003/06/20 20:00:32 dicuccio
* Minor reformatting
*
* Revision 1.17 2003/04/17 16:24:28 rsmith
* in definition of class CFltkMenuMgrBase, moved declaration of x_StaticCB before it is used in x_AddItem so Codewarrior will compile.
*
* Revision 1.16 2003/03/25 18:34:28 dicuccio
* Changed export from GUIUTILS --> GUIUTILS
*
* Revision 1.15 2003/03/21 16:57:30 dicuccio
* Moved from gui/core --> gui/utils. Added event type for double-click.
*
* Revision 1.14 2003/02/26 19:16:11 dicuccio
* Fixed menu removal, using Fl_Menu_Item::size()
*
* Revision 1.13 2003/02/26 18:57:42 dicuccio
* Revered change to menu removal function
*
* Revision 1.12 2003/02/26 17:52:26 dicuccio
* Cleaned up dynamic menus to make them resistant to refreshing the menu while
* the menu callback is running
*
* Revision 1.11 2003/02/20 19:44:06 dicuccio
* Created new plugin architecture, mediated via an ASN.1 spec. Moved GBENCH
* framework over to use new plugin architecture.
*
* Revision 1.10 2003/01/13 13:11:42 dicuccio
* Namespace clean-up. Retired namespace gui -> converted to namespace ncbi.
* Moved all FLUID-generated code into namespace ncbi.
*
* Revision 1.9 2003/01/09 04:02:36 vakatov
* Removed extraneous comma after the last enum value in
* CFltkEvent::EEventFlags -- it resulted in a warning with Forte
*
* Revision 1.8 2002/12/30 17:49:52 dicuccio
* Added mechanism for menu managers to define their own private static menu
* callback function
*
* Revision 1.7 2002/12/26 21:10:09 dicuccio
* Minor header rearrangement to avoid compiler warning for MSVC
*
* Revision 1.6 2002/12/23 14:35:54 kuznets
* Added #include<vector>
*
* Revision 1.5 2002/12/23 13:47:27 dicuccio
* Added missing #include <vector>. Changed all *EventState -> *Event - less
* verbose.
*
* Revision 1.4 2002/12/20 19:10:16 dicuccio
* Added a base class for the menu managers. This class is responsible for
* managing a container of dynamically created items, each of which serves as
* the callback data for an FLTK menu. These classes can encapsulate the
* information needed to launch a context-specific plugin.
*
* Revision 1.3 2002/12/19 18:13:02 dicuccio
* Added export specifiers for Win32.
*
* Revision 1.2 2002/12/12 15:18:16 dicuccio
* Minor formatting change.
*
* Revision 1.1 2002/11/19 16:58:15 dicuccio
* Initial revision.
*
* ===========================================================================
*/
#endif // GUI_UTILS___FLTK_UTILS__HPP