Wired up gtk widget destruction to nsWidget and related classes so that we don't ever have dangling points to dead gtk objects

This commit is contained in:
kipp%netscape.com 1999-04-30 00:13:47 +00:00
Родитель 9a7addb20e
Коммит 12389b25dd
19 изменённых файлов: 483 добавлений и 248 удалений

Просмотреть файл

@ -46,6 +46,20 @@ nsCheckButton::~nsCheckButton()
{
}
void
nsCheckButton::OnDestroySignal(GtkWidget* aGtkWidget)
{
if (aGtkWidget == mCheckButton) {
mCheckButton = nsnull;
}
else if (aGtkWidget == mLabel) {
mLabel = nsnull;
}
else {
nsWidget::OnDestroySignal(aGtkWidget);
}
}
//-------------------------------------------------------------------------
//
// Create the native CheckButton widget
@ -81,8 +95,13 @@ void nsCheckButton::InitCallbacks(char * aName)
GDK_KEY_RELEASE_MASK |
GDK_LEAVE_NOTIFY_MASK |
GDK_POINTER_MOTION_MASK);
}
// Add in destroy callback
gtk_signal_connect(GTK_OBJECT(mCheckButton),
"destroy",
GTK_SIGNAL_FUNC(DestroySignal),
this);
}
/**
* Implement the standard QueryInterface for NS_IWIDGET_IID and NS_ISUPPORTS_IID
@ -114,12 +133,13 @@ nsresult nsCheckButton::QueryInterface(const nsIID& aIID, void** aInstancePtr)
//-------------------------------------------------------------------------
NS_METHOD nsCheckButton::SetState(const PRBool aState)
{
GtkToggleButton * item = GTK_TOGGLE_BUTTON(mCheckButton);
if (mWidget) {
GtkToggleButton * item = GTK_TOGGLE_BUTTON(mCheckButton);
item->active = (gboolean) aState;
item->active = (gboolean) aState;
gtk_widget_queue_draw(GTK_WIDGET(item));
gtk_widget_queue_draw(GTK_WIDGET(item));
}
return NS_OK;
}
@ -130,12 +150,14 @@ NS_METHOD nsCheckButton::SetState(const PRBool aState)
//-------------------------------------------------------------------------
NS_METHOD nsCheckButton::GetState(PRBool& aState)
{
aState = (PRBool) GTK_TOGGLE_BUTTON(mCheckButton)->active;
// The check button will have been toggled twice (cough) -
// once by GTK and once by gecko. This is obviously messed up.
aState = !aState;
aState = PR_TRUE;
if (mWidget) {
aState = (PRBool) GTK_TOGGLE_BUTTON(mCheckButton)->active;
// The check button will have been toggled twice (cough) -
// once by GTK and once by gecko. This is obviously messed up.
aState = !aState;
}
return NS_OK;
}
@ -146,16 +168,22 @@ NS_METHOD nsCheckButton::GetState(PRBool& aState)
//-------------------------------------------------------------------------
NS_METHOD nsCheckButton::SetLabel(const nsString& aText)
{
NS_ALLOC_STR_BUF(label, aText, 256);
if (mLabel) {
gtk_label_set(GTK_LABEL(mLabel), label);
} else {
mLabel = gtk_label_new(label);
gtk_misc_set_alignment (GTK_MISC (mLabel), 0.0, 0.5);
gtk_container_add(GTK_CONTAINER(mCheckButton), mLabel);
gtk_widget_show(mLabel);
if (mWidget) {
NS_ALLOC_STR_BUF(label, aText, 256);
if (mLabel) {
gtk_label_set(GTK_LABEL(mLabel), label);
} else {
mLabel = gtk_label_new(label);
gtk_misc_set_alignment (GTK_MISC (mLabel), 0.0, 0.5);
gtk_container_add(GTK_CONTAINER(mCheckButton), mLabel);
gtk_widget_show(mLabel);
gtk_signal_connect(GTK_OBJECT(mLabel),
"destroy",
GTK_SIGNAL_FUNC(DestroySignal),
this);
}
NS_FREE_STR_BUF(label);
}
NS_FREE_STR_BUF(label);
return NS_OK;
}
@ -167,11 +195,13 @@ NS_METHOD nsCheckButton::SetLabel(const nsString& aText)
//-------------------------------------------------------------------------
NS_METHOD nsCheckButton::GetLabel(nsString& aBuffer)
{
char * text;
if (mLabel) {
gtk_label_get(GTK_LABEL(mLabel), &text);
aBuffer.SetLength(0);
aBuffer.Append(text);
aBuffer.SetLength(0);
if (mWidget) {
char * text;
if (mLabel) {
gtk_label_get(GTK_LABEL(mLabel), &text);
aBuffer.Append(text);
}
}
return NS_OK;
}

Просмотреть файл

@ -53,6 +53,7 @@ public:
protected:
NS_IMETHOD CreateNative(GtkWidget *parentWindow);
virtual void InitCallbacks(char * aName = nsnull);
virtual void OnDestroySignal(GtkWidget* aGtkWidget);
GtkWidget *mLabel;
GtkWidget *mCheckButton;

Просмотреть файл

@ -42,8 +42,6 @@ nsComboBox::nsComboBox() : nsWidget(), nsIListWidget(), nsIComboBox()
{
NS_INIT_REFCNT();
mMultiSelect = PR_FALSE;
// mBackground = NS_RGB(124, 124, 124);
mItems = nsnull;
mNumItems = 0;
}
@ -55,14 +53,12 @@ nsComboBox::nsComboBox() : nsWidget(), nsIListWidget(), nsIComboBox()
//-------------------------------------------------------------------------
nsComboBox::~nsComboBox()
{
for ( GList *items = mItems; items != NULL; items = (GList *) g_list_next(items))
{
if (mItems) {
for (GList *items = mItems; items; items = (GList*) g_list_next(items)){
g_free(items->data);
}
g_list_free(mItems);
#if 0
gtk_widget_destroy(mCombo);
#endif
g_list_free(mItems);
}
}
//-------------------------------------------------------------------------
@ -88,8 +84,10 @@ NS_METHOD nsComboBox::AddItemAt(nsString &aItem, PRInt32 aPosition)
{
NS_ALLOC_STR_BUF(val, aItem, 256);
mItems = g_list_insert( mItems, g_strdup(val), aPosition );
gtk_combo_set_popdown_strings( GTK_COMBO( mCombo ), mItems );
mNumItems++;
if (mCombo) {
gtk_combo_set_popdown_strings( GTK_COMBO( mCombo ), mItems );
}
NS_FREE_STR_BUF(val);
return NS_OK;
}
@ -138,8 +136,10 @@ PRBool nsComboBox::RemoveItemAt(PRInt32 aPosition)
g_free(g_list_nth(mItems, aPosition)->data);
mItems = g_list_remove_link(mItems, g_list_nth(mItems, aPosition));
gtk_combo_set_popdown_strings(GTK_COMBO( mCombo ), mItems);
mNumItems--;
if (mCombo) {
gtk_combo_set_popdown_strings(GTK_COMBO( mCombo ), mItems);
}
return PR_TRUE;
}
else
@ -153,13 +153,11 @@ PRBool nsComboBox::RemoveItemAt(PRInt32 aPosition)
//-------------------------------------------------------------------------
PRBool nsComboBox::GetItemAt(nsString& anItem, PRInt32 aPosition)
{
PRBool result = PR_FALSE;
if (aPosition >= 0 && aPosition < mNumItems) {
anItem = (gchar *) g_list_nth(mItems, aPosition)->data;
return PR_TRUE;
}
else
return PR_FALSE;
return PR_FALSE;
}
//-------------------------------------------------------------------------
@ -169,7 +167,10 @@ PRBool nsComboBox::GetItemAt(nsString& anItem, PRInt32 aPosition)
//-------------------------------------------------------------------------
NS_METHOD nsComboBox::GetSelectedItem(nsString& aItem)
{
aItem = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO(mCombo)->entry));
aItem.Truncate();
if (mCombo) {
aItem = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO(mCombo)->entry));
}
return NS_OK;
}
@ -200,7 +201,10 @@ NS_METHOD nsComboBox::SelectItem(PRInt32 aPosition)
if (!pos)
return NS_ERROR_FAILURE;
gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(mCombo)->entry), (gchar *) pos->data);
if (mCombo) {
gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(mCombo)->entry),
(gchar *) pos->data);
}
return NS_OK;
}
@ -288,11 +292,25 @@ NS_METHOD nsComboBox::CreateNative(GtkWidget *parentWindow)
/* make the stuff uneditable */
gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(mCombo)->entry), PR_FALSE);
gtk_container_add(GTK_CONTAINER(mWidget), mCombo);
// gtk_combo_set_value_in_list(GTK_COMBO(mCombo), PR_TRUE, PR_TRUE);
gtk_signal_connect(GTK_OBJECT(mCombo),
"destroy",
GTK_SIGNAL_FUNC(DestroySignal),
this);
return NS_OK;
}
void
nsComboBox::OnDestroySignal(GtkWidget* aGtkWidget)
{
if (aGtkWidget == mCombo) {
mCombo = nsnull;
}
else {
nsWidget::OnDestroySignal(aGtkWidget);
}
}
//-------------------------------------------------------------------------
//
// move, paint, resizes message - ignore

