|
From: Foster B. <fos...@us...> - 2006-02-03 18:21:23
|
Update of /cvsroot/adobe-source/adobe-source/adobe/future/widgets/headers/mac In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1031/adobe/future/widgets/headers/mac Modified Files: carbon_safe.hpp metrics.hpp ui_core_implementation.hpp Added Files: metric_extractor.hpp os_utilities.hpp Log Message: asl 1.0.13 Index: carbon_safe.hpp =================================================================== RCS file: /cvsroot/adobe-source/adobe-source/adobe/future/widgets/headers/mac/carbon_safe.hpp,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** carbon_safe.hpp 6 Jan 2006 18:35:21 -0000 1.4 --- carbon_safe.hpp 3 Feb 2006 18:20:44 -0000 1.5 *************** *** 1,6 **** /* ! Copyright 2005-2006 Adobe Systems Incorporated ! Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt ! or a copy at http://opensource.adobe.com/licenses.html) */ --- 1,6 ---- /* ! Copyright 2005-2006 Adobe Systems Incorporated ! Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt ! or a copy at http://opensource.adobe.com/licenses.html) */ *************** *** 20,24 **** #ifdef __MWERKS__ ! #pragma warn_implicitconv off #endif --- 20,24 ---- #ifdef __MWERKS__ ! #pragma warn_implicitconv off #endif *************** *** 26,42 **** #ifdef __MWERKS__ ! #pragma warn_implicitconv reset #endif /* ! REVISIT (sparent) : Apple insists that you include the entire Carbon/Carbon.h framework to ! use any of Carbon. This header file #defines check which conflicts with boost. The work- ! around is to undef check here. ! ! (In an unbelieveable set of circumstances, I wrote the check macro!) */ #ifdef check ! #undef check #endif --- 26,42 ---- #ifdef __MWERKS__ ! #pragma warn_implicitconv reset #endif /* ! REVISIT (sparent) : Apple insists that you include the entire Carbon/Carbon.h framework to ! use any of Carbon. This header file #defines check which conflicts with boost. The work- ! around is to undef check here. ! ! (In an unbelieveable set of circumstances, I wrote the check macro!) */ #ifdef check ! #undef check #endif *************** *** 50,95 **** { public: ! os_exception(long status, const char* file, long line) throw() ! { ! try ! { ! std::stringstream t; ! t << status; ! format(t.str().c_str(), file, line); ! } ! catch (...) ! { } ! } ! os_exception(const char* status, const char* file, long line) throw() ! { ! format(status, file, line); ! } ! os_exception(const std::string& status, const char* file, long line) throw() ! { ! format(status.c_str(), file, line); ! } ! ~os_exception() throw() {} ! const char* what () const throw() ! { return what_m.c_str(); } private: ! void format(const char* status, const char* file, long line) ! { ! try ! { ! std::stringstream t; ! t << "Error: " << status << " (" << file << ", line " << line << ")"; ! what_m.assign(t.str()); ! } ! catch (...) ! { } ! } ! std::string what_m; }; --- 50,95 ---- { public: ! os_exception(long status, const char* file, long line) throw() ! { ! try ! { ! std::stringstream t; ! t << status; ! format(t.str().c_str(), file, line); ! } ! catch (...) ! { } ! } ! os_exception(const char* status, const char* file, long line) throw() ! { ! format(status, file, line); ! } ! os_exception(const std::string& status, const char* file, long line) throw() ! { ! format(status.c_str(), file, line); ! } ! ~os_exception() throw() {} ! const char* what () const throw() ! { return what_m.c_str(); } private: ! void format(const char* status, const char* file, long line) ! { ! try ! { ! std::stringstream t; ! t << "Error: " << status << " (" << file << ", line " << line << ")"; ! what_m.assign(t.str()); ! } ! catch (...) ! { } ! } ! std::string what_m; }; *************** *** 101,120 **** // REVISIT (fbrereto) : Turn this back on when we have an interface to handle ! // errors on the callback side of the OS event loop #if 0 inline void ADOBE_REQUIRE_STATUS_impl(long status, char* file, long line) { ! if (status != 0) throw adobe::os_exception(status, file, line); } #else inline void ADOBE_REQUIRE_STATUS_impl(long status, char*, long) { ! if (status != 0) ::SysBeep(10); } #endif /*************************************************************************************************/ ! #define ADOBE_REQUIRE_STATUS(x) adobe::implementation::ADOBE_REQUIRE_STATUS_impl((x), __FILE__, __LINE__) /****************************************************************************************************/ --- 101,120 ---- // REVISIT (fbrereto) : Turn this back on when we have an interface to handle ! // errors on the callback side of the OS event loop #if 0 inline void ADOBE_REQUIRE_STATUS_impl(long status, char* file, long line) { ! if (status != 0) throw adobe::os_exception(status, file, line); } #else inline void ADOBE_REQUIRE_STATUS_impl(long status, char*, long) { ! if (status != 0) ::SysBeep(10); } #endif /*************************************************************************************************/ ! #define ADOBE_REQUIRE_STATUS(x) adobe::implementation::ADOBE_REQUIRE_STATUS_impl((x), __FILE__, __LINE__) /****************************************************************************************************/ Index: metrics.hpp =================================================================== RCS file: /cvsroot/adobe-source/adobe-source/adobe/future/widgets/headers/mac/metrics.hpp,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** metrics.hpp 6 Jan 2006 18:35:21 -0000 1.4 --- metrics.hpp 3 Feb 2006 18:20:44 -0000 1.5 *************** *** 1,6 **** /* ! Copyright 2005-2006 Adobe Systems Incorporated ! Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt ! or a copy at http://opensource.adobe.com/licenses.html) */ --- 1,6 ---- /* ! Copyright 2005-2006 Adobe Systems Incorporated ! Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt ! or a copy at http://opensource.adobe.com/licenses.html) */ *************** *** 24,28 **** /****************************************************************************************************/ ! adobe::dictionary_t widget_metrics(const std::string& xstr, const adobe::dictionary_t& context); /****************************************************************************************************/ --- 24,29 ---- /****************************************************************************************************/ ! adobe::dictionary_t widget_metrics( const std::string& xstr, ! const adobe::dictionary_t& context = adobe::dictionary_t()); /****************************************************************************************************/ --- NEW FILE: metric_extractor.hpp --- /* Copyright 2005-2006 Adobe Systems Incorporated Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt or a copy at http://opensource.adobe.com/licenses.html) */ /****************************************************************************************************/ #ifndef ADOBE_METRICS_EXTRACTOR_MAC_HPP #define ADOBE_METRICS_EXTRACTOR_MAC_HPP /****************************************************************************************************/ #include <adobe/config.hpp> #include <adobe/dictionary_fwd.hpp> /****************************************************************************************************/ namespace adobe { /****************************************************************************************************/ /*! \defgroup widget_metrics_mac Mac Widget Metrics \ingroup widget_lib \section widget_metrics_mac_parameters Parameters The following is a list of metrics one can supply for a widget on the Mac. All values are in unit pixels. All values default to 0. <table width="100%" border="1"> <tr><th width="10%">Name</th><th width="30%">Structure</th><th>Notes</th></tr> <tr> <td><code>size</code></td> <td><code>[ width, height ]</code></td> <td>Base size of the widget</td> </tr> <tr> <td><code>adjust_position</code></td> <td><code>[ left, top ]</code></td> <td>Number of pixels to push the widget. Positive values move the widget away from the origin of the window.</td> </tr> <tr> <td><code>adjust_size</code></td> <td><code>[ width, height ]</code></td> <td>Adjustments made to the base size of the widget. The adjusted size is passed to the OS so the resulting widget is the base size originally intended.</td> </tr> <tr> <td><code>adjust_baseline</code></td> <td><code>value</code></td> <td>Adjustment of the baseline. Positive values move the baseline away from the origin of the window.</td> </tr> <tr> <td><code>outset</code></td> <td><code>[ left, top, right, bottom ]</code></td> <td>Amount of outset for a given edge of the widget. These amounts affect the base size and position of the widget when the bounds of the widget are set. See \ref widget_metrics_mac_pipeline_placement.</td> </tr> <tr> <td><code>frame</code></td> <td><code>[ left, top, right, bottom ]</code></td> <td>Amount of frame for a given edge of the widget.</td> </tr> <tr> <td><code>inset</code></td> <td><code>[ left, top, right, bottom ]</code></td> <td>Amount of inset for a given edge of the widget.</td> </tr> <tr> <td><code>spacing</code></td> <td><code>value</code></td> <td>If there is text in the widget, this is the spacing needed between the widget's visual element and the text for the widget. Example: <code>check_box</code> has a nonzero spacing, but <code>button</code> has a spacing of 0 (because the text overlays the visual element).</td> </tr> </table> \section widget_metrics_mac_pipelines Metrics Pipelines \subsection widget_metrics_mac_pipeline_measurement Measurement Pipeline -# All the possible text strings for the widget are measured. The largest width, height and baseline are preserved on a per-element basis (i.e., it is possible for one piece of text to contribute the max width and another to contribute the max height) -# The base height of the widget is set to <code>size.height - adjust_size.height</code> -# The base width of the widget is set to <code>size.width - adjust_size.width</code> -# If text width is nonzero then <code>text_width + spacing</code> is added to the base width of the widget -# If there is a valid text baseline value the baseline of the result is set to <code>text_baseline + adjust_baseline</code> -# The <code>outset.left</code> is added to the resultant left outset -# The <code>outset.left + outset.right</code> is <i>subtracted</i> from the resultant right outset -# The <code>outset.top</code> is added to the resultant top outset -# The <code>outset.top + outset.bottom</code> is <i>subtracted</i> from the resultant bottom outset -# Resultant frame is set from <code>frame</code> -# Resultant inset is set from <code>inset</code> -# The resultant extents is returned \subsection widget_metrics_mac_pipeline_placement Placement Pipeline -# <code>adjust_position.left - extents.outset.left</code> is added to the left position of the widget -# <code>adjust_position.top - extents.outset.top</code> is added to the top position of the widget -# The height of the widget is increased by <code>adjust_size.height + extents.outset.top + extents.outset.bottom</code> -# The width of the widget is increased by <code>adjust_size.width + extents.outset.left + extents.outset.right</code> -# The bounds of the widget are set */ /*! \ingroup widget_lib \brief Utility class to access widget metrics for the Macintosh. metric_extractor_t is a struct that allows for easy access to the metrics found in a parsed and evaluated xstr definition from the mac metrics library. See \ref widget_metrics_mac for more information on the dictionary format describing the metrics for a given widget. */ struct metric_extractor_t { /// indices used to access elements for a compound (array-based) metric enum array_index_t { /// first element index_left = 0, /// second element index_top = 1, /// third element index_right = 2, /// fourth element index_bottom = 3, /// same as index_left index_width = index_left, /// same as index_top index_height = index_top }; /// \param dictionary the dictionary containing the widget metrics. /// Internally the dictionary is stored by value. explicit metric_extractor_t(const adobe::dictionary_t& dictionary = adobe::dictionary_t()) : dictionary_m(dictionary) { } /// Obtains a singleton metric /// \param tag the name of the metric we are interested in getting /// \return the value of the metric; 0 if the metric does not exist long operator () (const name_t& tag) const { long result(0); dictionary_m.get(tag, result); return result; } /// Obtains a singleton metric from a compound (array-based) metric /// \param tag the name of the metric we are interested in getting /// \param index the index inside the compound metric to fetch /// \return the value of the metric; 0 if the metric does not exist long operator () (const name_t& tag, array_index_t index) const { adobe::array_t array_result; long result(0); dictionary_m.get(tag, array_result); array_result.get(std::size_t(index), result); return result; } /// If this extractor hasn't been setup yet then this function returns /// true, otherwise it returns false. /// \return does this extractor have metrics available. bool empty() const { return dictionary_m.empty(); } private: adobe::dictionary_t dictionary_m; }; /****************************************************************************************************/ } /****************************************************************************************************/ #endif /****************************************************************************************************/ Index: ui_core_implementation.hpp =================================================================== RCS file: /cvsroot/adobe-source/adobe-source/adobe/future/widgets/headers/mac/ui_core_implementation.hpp,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** ui_core_implementation.hpp 6 Jan 2006 18:35:21 -0000 1.6 --- ui_core_implementation.hpp 3 Feb 2006 18:20:44 -0000 1.7 *************** *** 1,11 **** /* ! Copyright 2005-2006 Adobe Systems Incorporated ! Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt ! or a copy at http://opensource.adobe.com/licenses.html) */ /****************************************************************************************************/ ! #ifndef ADOBE_UI_CORE_IMPLEMENTATION_HPP #define ADOBE_UI_CORE_IMPLEMENTATION_HPP [...1775 lines suppressed...] /****************************************************************************************************/ + /****************************************************************************************************/ + /****************************************************************************************************/ + /****************************************************************************************************/ + /****************************************************************************************************/ + /****************************************************************************************************/ + /****************************************************************************************************/ ADOBE_SERIALIZABLE_EQUALITY_COMPARABLE_BOILERPLATE_DECLARATION(adobe::window_t::implementation_t); ADOBE_SERIALIZABLE_EQUALITY_COMPARABLE_BOILERPLATE_DECLARATION(adobe::group_t::implementation_t); ADOBE_SERIALIZABLE_EQUALITY_COMPARABLE_BOILERPLATE_DECLARATION(adobe::tab_group_t::implementation_t); *************** *** 804,808 **** ADOBE_SERIALIZABLE_EQUALITY_COMPARABLE_BOILERPLATE_DECLARATION(adobe::unit_edit_text_t::implementation_t); ADOBE_SERIALIZABLE_EQUALITY_COMPARABLE_BOILERPLATE_DECLARATION(adobe::slider_t::implementation_t); - ADOBE_SERIALIZABLE_EQUALITY_COMPARABLE_BOILERPLATE_DECLARATION(adobe::bevel_button_t::implementation_t); /****************************************************************************************************/ --- 1044,1047 ---- --- NEW FILE: os_utilities.hpp --- /* Copyright 2005-2006 Adobe Systems Incorporated Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt or a copy at http://opensource.adobe.com/licenses.html) */ /****************************************************************************************************/ #ifndef ADOBE_UI_CORE_OS_UTILITIES_HPP #define ADOBE_UI_CORE_OS_UTILITIES_HPP /****************************************************************************************************/ #include <adobe/config.hpp> #include <adobe/istream.hpp> #include <adobe/future/memory.hpp> #include <adobe/unicode.hpp> #include "carbon_safe.hpp" #include "ui_core.hpp" #include "ui_core_common.hpp" #include "metrics.hpp" #include "metric_extractor.hpp" #include <boost/noncopyable.hpp> #include <stdexcept> /****************************************************************************************************/ inline bool operator == (const ::EventTypeSpec& x, const ::EventTypeSpec& y) { return x.eventClass == y.eventClass && x.eventKind == y.eventKind; } /****************************************************************************************************/ namespace adobe { /****************************************************************************************************/ #define ADOBE_DELETE_PTR_SPECIALIZATION(type, func) \ template<> \ struct delete_ptr<type> \ { \ void operator()(type x) const \ { if (x) func(x); } \ }; /****************************************************************************************************/ //ADOBE_DELETE_PTR_SPECIALIZATION(::CGrafPtr, ::DisposePort) //ADOBE_DELETE_PTR_SPECIALIZATION(::MouseTrackingRef, ::ReleaseMouseTrackingRegion) //ADOBE_DELETE_PTR_SPECIALIZATION(::RgnHandle, ::DisposeRgn) ADOBE_DELETE_PTR_SPECIALIZATION(::ATSUStyle, ::ATSUDisposeStyle) ADOBE_DELETE_PTR_SPECIALIZATION(::ATSUTextLayout, ::ATSUDisposeTextLayout) ADOBE_DELETE_PTR_SPECIALIZATION(::CFBundleRef, ::CFRelease) ADOBE_DELETE_PTR_SPECIALIZATION(::CFLocaleRef, ::CFRelease) ADOBE_DELETE_PTR_SPECIALIZATION(::CFMutableDictionaryRef, ::CFRelease) ADOBE_DELETE_PTR_SPECIALIZATION(::CFNumberFormatterRef, ::CFRelease) ADOBE_DELETE_PTR_SPECIALIZATION(::CFStringRef, ::CFRelease) ADOBE_DELETE_PTR_SPECIALIZATION(::CFURLRef, ::CFRelease) ADOBE_DELETE_PTR_SPECIALIZATION(::CGDataProviderRef, ::CFRelease) ADOBE_DELETE_PTR_SPECIALIZATION(::CGImageRef, ::CFRelease) ADOBE_DELETE_PTR_SPECIALIZATION(::ControlEditTextValidationUPP, ::DisposeControlEditTextValidationUPP) ADOBE_DELETE_PTR_SPECIALIZATION(::EventHandlerRef, ::RemoveEventHandler) ADOBE_DELETE_PTR_SPECIALIZATION(::EventHandlerUPP, ::DisposeEventHandlerUPP) ADOBE_DELETE_PTR_SPECIALIZATION(::EventLoopTimerRef, ::RemoveEventLoopTimer) ADOBE_DELETE_PTR_SPECIALIZATION(::Handle, ::DisposeHandle) ADOBE_DELETE_PTR_SPECIALIZATION(::WindowRef, ::ReleaseWindow) /****************************************************************************************************/ namespace implementation { /****************************************************************************************************/ extern adobe::static_name_t k_attribute_theme; extern adobe::static_name_t k_attribute_theme_large; extern adobe::static_name_t k_attribute_theme_normal; extern adobe::static_name_t k_attribute_theme_small; extern adobe::static_name_t k_attribute_theme_mini; extern adobe::static_name_t k_metric_gap; extern adobe::static_name_t k_metric_size; extern adobe::static_name_t k_metric_adjust_position; extern adobe::static_name_t k_metric_adjust_size; extern adobe::static_name_t k_metric_adjust_baseline; extern adobe::static_name_t k_metric_outset; extern adobe::static_name_t k_metric_frame; extern adobe::static_name_t k_metric_inset; extern adobe::static_name_t k_metric_spacing; /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ std::string cfstring_to_string(::CFStringRef x); /****************************************************************************************************/ inline std::string cfstring_to_string(const adobe::auto_resource< ::CFStringRef >& x) { return cfstring_to_string(x.get()); } /****************************************************************************************************/ inline adobe::auto_resource< ::CFStringRef > string_to_cfstring(const std::string& x) { adobe::auto_resource< ::CFStringRef > converted(::CFStringCreateWithCString( NULL, x.c_str(), kCFStringEncodingUTF8)); return converted; } /****************************************************************************************************/ inline adobe::auto_resource< ::CFStringRef > localize_to_cfstring(const std::string& x) { return string_to_cfstring(adobe::localize(x)); } /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ template <typename T> struct event_param_type; template <> struct event_param_type< ::UInt32 > { static const ::EventParamType value = typeUInt32; }; template <> struct event_param_type< ::HICommand > { static const ::EventParamType value = typeHICommand; }; template <> struct event_param_type< ::ControlPartCode > { static const ::EventParamType value = typeControlPartCode; }; /****************************************************************************************************/ template < ::EventParamName name, typename T> void get_event_parameter(::EventRef the_event, T& value) { ::EventParamType actual_type; ::UInt32 actual_size; ::ADOBE_REQUIRE_STATUS(::GetEventParameter( the_event, name, event_param_type<T>::value, &actual_type, sizeof(T), &actual_size, &value)); if (actual_type != event_param_type<T>::value) throw std::runtime_error("get_event_parameter differing types"); if (actual_size != sizeof(T)) throw std::runtime_error("get_event_parameter differing sizes"); } /****************************************************************************************************/ template <typename T> bool get_widget_data(::ControlRef widget, ::ControlPartCode part, ::ResType tag, T& data, bool throwing = true) { ::Size t_size(sizeof(T)); ::Size actual_size(0); ::OSStatus result(::GetControlData(widget, part, tag, t_size, &data, &actual_size)); if (!throwing) return result == noErr; ::ADOBE_REQUIRE_STATUS(result); assert(t_size == actual_size); return true; } /****************************************************************************************************/ inline unsigned long get_current_tick_time() { return ::EventTimeToTicks(::GetLastUserEventTime()); } /****************************************************************************************************/ template <typename Widget> inline boost::uint32_t get_value(const Widget& widget) { return get_value< ::ControlRef >(widget.control_m); } /****************************************************************************************************/ template <> inline boost::uint32_t get_value< ::ControlRef >(const ::ControlRef& control) { if (!control) return 0; return ::GetControl32BitValue(control); } /****************************************************************************************************/ template <typename T> void get_bounds(const T& widget, ::Rect& bounds, bool absolute = false); /****************************************************************************************************/ template <> void get_bounds< ::ControlRef >(const ::ControlRef& control, ::Rect& bounds, bool absolute); /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /// The field text is text that relates to (e.g. a popup) or is (e.g. an edit text) the value of the /// widget. This is different from the label, as the field text corresponds directly to the value this /// widget helps manage. If a widget has no field text (e.g. a checkbox) this function is undefined. template <typename T> std::string get_field_text(T&); /****************************************************************************************************/ template <> std::string get_field_text< ::ControlRef >(::ControlRef& control); /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ std::string get_name(const ::ControlRef& control); /****************************************************************************************************/ std::string get_name(const ::WindowRef& window); /****************************************************************************************************/ /// The name is text that decorates the widget, but is not related to the value of the /// widget itself. For widgets that have no extra-text decorations, this function is undefined. /// Note that a static text widget is a name by definition. template <typename Widget> std::string get_name(const Widget& widget) { return get_name(widget.control_m); } /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ inline ::ATSUFontID get_atsui_font_id(const char* font_name, std::size_t name_length) { ::ATSUFontID atsui_font_id; ::ADOBE_REQUIRE_STATUS(::ATSUFindFontFromName( font_name, name_length, static_cast<unsigned long>(kFontNoName), kFontNoPlatformCode, kFontNoScriptCode, kFontNoLanguageCode, &atsui_font_id)); return atsui_font_id; } /****************************************************************************************************/ inline ::ATSUFontID get_atsui_font_id(const char* font_name) { return get_atsui_font_id(font_name, std::strlen(font_name)); } /****************************************************************************************************/ ::FMFontFamily get_classic_font_id(const char* font_name, std::size_t name_length); /****************************************************************************************************/ inline ::FMFontFamily get_classic_font_id(const char* font_name) { return get_classic_font_id(font_name, std::strlen(font_name)); } /****************************************************************************************************/ inline ::FMFontFamily get_classic_font_id(Str255 font_name) { const char* first(reinterpret_cast<char*>(&font_name[1])); const char* last(first + font_name[0]); std::string font_name_c(first, last); return get_classic_font_id(font_name_c.c_str(), font_name_c.size()); } /****************************************************************************************************/ inline ::ThemeFontID theme_to_ThemeFontID(const adobe::theme_t& style) { adobe::theme_t masked(style & adobe::theme_mask_s); ::ThemeFontID font_id(kThemeSystemFont); switch (masked) { case adobe::theme_mini_s: font_id = kThemeMiniSystemFont; break; case adobe::theme_small_s: font_id = kThemeSmallSystemFont; break; case adobe::theme_large_s: case adobe::theme_normal_s: default: font_id = kThemeSystemFont; break; } return font_id; } /****************************************************************************************************/ template <typename T> void atsu_set_attribute(::ATSUStyle style, ::ATSUAttributeTag tag, T value) { ::ByteCount size = sizeof(value); ::ATSUAttributeValuePtr ptr = &value; ADOBE_REQUIRE_STATUS(::ATSUSetAttributes(style, 1, &tag, &size, &ptr)); } /****************************************************************************************************/ adobe::extents_t get_text_dimensions(const std::string& text, adobe::theme_t theme); /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ void theme_to_rec(const adobe::theme_t& style, ControlFontStyleRec& style_rec); /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ template <typename T> bool set_widget_data(::ControlRef widget, ::ControlPartCode part, ::ResType tag, const T& data, bool throwing = true) { ::OSStatus result(::SetControlData(widget, part, tag, sizeof(T), &data)); if (!throwing) return result == noErr; ::ADOBE_REQUIRE_STATUS(result); return true; } /****************************************************************************************************/ void set_popup_with_text(ControlRef control, const std::string& text, unsigned long cur_time); /****************************************************************************************************/ /// selects the text within a widget from [ start_pos, end_pos ] (note: inclusive end!) template <typename T> void set_selection(T& control, std::size_t start_pos, std::size_t end_pos); /****************************************************************************************************/ template <> inline void set_selection< ::TXNObject >( ::TXNObject& control, std::size_t start_pos, std::size_t end_pos) { ::ADOBE_REQUIRE_STATUS(::TXNSetSelection(control, start_pos, end_pos)); } /****************************************************************************************************/ template <typename Widget> void set_focus(Widget& widget, bool make_focused) { set_focus< ::ControlRef >(widget.control_m, make_focused); } /****************************************************************************************************/ template <> void set_focus< ::ControlRef >(::ControlRef& control, bool make_focused); /****************************************************************************************************/ template <typename T> void set_refresh(T& widget); /****************************************************************************************************/ template <> inline void set_refresh< ::ControlRef >(::ControlRef& control) { assert(control); ADOBE_REQUIRE_STATUS(::HIViewSetNeedsDisplay(control, true)); } /****************************************************************************************************/ void set_bounds(::ControlRef control, const ::Rect& new_bounds); /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ template <typename Widget> inline const std::string& widget_tag(const Widget&) { static const std::string value_s("<xstr id='metric_unknown'/>{ }</xstr>"); return value_s; } template <typename Widget> inline adobe::dictionary_t extra_widget_context(const Widget&) { return adobe::dictionary_t(); } #define ADOBE_WIDGET_TAG_BOILERPLATE(widgettype, static_tag) \ namespace implementation { \ template <> inline const std::string& widget_tag< widgettype >(const widgettype&) \ { static const std::string value_s(static_tag); return value_s; } \ } // namespace implementation /****************************************************************************************************/ inline adobe::dictionary_t dictionary_union(const adobe::dictionary_t& src1, const adobe::dictionary_t& src2) { if (src1.empty()) return src2; else if (src2.empty()) return src1; adobe::dictionary_t dst; adobe::set_union(src1, src2, dst.inserter(), adobe::compare_members(&adobe::dictionary_t::value_type::first)); return dst; } /****************************************************************************************************/ template <typename Widget> void set_metric_extractor(Widget& w) { // REVISIT (fbrereto) : If metrics can be changed at runtime for this // widget specifically this shortcut will have to go. if (!w.metrics_m.empty()) return; adobe::static_name_t attribute_theme_value("unknown"); adobe::dictionary_t context; switch (w.theme_m & adobe::theme_mask_s) { case adobe::theme_large_s: attribute_theme_value = k_attribute_theme_large; break; case adobe::theme_normal_s: attribute_theme_value = k_attribute_theme_normal; break; case adobe::theme_small_s: attribute_theme_value = k_attribute_theme_small; break; case adobe::theme_mini_s: attribute_theme_value = k_attribute_theme_mini; break; default: break; } adobe::dictionary_t::write_reference context_write(context.write()); context_write[k_attribute_theme] = adobe::value_t(attribute_theme_value); w.metrics_m = adobe::metric_extractor_t(widget_metrics(widget_tag(w), dictionary_union(extra_widget_context(w), context))); } /****************************************************************************************************/ template <typename Widget> void shed_fudges(const Widget& control, adobe::point_2d_t& position, adobe::extents_t& extents) { extents.height() += control.metrics_m(k_metric_adjust_size, adobe::metric_extractor_t::index_height); extents.width() += control.metrics_m(k_metric_adjust_size, adobe::metric_extractor_t::index_width); long fudge_left(control.metrics_m(k_metric_adjust_position, adobe::metric_extractor_t::index_left)); long fudge_top(control.metrics_m(k_metric_adjust_position, adobe::metric_extractor_t::index_top)); position.x_m += fudge_left; position.y_m += fudge_top; /* NOTE (fbrereto) : All Eve containers need to expand themselves to compensate for the the case when their children have outsets. If this does not happen, you will see visual clipping of the children's visual outset artifacts. */ float left_shift(fudge_left - extents.horizontal().outset_m.first); float top_shift(fudge_top - extents.vertical().outset_m.first); ADOBE_REQUIRE_STATUS(::HIViewSetBoundsOrigin(control.control_m, left_shift, top_shift)); } /****************************************************************************************************/ template <typename Widget> adobe::extents_t apply_fudges(Widget& w, const adobe::extents_t& dimensions) { adobe::extents_t result(dimensions); set_metric_extractor(w); result.height() -= w.metrics_m(k_metric_adjust_size, adobe::metric_extractor_t::index_height); result.width() -= w.metrics_m(k_metric_adjust_size, adobe::metric_extractor_t::index_width); // frame inset and outsets are directly transcribed result.horizontal().outset_m.first += w.metrics_m(k_metric_outset, adobe::metric_extractor_t::index_left); result.horizontal().outset_m.second += w.metrics_m(k_metric_outset, adobe::metric_extractor_t::index_right); result.vertical().outset_m.first += w.metrics_m(k_metric_outset, adobe::metric_extractor_t::index_top); result.vertical().outset_m.second += w.metrics_m(k_metric_outset, adobe::metric_extractor_t::index_bottom); result.horizontal().frame_m.first += w.metrics_m(k_metric_frame, adobe::metric_extractor_t::index_left); result.horizontal().frame_m.second += w.metrics_m(k_metric_frame, adobe::metric_extractor_t::index_right); result.vertical().frame_m.first += w.metrics_m(k_metric_frame, adobe::metric_extractor_t::index_top); result.vertical().frame_m.second += w.metrics_m(k_metric_frame, adobe::metric_extractor_t::index_bottom); result.horizontal().inset_m.first += w.metrics_m(k_metric_inset, adobe::metric_extractor_t::index_left); result.horizontal().inset_m.second += w.metrics_m(k_metric_inset, adobe::metric_extractor_t::index_right); result.vertical().inset_m.first += w.metrics_m(k_metric_inset, adobe::metric_extractor_t::index_top); result.vertical().inset_m.second += w.metrics_m(k_metric_inset, adobe::metric_extractor_t::index_bottom); if (!result.vertical().poi_m.empty()) { // REVISIT (fbrereto) It will not always be safe to assume the first vertical poi is the baseline. result.vertical().poi_m[0] += w.metrics_m(adobe::implementation::k_metric_adjust_baseline); } return result; } /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ adobe::extents_t measure(::ControlRef& control); /****************************************************************************************************/ template <typename Widget> adobe::extents_t measure(Widget& widget) { return apply_fudges(widget, measure(widget.control_m)); } /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ template <typename Widget> void set_bounds(Widget& widget, const point_2d_t& pos, const extents_t& ext) { assert(widget.control_m); point_2d_t position(pos); extents_t extents(ext); implementation::shed_fudges(widget, position, extents); ::Rect new_bounds = { static_cast<short>(position.y_m), static_cast<short>(position.x_m), static_cast<short>(position.y_m + extents.height()), static_cast<short>(position.x_m + extents.width()) }; set_bounds(widget.control_m, new_bounds); } /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ inline void set_name(::ControlRef& control, const std::string& name) { assert(control); ADOBE_REQUIRE_STATUS(::SetControlTitleWithCFString(control, localize_to_cfstring(name).get())); } /****************************************************************************************************/ /// See comment in adobe::implementation::get_name about the differences between names and field texts template <typename Widget> void set_name(Widget& widget, const std::string& name) { set_name(widget.control_m, name); } /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /// See comment in adobe::implementation::get_field_text about the differences between names and field texts template <typename T> void set_field_text(T&, const std::string& name); /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ template <typename Widget> void set_theme(Widget& widget, adobe::theme_t theme) { assert(widget.control_m); widget.theme_m = theme; set_theme(widget.control_m, theme); } /****************************************************************************************************/ template <> void set_theme< ::ControlRef >(::ControlRef& control, adobe::theme_t theme); /****************************************************************************************************/ template <> void set_theme< ::TXNObject >(::TXNObject& hitextview, adobe::theme_t theme); /****************************************************************************************************/ template <typename Widget> void adorn_theme(Widget& widget, theme_t theme) { theme_t current(widget.theme_m); // wipe base from current if new base specified if (theme & theme_mask_s) current &= ~theme_mask_s; current |= theme; // logical OR the two themes together set_theme(widget, current); } /****************************************************************************************************/ template <typename Widget> void unadorn_theme(Widget& widget, theme_t theme) { theme_t current(widget.theme_m); current &= ~theme; // If no base is specified now, default to normal if (!(current & theme_mask_s)) current |= theme_normal_s; set_theme(widget, current); } /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ template <typename T> void set_active(T&, bool make_active); /****************************************************************************************************/ template <> void set_active< ::ControlRef >(::ControlRef& control, bool make_active); /****************************************************************************************************/ template <typename T> void set_visible(T&, bool make_visible); /****************************************************************************************************/ template <> inline void set_visible< ::ControlRef >(::ControlRef& control, bool make_visible) { assert(control); ADOBE_REQUIRE_STATUS(::HIViewSetVisible(control, make_visible)); } /****************************************************************************************************/ template <typename T> void set_focused(T&, bool make_focused); /****************************************************************************************************/ template <> inline void set_focused< ::ControlRef >(::ControlRef& control, bool make_focused) { assert(control); set_focus(control, make_focused); } /****************************************************************************************************/ // REVISIT (fbrereto) is_focused needs to go away -- use a cached result of signal_focus instead template <typename T> bool is_focused(T&); /****************************************************************************************************/ template <> inline bool is_focused< ::ControlRef >(::ControlRef& control) { assert(control); ::ControlRef cur_focus; ADOBE_REQUIRE_STATUS(::GetKeyboardFocus(::GetControlOwner(control), &cur_focus)); return cur_focus == control; } /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ std::string convert_utf(::UniChar* buffer, std::size_t size); /****************************************************************************************************/ std::string convert_utf(UniChar* buffer); /****************************************************************************************************/ adobe::modifiers_t convert_modifiers(::UInt32 os_modifiers); /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ template <typename Target> ::EventTargetRef get_event_target(Target target); template <> inline ::EventTargetRef get_event_target< ::WindowRef >(::WindowRef target) { return ::GetWindowEventTarget(target); } template <> inline ::EventTargetRef get_event_target< ::ControlRef >(::ControlRef target) { return ::GetControlEventTarget(target); } #if 0 template <> inline ::EventTargetRef get_event_target< ::MenuRef >(::MenuRef target) { return ::GetMenuEventTarget(target); } #endif /****************************************************************************************************/ template <typename UserDataType> struct event_handler : boost::noncopyable { typedef UserDataType user_data_type; typedef typename adobe::auto_resource< ::EventHandlerRef > auto_ref_t; typedef typename adobe::auto_resource< ::EventHandlerUPP > auto_upp_t; typedef typename std::vector< ::EventTypeSpec > event_type_set_t; event_handler() : upp_m(::NewEventHandlerUPP(do_handle)), installed_m(false) { } virtual ~event_handler() { } void set_user_data(const user_data_type& data) { user_data_m = data; } template <typename Target> void install(Target& target) { if (is_installed()) return; if (event_type_set_m.empty()) throw std::runtime_error("No events specified for handler"); ::EventHandlerRef handler_ref(0); ::ADOBE_REQUIRE_STATUS(::InstallEventHandler( get_event_target(target), upp_m.get(), event_type_set_m.size(), &event_type_set_m[0], this, &handler_ref)); ref_m.reset(handler_ref); installed_m = true; } void uninstall() { if (!is_installed()) return; ref_m.reset(0); upp_m.reset(0); installed_m = false; } bool is_installed() const { return installed_m; } void insert_event(::UInt32 event_class, ::UInt32 event_kind) { ::EventTypeSpec event = { event_class, event_kind }; event_type_set_t::iterator pos(std::find(event_type_set_m.begin(), event_type_set_m.end(), event)); if (pos == event_type_set_m.end()) { event_type_set_m.push_back(event); if (is_installed()) ::ADOBE_REQUIRE_STATUS(::AddEventTypesToHandler( ref_m.get(), 1, &event)); } } void erase_event(::UInt32 event_class, ::UInt32 event_kind) { ::EventTypeSpec event = { event_class, event_kind }; event_type_set_t::iterator pos(adobe::find(event_type_set_m, event)); if (pos != event_type_set_m.end()) { event_type_set_m.erase(pos); if (is_installed()) ::ADOBE_REQUIRE_STATUS(::RemoveEventTypesFromHandler( ref_m.get(), 1, &event)); } } static pascal ::OSStatus do_handle( ::EventHandlerCallRef call_ref, ::EventRef event, void* data) try { event_handler<user_data_type>& myself(*reinterpret_cast<event_handler<user_data_type>*>(data)); return myself.handle_event(call_ref, event); } catch (const adobe::stream_error_t& err) { adobe::report_ui_element_error(adobe::format_stream_error(err)); return eventNotHandledErr; } catch (const std::exception& err) { adobe::report_ui_element_error(std::string("Exception: ") + err.what()); return eventNotHandledErr; } catch (...) { adobe::report_ui_element_error("Exception: Unknown"); return eventNotHandledErr; } virtual ::OSStatus handle_event( ::EventHandlerCallRef next, ::EventRef event) = 0; user_data_type user_data_m; private: auto_ref_t ref_m; auto_upp_t upp_m; event_type_set_t event_type_set_m; bool installed_m; }; /****************************************************************************************************/ } // namespace implementation /****************************************************************************************************/ } // namespace adobe /****************************************************************************************************/ #endif /****************************************************************************************************/ |