00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "mmsgui/mmshboxwidget.h"
00034
00035 MMSHBoxWidget::MMSHBoxWidget(MMSWindow *root) : MMSWidget::MMSWidget() {
00036 create(root);
00037 }
00038
00039 bool MMSHBoxWidget::create(MMSWindow *root) {
00040 this->type = MMSWIDGETTYPE_HBOX;
00041 return MMSWidget::create(root, false, true, false, false, true, true, false);
00042 }
00043
00044 MMSWidget *MMSHBoxWidget::copyWidget() {
00045
00046 MMSHBoxWidget *newWidget = new MMSHBoxWidget(this->rootwindow);
00047
00048
00049 MMSWidget::copyWidget((MMSWidget*)newWidget);
00050
00051 return newWidget;
00052 }
00053
00054 void MMSHBoxWidget::add(MMSWidget *widget) {
00055 widget->setParent(this);
00056 this->children.push_back(widget);
00057 if (this->getRootWindow())
00058 this->getRootWindow()->add(widget);
00059 this->recalculateChildren();
00060 }
00061
00062
00063 void MMSHBoxWidget::calcSize(int *num_spacers, int *last_spacer,
00064 int *required_pix, int *remain_pix, int *avail_pix, int *fixed_pix, int *dyn_pix, int *min_dyn_pix,
00065 float dyn_reduce_factor) {
00066 *num_spacers = 0;
00067 *last_spacer = -1;
00068 *required_pix = 0;
00069 *remain_pix = 0;
00070 *avail_pix = 0;
00071 *fixed_pix = 0;
00072 *dyn_pix = 0;
00073 *min_dyn_pix = 0;
00074
00075
00076 for(unsigned int i = 0; i < this->children.size(); i++) {
00077 int content_width;
00078 int content_height;
00079 if (!children.at(i)->getContentSize(&content_width, &content_height)) {
00080
00081 string sizehint = children.at(i)->getSizeHint();
00082
00083 if (sizehint == "") {
00084
00085 (*num_spacers)++;
00086 *last_spacer = i;
00087 }
00088 else {
00089
00090 int len;
00091 getPixelFromSizeHint(&len, sizehint, this->geom.w, this->geom.h);
00092 (*fixed_pix)+= len;
00093 }
00094 }
00095 else
00096 if (dyn_reduce_factor < 0.0001) {
00097
00098 (*fixed_pix)+= children.at(i)->getMinWidthPix();
00099 }
00100 else {
00101
00102 content_width = (int)((float)content_width * dyn_reduce_factor + 0.5);
00103 if (content_width <= children.at(i)->getMinWidthPix()) {
00104
00105 (*fixed_pix)+= children.at(i)->getMinWidthPix();
00106 }
00107 else {
00108
00109 (*dyn_pix)+= content_width;
00110 (*min_dyn_pix)+= children.at(i)->getMinWidthPix();
00111 }
00112 }
00113 }
00114
00115
00116 *required_pix = *fixed_pix + *dyn_pix;
00117
00118
00119 *remain_pix = this->geom.w - *required_pix;
00120
00121
00122 *avail_pix = this->geom.w - *fixed_pix;
00123 }
00124
00125
00126 void MMSHBoxWidget::recalculateChildren() {
00127
00128
00129 if(this->children.empty())
00130 return;
00131
00132 if(this->geomset == false)
00133 return;
00134
00135
00136 int num_spacers, last_spacer;
00137 int required_pix, remain_pix, avail_pix, fixed_pix, dyn_pix, min_dyn_pix;
00138 float dyn_reduce_factor = 1.0f;
00139 while (1) {
00140
00141 calcSize(&num_spacers, &last_spacer,
00142 &required_pix, &remain_pix, &avail_pix, &fixed_pix, &dyn_pix, &min_dyn_pix,
00143 dyn_reduce_factor);
00144
00145 if (remain_pix >= 0) {
00146
00147 break;
00148 }
00149
00150
00151 if (avail_pix > min_dyn_pix) {
00152
00153 dyn_reduce_factor = (float)((float)avail_pix) / ((float)dyn_pix / dyn_reduce_factor);
00154 continue;
00155 }
00156 else
00157 if (avail_pix == min_dyn_pix) {
00158
00159 dyn_reduce_factor = 0.0f;
00160 continue;
00161 }
00162 else {
00163
00164 if (!this->getName().empty())
00165 printf("HBOX (%s): cannot calculate geometry (not enough free pixels)\n", this->getName().c_str());
00166 else
00167 printf("HBOX: cannot calculate geometry (not enough free pixels)\n");
00168 return;
00169
00170
00171 }
00172 }
00173
00174
00175
00176 int next_pos = this->geom.x;
00177 int safe_len = (num_spacers) ? remain_pix / num_spacers : 0;
00178 for (unsigned int i = 0; i < this->children.size(); i++) {
00179 MMSFBRectangle rect;
00180 int content_width, content_height;
00181
00182 if (!children.at(i)->getContentSize(&content_width, &content_height)) {
00183
00184 string sizehint = children.at(i)->getSizeHint();
00185
00186 if (sizehint == "") {
00187
00188 rect.w = safe_len;
00189 if (i == last_spacer)
00190 rect.w+= remain_pix % num_spacers;
00191 }
00192 else {
00193
00194 getPixelFromSizeHint(&rect.w, sizehint, this->geom.w, this->geom.h);
00195 }
00196 }
00197 else {
00198
00199 rect.w = (int)((float)content_width * dyn_reduce_factor + 0.5);
00200 if (rect.w < children.at(i)->getMinWidthPix())
00201 rect.w = children.at(i)->getMinWidthPix();
00202 }
00203
00204
00205 rect.x = next_pos;
00206 rect.y = this->geom.y;
00207 rect.h = this->geom.h;
00208 this->children.at(i)->setGeometry(rect);
00209
00210
00211 next_pos+= rect.w;
00212 }
00213 }
00214
00215 void MMSHBoxWidget::setContentSizeFromChildren() {
00216 if (!this->minmax_set) {
00217 return;
00218 }
00219
00220 if (!this->parent)
00221 return;
00222
00223
00224 int mycw = 0;
00225 int mych = getMinHeightPix();
00226 for (unsigned int i = 0; i < this->children.size(); i++) {
00227 int content_width, content_height;
00228
00229 if (!children.at(i)->getContentSize(&content_width, &content_height)) {
00230
00231 string sizehint = children.at(i)->getSizeHint();
00232
00233 if (sizehint == "") {
00234
00235 content_width = 0;
00236 }
00237 else {
00238
00239 getPixelFromSizeHint(&content_width, sizehint, this->geom.w, this->geom.h);
00240 }
00241 }
00242 else {
00243
00244 if (mych < content_height)
00245 mych = content_height;
00246 }
00247
00248 mycw+= content_width;
00249 }
00250
00251 if (mycw > 0 && mych > 0) {
00252
00253 if (mycw < getMinWidthPix())
00254 mycw = getMinWidthPix();
00255 if (getMaxHeightPix() > 0 && mych > getMaxHeightPix())
00256 mych = getMaxHeightPix();
00257 if (getMaxWidthPix() > 0 && mycw > getMaxWidthPix())
00258 mycw = getMaxWidthPix();
00259
00260
00261 this->content_width_child = mycw;
00262 this->content_height_child = mych;
00263 this->parent->setContentSizeFromChildren();
00264 }
00265 }
00266