Просмотреть файл

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
@ -61,10 +61,9 @@ public:
protected:
NS_IMETHOD CreateNative(GtkWidget *parentWindow);
virtual void OnDestroySignal(GtkWidget* aGtkWidget);
GtkWidget *mCombo; /* workaround for gtkcombo bug */
GtkWidget *mPullDownMenu;
GtkWidget *mOptionMenu;
GList *mItems;
PRBool mMultiSelect;
int mNumItems;

Просмотреть файл

@ -65,23 +65,27 @@ static void file_cancel_clicked(GtkWidget *w, PRBool *ret)
//-------------------------------------------------------------------------
PRBool nsFileWidget::Show()
{
// make things shorter
GtkFileSelection *fs = GTK_FILE_SELECTION(mWidget);
PRBool ret;
if (mWidget) {
// make things shorter
GtkFileSelection *fs = GTK_FILE_SELECTION(mWidget);
gtk_window_set_modal(GTK_WINDOW(mWidget), PR_TRUE);
gtk_widget_show(mWidget);
// handle close, destroy, etc on the dialog
gtk_signal_connect(GTK_OBJECT(fs->ok_button), "clicked",
GTK_SIGNAL_FUNC(file_ok_clicked),
&ret);
gtk_signal_connect(GTK_OBJECT(fs->cancel_button), "clicked",
GTK_SIGNAL_FUNC(file_cancel_clicked),
&ret);
// start new loop. ret is set in the above callbacks.
gtk_main();
gtk_window_set_modal(GTK_WINDOW(mWidget), PR_TRUE);
gtk_widget_show(mWidget);
// handle close, destroy, etc on the dialog
gtk_signal_connect(GTK_OBJECT(fs->ok_button), "clicked",
GTK_SIGNAL_FUNC(file_ok_clicked),
&ret);
gtk_signal_connect(GTK_OBJECT(fs->cancel_button), "clicked",
GTK_SIGNAL_FUNC(file_cancel_clicked),
&ret);
// start new loop. ret is set in the above callbacks.
gtk_main();
}
else {
ret = PR_FALSE;
}
return ret;
}
@ -109,27 +113,26 @@ NS_METHOD nsFileWidget::SetFilterList(PRUint32 aNumberOfFilters,
NS_METHOD nsFileWidget::GetFile(nsString& aFile)
{
gchar *fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION(mWidget));
aFile.SetLength(0);
aFile.Append(fn);
aFile.Truncate();
if (mWidget) {
gchar *fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION(mWidget));
aFile.Append(fn);
// g_free(fn);
}
return NS_OK;
}
NS_METHOD nsFileWidget::GetFile(nsFileSpec& aFile)
{
gchar *fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION(mWidget));
aFile = fn; // Put the filename into the nsFileSpec instance.
if (mWidget) {
gchar *fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION(mWidget));
aFile = fn; // Put the filename into the nsFileSpec instance.
}
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Get the file + path
@ -137,10 +140,12 @@ NS_METHOD nsFileWidget::GetFile(nsFileSpec& aFile)
//-------------------------------------------------------------------------
NS_METHOD nsFileWidget::SetDefaultString(nsString& aString)
{
char *fn = aString.ToNewCString();
g_print("%s\n",fn);
gtk_file_selection_set_filename(GTK_FILE_SELECTION(mWidget), fn);
delete[] fn;
if (mWidget) {
char *fn = aString.ToNewCString();
g_print("%s\n",fn);
gtk_file_selection_set_filename(GTK_FILE_SELECTION(mWidget), fn);
delete[] fn;
}
return NS_OK;
}
@ -183,6 +188,10 @@ NS_METHOD nsFileWidget::Create(nsIWidget *aParent,
char *title = mTitle.ToNewCString();
mWidget = gtk_file_selection_new(title);
gtk_signal_connect(GTK_OBJECT(mWidget),
"destroy",
GTK_SIGNAL_FUNC(DestroySignal),
this);
// Hide the file column for the folder case.
if(aMode == eMode_getfolder) {
@ -194,6 +203,22 @@ NS_METHOD nsFileWidget::Create(nsIWidget *aParent,
return NS_OK;
}
gint
nsFileWidget::DestroySignal(GtkWidget * aGtkWidget,
nsFileWidget* aWidget)
{
aWidget->OnDestroySignal(aGtkWidget);
return TRUE;
}
void
nsFileWidget::OnDestroySignal(GtkWidget* aGtkWidget)
{
if (aGtkWidget == mWidget) {
mWidget = nsnull;
}
}
nsFileDlgResults nsFileWidget::GetFile(nsIWidget *aParent,
nsString &promptString,
nsFileSpec &theFileSpec)

Просмотреть файл

@ -32,35 +32,35 @@
class nsFileWidget : public nsIFileWidget
{
public:
nsFileWidget();
virtual ~nsFileWidget();
public:
nsFileWidget();
virtual ~nsFileWidget();
NS_DECL_ISUPPORTS
NS_DECL_ISUPPORTS
PRBool OnPaint();
PRBool OnPaint();
// nsIWidget interface
// nsIWidget interface
NS_IMETHOD Create(nsIWidget *aParent,
nsString& aTitle,
nsFileDlgMode aMode,
nsIDeviceContext *aContext = nsnull,
nsIAppShell *aAppShell = nsnull,
nsIToolkit *aToolkit = nsnull,
void *aInitData = nsnull);
NS_IMETHOD Create(nsIWidget *aParent,
nsString& aTitle,
nsFileDlgMode aMode,
nsIDeviceContext *aContext = nsnull,
nsIAppShell *aAppShell = nsnull,
nsIToolkit *aToolkit = nsnull,
void *aInitData = nsnull);
// nsIFileWidget part
virtual PRBool Show();
NS_IMETHOD GetFile(nsString& aFile);
NS_IMETHOD GetFile(nsFileSpec& aFile);
NS_IMETHOD SetDefaultString(nsString& aFile);
NS_IMETHOD SetFilterList(PRUint32 aNumberOfFilters,
const nsString aTitles[],
const nsString aFilters[]);
// nsIFileWidget part
virtual PRBool Show();
NS_IMETHOD GetFile(nsString& aFile);
NS_IMETHOD GetFile(nsFileSpec& aFile);
NS_IMETHOD SetDefaultString(nsString& aFile);
NS_IMETHOD SetFilterList(PRUint32 aNumberOfFilters,
const nsString aTitles[],
const nsString aFilters[]);
NS_IMETHOD GetDisplayDirectory(nsString& aDirectory);
NS_IMETHOD SetDisplayDirectory(nsString& aDirectory);
NS_IMETHOD GetDisplayDirectory(nsString& aDirectory);
NS_IMETHOD SetDisplayDirectory(nsString& aDirectory);
virtual nsFileDlgResults GetFile(nsIWidget *aParent,
nsString &promptString,
@ -74,15 +74,20 @@ class nsFileWidget : public nsIFileWidget
nsString &promptString,
nsFileSpec &theFileSpec);
protected:
GtkWidget *mWidget;
nsString mTitle;
nsFileDlgMode mMode;
PRUint32 mNumberOfFilters;
const nsString* mTitles;
const nsString* mFilters;
nsString mDefault;
nsString mDisplayDirectory;
protected:
static gint DestroySignal(GtkWidget * aGtkWidget,
nsFileWidget* aWidget);
virtual void OnDestroySignal(GtkWidget* aGtkWidget);
GtkWidget *mWidget;
nsString mTitle;
nsFileDlgMode mMode;
PRUint32 mNumberOfFilters;
const nsString* mTitles;
const nsString* mFilters;
nsString mDefault;
nsString mDisplayDirectory;
};
#endif // nsFileWidget_h__

Просмотреть файл

@ -431,8 +431,8 @@ void menu_item_activate_handler(GtkWidget *w, gpointer p)
mevent.mMenuItem = menuItem;
mevent.time = PR_IntervalNow();
nsEventStatus status;
// FIXME - THIS SHOULD WORK. FIX EVENTS FOR XP CODE!!!!! (pav)
// nsEventStatus status;
// mevent.widget->DispatchEvent((nsGUIEvent *)&mevent, status);
menuItem->QueryInterface(kIMenuListenerIID, (void**)&menuListener);
@ -458,16 +458,14 @@ void menu_map_handler(GtkWidget *w, gpointer p)
mevent.time = PR_IntervalNow();
nsEventStatus status;
menu->QueryInterface(kIMenuListenerIID, (void**)&menuListener);
if(menuListener) {
menuListener->MenuConstruct(
mevent,
nsnull, //parent window
nsnull, //menuNode
nsnull ); // webshell
nsnull, //menuNode
nsnull ); // webshell
NS_IF_RELEASE(menuListener);
}
}
@ -488,8 +486,6 @@ void menu_unmap_handler(GtkWidget *w, gpointer p)
mevent.time = PR_IntervalNow();
nsEventStatus status;
menu->QueryInterface(kIMenuListenerIID, (void**)&menuListener);
if(menuListener) {
menuListener->MenuDestruct(mevent);

Просмотреть файл

@ -54,6 +54,7 @@ public:
protected:
NS_METHOD CreateNative(GtkWidget *parentWindow);
GtkJustification GetNativeAlignment();
nsLabelAlignment mAlignment;
};

