|
From: Foster B. <fos...@us...> - 2006-02-23 23:29:31
|
Update of /cvsroot/adobe-source/sandbox/adobe-source/adobe/future/widgets/sources/win32 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25760/adobe/future/widgets/sources/win32 Modified Files: metrics.cpp ui_core_implementation.cpp Added Files: label_t_impl.cpp Log Message: the state of things. We've been working to isolate static_text_t (now called label_t) but it has been slow going because we're trying to wrestle with perfecting the API and what effect that has on other components that were using label_t in a way that isn't in accordance with the new API we're trying to write. As it stands static_disabled_text_m is broken on both platforms, but everything else should be working better. Index: metrics.cpp =================================================================== RCS file: /cvsroot/adobe-source/sandbox/adobe-source/adobe/future/widgets/sources/win32/metrics.cpp,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** metrics.cpp 3 Feb 2006 18:33:37 -0000 1.2 --- metrics.cpp 23 Feb 2006 23:28:56 -0000 1.3 *************** *** 20,24 **** #include <stdexcept> #include <tchar.h> ! #include <cstring> #include <boost/static_assert.hpp> --- 20,24 ---- #include <stdexcept> #include <tchar.h> ! #include <cassert> #include <cstring> #include <boost/static_assert.hpp> *************** *** 34,37 **** --- 34,39 ---- namespace adobe { + + const RECT metrics_t::kBigExtents = {0, 0, 10000, 10000}; /****************************************************************************************************/ // *************** *** 64,67 **** --- 66,73 ---- class_name_m = class_name_buf; return true; + } + void set_theme_name(const WCHAR* theme_name) + { + class_name_m = theme_name; } bool get_font(int widget_type, LOGFONTW& out_font) const *************** *** 104,108 **** return hackery::cast<bool>(have_metrics); } ! bool get_text_extents(int widget_type, std::wstring text, RECT& out_extents) const { // --- 110,114 ---- return hackery::cast<bool>(have_metrics); } ! bool get_text_extents(int widget_type, std::wstring text, RECT& out_extents, const RECT*) const { // *************** *** 418,427 **** return false; } ! // ! // Previously we had implementations of get_font_metrics and get_text_extents ! // which used the UXTheme API. We were not getting the values back that we ! // expected, so we now use the Win32 API for getting those measurements (although ! // note that we still get the actual widget font with UxTheme). ! // bool get_integer(int widget_type, int measurement, int& out_val) const { --- 424,467 ---- return false; } ! bool get_font_metrics(int widget_type, TEXTMETRIC& out_metrics) const ! { ! HDC tmp_dc = GetDC(0); ! ! bool have_metrics = S_OK == (*GetThemeTextMetricsPtr)(theme_m, tmp_dc, widget_type, kState, &out_metrics); ! ! ReleaseDC(0, tmp_dc); ! return hackery::cast<bool>(have_metrics); ! } ! ! bool get_text_extents(int widget_type, std::wstring text, RECT& out_extents, const RECT* in_extents) const ! { ! if(!in_extents) in_extents=&kBigExtents; ! // ! // Create the font and select it into a temporary device context. ! // ! HDC tmp_dc = GetDC(0); ! LOGFONTW logical_font = {0}; ! HGDIOBJ font = 0; ! // ! // Try to use get_font, in case there is another font we're meant ! // to use. Then fallback on DEFAULT_GUI_FONT. ! // ! if (get_font(widget_type, logical_font)) ! { ! font = (HGDIOBJ)CreateFontIndirectW(&logical_font); ! } ! assert(font); ! // ! // Extract the extents. ! // ! HGDIOBJ original_font = SelectObject(tmp_dc, font); ! BOOL have_extents = S_OK == (*GetThemeTextExtentPtr)(theme_m, tmp_dc, widget_type, kState, text.c_str(), static_cast<int>(text.size()), DT_CALCRECT + DT_WORDBREAK, in_extents, &out_extents); ! // ! // Clean up, and convert the size to a rect. ! // ! DeleteObject(SelectObject(tmp_dc, original_font)); ! ReleaseDC(0, tmp_dc); ! return hackery::cast<bool>(have_extents); ! } bool get_integer(int widget_type, int measurement, int& out_val) const { --- NEW FILE: label_t_impl.cpp --- #include <windows.h> #include <uxtheme.h> #include <tmschema.h> #define SCHEME_STRINGS 1 #include <tmschema.h> //Yes, we include this twice -- read the top of the file #include "event_dispatcher.hpp" #include "ui_core.hpp" #include "ui_core_common.hpp" #include "ui_core_implementation.hpp" #include "adobe/unicode.hpp" #include "wincast.hpp" #include "metrics.hpp" #include "label_t_impl.hpp" #include "display.hpp" #include <string> #include <cassert> /****************************************************************************************************/ #define ADOBE_THROW_LAST_ERROR adobe::implementation::throw_last_error_exception(__FILE__, __LINE__) /****************************************************************************************************/ namespace adobe { /****************************************************************************************************/ namespace implementation { /****************************************************************************************************/ extern void throw_last_error_exception(const char* file, long line); /****************************************************************************************************/ } // namespace implementation /****************************************************************************************************/ label_t::implementation_t::implementation_t(const std::string& name, std::size_t characters, theme_t theme) : characters_m(characters), theme_m(theme) { RECT bounds = { 0, 0, 100, 100 }; initialize(bounds, name); } /****************************************************************************************************/ label_t::implementation_t::implementation_t(const implementation_t& rhs) : characters_m(rhs.characters_m), theme_m(rhs.theme_m) { RECT bounds; implementation::get_control_bounds(rhs.window_m.get(), bounds); initialize(bounds, implementation::get_window_title(rhs.window_m.get())); } /****************************************************************************************************/ label_t::implementation_t& label_t::implementation_t::operator=(const implementation_t& rhs) { characters_m = rhs.characters_m; theme_m = rhs.theme_m; RECT bounds; implementation::get_control_bounds(rhs.window_m.get(), bounds); initialize(bounds, implementation::get_window_title(rhs.window_m.get())); return *this; } /****************************************************************************************************/ label_t::implementation_t::~implementation_t() { } /****************************************************************************************************/ void label_t::implementation_t::place(const point_2d_t& position, const extents_t& extents) { RECT new_bounds = { position.x_m, position.y_m, position.x_m + extents.width(), position.y_m + extents.height() }; implementation::set_control_bounds(window_m.get(), new_bounds); } /****************************************************************************************************/ void label_t::implementation_t::enable(bool make_enabled) { ::EnableWindow(window_m.get(), make_enabled); } /****************************************************************************************************/ void label_t::implementation_t::initialize( const RECT& bounds, const std::string& name) { bounds_m = bounds; name_m = name; long width(bounds.right - bounds.left); long height(bounds.bottom - bounds.top); std::string lname(adobe::localize(name)); window_m.reset( ::CreateWindowExA( WS_EX_COMPOSITED, "STATIC", lname.c_str(), WS_CHILD | WS_VISIBLE, bounds.left, bounds.top, width, height, invisible_parent(), NULL, ::GetModuleHandle(NULL), NULL)); if (window_m.get() == NULL) ADOBE_THROW_LAST_ERROR; set_font(window_m.get(), EP_EDITTEXT, L"Edit"); // set_user_reference(window_m, this); // default_window_proc_m = trap_window_proc(window_m, label_window_proc); } /****************************************************************************************************/ extents_t::slice_t label_t::implementation_t::measure_horizontal() { assert(window_m.get()); metrics_t::get_instance().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_m = EP_EDITTEXT; // // Discover the size of the widget. // SIZE widget_size; bool have_size = metrics_t::get_instance().get_size(uxtheme_type_m, TS_DRAW, widget_size); // // Discover any margins of this widget. // MARGINS widget_margins; bool have_margins = metrics_t::get_instance().get_margins(uxtheme_type_m, widget_margins); // // Get the text metrics (and calculate the baseline of this widget) // TEXTMETRIC widget_tm; bool have_tm = metrics_t::get_instance().get_font_metrics(uxtheme_type_m, widget_tm); // // We need the text dimensions to figure out what the width of the widget should // be. // RECT text_extents; RECT in_extents = {0,0,10000,10000}; if(characters_m){ std::wstring wrap(characters_m * 2, L'0'); bool have_extents = metrics_t::get_instance().get_text_extents(uxtheme_type_m, wrap.c_str(), text_extents, &in_extents); assert(have_extents); in_extents = text_extents; in_extents.bottom = 10000; } std::wstring wname; to_utf16(name_m.begin(), name_m.end(), back_inserter(wname)); bool have_extents = metrics_t::get_instance().get_text_extents(uxtheme_type_m, wname.c_str(), text_extents, &in_extents); // // Get any border the widget may have. // int border; bool have_border = metrics_t::get_instance().get_integer(uxtheme_type_m, TMT_BORDERSIZE, border); // // Now we can calculate the size we want to return. // extents_t::slice_t result; result.length_m = text_extents.right - text_extents.left; assert(result.length_m); // have_size ? &widget_size : 0; /*, have_margins ? &widget_margins : 0, have_tm ? &widget_tm : 0, have_extents ? &text_extents : 0, have_border ? &border : 0);*/ return result; } extents_t::slice_t label_t::implementation_t::measure_vertical(const extents_t::slice_t& horizontal) { assert(window_m.get()); RECT static_bounds = { 0, 0, horizontal.length_m, 10000 /* bottomless */}; implementation::set_control_bounds(window_m.get(), static_bounds); HDC hdc(::GetWindowDC(window_m.get())); std::string title(implementation::get_window_title(window_m.get())); std::wstring wtitle; adobe::to_utf16(title.begin(), title.end(), std::back_inserter(wtitle)); RECT out_extent; metrics_t::get_instance().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_m = EP_EDITTEXT; // // Get the text metrics (and calculate the baseline of this widget) // TEXTMETRIC widget_tm; bool have_tm = metrics_t::get_instance().get_font_metrics(uxtheme_type_m, widget_tm); assert(have_tm); bool have_extents = metrics_t::get_instance().get_text_extents(uxtheme_type_m, wtitle.c_str(), out_extent, &static_bounds); assert(have_extents); extents_t::slice_t vert; vert.length_m = out_extent.bottom - out_extent.top; // set the baseline for the text if (have_tm) // distance from top to baseline vert.poi_m.push_back(widget_tm.tmHeight - widget_tm.tmDescent); return vert; // // Now we can calculate the size we want to return. // //return calculate_best_bounds(have_size ? &widget_size : 0, have_margins ? &widget_margins : 0, // have_tm ? &widget_tm : 0, have_extents ? &text_extents : 0, have_border ? &border : 0); } /****************************************************************************************************/ template <> HWND view_for_element< HWND, adobe::label_t >(adobe::label_t& widget) { return widget.implementation().window_m.get(); } /****************************************************************************************************/ template <> display_t::position_t insert<adobe::label_t>(display_t& display, display_t::position_t& parent, adobe::label_t& element) { HWND ref(adobe::view_for_element< HWND >(element)); return display.insert<HWND>(parent, ref); } /****************************************************************************************************/ } // namespace adobe /****************************************************************************************************/ Index: ui_core_implementation.cpp =================================================================== RCS file: /cvsroot/adobe-source/sandbox/adobe-source/adobe/future/widgets/sources/win32/ui_core_implementation.cpp,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** ui_core_implementation.cpp 3 Feb 2006 18:33:37 -0000 1.3 --- ui_core_implementation.cpp 23 Feb 2006 23:28:56 -0000 1.4 *************** *** 22,25 **** --- 22,26 ---- #include <adobe/algorithm.hpp> #include <adobe/dictionary.hpp> + #include <adobe/unicode.hpp> #include <boost/cstdint.hpp> *************** *** 53,60 **** --- 54,108 ---- /****************************************************************************************************/ [...1590 lines suppressed...] + void adobe::implementation::get_control_bounds(HWND control, RECT& bounds) + { + assert(control); + + ::GetWindowRect(control, &bounds); + } + + /****************************************************************************************************/ + + void adobe::implementation::set_control_bounds(HWND control, const RECT& bounds) + { + assert(control); + + long width = bounds.right - bounds.left; + long height = bounds.bottom - bounds.top; + + ::MoveWindow(control, bounds.left, bounds.top, width, height, TRUE); + } + + /****************************************************************************************************/ |