Česky
Kamil Dudka

GED 2006 (C++)

File detail

Name:Downloadmenu.cc [Download]
Location: ged2006 > src
Size:9.3 KB
Last modification:2007-08-29 02:16

Source code

/*
 * File: menu.cc - Menu classes
 * Project: GED - bitmap editor (ICP)
 * Author: Kamil Dudka, xdudka00
 * Team: xdudka00, xfilak01, xhefka00, xhradi08
 * Created: 2006-04-08
 */
 
#include <iostream>
#include <string>
#include <map>
 
#include <FL/Fl_Menu_Item.H>
#include <FL/Fl_File_Chooser.H>
#include <FL/fl_ask.H>
 
#include "global.h"
#include "pngimage.h"
#include "pluginsupport.h"
#include "gedconf.h"
#include "command.h"
#include "appwnd.h"
#include "menu.h"
 
using std::string;
 
namespace {
	/*
	 * Menu callback functions
	 */
	void cb_new (Fl_Widget *, void *);
	void cb_open (Fl_Widget *, void *);
	void cb_save (Fl_Widget *, void *);
	void cb_saveas (Fl_Widget *, void *);
	void cb_close (Fl_Widget *, void *);
	void cb_closeall (Fl_Widget *, void *);
	void cb_exit (Fl_Widget *, void *);
	void cb_undo (Fl_Widget *, void *);
	void cb_redo (Fl_Widget *, void *);
	void cb_unselect (Fl_Widget *, void *);
	void cb_apphelp (Fl_Widget *, void *);
	void cb_dochelp (Fl_Widget *, void *);
	void cb_draw (Fl_Widget *, void *);
	void cb_gray (Fl_Widget *, void *);
	void cb_invert (Fl_Widget *, void *);
	void cb_filter (Fl_Widget *, void *);
	void cb_load (Fl_Widget *, void *);
	void cb_stop (Fl_Widget *, void *);
	void cb_mac (Fl_Widget *, void *);
}
 
/*
 * Initialize singleton HelpBrowser
 */
HelpBrowser *HelpBrowser::_instance = 0;
 
/*
 * Global point to singleton HelpBrowser
 */
HelpBrowser *HelpBrowser::ptr ()
{
	if (0== _instance)
		_instance = new HelpBrowser;
 
	return _instance;
}
 
/*
 * Close help browser
 */
void HelpBrowser::close ()
{
	if (0== _instance)
		return;
 
	_instance->hide ();
	delete _instance;
}
 
/*
 * HelpBrowser destructor
 */
HelpBrowser::~HelpBrowser ()
{
	_instance = 0;
}
 
/*
 * Document menu
 * pDoc: pointer to document object
 * at: position of menu bar
 * size: size of menu bar
 */
DocMenu::DocMenu (DocWnd *pDoc, const Point &at, const BoxSize &size):
	Fl_Menu_Bar (at.x, at.y, size.width, size.height),
	_doc (pDoc)
{
	// Submenu file
	add ("&File/&New", FL_CTRL + 'n', cb_new, 0);
	add ("&File/&Open", FL_CTRL + 'o', cb_open, 0, FL_MENU_DIVIDER);
	_iSave = add ("&File/&Save", FL_CTRL + 's', cb_save, _doc);
	add ("&File/Save &as", 0, cb_saveas, _doc, FL_MENU_DIVIDER);
	add ("&File/Close", FL_CTRL + 'w', cb_close, _doc);
	add ("&File/Close all", 0, cb_closeall);
	add ("&File/E&xit", FL_CTRL + 'q', cb_exit);
 
	// Submenu Edit
	add ("&Edit/Select &all", 0, cb_unselect, _doc, FL_MENU_DIVIDER);
	_iUndo = add ("&Edit/&Undo", FL_CTRL + 'z', cb_undo, _doc);
	_iRedo = add ("&Edit/&Redo", FL_CTRL + 'y', cb_redo, _doc);
 
	// Submenu Tool
	for (int i=1; i<iDrawToolCnt; i++) {
		string item ("&Tool/");
		item.append (DrawContext::toolLabel (static_cast<EDrawTool>(i)) );
		add (item.c_str(), 0, cb_draw);
	}
 
	// Submenu Filter (if needed)
	add ("&Filter/Grayscale", 0, cb_gray, _doc);
	add ("&Filter/Invert", 0, cb_invert, _doc, FL_MENU_DIVIDER);
 
	// Read plugin filters
	typedef std::map<string, string> TPluginMap;
	TPluginMap &pluginMap = PluginList::ptr()->_pluginNameMap;
 
	const string filterPrefix ("filter:");
 
	for (TPluginMap::iterator i = pluginMap.begin(); i!= pluginMap.end(); i++) {
		string item = (*i).first;
		if (0!=item.find (filterPrefix))
			// Not filter category plugin
			return;
		item.replace (0, filterPrefix.size(), "Fil&ter/");
		add (item.c_str(), 0, cb_filter, _doc);
	}
 
	// Submenu Macro
	MacroList macList = GedConf::ptr()->getMacroList ();
	_iLoad = add ("&Macro/&Load", 0, cb_load, this);
	_iStop = add ("&Macro/&Create macro...", 0, cb_stop, this, FL_MENU_INACTIVE | FL_MENU_DIVIDER);
 
	for (MacroList::iterator i= macList.begin(); i!= macList.end(); i++) {
		std::string item ("&Macro/");
		item.append ((*i).first);
		add (item.c_str(), 0, cb_mac, _doc);
	}
 
 
	// Help item on menu bar
	add ("&Help", 0, cb_dochelp);
}
 