Просмотреть файл

@ -37,7 +37,6 @@ nsListBox::nsListBox() : nsWidget(), nsIListWidget(), nsIListBox()
NS_INIT_REFCNT();
mMultiSelect = PR_FALSE;
mCList = nsnull;
// mBackground = NS_RGB(124, 124, 124);
}
//-------------------------------------------------------------------------
@ -47,13 +46,6 @@ nsListBox::nsListBox() : nsWidget(), nsIListWidget(), nsIListBox()
//-------------------------------------------------------------------------
nsListBox::~nsListBox()
{
#if 0
if (mCList)
{
::gtk_widget_destroy(mCList);
mCList = nsnull;
}
#endif
}
//-------------------------------------------------------------------------
@ -93,12 +85,12 @@ nsresult nsListBox::QueryInterface(const nsIID& aIID, void** aInstancePtr)
NS_METHOD nsListBox::SetMultipleSelection(PRBool aMultipleSelections)
{
mMultiSelect = aMultipleSelections;
if (mMultiSelect)
gtk_clist_set_selection_mode(GTK_CLIST(mCList), GTK_SELECTION_MULTIPLE);
else
gtk_clist_set_selection_mode(GTK_CLIST(mCList), GTK_SELECTION_BROWSE);
if (mCList) {
if (mMultiSelect)
gtk_clist_set_selection_mode(GTK_CLIST(mCList), GTK_SELECTION_MULTIPLE);
else
gtk_clist_set_selection_mode(GTK_CLIST(mCList), GTK_SELECTION_BROWSE);
}
return NS_OK;
}
@ -111,20 +103,19 @@ NS_METHOD nsListBox::SetMultipleSelection(PRBool aMultipleSelections)
NS_METHOD nsListBox::AddItemAt(nsString &aItem, PRInt32 aPosition)
{
// cout << "nsListBox::AddItemAt(" << aItem << "," << aPosition << ")" << endl;
if (mCList) {
char *buf = aItem.ToNewCString();
gchar *text[2];
text[0] = buf;
text[1] = (char *)NULL;
gtk_clist_insert(GTK_CLIST(mCList), (int)aPosition, text);
char *buf = aItem.ToNewCString();
gchar *text[2];
text[0] = buf;
text[1] = (char *)NULL;
gtk_clist_insert(GTK_CLIST(mCList), (int)aPosition, text);
// XXX Im not sure using the string address is the right thing to
// store in the row data.
gtk_clist_set_row_data(GTK_CLIST(mCList), (int)aPosition, (gpointer)&aItem);
delete[] buf;
// XXX Im not sure using the string address is the right thing to
// store in the row data.
gtk_clist_set_row_data(GTK_CLIST(mCList), aPosition, (gpointer)&aItem);
delete[] buf;
}
return NS_OK;
}
@ -135,14 +126,13 @@ NS_METHOD nsListBox::AddItemAt(nsString &aItem, PRInt32 aPosition)
//-------------------------------------------------------------------------
PRInt32 nsListBox::FindItem(nsString &aItem, PRInt32 aStartPos)
{
// cout << "nsListBox::FindItem(" << aItem << "," << aStartPos << ")" << endl;
int index = gtk_clist_find_row_from_data(GTK_CLIST(mCList), (gpointer)&aItem);
if (index < aStartPos) {
index = -1;
int index = -1;
if (mCList) {
index = gtk_clist_find_row_from_data(GTK_CLIST(mCList), (gpointer)&aItem);
if (index < aStartPos) {
index = -1;
}
}
return index;
}
@ -153,7 +143,12 @@ PRInt32 nsListBox::FindItem(nsString &aItem, PRInt32 aStartPos)
//-------------------------------------------------------------------------
PRInt32 nsListBox::GetItemCount()
{
return GTK_CLIST(mCList)->rows;
if (mCList) {
return GTK_CLIST(mCList)->rows;
}
else {
return 0;
}
}
//-------------------------------------------------------------------------
@ -163,7 +158,9 @@ PRInt32 nsListBox::GetItemCount()
//-------------------------------------------------------------------------
PRBool nsListBox::RemoveItemAt(PRInt32 aPosition)
{
gtk_clist_remove(GTK_CLIST(mCList), aPosition);
if (mCList) {
gtk_clist_remove(GTK_CLIST(mCList), aPosition);
}
return PR_TRUE;
}
@ -175,13 +172,14 @@ PRBool nsListBox::RemoveItemAt(PRInt32 aPosition)
PRBool nsListBox::GetItemAt(nsString& anItem, PRInt32 aPosition)
{
PRBool result = PR_FALSE;
char *text = nsnull;
gtk_clist_get_text(GTK_CLIST(mCList),aPosition,0,&text);
if (text) {
anItem.SetLength(0);
anItem.Append(text);
result = PR_TRUE;
anItem.Truncate();
if (mCList) {
char *text = nsnull;
gtk_clist_get_text(GTK_CLIST(mCList),aPosition,0,&text);
if (text) {
anItem.Append(text);
result = PR_TRUE;
}
}
return result;
}
@ -193,19 +191,21 @@ PRBool nsListBox::GetItemAt(nsString& anItem, PRInt32 aPosition)
//-------------------------------------------------------------------------
NS_METHOD nsListBox::GetSelectedItem(nsString& aItem)
{
PRInt32 i=0, index=-1;
GtkCList *clist = GTK_CLIST(mCList);
GList *list = clist->row_list;
aItem.Truncate();
if (mCList) {
PRInt32 i=0, index=-1;
GtkCList *clist = GTK_CLIST(mCList);
GList *list = clist->row_list;
for (i=0; i < clist->rows && index == -1; i++, list = list->next) {
if (GTK_CLIST_ROW (list)->state == GTK_STATE_SELECTED) {
char *text = nsnull;
gtk_clist_get_text(GTK_CLIST(mCList),i,0,&text);
if (text) {
aItem.SetLength(0);
aItem.Append(text);
for (i=0; i < clist->rows && index == -1; i++, list = list->next) {
if (GTK_CLIST_ROW (list)->state == GTK_STATE_SELECTED) {
char *text = nsnull;
gtk_clist_get_text(GTK_CLIST(mCList),i,0,&text);
if (text) {
aItem.Append(text);
}
return NS_OK;
}
return NS_OK;
}
}
return NS_OK;
@ -219,19 +219,20 @@ NS_METHOD nsListBox::GetSelectedItem(nsString& aItem)
PRInt32 nsListBox::GetSelectedIndex()
{
PRInt32 i=0, index=-1;
if (!mMultiSelect) {
GtkCList *clist = GTK_CLIST(mCList);
GList *list = clist->row_list;
if (mCList) {
if (!mMultiSelect) {
GtkCList *clist = GTK_CLIST(mCList);
GList *list = clist->row_list;
for (i=0; i < clist->rows && index == -1; i++, list = list->next) {
if (GTK_CLIST_ROW (list)->state == GTK_STATE_SELECTED) {
index = i;
for (i=0; i < clist->rows && index == -1; i++, list = list->next) {
if (GTK_CLIST_ROW (list)->state == GTK_STATE_SELECTED) {
index = i;
}
}
} else {
NS_ASSERTION(PR_FALSE, "Multi selection list box does not support GetSelectedIndex()");
}
} else {
NS_ASSERTION(PR_FALSE, "Multi selection list box does not support GetSelectedIndex()");
}
return index;
}
@ -242,7 +243,9 @@ PRInt32 nsListBox::GetSelectedIndex()
//-------------------------------------------------------------------------
NS_METHOD nsListBox::SelectItem(PRInt32 aPosition)
{
gtk_clist_select_row(GTK_CLIST(mCList), aPosition, 0);
if (mCList) {
gtk_clist_select_row(GTK_CLIST(mCList), aPosition, 0);
}
return NS_OK;
}
@ -253,10 +256,15 @@ NS_METHOD nsListBox::SelectItem(PRInt32 aPosition)
//-------------------------------------------------------------------------
PRInt32 nsListBox::GetSelectedCount()
{
if (!GTK_CLIST(mCList)->selection)
if (mCList) {
if (!GTK_CLIST(mCList)->selection)
return 0;
else
return (PRInt32)g_list_length(GTK_CLIST(mCList)->selection);
}
else {
return 0;
else
return (PRInt32)g_list_length(GTK_CLIST(mCList)->selection);
}
}
//-------------------------------------------------------------------------
@ -266,16 +274,22 @@ PRInt32 nsListBox::GetSelectedCount()
//-------------------------------------------------------------------------
NS_METHOD nsListBox::GetSelectedIndices(PRInt32 aIndices[], PRInt32 aSize)
{
PRInt32 i=0, num = 0;
GtkCList *clist = GTK_CLIST(mCList);
GList *list = clist->row_list;
if (mCList) {
PRInt32 i=0, num = 0;
GtkCList *clist = GTK_CLIST(mCList);
GList *list = clist->row_list;
for (i=0; i < clist->rows && num < aSize; i++, list = list->next) {
if (GTK_CLIST_ROW (list)->state == GTK_STATE_SELECTED) {
aIndices[num] = i;
num++;
for (i=0; i < clist->rows && num < aSize; i++, list = list->next) {
if (GTK_CLIST_ROW (list)->state == GTK_STATE_SELECTED) {
aIndices[num] = i;
num++;
}
}
}
else {
PRInt32 i = 0;
for (i = 0; i < aSize; i++) aIndices[i] = 0;
}
return NS_OK;
}
@ -286,10 +300,12 @@ NS_METHOD nsListBox::GetSelectedIndices(PRInt32 aIndices[], PRInt32 aSize)
//-------------------------------------------------------------------------
NS_METHOD nsListBox::SetSelectedIndices(PRInt32 aIndices[], PRInt32 aSize)
{
gtk_clist_unselect_all(GTK_CLIST(mCList));
int i;
for (i=0;i<aSize;i++) {
SelectItem(aIndices[i]);
if (mCList) {
gtk_clist_unselect_all(GTK_CLIST(mCList));
int i;
for (i=0;i<aSize;i++) {
SelectItem(aIndices[i]);
}
}
return NS_OK;
}
@ -301,7 +317,9 @@ NS_METHOD nsListBox::SetSelectedIndices(PRInt32 aIndices[], PRInt32 aSize)
//-------------------------------------------------------------------------
NS_METHOD nsListBox::Deselect()
{
gtk_clist_unselect_all(GTK_CLIST(mCList));
if (mCList) {
gtk_clist_unselect_all(GTK_CLIST(mCList));
}
return NS_OK;
}
@ -331,7 +349,7 @@ NS_METHOD nsListBox::CreateNative(GtkWidget *parentWindow)
gtk_widget_set_name(mWidget, "nsListBox");
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (mWidget),
GTK_POLICY_NEVER,
GTK_POLICY_AUTOMATIC);
GTK_POLICY_AUTOMATIC);
mCList = ::gtk_clist_new(1);
gtk_clist_column_titles_hide(GTK_CLIST(mCList));
@ -339,12 +357,27 @@ NS_METHOD nsListBox::CreateNative(GtkWidget *parentWindow)
gtk_clist_set_selection_mode(GTK_CLIST(mCList), GTK_SELECTION_BROWSE);
SetMultipleSelection(mMultiSelect);
gtk_widget_show(mCList);
gtk_signal_connect(GTK_OBJECT(mCList),
"destroy",
GTK_SIGNAL_FUNC(DestroySignal),
this);
gtk_container_add (GTK_CONTAINER (mWidget), mCList);
return NS_OK;
}
void
nsListBox::OnDestroySignal(GtkWidget* aGtkWidget)
{
if (aGtkWidget == mCList) {
mCList = nsnull;
}
else {
nsWidget::OnDestroySignal(aGtkWidget);
}
}
//-------------------------------------------------------------------------
//
// move, paint, resizes message - ignore

Просмотреть файл

@ -63,6 +63,7 @@ public:
protected:
NS_IMETHOD CreateNative(GtkWidget *parentWindow);
virtual void OnDestroySignal(GtkWidget* aGtkWidget);
GtkWidget *mCList;
PRBool mMultiSelect;

Просмотреть файл

@ -228,7 +228,7 @@ NS_METHOD nsMenu::AddMenuItem(nsIMenuItem * aMenuItem)
NS_METHOD nsMenu::AddMenu(nsIMenu * aMenu)
{
nsString Label;
GtkWidget *item=nsnull, *newmenu=nsnull;
GtkWidget *newmenu=nsnull;
char *labelStr;
void *voidData=NULL;

Просмотреть файл

@ -92,9 +92,28 @@ NS_METHOD nsRadioButton::CreateNative(GtkWidget *parentWindow)
gtk_radio_button_set_group(GTK_RADIO_BUTTON(mRadioButton), nsnull);
gtk_signal_connect(GTK_OBJECT(mRadioButton),
"destroy",
GTK_SIGNAL_FUNC(DestroySignal),
this);
return NS_OK;
}
void
nsRadioButton::OnDestroySignal(GtkWidget* aGtkWidget)
{
if (aGtkWidget == mLabel) {
mLabel = nsnull;
}
else if (aGtkWidget == mRadioButton) {
mRadioButton = nsnull;
}
else {
nsWidget::OnDestroySignal(aGtkWidget);
}
}
void nsRadioButton::InitCallbacks(char * aName)
{
InstallButtonPressSignal(mRadioButton);
@ -120,12 +139,11 @@ void nsRadioButton::InitCallbacks(char * aName)
//-------------------------------------------------------------------------
NS_METHOD nsRadioButton::SetState(const PRBool aState)
{
GtkToggleButton * item = GTK_TOGGLE_BUTTON(mRadioButton);
item->active = (gboolean) aState;
gtk_widget_queue_draw(GTK_WIDGET(item));
if (mWidget) {
GtkToggleButton * item = GTK_TOGGLE_BUTTON(mRadioButton);
item->active = (gboolean) aState;
gtk_widget_queue_draw(GTK_WIDGET(item));
}
return NS_OK;
}
@ -135,8 +153,12 @@ NS_METHOD nsRadioButton::SetState(const PRBool aState)
//-------------------------------------------------------------------------
NS_METHOD nsRadioButton::GetState(PRBool& aState)
{
aState = (PRBool) GTK_TOGGLE_BUTTON(mRadioButton)->active;
if (mWidget) {
aState = (PRBool) GTK_TOGGLE_BUTTON(mRadioButton)->active;
}
else {
aState = PR_TRUE;
}
return NS_OK;
}
@ -147,17 +169,23 @@ NS_METHOD nsRadioButton::GetState(PRBool& aState)
//-------------------------------------------------------------------------
NS_METHOD nsRadioButton::SetLabel(const nsString& aText)
{
NS_ALLOC_STR_BUF(label, aText, 256);
g_print("nsRadioButton::SetLabel(%s)\n",label);
if (mLabel) {
gtk_label_set(GTK_LABEL(mLabel), label);
} else {
mLabel = gtk_label_new(label);
gtk_misc_set_alignment (GTK_MISC (mLabel), 0.0, 0.5);
gtk_container_add(GTK_CONTAINER(mRadioButton), mLabel);
gtk_widget_show(mLabel); /* XXX */
if (mWidget) {
NS_ALLOC_STR_BUF(label, aText, 256);
g_print("nsRadioButton::SetLabel(%s)\n",label);
if (mLabel) {
gtk_label_set(GTK_LABEL(mLabel), label);
} else {
mLabel = gtk_label_new(label);
gtk_misc_set_alignment (GTK_MISC (mLabel), 0.0, 0.5);
gtk_container_add(GTK_CONTAINER(mRadioButton), mLabel);
gtk_widget_show(mLabel); /* XXX */
gtk_signal_connect(GTK_OBJECT(mLabel),
"destroy",
GTK_SIGNAL_FUNC(DestroySignal),
this);
}
NS_FREE_STR_BUF(label);
}
NS_FREE_STR_BUF(label);
return NS_OK;
}
@ -169,11 +197,13 @@ NS_METHOD nsRadioButton::SetLabel(const nsString& aText)
//-------------------------------------------------------------------------
NS_METHOD nsRadioButton::GetLabel(nsString& aBuffer)
{
char * text;
if (mLabel) {
gtk_label_get(GTK_LABEL(mLabel), &text);
aBuffer.SetLength(0);
aBuffer.Append(text);
aBuffer.Truncate();
if (mWidget) {
if (mLabel) {
char* text;
gtk_label_get(GTK_LABEL(mLabel), &text);
aBuffer.Append(text);
}
}
return NS_OK;
}

Просмотреть файл

@ -58,6 +58,7 @@ public:
protected:
NS_IMETHOD CreateNative(GtkWidget *parentWindow);
virtual void InitCallbacks(char * aName = nsnull);
virtual void OnDestroySignal(GtkWidget* aGtkWidget);
GtkWidget *mLabel;
GtkWidget *mRadioButton;

Просмотреть файл

@ -61,25 +61,40 @@ NS_METHOD nsScrollbar::CreateNative (GtkWidget * parentWindow)
mAdjustment = GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, 100, 1, 25, 25));
switch (mOrientation)
{
{
case GTK_ORIENTATION_HORIZONTAL:
mWidget = gtk_hscrollbar_new (mAdjustment);
break;
case GTK_ORIENTATION_VERTICAL:
mWidget = gtk_vscrollbar_new (mAdjustment);
break;
}
}
gtk_widget_set_name (mWidget, "nsScrollbar");
gtk_signal_connect (GTK_OBJECT (mAdjustment),
"value_changed",
GTK_SIGNAL_FUNC (handle_scrollbar_value_changed),
this);
"value_changed",
GTK_SIGNAL_FUNC (handle_scrollbar_value_changed),
this);
gtk_signal_connect (GTK_OBJECT (mAdjustment),
"destroy",
GTK_SIGNAL_FUNC (DestroySignal),
this);
return NS_OK;
}
void
nsScrollbar::OnDestroySignal(GtkWidget* aGtkWidget)
{
if ((void*)aGtkWidget == (void*)mAdjustment) {
mAdjustment = nsnull;
}
else {
nsWidget::OnDestroySignal(aGtkWidget);
}
}
//-------------------------------------------------------------------------
//
// Query interface implementation
@ -276,15 +291,6 @@ PRBool nsScrollbar::OnResize(nsSizeEvent &aEvent)
//-------------------------------------------------------------------------
int nsScrollbar::AdjustScrollBarPosition (int aPosition)
{
int maxRange;
int sliderSize;
#if 0
XtVaGetValues (mWidget, XmNmaximum, &maxRange,
XmNsliderSize, &sliderSize,
nsnull);
int cap = maxRange - sliderSize;
return aPosition > cap ? cap : aPosition;
#endif
return 0; /* XXX */
}

Просмотреть файл

@ -57,6 +57,7 @@ public:
protected:
NS_IMETHOD CreateNative(GtkWidget *parentWindow);
virtual void OnDestroySignal(GtkWidget* aGtkWidget);
private:
int mOrientation;
@ -65,4 +66,4 @@ private:
int AdjustScrollBarPosition(int aPosition);
};
#endif // nsScrollbar_
#endif /* nsScrollbar_h__ */

Просмотреть файл

@ -92,6 +92,10 @@ nsWidget::nsWidget()
nsWidget::~nsWidget()
{
#ifdef NOISY_DESTROY
IndentByDepth(stdout);
printf("nsWidget::~nsWidget:%p\n", this);
#endif
mIsDestroying = PR_TRUE;
if (nsnull != mWidget) {
Destroy();
@ -116,6 +120,20 @@ NS_METHOD nsWidget::ScreenToWidget(const nsRect& aOldRect, nsRect& aNewRect)
return NS_OK;
}
#ifdef DEBUG
void
nsWidget::IndentByDepth(FILE* out)
{
PRInt32 depth = 0;
nsWidget* parent = (nsWidget*)mParent;
while (parent) {
parent = (nsWidget*) parent->mParent;
depth++;
}
while (--depth >= 0) fprintf(out, " ");
}
#endif
//-------------------------------------------------------------------------
//
// Close this nsWidget
@ -124,7 +142,8 @@ NS_METHOD nsWidget::ScreenToWidget(const nsRect& aOldRect, nsRect& aNewRect)
NS_IMETHODIMP nsWidget::Destroy(void)
{
#ifdef NOISY_WIDGET_DESTROY
#ifdef NOISY_DESTROY
IndentByDepth(stdout);
printf("nsWidget::Destroy:%p: isDestroying=%s widget=%p parent=%p\n",
this, mIsDestroying ? "yes" : "no", mWidget, mParent);
#endif
@ -168,6 +187,21 @@ void nsWidget::OnDestroy()
}
}
gint
nsWidget::DestroySignal(GtkWidget* aGtkWidget, nsWidget* aWidget)
{
aWidget->OnDestroySignal(aGtkWidget);
return PR_TRUE;
}
void
nsWidget::OnDestroySignal(GtkWidget* aGtkWidget)
{
if (aGtkWidget == mWidget) {
mWidget = nsnull;
}
}
//-------------------------------------------------------------------------
//
// Get this nsWidget parent
@ -741,7 +775,7 @@ nsresult nsWidget::CreateWidget(nsIWidget *aParent,
{
GtkWidget *parentWidget = nsnull;
#if 0
#ifdef NOISY_DESTROY
if (aParent)
g_print("nsWidget::CreateWidget (%p) nsIWidget parent\n",
this);
@ -786,6 +820,12 @@ nsresult nsWidget::CreateWidget(nsIWidget *aParent,
DispatchStandardEvent(NS_CREATE);
InitCallbacks();
// Add in destroy callback
gtk_signal_connect(GTK_OBJECT(mWidget),
"destroy",
GTK_SIGNAL_FUNC(DestroySignal),
this);
#ifdef NS_GTK_REF
if (aNativeParent) {
gtk_widget_unref(GTK_WIDGET(aNativeParent));
@ -804,16 +844,16 @@ nsresult nsWidget::CreateWidget(nsIWidget *aParent,
//-------------------------------------------------------------------------
NS_METHOD nsWidget::Create(nsIWidget *aParent,
const nsRect &aRect,
EVENT_CALLBACK aHandleEventFunction,
nsIDeviceContext *aContext,
nsIAppShell *aAppShell,
nsIToolkit *aToolkit,
nsWidgetInitData *aInitData)
const nsRect &aRect,
EVENT_CALLBACK aHandleEventFunction,
nsIDeviceContext *aContext,
nsIAppShell *aAppShell,
nsIToolkit *aToolkit,
nsWidgetInitData *aInitData)
{
return(CreateWidget(aParent, aRect, aHandleEventFunction,
aContext, aAppShell, aToolkit, aInitData,
nsnull));
return CreateWidget(aParent, aRect, aHandleEventFunction,
aContext, aAppShell, aToolkit, aInitData,
nsnull);
}
//-------------------------------------------------------------------------
@ -822,16 +862,16 @@ NS_METHOD nsWidget::Create(nsIWidget *aParent,
//
//-------------------------------------------------------------------------
NS_METHOD nsWidget::Create(nsNativeWidget aParent,
const nsRect &aRect,
EVENT_CALLBACK aHandleEventFunction,
nsIDeviceContext *aContext,
nsIAppShell *aAppShell,
nsIToolkit *aToolkit,
nsWidgetInitData *aInitData)
const nsRect &aRect,
EVENT_CALLBACK aHandleEventFunction,
nsIDeviceContext *aContext,
nsIAppShell *aAppShell,
nsIToolkit *aToolkit,
nsWidgetInitData *aInitData)
{
return(CreateWidget(nsnull, aRect, aHandleEventFunction,
aContext, aAppShell, aToolkit, aInitData,
aParent));
return CreateWidget(nsnull, aRect, aHandleEventFunction,
aContext, aAppShell, aToolkit, aInitData,
aParent);
}
//-------------------------------------------------------------------------

Просмотреть файл

@ -31,6 +31,11 @@
#include <gtk/gtk.h>
#ifdef DEBUG
#undef NOISY_DESTROY
#else
#undef NOISY_DESTROY
#endif
/**
* Base of all GTK+ native widgets.
@ -122,6 +127,10 @@ class nsWidget : public nsBaseWidget
// are we a "top level" widget?
PRBool mIsToplevel;
#ifdef DEBUG
void IndentByDepth(FILE* out);
#endif
protected:
virtual void InitCallbacks(char * aName = nsnull);
@ -176,6 +185,8 @@ class nsWidget : public nsBaseWidget
virtual void OnButtonReleaseSignal(GdkEventButton * aGdkButtonEvent);
virtual void OnRealize();
virtual void OnDestroySignal(GtkWidget* aGtkWidget);
private:
//////////////////////////////////////////////////////////////////
@ -207,6 +218,9 @@ private:
static gint RealizeSignal(GtkWidget * aWidget,
gpointer aData);
static gint DestroySignal(GtkWidget * aGtkWidget,
nsWidget* aWidget);
//////////////////////////////////////////////////////////////////
//
// GTK event support methods
@ -222,6 +236,7 @@ private:
void InitMouseEvent(GdkEventButton * aGdkButtonEvent,
nsMouseEvent & anEvent,
PRUint32 aEventType);
protected:
GtkWidget *mWidget;
nsIWidget *mParent;

Просмотреть файл

@ -94,6 +94,10 @@ nsWindow::nsWindow()
//-------------------------------------------------------------------------
nsWindow::~nsWindow()
{
#ifdef NOISY_DESTROY
IndentByDepth(stdout);
printf("nsWindow::~nsWindow:%p\n", this);
#endif
mIsDestroyingWindow = PR_TRUE;
if (nsnull != mShell) {
Destroy();
@ -146,6 +150,11 @@ NS_METHOD nsWindow::RemoveTooltips()
NS_METHOD nsWindow::Destroy()
{
#ifdef NOISY_DESTROY
IndentByDepth(stdout);
printf("nsWindow::Destroy:%p: isDestroyingWindow=%s widget=%p shell=%p parent=%p\n",
this, mIsDestroyingWindow ? "yes" : "no", mWidget, mShell, mParent);
#endif
NS_IF_RELEASE(m_nsIMenuBar);
// Call base class first... we need to ensure that upper management
@ -166,6 +175,15 @@ NS_METHOD nsWindow::Destroy()
return NS_OK;
}
void
nsWindow::OnDestroySignal(GtkWidget* aGtkWidget)
{
nsWidget::OnDestroySignal(aGtkWidget);
if (aGtkWidget == mShell) {
mShell = nsnull;
}
}
gint handle_delete_event(GtkWidget *w, GdkEventAny *e, nsWindow *win)
{
win->SetIsDestroying( PR_TRUE );
@ -648,6 +666,14 @@ ChildWindow::ChildWindow()
{
}
ChildWindow::~ChildWindow()
{
#ifdef NOISY_DESTROY
IndentByDepth(stdout);
printf("ChildWindow::~ChildWindow:%p\n", this);
#endif
}
PRBool ChildWindow::IsChild() const
{
return PR_TRUE;
@ -655,6 +681,10 @@ PRBool ChildWindow::IsChild() const
NS_METHOD ChildWindow::Destroy()
{
#ifdef NOISY_DESTROY
IndentByDepth(stdout);
printf("ChildWindow::Destroy:%p \n", this);
#endif
// Skip over baseclass Destroy method which doesn't do what we want;
// instead make sure widget destroy method gets invoked.
return nsWidget::Destroy();

Просмотреть файл

@ -110,6 +110,8 @@ protected:
virtual gint OnDrawSignal(GdkRectangle * aArea);
virtual void OnDestroySignal(GtkWidget* aGtkWidget);
//////////////////////////////////////////////////////////////////////
virtual void InitCallbacks(char * aName = nsnull);
@ -144,6 +146,7 @@ protected:
class ChildWindow : public nsWindow {
public:
ChildWindow();
~ChildWindow();
virtual PRBool IsChild() const;
NS_IMETHOD Destroy(void);
};