void edit_text_t::measure(extents_t& result) { assert(control_m); extents_t attrs; std::string base_text(cols_m, std::string::value_type('0')); if (rows_m > 1) { attrs = implementation::measure_theme_text(base_text, theme_m); result = attrs; // REVISIT (fbrereto) : There is an issue here where the attributes of an edit_text // widget don't propagate properly to a static_text widget, so // measurement is inherently inaccurate. A better solution should // be found than simply doubling the row count. result.height() *= rows_m; } else { std::string placeholder(implementation::get_field_text(*this)); implementation::set_field_text(*this, base_text); // measure the control directly because we don't apply the // fudges yet; we want to do that with the edit text values result = implementation::measure(this->control_m); implementation::set_field_text(*this, placeholder); } result = implementation::apply_fudges(*this, result); edit_height_m = result.height(); edit_baseline_m = result.vertical().guide_set_m[0]; if (!using_label_m) return; extents_t label_bounds(implementation::measure_theme_text(implementation::get_name(get_label()), theme_m)); if (result.vertical().guide_set_m.size() && label_bounds.vertical().guide_set_m.size()) align_slices(result.vertical(), label_bounds.vertical()); result.horizontal() = implementation::merge_slices_with(result, metrics_m, label_bounds, get_label().metrics_m, extents_slices_t::horizontal); result.width() += implementation::global_metrics()(implementation::k_metric_gap); result.horizontal().guide_set_m.push_back(label_bounds.width()); static_width_m = label_bounds.width(); static_height_m = label_bounds.height(); static_baseline_m = label_bounds.vertical().guide_set_m.empty() ? 0 : label_bounds.vertical().guide_set_m[0]; }
void measure_vertical(label_t& value, extents_t& calculated_horizontal, const place_data_t& placed_horizontal) { assert(value.window_m); GG::Pt extent = implementation::DefaultFont()->TextExtent(value.name_m, value.format_m, GG::X(width(placed_horizontal))); calculated_horizontal.vertical().length_m = Value(extent.y); calculated_horizontal.vertical().guide_set_m.push_back( Value(implementation::DefaultFont()->Ascent())); }
void separator_t::measure(extents_t& result) { #ifdef BOOST_MSVC result.horizontal().length_m = 2; result.vertical().length_m = 2; #elif ADOBE_PLATFORM_MAC result.horizontal().length_m = is_vertical_m ? 5 : 6; result.vertical().length_m = is_vertical_m ? 6 : 5; #endif }
void image_t::measure_vertical(extents_t& result, const place_data_t& placed_horizontal) { if (callback_m) result.vertical().length_m = fixed_height; // REVISIT (fbrereto) : Fixed value else { // NOTE (fbrereto) : We calculate and use the aspect ratio here to // maintain a proper initial height and width in // the case when the image grew based on how it // is being laid out. float aspect_ratio(image_m.height() / static_cast<float>(image_m.width())); result.vertical().length_m = static_cast<long>(placed_horizontal.horizontal().length_m * aspect_ratio); } }
void measure_vertical(label_t& value, extents_t& result, const place_data_t& placed_horizontal) { // Note (fbrereto) : This is explicit (instead of using implementation::measure) because // we need to set the inbound rect to be the potential dimensions of the // text so the reflow will shrink the bounds if it needs to. assert(value.control_m.get()); ::Rect old_bounds = { 0 }; ::GetControlBounds(value.control_m.get(), &old_bounds); ::Rect static_bounds = { 0, 0, 2048, static_cast<short>(placed_horizontal.horizontal().length_m) }; ::Rect bounds = { 0 }; ::SInt16 best_baseline(0); implementation::set_bounds(value.control_m, static_bounds); ::GetBestControlRect(value.control_m.get(), &bounds, &best_baseline); result.height() = bounds.bottom - bounds.top; result.width() = bounds.right - bounds.left; if (best_baseline) result.vertical().guide_set_m.push_back(result.height() + best_baseline); result = implementation::apply_fudges(value, result); implementation::set_bounds(value.control_m, old_bounds); }
void display_text_t::measure_vertical(extents_t& calculated_horizontal, const place_data_t& placed_horizontal) { assert(window_m); extents_t::slice_t& vert = calculated_horizontal.vertical(); vert.length_m = Value(implementation::DefaultFont()->Lineskip()); vert.guide_set_m.push_back(Value(implementation::DefaultFont()->Ascent())); }
void link_t::measure(extents_t& result) { result.width() = 15; result.height() = 5; for (long i(0); i < count_m; ++i) result.vertical().guide_set_m.push_back(2); }
void display_number_t::measure_vertical(extents_t& calculated_horizontal, const place_data_t& placed_horizontal) { assert(window_m); place_data_t save_bounds; implementation::get_control_bounds(window_m, save_bounds); place_data_t static_bounds; top(static_bounds) = top(placed_horizontal); left(static_bounds) = left(placed_horizontal); width(static_bounds) = width(placed_horizontal); height(static_bounds) = 10000; // bottomless implementation::set_control_bounds(window_m, static_bounds); HDC hdc(::GetWindowDC(window_m)); std::string title(implementation::get_window_title(window_m)); std::wstring wtitle; to_utf16(title.begin(), title.end(), std::back_inserter(wtitle)); place_data_liukahr_t out_extent; // metrics::set_theme_name(L"Edit"); // // If we don't have the type of this widget, then we should return a // zero sized rectangle. This is usually correct, and a good assumption // anyway. // int uxtheme_type = EP_EDITTEXT; // // Get the text metrics (and calculate the baseline of this widget) // TEXTMETRIC widget_tm; bool have_tm = metrics::get_font_metrics(uxtheme_type, widget_tm); assert(have_tm); const place_data_liukahr_t in_extents = static_bounds; bool have_extents = metrics::get_text_extents(uxtheme_type, wtitle.c_str(), out_extent, &in_extents); assert(have_extents); extents_t::slice_t& vert = calculated_horizontal.vertical(); vert.length_m = height(out_extent); // set the baseline for the text metrics::set_window(window_m); if (have_tm) // distance from top to baseline vert.guide_set_m.push_back(widget_tm.tmHeight - widget_tm.tmDescent); implementation::set_control_bounds(window_m, save_bounds); }
void edit_text_t::measure(extents_t& result) { assert(control_m); // // The calculate_edit_bounds function can figure out the size this edit box // should be, based on the number of rows and columns. // result = calculate_edit_bounds(control_m, cols_m, rows_m); // // Store the height and baseline so that we can correctly align the edit widget // in set_bounds. // edit_height_m = result.height(); if (!result.vertical().guide_set_m.empty()) edit_baseline_m = result.vertical().guide_set_m[0]; // // If we have a label then we need to make extra space // for it. // if (!using_label_m) return; extents_t label_bounds; measure_label_text(get_label(), label_bounds, ::GetParent(control_m)); // // Make sure that the height can accomodate both the label // and the edit widget. // align_slices(result.vertical(), label_bounds.vertical()); // // We put the label on the left side of the edit box, and // place a point of interest at the end of the label, so // that colon alignment can be performed. // result.width() += gap + label_bounds.width(); result.horizontal().guide_set_m.push_back(label_bounds.width()); // // We use the height and baseline of the label to size and // align it in set_bounds. // static_height_m = label_bounds.height(); static_baseline_m = label_bounds.vertical().guide_set_m[0]; }
void color_button_t::measure(extents_t& result) { assert(control_m); result.width() = Value(original_size_m.x); result.height() = Value(original_size_m.y); boost::shared_ptr<GG::Font> font = implementation::DefaultFont(); GG::Y baseline_offset = (control_m->Height() - font->Height()) / 2; result.vertical().guide_set_m.push_back(Value(baseline_offset)); if (!using_label_m) return; extents_t label_bounds(measure_text(name_m.name_m, font)); label_bounds.vertical().guide_set_m.push_back(0); align_slices(result.vertical(), label_bounds.vertical()); result.width() += gap + label_bounds.width(); result.horizontal().guide_set_m.push_back(label_bounds.width()); }
void tab_group_t::measure(extents_t& result) { assert(control_m); // REVISIT (fbrereto) : A lot of static metrics values added here for (tab_set_t::iterator first(items_m.begin()), last(items_m.end()); first != last; ++first) { extents_t attrs; measure_label_text(label_t(first->name_m, std::string(), 0, theme_m), attrs, ::GetParent(control_m)); result.width() += attrs.width() + 18; result.height() = (std::max)(result.height(), attrs.height()); } result.vertical().frame_m.first = result.height() + 7; result.height() = 5; }
void tab_group_t::measure(extents_t& result) { assert(control_m); // REVISIT (fbrereto) : A lot of static metrics values added here boost::shared_ptr<GG::StyleFactory> style = GG::GUI::GetGUI()->GetStyleFactory(); for (tab_set_t::iterator first(items_m.begin()), last(items_m.end()); first != last; ++first) { GG::X text_width = style->DefaultFont()->TextExtent(first->name_m).x; result.width() += Value(text_width) + 18; } result.height() = Value(control_m->MinUsableSize().y); result.vertical().frame_m.first = result.height() + 7; result.height() = 5; }
void group_t::measure(extents_t& result) { assert(control_m); if (name_m.empty()) { result.height() = 15; result.width() = 15; return; } // REVISIT (fbrereto) : A lot of static metrics values added here result = measure_text(name_m, theme_m, ::GetParent(control_m)); result.width() += 15; result.vertical().frame_m.first = result.height() + 7; result.height() = 5; }
void popup_t::measure(extents_t& result) { assert(control_m); // // Make sure that metrics_t is initialized. // metrics::set_window(control_m); // // The popup_t has multiple text items. We need to find the one with // the widest extents (when drawn). Then we can make sure that we get // enough space to draw our largest text item. // menu_item_set_t::iterator first(menu_items_m.begin()); menu_item_set_t::iterator last(menu_items_m.end()); RECT largest_extents = { 0, 0, 0, 0 }; bool have_extents = false; // // Now iterate through all of our text. // while (first != last) { // // Discover the extents of this text! // RECT extents; if (metrics::get_text_extents(CP_DROPDOWNBUTTON, hackery::convert_utf(first->first), extents)) { // // Alright, we were able to obtain the required extents. // Now we just need to see if they are larger than the // ones we already have. // if ((extents.right - extents.left) > (largest_extents.right - largest_extents.left)) largest_extents = extents; have_extents = true; } ++first; } // // We don't really use much of UxTheme to discover the bounds of // the combobox. We can use the GetComboboxInfo function to get // most of the information we require (such as where the text will // lie). // TEXTMETRIC font_metrics; int border; bool have_metrics = metrics::get_font_metrics(CP_DROPDOWNBUTTON, font_metrics); bool have_border = metrics::get_integer(CP_DROPDOWNBUTTON, TMT_BORDERSIZE, border); COMBOBOXINFO cbi; cbi.cbSize = sizeof(cbi); if (GetComboBoxInfo(control_m, &cbi)) { RECT text = { 0, 0, 0, 0 }; // currently unused // RECT size = { 0, 0, 0, 0 }; WINDOWINFO wi = { 0 }; wi.cbSize = sizeof(wi); if (!GetWindowInfo(control_m, &wi)) ADOBE_THROW_LAST_ERROR; // // Figure out the borders around the text entry area. // text.left = wi.rcClient.left - wi.rcWindow.left + cbi.rcItem.left; text.right = wi.rcWindow.right - wi.rcClient.right + cbi.rcItem.right; text.top = wi.rcClient.top - wi.rcWindow.top + cbi.rcItem.top; text.bottom = wi.rcWindow.bottom - wi.rcWindow.bottom + cbi.rcItem.bottom; // // Figure out the dimensions for the entire control. // result.width() = text.left + largest_extents.right - largest_extents.left + cbi.rcButton.right - cbi.rcButton.left; result.height() = wi.rcWindow.bottom - wi.rcWindow.top; // // Deduce the baseline from the text rectangle. // int baseline = 0; if (have_metrics) { baseline = text.top + font_metrics.tmAscent; if (have_border) baseline += border; } result.vertical().guide_set_m.push_back(baseline); } else ADOBE_THROW_LAST_ERROR; // // If we have a label (always on our left side?) then we // need to add the size of the label to our result. We try // to align the label with the popup by baseline. Which is // kind of what Eve does, so it's bad that we do this // ourselves, really... // if (!using_label_m) return; // // We store the height of the label, from this we can // figure out how much to offset it when positioning // the widgets in set_bounds. // extents_t label_bounds; measure_label_text(name_m, label_bounds, ::GetParent(control_m)); static_height_m = label_bounds.height(); static_baseline_m = label_bounds.vertical().guide_set_m[0]; // // Now we can align the label within the vertical // slice of the result. This doesn't do anything if // the label is shorter than the popup. // align_slices(result.vertical(), label_bounds.vertical()); // // Add the width of the label (plus a gap) to the // resulting width. // result.width() += gap + label_bounds.width(); // // Don't let the width of the popup go too crazy now... // result.width() = std::min<long>(static_cast<long>(result.width()), 300); // REVISIT (fbrereto) : fixed width // // Add a point-of-interest where the label ends. // We put the label to the left of the popup. // result.horizontal().guide_set_m.push_back(label_bounds.width()); return; }