/*
 * Unused destructor (for now)
 */
DocMenu::~DocMenu ()
{
}
 
/*
 * Application menu
 * at: position of menu bar
 * size: size of menu bar
 */
AppMenu::AppMenu (const Point &at, const BoxSize &size):
	Fl_Menu_Bar (at.x, at.y, size.width, size.height)
{
	// Standart menu options
	add ("&File/&New", FL_CTRL + 'n', cb_new);
	add ("&File/&Open", FL_CTRL + 'o', cb_open, 0, FL_MENU_DIVIDER);
	_iCloseAll = add ("&File/Close all", 0, cb_closeall);
	add ("&File/E&xit", FL_CTRL + 'q', cb_exit);
	add ("&Help", 0, cb_apphelp);
}
 
void AppMenu::enableCloseAll (bool enable)
{
	mode (_iCloseAll, enable ? 0:FL_MENU_INACTIVE);
}
 
/*
 * Unused destructor (for now)
 */
AppMenu::~AppMenu ()
{
}
 
/*
 * enable/disable menu items fro image "img"
 */
void DocMenu::menuInit (Image &img)
{
	mode (_iSave, img.needSave() ? 0:FL_MENU_INACTIVE);
	mode (_iUndo, img.canUndo() ? 0:FL_MENU_INACTIVE);
	mode (_iRedo, img.canRedo() ? 0:FL_MENU_INACTIVE);
}
 
/*
 * Start macro loading
 */
void DocMenu::macLoad ()
{
	mode (_iLoad, FL_MENU_INACTIVE);
	mode (_iStop, FL_MENU_DIVIDER);
	_doc -> macLoad ();
}
 
/*
 * Stop macro laoding
 */
void DocMenu::macStop ()
{
	const char *szMacName = fl_input ("New macro name:");
	if (0== szMacName || '\0'== *szMacName)
		return;
 
	_doc -> macCreate (szMacName);
 
	std::string item ("&Macro/");
	item.append (szMacName);
	add (item.c_str(), 0, cb_mac, _doc);
 
	mode (_iLoad, 0);
	mode (_iStop, FL_MENU_INACTIVE | FL_MENU_DIVIDER);
}
 
namespace {
	/*
	 * File/New callback
	 */
	void cb_new (Fl_Widget *, void *)
	{
		Image *img = new PNGImage (GlobalH::newImageSize);
		DocWnd *doc = new Document (img);
		doc->show ();
	}
 
	/*
	 * File/Open callback
	 */
	void cb_open (Fl_Widget *, void *)
	{
		// Ask for name
		char *szImg = fl_file_chooser ("Open image", "Image files (*.png)", 0);
		if (NULL==szImg)
			return;
 
		try {
			// Create image object
			Image *img = Image::readImageFromFile (szImg);
 
			// Create image window
			Document *doc = new Document (img);
			doc -> show ();
		}
		catch (Image::ErrUnknownFF) {
			std::string msg (szImg);
			msg.append (": Unknown file format!");
			fl_alert (msg.c_str ());
		}
		catch (Image::ErrLoad) {
			std::string msg (szImg);
			msg.append (": could not open image!");
			fl_alert (msg.c_str ());
		}
	}
 
	/*
	 * Save callback
	 */
	void cb_save (Fl_Widget *, void *data)
	{
		DocWnd *const pDoc = static_cast<DocWnd *>(data);
		try {
			pDoc->save();
		}
		catch (Image::ErrSave) {
			fl_alert ("Could not save image!");
		}
	}
 
