mirror of
https://git.lyx.org/repos/lyx.git
synced 2025-01-03 16:31:13 +00:00
Prevent crashes experienced by speakers of "long" languages like Norwegian
and German when they select a tab of some tabbed-folder that is only partly displayed. Of course, the crash no longer happens with xforms 0.9999, but this is still the elegant thing to do. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@4141 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
060cb00dfc
commit
38b1890429
@ -1,3 +1,15 @@
|
|||||||
|
2002-05-06 Angus Leeming <a.leeming@ic.ac.uk>
|
||||||
|
|
||||||
|
* FormBase.C (show):
|
||||||
|
* FormBaseDeprecated.C (show): having built the dialog, ensure that the
|
||||||
|
tabs of any tabbed-folders are sufficiently lengthened to be displayed
|
||||||
|
whole. This is more than just cosmetic as it will prevent crashes
|
||||||
|
when a partly displayed tab is selected (xforms < 0.9999).
|
||||||
|
|
||||||
|
* xforms_resize.[Ch]: new files doing the grunt work of ascertaining
|
||||||
|
by how much a dialog should be scaled to show its tabs fully (should
|
||||||
|
it have a tabfolder).
|
||||||
|
|
||||||
2002-05-08 Garst Reese <reese@isn.net>
|
2002-05-08 Garst Reese <reese@isn.net>
|
||||||
|
|
||||||
* FormMathsDeco.C: fix offset to normal size decos.
|
* FormMathsDeco.C: fix offset to normal size decos.
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "Dialogs.h"
|
#include "Dialogs.h"
|
||||||
#include "FormBase.h"
|
#include "FormBase.h"
|
||||||
#include "xformsBC.h"
|
#include "xformsBC.h"
|
||||||
|
#include "xforms_resize.h"
|
||||||
#include "GUIRunTime.h"
|
#include "GUIRunTime.h"
|
||||||
#include "Tooltips.h"
|
#include "Tooltips.h"
|
||||||
#include "support/LAssert.h"
|
#include "support/LAssert.h"
|
||||||
@ -65,6 +66,10 @@ void FormBase::show()
|
|||||||
// use minw_ to flag whether the dialog has ever been shown
|
// use minw_ to flag whether the dialog has ever been shown
|
||||||
// (Needed now that build() is/should be called from the controller)
|
// (Needed now that build() is/should be called from the controller)
|
||||||
if (minw_ == 0) {
|
if (minw_ == 0) {
|
||||||
|
double const scale = scale_to_fit_tabs(form());
|
||||||
|
if (scale > 1.001)
|
||||||
|
scale_form(form(), scale);
|
||||||
|
|
||||||
bc().refresh();
|
bc().refresh();
|
||||||
|
|
||||||
// work around dumb xforms sizing bug
|
// work around dumb xforms sizing bug
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "Dialogs.h"
|
#include "Dialogs.h"
|
||||||
#include "FormBaseDeprecated.h"
|
#include "FormBaseDeprecated.h"
|
||||||
#include "xformsBC.h"
|
#include "xformsBC.h"
|
||||||
|
#include "xforms_resize.h"
|
||||||
#include "GUIRunTime.h"
|
#include "GUIRunTime.h"
|
||||||
#include "Tooltips.h"
|
#include "Tooltips.h"
|
||||||
#include "LyXView.h"
|
#include "LyXView.h"
|
||||||
@ -83,6 +84,10 @@ void FormBaseDeprecated::show()
|
|||||||
if (!form()) {
|
if (!form()) {
|
||||||
build();
|
build();
|
||||||
|
|
||||||
|
double const scale = scale_to_fit_tabs(form());
|
||||||
|
if (scale > 1.001)
|
||||||
|
scale_form(form(), scale);
|
||||||
|
|
||||||
bc().refresh();
|
bc().refresh();
|
||||||
|
|
||||||
// work around dumb xforms sizing bug
|
// work around dumb xforms sizing bug
|
||||||
|
@ -210,6 +210,8 @@ libxforms_la_SOURCES = \
|
|||||||
Tooltips.h \
|
Tooltips.h \
|
||||||
xforms_helpers.C \
|
xforms_helpers.C \
|
||||||
xforms_helpers.h \
|
xforms_helpers.h \
|
||||||
|
xforms_resize.C \
|
||||||
|
xforms_resize.h \
|
||||||
$(XFORMSGIMAGE) xformsBC.C \
|
$(XFORMSGIMAGE) xformsBC.C \
|
||||||
xformsBC.h
|
xformsBC.h
|
||||||
|
|
||||||
|
235
src/frontends/xforms/xforms_resize.C
Normal file
235
src/frontends/xforms/xforms_resize.C
Normal file
@ -0,0 +1,235 @@
|
|||||||
|
/**
|
||||||
|
* \file xforms_resize.C
|
||||||
|
* Copyright 2000-2002 the LyX Team
|
||||||
|
* Read the file COPYING
|
||||||
|
*
|
||||||
|
* \author Angus Leeming, a.leeming@ic.ac.uk
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#ifdef __GNUG__
|
||||||
|
#pragma implementation
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "xforms_resize.h"
|
||||||
|
|
||||||
|
#include "LString.h"
|
||||||
|
#include <algorithm>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
using std::vector;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// Returns the FL_OBJECT * of class FL_TABFOLDER if present in the form.
|
||||||
|
// Else 0.
|
||||||
|
FL_OBJECT * find_tabfolder(FL_FORM * form);
|
||||||
|
|
||||||
|
// Takes an FL_OBJECT * folder of class FL_TABFOLDER and calculates how much it
|
||||||
|
// should be scaled to display all the tabs.
|
||||||
|
// Returns 1 if the tabs are alll fully visible.
|
||||||
|
// Nested tabfolders are not considered.
|
||||||
|
double scale_to_fit_tabs(FL_OBJECT * folder);
|
||||||
|
|
||||||
|
// Returns the leaves making up a tabfolder.
|
||||||
|
vector<FL_FORM *> const leaves_in_tabfolder(FL_OBJECT * folder);
|
||||||
|
|
||||||
|
// The labels of each tab in the folder.
|
||||||
|
vector<string> const tab_names(FL_OBJECT * folder);
|
||||||
|
|
||||||
|
} // namespace anon
|
||||||
|
|
||||||
|
|
||||||
|
double scale_to_fit_tabs(FL_FORM * form)
|
||||||
|
{
|
||||||
|
if (!form)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
FL_OBJECT * folder = find_tabfolder(form);
|
||||||
|
if (!folder)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
double scale = scale_to_fit_tabs(folder);
|
||||||
|
|
||||||
|
vector<FL_FORM *> const leaves = leaves_in_tabfolder(folder);
|
||||||
|
vector<FL_FORM *>::const_iterator it = leaves.begin();
|
||||||
|
vector<FL_FORM *>::const_iterator end = leaves.end();
|
||||||
|
|
||||||
|
for (; it != end; ++it) {
|
||||||
|
folder = find_tabfolder(*it);
|
||||||
|
if (!folder)
|
||||||
|
continue;
|
||||||
|
double folder_scale = scale_to_fit_tabs(folder);
|
||||||
|
scale = std::max(scale, folder_scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
return scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void scale_form(FL_FORM * form, double scale_factor)
|
||||||
|
{
|
||||||
|
if (!form)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fl_scale_form(form, scale_factor, 1);
|
||||||
|
|
||||||
|
FL_OBJECT * folder = find_tabfolder(form);
|
||||||
|
if (!folder)
|
||||||
|
return;
|
||||||
|
|
||||||
|
vector<FL_FORM *> const leaves = leaves_in_tabfolder(folder);
|
||||||
|
vector<FL_FORM *>::const_iterator it = leaves.begin();
|
||||||
|
vector<FL_FORM *>::const_iterator end = leaves.end();
|
||||||
|
|
||||||
|
for (; it != end; ++it) {
|
||||||
|
fl_scale_form(*it, scale_factor, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
FL_OBJECT * find_tabfolder(FL_FORM * form)
|
||||||
|
{
|
||||||
|
for (FL_OBJECT * ob = form->first; ob; ob = ob->next) {
|
||||||
|
if (ob->objclass == FL_TABFOLDER)
|
||||||
|
return ob;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Return the scaling factor needed to render all the tab labels.
|
||||||
|
double scale_to_fit_tabs(FL_OBJECT * folder)
|
||||||
|
{
|
||||||
|
if (folder->objclass != FL_TABFOLDER)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
// The problem here is that we can access the names of a tabfolder's
|
||||||
|
// tabs directly (through fl_get_folder_name(folder)), but we
|
||||||
|
// can't access directly the tabs themselves. Nonetheless, they are
|
||||||
|
// made visible as buttons on the parent form, so we can obtain
|
||||||
|
// the style info by a judicious camparison of names. This style info
|
||||||
|
// (label font size, style) is needed to ascertain how much space
|
||||||
|
// the label takes up.
|
||||||
|
|
||||||
|
// The tabfolder makes the tabs (buttons) visible to the parent form,
|
||||||
|
// so to identify them, we need their names.
|
||||||
|
vector<string> const names = tab_names(folder);
|
||||||
|
if (names.empty())
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
FL_FORM * parent = folder->form;
|
||||||
|
if (!parent)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
// Ascertain the style parameters of the tabs.
|
||||||
|
int label_style = FL_BOLD_STYLE;
|
||||||
|
int label_size = FL_NORMAL_SIZE;
|
||||||
|
int box_width = 1;
|
||||||
|
// Hard-coded within xforms' fl_create_tabfolder in tabfolder.c.
|
||||||
|
int const tab_padding = 12;
|
||||||
|
|
||||||
|
for (FL_OBJECT * ob = parent->first; ob; ob = ob->next) {
|
||||||
|
if (!ob->label)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
vector<string>::const_iterator it = names.begin();
|
||||||
|
vector<string>::const_iterator end = names.end();
|
||||||
|
it = std::find(it, end, ob->label);
|
||||||
|
|
||||||
|
if (it == end)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
label_style = ob->lstyle;
|
||||||
|
label_size = ob->lsize;
|
||||||
|
|
||||||
|
if (ob->boxtype == FL_UP_BOX || ob->boxtype == FL_DOWN_BOX)
|
||||||
|
box_width = FL_abs(ob->bw);
|
||||||
|
|
||||||
|
// achieved all we set out to achieve, so break.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Hard coded in xforms' get_tabsize in tabfolder.c as
|
||||||
|
// (2 + fudge) * box_width, where fudge is always 1.
|
||||||
|
int const box_width_factor = 3 * box_width;
|
||||||
|
|
||||||
|
// Loop over the names and calculate how much space is needed to display
|
||||||
|
// them.
|
||||||
|
int length = 0;
|
||||||
|
|
||||||
|
vector<string>::const_iterator it = names.begin();
|
||||||
|
vector<string>::const_iterator end = names.end();
|
||||||
|
|
||||||
|
for (; it != end; ++it) {
|
||||||
|
int sw, sh;
|
||||||
|
|
||||||
|
fl_get_string_dimension(label_style, label_size,
|
||||||
|
it->c_str(), int(it->size()),
|
||||||
|
&sw, &sh);
|
||||||
|
|
||||||
|
// This is the minimum width the object must be to contain
|
||||||
|
// the label
|
||||||
|
length += sw + tab_padding + box_width_factor;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare this length to the width of the tabfolder
|
||||||
|
double scale = double(length) / double(folder->w);
|
||||||
|
return std::max(double(1), scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Returns the leaves making up a tabfolder.
|
||||||
|
vector<FL_FORM *> const leaves_in_tabfolder(FL_OBJECT * folder)
|
||||||
|
{
|
||||||
|
if (folder->objclass != FL_TABFOLDER)
|
||||||
|
return vector<FL_FORM *>();
|
||||||
|
|
||||||
|
fl_freeze_form(folder->form);
|
||||||
|
int const folder_id = fl_get_folder_number(folder);
|
||||||
|
|
||||||
|
int const size = fl_get_tabfolder_numfolders(folder);
|
||||||
|
vector<FL_FORM *> leaves(size);
|
||||||
|
|
||||||
|
for (int i = 0; i < size; ++i) {
|
||||||
|
fl_set_folder_bynumber(folder, i+1);
|
||||||
|
leaves[i] = fl_get_folder(folder);
|
||||||
|
}
|
||||||
|
|
||||||
|
fl_set_folder_bynumber(folder, folder_id);
|
||||||
|
fl_unfreeze_form(folder->form);
|
||||||
|
|
||||||
|
return leaves;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// The labels of each tab in the folder.
|
||||||
|
vector<string> const tab_names(FL_OBJECT * folder)
|
||||||
|
{
|
||||||
|
if (folder->objclass != FL_TABFOLDER)
|
||||||
|
return vector<string>();
|
||||||
|
|
||||||
|
fl_freeze_form(folder->form);
|
||||||
|
int const folder_id = fl_get_folder_number(folder);
|
||||||
|
|
||||||
|
int const size = fl_get_tabfolder_numfolders(folder);
|
||||||
|
vector<string> names(size);
|
||||||
|
|
||||||
|
for (int i = 0; i < size; ++i) {
|
||||||
|
fl_set_folder_bynumber(folder, i+1);
|
||||||
|
|
||||||
|
const char * const name = fl_get_folder_name(folder);
|
||||||
|
if (name)
|
||||||
|
names[i] = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
fl_set_folder_bynumber(folder, folder_id);
|
||||||
|
fl_unfreeze_form(folder->form);
|
||||||
|
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace anon
|
33
src/frontends/xforms/xforms_resize.h
Normal file
33
src/frontends/xforms/xforms_resize.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// -*- C++ -*-
|
||||||
|
/**
|
||||||
|
* \file xforms_resize.h
|
||||||
|
* Copyright 2000-2002 the LyX Team
|
||||||
|
* Read the file COPYING
|
||||||
|
*
|
||||||
|
* \author Angus Leeming, a.leeming@ic.ac.uk
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XFORMS_RESIZE_H
|
||||||
|
#define XFORMS_RESIZE_H
|
||||||
|
|
||||||
|
#ifdef __GNUG__
|
||||||
|
#pragma interface
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include FORMS_H_LOCATION
|
||||||
|
|
||||||
|
/** Returns 1 if the form does not contain a tabfolder.
|
||||||
|
If it does contain a tabfolder, then by how much should the form be
|
||||||
|
scaled to render the tabs (buttons) visible.
|
||||||
|
|
||||||
|
This routine works for two levels of nested tabfolders.
|
||||||
|
*/
|
||||||
|
double scale_to_fit_tabs(FL_FORM * form);
|
||||||
|
|
||||||
|
/** A wrapper for fl_scale_form(form, scale, 1) that scales the parent form
|
||||||
|
horizontally, but also scales the leaves (FL_FORMs) of the tabfolder,
|
||||||
|
should one exist.
|
||||||
|
*/
|
||||||
|
void scale_form(FL_FORM * form, double scale_factor);
|
||||||
|
|
||||||
|
#endif // XFORMS_RESIZE_H
|
Loading…
Reference in New Issue
Block a user