i thought I'd follow in Allan Rae's footsteps and try and
port a pop-up to frontends.

Thinking, "let's keep this simple", I chose the
Help->Credits pop-up. I now have a FormCredits.[Ch] in the
src/frontends/xforms/ directory and...

it all works!

The changes I've made in src/ are minimal --- remove
credits.[Ch}, credits_form.[Ch] from Makefile.am and change
a FEW lines in LyXAction.C, commandtags.h, lyxfunc.C,
menus.[Ch]

I also modified a FEW lines of a few files in
src/frontends/xforms/ and, of course, created two more,
FormCredits.[Ch] which are closely modelled on
FormCopyright.[Ch]

The close similarity between FormCredits.[Ch] and
FormCopyright.[Ch] (see attachments), suggests that I
should proceed by creating a base class with virtual
build() and two derived classes FormCredits, and
FormCopyright implementing the build() function. Is this a
Good Idea? (I ask because C++ is new to me and I'm learing
as I go ;-).)

Angus
/* FormCredits.C
 * FormCredits Interface Class Implementation
 */

#include <config.h>
#include "lyx_gui_misc.h"
#include "gettext.h"
#include FORMS_H_LOCATION

#include "FormCredits.h"
#include "Dialogs.h"
#include "lyxfunc.h"
#include "support/filetools.h"

#ifdef __GNUG__
#pragma implementation
#endif

extern string system_lyxdir;

FormCredits::FormCredits(LyXFunc * c, Dialogs * d)
	: dialog_(0), lf_(c), d_(d), h_(0)
{
	// let the dialog be shown
	// This is a permanent connection so we won't bother
	// storing a copy because we won't be disconnecting.
	d->showCredits.connect(slot(this, &FormCredits::show));
}


FormCredits::~FormCredits()
{
	free();
}


void FormCredits::build()
{
	FL_OBJECT *obj;
	FD_form_credits *fdui = dialog_ = new FD_form_credits;

	fdui->form_credits = fl_bgn_form(FL_NO_BOX, 500, 330);
	fdui->form_credits->u_vdata = this;
	obj = fl_add_box(FL_UP_BOX, 0, 0, 500, 330, "");
	
	obj = fl_add_text(FL_NORMAL_TEXT, 10, 10, 480, 30, _("All these people have contributed to the LyX project. Thanks, "));
	fl_set_object_lsize(obj, FL_NORMAL_SIZE);
	fl_set_object_lalign(obj, FL_ALIGN_CENTER|FL_ALIGN_INSIDE);
	fl_set_object_gravity(obj, FL_NorthWest, FL_NorthEast);

	obj = fl_add_text(FL_NORMAL_TEXT, 10, 40, 480, 30, _("Matthias"));
	fl_set_object_lsize(obj, FL_NORMAL_SIZE);
	fl_set_object_lalign(obj, FL_ALIGN_CENTER|FL_ALIGN_INSIDE);
	fl_set_object_lstyle(obj, FL_ITALIC_STYLE);
	fl_set_object_gravity(obj, FL_NorthWest, FL_NorthEast);

	fdui->browser_credits =
	  obj = fl_add_browser(FL_NORMAL_BROWSER, 10, 80, 480, 200, "");
	fl_set_object_gravity(obj, FL_NorthWest, FL_SouthEast);

	fdui->button_ok =
	  obj = fl_add_button(FL_RETURN_BUTTON, 180, 290, 140, 30, _("OK"));
	fl_set_object_lsize(obj, FL_NORMAL_SIZE);
	fl_set_object_gravity(obj, FL_South, FL_South);
	fl_set_object_resize(obj, FL_RESIZE_NONE);
	fl_set_object_callback(obj, FormCredits::CreditsOKCB, 0);

	fl_end_form();

	fdui->form_credits->fdui = fdui;

	// Insert the contents of the credits file into browser_credits
	string real_file = AddName (system_lyxdir, "CREDITS");
	if (!fl_load_browser(fdui->browser_credits, real_file.c_str()))
	{
	  char const 
	    * const line1 = "ERROR: LyX wasn't able to read CREDITS file",
	    * const line2 = "Please install correctly to estimate the great",
	    * const line3 = "amount of work other people have done for the LyX project.";
	  fl_add_browser_line(fdui->browser_credits, _(line1));
	  fl_add_browser_line(fdui->browser_credits, "");
	  fl_add_browser_line(fdui->browser_credits, _(line2));
	  fl_add_browser_line(fdui->browser_credits, _(line3));
	}
}