	/*
	 * SaveAs callback
	 */
	void cb_saveas (Fl_Widget *, void *data)
	{
		try {
			DocWnd *const pDoc = static_cast<DocWnd *>(data);
			pDoc->saveAs();
		}
		catch (Image::ErrSave) {
			fl_alert ("Could not save image!");
		}
	}
 
 
	/*
	 * Close callback
	 */
	void cb_close (Fl_Widget *, void *data)
	{
		DocWnd *const pDoc = static_cast<DocWnd *>(data);
		pDoc->tryClose();
	}
 
	/*
	 * CloseAll callback
	 */
	void cb_closeall (Fl_Widget *, void *)
	{
		if (0==fl_choice ("Close all windows?", "No", "Yes", 0))
			return;
 
		AppWnd *app = AppWnd::ptr();
		if (app->closeAll())
			app->show ();
	}
 
	/*
	 * Exit callback
	 */
	void cb_exit (Fl_Widget *, void *)
	{
		AppWnd::ptr()->exit();
	}
 
	/*
	 * Undo callback
	 */
	void cb_undo (Fl_Widget *, void *data)
	{
		DocWnd *const pDoc = static_cast<DocWnd *>(data);
		pDoc->undo();
	}
 
	/*
	 * Redo callback
	 */
	void cb_redo (Fl_Widget *, void *data)
	{
		DocWnd *const pDoc = static_cast<DocWnd *>(data);
		pDoc->redo();
	}
 
	/*
	 * Help callback (called from main window)
	 */
	void cb_apphelp (Fl_Widget *, void *)
	{
		std::string helpFile= GedConf::ptr()->getHelpDir() + "/index.html";
		HelpBrowser::ptr()->load (helpFile.c_str ());
		HelpBrowser::ptr()->show ();
	}
 
	/*
	 * Help callback (called from document window)
	 */
	void cb_dochelp (Fl_Widget *, void *)
	{
		std::string helpFile= GedConf::ptr()->getHelpDir() + "/index.html#document";
		HelpBrowser::ptr()->load (helpFile.c_str ());
		HelpBrowser::ptr()->show ();
	}
 
	/*
	 * Select whole image
	 */
	void cb_unselect (Fl_Widget *, void *data)
	{
		DocWnd *const pDoc = static_cast<DocWnd *>(data);
		pDoc->unSelect ();
	}
 
	/*
	 * One of draw items was selected
	 */
	void cb_draw (Fl_Widget *widget, void *)
	{
		const Fl_Menu_Item *const item = reinterpret_cast<Fl_Menu_ *>(widget)->mvalue();
 
		AppWnd::ptr()->selectTool (DrawContext::toolByLabel (item->label ()));
	}
 
	/*
	 * Built-in grayscale filter
	 */
	void cb_gray (Fl_Widget *, void *data)
	{
		DocWnd *const pDoc = static_cast<DocWnd *>(data);
		pDoc->filterGray ();
	}
 
	/*
	 * Built-in inbert filter
	 */
	void cb_invert (Fl_Widget *, void *data)
	{
		DocWnd *const pDoc = static_cast<DocWnd *>(data);
		pDoc->filterInvert ();
	}
 
	/*
	 * One of filter items was selected
	 */
	void cb_filter (Fl_Widget *widget, void *data)
	{
		const Fl_Menu_Item *const item = reinterpret_cast<Fl_Menu_ *>(widget)->mvalue();
		DocWnd *const pDoc = static_cast<DocWnd *>(data);
 
		// Retrieve original plugin name
		string pluginName ("filter:");
		pluginName.append (item->label ());
 
		pDoc->applyPlugin (pluginName);
	}
 
	/*
	 * One of macro items was selected
	 */
	void cb_mac (Fl_Widget *widget, void *data)
	{
		const Fl_Menu_Item *const item = reinterpret_cast<Fl_Menu_ *>(widget)->mvalue();
		DocWnd *const pDoc = static_cast<DocWnd *>(data);
 
		pDoc -> applyMacro (item->label ());
	}
 
	/*
	 * Load macro callback
	 */
	void cb_load (Fl_Widget *, void *data)
	{
		DocMenu *const menu = static_cast<DocMenu *>(data);
		menu->macLoad ();
	}
 
	/*
	 * Stop macro callback
	 */
	void cb_stop (Fl_Widget *, void *data)
	{
		DocMenu *const menu = static_cast<DocMenu *>(data);
		menu->macStop ();
	}
}