]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/xforms_resize.C
introduce namespace lyx::support
[lyx.git] / src / frontends / xforms / xforms_resize.C
1 /**
2  * \file xforms_resize.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Angus Leeming
7  *
8  * Full author contact details are available in file CREDITS
9  */
10
11 #include <config.h>
12
13
14 #include "xforms_resize.h"
15 #include "support/LAssert.h"
16 #include <algorithm> // std::max. Use FL_max in .c code...
17 #include "lyx_forms.h"
18
19 using namespace lyx::support;
20
21 namespace {
22
23 /* This is hacked straight out of the xforms source.
24    It is fl_adjust_form_size without the last few lines that do the
25    adjusting.
26  */
27 double get_scaling_factor(FL_FORM * form)
28 {
29     FL_OBJECT *ob;
30     float xfactor, yfactor, max_factor, factor;
31     int sw, sh, osize;
32     float xm = 0.5f, ym = 0.5f;
33     int bw;
34
35 //      if (fl_no_connection)
36 //      return 1.0f;
37
38     max_factor = factor = 1.0f;
39     for (ob = form->first; ob; ob = ob->next)
40     {
41         if ((ob->align == FL_ALIGN_CENTER || (ob->align & FL_ALIGN_INSIDE) ||
42              ob->objclass == FL_INPUT) &&
43             !ob->is_child && *(ob->label) && ob->label[0] != '@' &&
44             ob->boxtype != FL_NO_BOX &&
45             (ob->boxtype != FL_FLAT_BOX || ob->objclass == FL_MENU))
46         {
47             fl_get_string_dimension(ob->lstyle, ob->lsize, ob->label,
48                        strlen(ob->label), &sw, &sh);
49
50             bw = (ob->boxtype == FL_UP_BOX || ob->boxtype == FL_DOWN_BOX) ?
51                 FL_abs(ob->bw) : 1;
52
53             if (ob->objclass == FL_BUTTON &&
54                 (ob->type == FL_RETURN_BUTTON || ob->type == FL_MENU_BUTTON))
55                 sw += (int)FL_min(0.6f * ob->h, 0.6f * ob->w) - 1;
56
57             if (ob->objclass == FL_BUTTON && ob->type == FL_LIGHTBUTTON)
58                 sw += FL_LIGHTBUTTON_MINSIZE + 1;
59
60             if (sw <= (ob->w - 2 * (bw + xm)) && sh <= (ob->h - 2 * (bw + ym)))
61                 continue;
62
63             if ((osize = ob->w - 2 * (int)(bw + xm)) <= 0)
64                 osize = 1;
65             xfactor = (float) sw / (float)osize;
66
67             if ((osize = ob->h - 2 * (int)(bw + ym)) <= 0)
68                 osize = 1;
69             yfactor = (float) sh / osize;
70
71             if (ob->objclass == FL_INPUT)
72             {
73                 xfactor = 1.0f;
74                 yfactor = (sh + 1.6f) / osize;
75             }
76
77             if ((factor = FL_max(xfactor, yfactor)) > max_factor)
78             {
79                 max_factor = factor;
80             }
81         }
82     }
83
84     if (max_factor <= 1.0f)
85         return 1.0f;
86
87     max_factor = 0.01f * (int) (max_factor * 100.0f);
88
89     if (max_factor > 1.25f)
90         max_factor = 1.25f;
91
92     return max_factor;
93 }
94
95
96 double get_tabfolder_scale_to_fit(FL_OBJECT * folder)
97 {
98         Assert(folder && folder->objclass == FL_TABFOLDER);
99
100         fl_freeze_form(folder->form);
101         int const saved_folder_id = fl_get_folder_number(folder);
102
103         double factor = 1.0;
104         int const size = fl_get_tabfolder_numfolders(folder);
105         for (int i = 0; i < size; ++i) {
106                 fl_set_folder_bynumber(folder, i+1);
107                 FL_FORM * leaf = fl_get_folder(folder);
108                 factor = std::max(factor, get_scale_to_fit(leaf));
109         }
110
111         fl_set_folder_bynumber(folder, saved_folder_id);
112         fl_unfreeze_form(folder->form);
113
114         return factor;
115 }
116
117
118 void scale_tabfolder_horizontally(FL_OBJECT * folder, double factor)
119 {
120         Assert(folder && folder->objclass == FL_TABFOLDER);
121
122         fl_freeze_form(folder->form);
123         int const saved_folder_id = fl_get_folder_number(folder);
124
125         int const size = fl_get_tabfolder_numfolders(folder);
126         for (int i = 0; i < size; ++i) {
127                 fl_set_folder_bynumber(folder, i+1);
128                 FL_FORM * leaf = fl_get_folder(folder);
129                 scale_form_horizontally(leaf, factor);
130         }
131
132         fl_set_folder_bynumber(folder, saved_folder_id);
133         fl_unfreeze_form(folder->form);
134 }
135
136 } // namespace anon
137
138
139 double get_scale_to_fit(FL_FORM * form)
140 {
141         Assert(form);
142
143         double factor = get_scaling_factor(form);
144         for (FL_OBJECT * ob = form->first; ob; ob = ob->next) {
145                 if (ob->objclass == FL_TABFOLDER)
146                         factor = std::max(factor,
147                                           get_tabfolder_scale_to_fit(ob));
148         }
149         return factor;
150 }
151
152
153 void scale_form_horizontally(FL_FORM * form, double factor)
154 {
155         Assert(form);
156
157         if (factor <= 1.0)
158                 return;
159
160         fl_scale_form(form, factor, 1);
161
162         for (FL_OBJECT * ob = form->first; ob; ob = ob->next) {
163                 if (ob->objclass == FL_TABFOLDER)
164                         scale_tabfolder_horizontally(ob, factor);
165         }
166 }