void FormCredits::show()
{
	if (!dialog_) {
		build();
		fl_set_form_atclose(dialog_->form_credits,
				    FormCredits::CreditsWMHideCB, 0);
	}

	if (dialog_->form_credits->visible) {
		fl_raise_form(dialog_->form_credits);
	} else {
		fl_show_form(dialog_->form_credits,
			     FL_PLACE_MOUSE,
			     FL_FULLBORDER,
			     _("Credits"));
		h_ = d_->hideAll.connect(slot(this, &FormCredits::hide));
	}
}


void FormCredits::hide()
{
	if (dialog_
	    && dialog_->form_credits
	    && dialog_->form_credits->visible) {
		fl_hide_form(dialog_->form_credits);
		h_.disconnect();
	}
	free();
}


void FormCredits::free()
{
	// we don't need to delete h here because
	// hide() does that after disconnecting.
	if (dialog_) {
		if (dialog_->form_credits
		    && dialog_->form_credits->visible) {
			hide();
		}
		fl_free_form(dialog_->form_credits);
		delete dialog_;
		dialog_ = 0;
	}
}


int FormCredits::CreditsWMHideCB(FL_FORM * form, void *)
{
	// Ensure that the signal h is disconnected even if the
	// window manager is used to close the dialog.
	FormCredits * pre = (FormCredits*)form->u_vdata;
	pre->hide();
	return FL_CANCEL;
}


void FormCredits::CreditsOKCB(FL_OBJECT * ob, long)
{
	FormCredits * pre = (FormCredits*)ob->form->u_vdata;
	pre->hide();
}
// -*- C++ -*-
/* FormCredits.h
 * FormCredits Interface Class
 */

#ifndef FORMCREDITS_H
#define FORMCREDITS_H

#include "DialogBase.h"

class Dialogs;
// same arguement as in Dialogs.h s/LyX/UI/
class LyXFunc;

/** This class provides an XForms implementation of the FormCredits Dialog.
 */
class FormCredits : public DialogBase {
public:
	/**@name Constructors and Destructors */
	//@{
	/// #FormCredits x(LyXFunc ..., Dialogs ...);#
	FormCredits(LyXFunc *, Dialogs *);
	///
	~FormCredits();
	//@}
private:
	FormCredits() {}
	FormCredits(FormCredits &): DialogBase() {}

	/**@name Real per-instance Callback Methods */
	//@{
	static int CreditsWMHideCB(FL_FORM *, void *);
	static void CreditsOKCB(FL_OBJECT *, long);
	//@}
	
	/**@name Slot Methods */
	//@{
	/// Create the dialog if necessary, update it and display it.
	void show();
	/// Hide the dialog.
	void hide();
	/// Not used but we've got to implement it.
	void update() {}
	//@}

	/// Build the dialog
	void build();
	/// Explicitly free the dialog.
	void free();

	typedef struct {
	FL_FORM *form_credits;
		void *vdata;
		char *cdata;
		long  ldata;
		FL_OBJECT * browser_credits;
		FL_OBJECT * button_ok;
	} FD_form_credits;

	/**@name Private Data */
	//@{
	/// Real GUI implementation.
	FD_form_credits * dialog_;
	/** Which LyXFunc do we use?
	    We could modify Dialogs to have a visible LyXFunc* instead and
	    save a couple of bytes per dialog.
	*/
	LyXFunc * lf_;
	/** Which Dialogs do we belong to?
	    Used so we can get at the signals we have to connect to.
	*/
	Dialogs * d_;
	/// Hide connection.
	Connection h_;
	//@}
};

#endif

Reply via email to