diff --git a/RNWCPP/ReactUWP/Base/UwpReactInstance.cpp b/RNWCPP/ReactUWP/Base/UwpReactInstance.cpp index 87962751e71..ff241fd6e49 100644 --- a/RNWCPP/ReactUWP/Base/UwpReactInstance.cpp +++ b/RNWCPP/ReactUWP/Base/UwpReactInstance.cpp @@ -20,7 +20,6 @@ // Standard View Managers #include -#include #include #include #include @@ -102,7 +101,6 @@ REACTWINDOWS_API_(std::shared_ptr) CreateUIManager( // Standard view managers viewManagers.push_back(std::make_unique(instance)); - viewManagers.push_back(std::make_unique(instance)); viewManagers.push_back(std::make_unique(instance)); viewManagers.push_back(std::make_unique(instance)); viewManagers.push_back(std::make_unique(instance)); diff --git a/RNWCPP/ReactUWP/CMakeLists.txt b/RNWCPP/ReactUWP/CMakeLists.txt index 0ef7f922174..bd613b8910a 100644 --- a/RNWCPP/ReactUWP/CMakeLists.txt +++ b/RNWCPP/ReactUWP/CMakeLists.txt @@ -35,7 +35,6 @@ set(SOURCES Utils/LocalBundleReader.cpp Utils/ValueUtils.cpp Views/ActivityIndicatorViewManager.cpp - Views/CalendarViewViewManager.cpp Views/CheckboxViewManager.cpp Views/ControlViewManager.cpp Views/DatePickerViewManager.cpp @@ -54,6 +53,7 @@ set(SOURCES Views/TextViewManager.cpp Views/TouchEventHandler.cpp Views/ViewManagerBase.cpp + Views/ViewControl.cpp Views/ViewPanel.cpp Views/ViewViewManager.cpp Views/VirtualTextViewManager.cpp diff --git a/RNWCPP/ReactUWP/ReactUWP.vcxproj b/RNWCPP/ReactUWP/ReactUWP.vcxproj index 71283bfc248..2d16a001e3f 100644 --- a/RNWCPP/ReactUWP/ReactUWP.vcxproj +++ b/RNWCPP/ReactUWP/ReactUWP.vcxproj @@ -180,8 +180,12 @@ - + + + + + @@ -194,6 +198,7 @@ + @@ -246,7 +251,6 @@ - @@ -264,6 +268,7 @@ + diff --git a/RNWCPP/ReactUWP/ReactUWP.vcxproj.filters b/RNWCPP/ReactUWP/ReactUWP.vcxproj.filters index f02148b8b8b..2132ca7136c 100644 --- a/RNWCPP/ReactUWP/ReactUWP.vcxproj.filters +++ b/RNWCPP/ReactUWP/ReactUWP.vcxproj.filters @@ -163,9 +163,6 @@ Views - - Views - Views @@ -200,6 +197,9 @@ Views + + Views + @@ -352,9 +352,6 @@ Views - - Views - Views @@ -385,6 +382,24 @@ Utils + + Views\cppwinrt + + + Views\cppwinrt + + + Views\cppwinrt + + + Views\cppwinrt + + + Views\cppwinrt + + + Views + @@ -507,6 +522,9 @@ {6ce02bc1-7b54-4e9f-a950-8d794d89de63} + + {4dbf6aed-54f8-4ebd-b99d-667a4b380d8a} + diff --git a/RNWCPP/ReactUWP/Views/CalendarViewViewManager.cpp b/RNWCPP/ReactUWP/Views/CalendarViewViewManager.cpp deleted file mode 100644 index a62eaf75ee2..00000000000 --- a/RNWCPP/ReactUWP/Views/CalendarViewViewManager.cpp +++ /dev/null @@ -1,687 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#include "pch.h" - -#include "CalendarViewViewManager.h" -#include - -#include - -#include -#include -#include -#include -#include - -namespace winrt { - using namespace Windows::Foundation; - using namespace Windows::UI::Text; - using namespace Windows::UI::Xaml; - using namespace Windows::UI::Xaml::Controls; -} - -namespace react { namespace uwp { - -class CalendarViewShadowNode : public ShadowNodeBase -{ - using Super = ShadowNodeBase; -public: - CalendarViewShadowNode() = default; - void createView() override; - void updateProperties(const folly::dynamic&& props) override; - -private: - void OnSelectedDateChanged(IReactInstance& instance, int64_t tag, winrt::DateTime const& selectedDate); - - int64_t m_selectedTime, m_maxTime, m_minTime; // These values are expected to be in milliseconds - int64_t m_timeZoneOffsetInSeconds = 0; // Timezone offset is expected to be in seconds -}; - -void CalendarViewShadowNode::createView() -{ - Super::createView(); - - auto calendarView = GetView().as(); - auto wkinstance = GetViewManager()->GetReactInstance(); - - calendarView.SelectedDatesChanged([=](winrt::CalendarView calendarView, winrt::CalendarViewSelectedDatesChangedEventArgs) - { - auto instance = wkinstance.lock(); - if (!m_updating && instance != nullptr) - { - winrt::Collections::IVector selectedDates = calendarView.SelectedDates(); - if (selectedDates.Size() > 0) - OnSelectedDateChanged(*instance, m_tag, selectedDates.GetAt(0)); - } - }); - - // Adjust day item style with zero values of MinWidth and MinHeight - without that adjustment CalendarView does not - // auto-size below certain thresholds. - auto dayItemStyle = winrt::Style(winrt::xaml_typename()); - winrt::Windows::Foundation::IInspectable boxed0(winrt::box_value(0)); - dayItemStyle.Setters().Append(winrt::Setter(winrt::FrameworkElement::MinWidthProperty(), boxed0)); - dayItemStyle.Setters().Append(winrt::Setter(winrt::FrameworkElement::MinHeightProperty(), boxed0)); - calendarView.CalendarViewDayItemStyle(dayItemStyle); -} - -void CalendarViewShadowNode::updateProperties(const folly::dynamic&& props) -{ - m_updating = true; - - auto calendarView = GetView().as(); - if (calendarView == nullptr) - return; - - bool updateSelectedDate = false; - bool updateMaxDate = false; - bool updateMinDate = false; - - for (auto& pair : props.items()) - { - const folly::dynamic& propertyName = pair.first; - const folly::dynamic& propertyValue = pair.second; - - // For the sake of consistency, please keep conditions below in alphabetical order (on property names). - if (propertyName == "calendarIdentifier") - { - if (propertyValue.isString()) - calendarView.CalendarIdentifier(asHstring(propertyValue)); - else if (propertyValue.isNull()) - calendarView.ClearValue(winrt::CalendarView::CalendarIdentifierProperty()); - else - assert(false); // calendarIndentifier?: string - we don't expect anything but string - } - else if (propertyName == "calendarItemBackgroundColor") - { - if (propertyValue.isInt()) - calendarView.CalendarItemBackground(BrushFrom(propertyValue)); - else if (propertyValue.isNull()) - calendarView.ClearValue(winrt::CalendarView::CalendarItemBackgroundProperty()); - else - assert(false); // calendarItemBackgroundColor?: string - we don't expect anything but int after processColor conversion - } - else if (propertyName == "calendarItemBorderColor") - { - if (propertyValue.isInt()) - calendarView.CalendarItemBorderBrush(BrushFrom(propertyValue)); - else if (propertyValue.isNull()) - calendarView.ClearValue(winrt::CalendarView::CalendarItemBorderBrushProperty()); - else - assert(false); // calendarItemBorderColor?: string - we don't expect anything but int after processColor conversion - } - else if (propertyName == "calendarItemBorderThickness") - { - if (propertyValue.isInt() || propertyValue.isDouble()) - { - double thickness = propertyValue.isInt() ? propertyValue.asInt() : propertyValue.asDouble(); - calendarView.CalendarItemBorderThickness( - { thickness /*Left*/, thickness /*Top*/, thickness /*Right*/, thickness /*Bottom*/ }); - } - else if (propertyValue.isNull()) - { - calendarView.ClearValue(winrt::CalendarView::CalendarItemBorderThicknessProperty()); - } - else - { - assert(false); // calendarItemBorderThickness?: number - we don't expect anything but int or double - } - } - else if (propertyName == "calendarItemColor") - { - if (propertyValue.isInt()) - calendarView.CalendarItemForeground(BrushFrom(propertyValue)); - else if (propertyValue.isNull()) - calendarView.ClearValue(winrt::CalendarView::CalendarItemForegroundProperty()); - else - assert(false); // calendarItemColor?: string - we don't expect anything but int after processColor conversion - } - else if (propertyName == "dayItemFontFamily") - { - if (propertyValue.isString()) - calendarView.DayItemFontFamily(winrt::Media::FontFamily(asHstring(propertyValue))); - else if (propertyValue.isNull()) - calendarView.ClearValue(winrt::CalendarView::DayItemFontFamilyProperty()); - else - assert(false); // dayItemFontFamily?: string - we don't expect anything but string - } - else if (propertyName == "dayItemFontSize") - { - if (propertyValue.isInt()) - calendarView.DayItemFontSize(propertyValue.asInt()); - else if (propertyValue.isDouble()) - calendarView.DayItemFontSize(propertyValue.asDouble()); - else if (propertyValue.isNull()) - calendarView.ClearValue(winrt::CalendarView::DayItemFontSizeProperty()); - else - assert(false); // dayItemFontSize?: number - we don't expect anything but int or double - } - else if (propertyName == "dayItemFontWeight") - { - if (propertyValue.isInt()) - { - winrt::FontWeight fontWeight; - fontWeight.Weight = propertyValue.asInt(); - calendarView.DayItemFontWeight(fontWeight); - } - else if (propertyValue.isNull()) - { - calendarView.ClearValue(winrt::CalendarView::DayItemFontWeightProperty()); - } - else - { - assert(false); // dayItemFontWeight?: number - we don't expect anything but int - } - } - else if (propertyName == "dayOfWeekFormat") - { - if (propertyValue.isString()) - calendarView.DayOfWeekFormat(asHstring(propertyValue)); - else if (propertyValue.isNull()) - calendarView.ClearValue(winrt::CalendarView::DayOfWeekFormatProperty()); - else - assert(false); // dayOfWeekFormat?: string - we don't expect anything but string - } - else if (propertyName == "firstDayOfWeek") - { - if (propertyValue.isInt()) - { - int value = propertyValue.asInt(); - if (value >= static_cast(winrt::Windows::Globalization::DayOfWeek::Sunday) - && value <= static_cast(winrt::Windows::Globalization::DayOfWeek::Saturday)) - { - calendarView.FirstDayOfWeek(static_cast(value)); - } - else - { - assert(false); // firstDayOfWeek?: 0 | 1 | 2 | 3 | 4 | 5 | 6 - we don't expect anything else - } - } - else if (propertyValue.isNull()) - { - calendarView.ClearValue(winrt::CalendarView::FirstDayOfWeekProperty()); - } - else - { - assert(false); // firstDayOfWeek?: 0 | 1 | 2 | 3 | 4 | 5 | 6 - we don't expect anything else - } - } - else if (propertyName == "firstOfMonthLabelFontFamily") - { - if (propertyValue.isString()) - calendarView.FirstOfMonthLabelFontFamily(winrt::Media::FontFamily(asHstring(propertyValue))); - else if (propertyValue.isNull()) - calendarView.ClearValue(winrt::CalendarView::FirstOfMonthLabelFontFamilyProperty()); - else - assert(false); // firstOfMonthLabelFontFamily?: string - we don't expect anything but string - } - else if (propertyName == "firstOfMonthLabelFontSize") - { - if (propertyValue.isInt()) - calendarView.FirstOfMonthLabelFontSize(propertyValue.asInt()); - else if (propertyValue.isDouble()) - calendarView.FirstOfMonthLabelFontSize(propertyValue.asDouble()); - else if (propertyValue.isNull()) - calendarView.ClearValue(winrt::CalendarView::FirstOfMonthLabelFontSizeProperty()); - else - assert(false); // firstOfMonthLabelFontSize?: number - we don't expect anything but int or double - } - else if (propertyName == "firstOfMonthFontWeight") - { - if (propertyValue.isInt()) - { - winrt::FontWeight fontWeight; - fontWeight.Weight = propertyValue.asInt(); - calendarView.FirstOfMonthLabelFontWeight(fontWeight); - } - else if (propertyValue.isNull()) - { - calendarView.ClearValue(winrt::CalendarView::FirstOfMonthLabelFontWeightProperty()); - } - else - { - assert(false); // firstOfMonthFontWeight?: number - we don't expect anything but int - } - } - else if (propertyName == "firstOfYearDecadeLabelFontFamily") - { - if (propertyValue.isString()) - calendarView.FirstOfMonthLabelFontFamily(winrt::Media::FontFamily(asHstring(propertyValue))); - else if (propertyValue.isNull()) - calendarView.ClearValue(winrt::CalendarView::FirstOfMonthLabelFontFamilyProperty()); - else - assert(false); // firstOfYearDecadeLabelFontFamily?: string - we don't expect anything but string - } - else if (propertyName == "firstOfYearDecadeLabelFontSize") - { - if (propertyValue.isInt()) - calendarView.FirstOfYearDecadeLabelFontSize(propertyValue.asInt()); - else if (propertyValue.isDouble()) - calendarView.FirstOfYearDecadeLabelFontSize(propertyValue.asDouble()); - else if (propertyValue.isNull()) - calendarView.ClearValue(winrt::CalendarView::FirstOfYearDecadeLabelFontSizeProperty()); - else - assert(false); // firstOfYearDecadeLabelFontSize?: number - we don't expect anything but int or double - } - else if (propertyName == "firstOfYearDecadeFontWeight") - { - if (propertyValue.isInt()) - { - winrt::FontWeight fontWeight; - fontWeight.Weight = propertyValue.asInt(); - calendarView.FirstOfYearDecadeLabelFontWeight(fontWeight); - } - else if (propertyValue.isNull()) - { - calendarView.ClearValue(winrt::CalendarView::FirstOfYearDecadeLabelFontWeightProperty()); - } - else - { - assert(false); // firstOfYearDecadeFontWeight?: number - we don't expect anything but int - } - } - else if (propertyName == "focusBorderColor") - { - if (propertyValue.isInt()) - calendarView.FocusBorderBrush(BrushFrom(propertyValue)); - else if (propertyValue.isNull()) - calendarView.ClearValue(winrt::CalendarView::FocusBorderBrushProperty()); - else - assert(false); // focusBorderColor?: string - we don't expect anything but int after processColor conversion - } - else if (propertyName == "horizontalDayItemAlignment") - { - if (propertyValue.isString()) - calendarView.HorizontalDayItemAlignment(HorizontalAlignmentFrom(propertyValue)); - else if (propertyValue.isNull()) - calendarView.ClearValue(winrt::CalendarView::HorizontalDayItemAlignmentProperty()); - else - assert(false); // horizontalDayItemAlignment?: "center" | "left" | "right" | "stretch" - we don't expect anything else - } - else if (propertyName == "horizontalFirstOfMonthLabelAlignment") - { - if (propertyValue.isString()) - calendarView.HorizontalFirstOfMonthLabelAlignment(HorizontalAlignmentFrom(propertyValue)); - else if (propertyValue.isNull()) - calendarView.ClearValue(winrt::CalendarView::HorizontalFirstOfMonthLabelAlignmentProperty()); - else - assert(false); // horizontalFirstOfMonthLabelAlignment?: "center" | "left" | "right" | "stretch" - we don't expect anything else - } - else if (propertyName == "hoverBorderColor") - { - if (propertyValue.isString()) - calendarView.HoverBorderBrush(BrushFrom(propertyValue)); - else if (propertyValue.isNull()) - calendarView.ClearValue(winrt::CalendarView::HoverBorderBrushProperty()); - else - assert(false); // hoverBorderColor?: string - we don't expect anything but int after processColor conversion - } - else if (propertyName == "isGroupLabelVisible") - { - if (propertyValue.isBool()) - calendarView.IsGroupLabelVisible(propertyValue.asBool()); - else if (propertyValue.isNull()) - calendarView.ClearValue(winrt::CalendarView::IsGroupLabelVisibleProperty()); - else - assert(false); // isGroupLabelVisible?: boolean - we don't expect anything but bool - } - else if (propertyName == "isOutOfScopeEnabled") - { - if (propertyValue.isBool()) - calendarView.IsOutOfScopeEnabled(propertyValue.asBool()); - else if (propertyValue.isNull()) - calendarView.ClearValue(winrt::CalendarView::IsOutOfScopeEnabledProperty()); - else - assert(false); // isOutOfScopeEnabled?: boolean - we don't expect anything but bool - } - else if (propertyName == "isTodayHighlighted") - { - if (propertyValue.isBool()) - calendarView.IsTodayHighlighted(propertyValue.asBool()); - else if (propertyValue.isNull()) - calendarView.ClearValue(winrt::CalendarView::IsTodayHighlightedProperty()); - else - assert(false); // isTodayHighlighted?: boolean - we don't expect anything but bool - } - else if (propertyName == "maxDate") - { - if (propertyValue.isInt()) - { - m_maxTime = propertyValue.asInt(); - updateMaxDate = true; - } - else if (propertyValue.isNull()) - { - calendarView.ClearValue(winrt::CalendarView::MaxDateProperty()); - } - else - { - assert(false); // maxDate?: number - we don't expect anything but int - } - } - else if (propertyName == "minDate") - { - if (propertyValue.isInt()) - { - m_minTime = propertyValue.asInt(); - updateMinDate = true; - } - else if (propertyValue.isNull()) - { - calendarView.ClearValue(winrt::CalendarView::MinDateProperty()); - } - else - { - assert(false); // minDate?: number - we don't expect anything but int - } - } - else if (propertyName == "monthYearItemFontFamily") - { - if (propertyValue.isString()) - calendarView.MonthYearItemFontFamily(winrt::Media::FontFamily(asHstring(propertyValue))); - else if (propertyValue.isNull()) - calendarView.ClearValue(winrt::CalendarView::MonthYearItemFontFamilyProperty()); - else - assert(false); // monthYearItemFontFamily?: string - we don't expect anything but string - } - else if (propertyName == "monthYearItemFontSize") - { - if (propertyValue.isInt()) - calendarView.MonthYearItemFontSize(propertyValue.asInt()); - else if (propertyValue.isDouble()) - calendarView.MonthYearItemFontSize(propertyValue.asDouble()); - else if (propertyValue.isNull()) - calendarView.ClearValue(winrt::CalendarView::MonthYearItemFontSizeProperty()); - else - assert(false); // monthYearItemFontSize?: number - we don't expect anything but int or double - } - else if (propertyName == "monthYearItemFontWeight") - { - if (propertyValue.isInt()) - { - winrt::FontWeight fontWeight; - fontWeight.Weight = propertyValue.asInt(); - calendarView.MonthYearItemFontWeight(fontWeight); - } - else if (propertyValue.isNull()) - { - calendarView.ClearValue(winrt::CalendarView::MonthYearItemFontWeightProperty()); - } - else - { - assert(false); // monthYearItemFontWeight?: number - we don't expect anything but int - } - } - else if (propertyName == "numberOfWeeksInView") - { - if (propertyValue.isInt()) - { - int value = propertyValue.asInt(); - if (value >= 1 && value <= 10) - calendarView.NumberOfWeeksInView(value); - else - assert(false); // numberOfWeeksInView?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 - we don't expect anything else - } - else if (propertyValue.isNull()) - { - calendarView.ClearValue(winrt::CalendarView::NumberOfWeeksInViewProperty()); - } - else - { - assert(false); // numberOfWeeksInView?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 - we don't expect anything else - } - } - else if (propertyName == "outOfScopeColor") - { - if (propertyValue.isString()) - calendarView.OutOfScopeForeground(BrushFrom(propertyValue)); - else if (propertyValue.isNull()) - calendarView.ClearValue(winrt::CalendarView::OutOfScopeForegroundProperty()); - else - assert(false); // outOfScopeColor?: string - we don't expect anything but int after processColor conversion - } - else if (propertyName == "outOfScopeBackgroundColor") - { - if (propertyValue.isString()) - calendarView.OutOfScopeBackground(BrushFrom(propertyValue)); - else if (propertyValue.isNull()) - calendarView.ClearValue(winrt::CalendarView::OutOfScopeBackgroundProperty()); - else - assert(false); // outOfScopeBackgroundColor?: string - we don't expect anything but int after processColor conversion - } - else if (propertyName == "pressedBorderColor") - { - if (propertyValue.isString()) - calendarView.PressedBorderBrush(BrushFrom(propertyValue)); - else if (propertyValue.isNull()) - calendarView.ClearValue(winrt::CalendarView::PressedBorderBrushProperty()); - else - assert(false); // pressedBorderColor?: string - we don't expect anything but int after processColor conversion - } - else if (propertyName == "pressedColor") - { - if (propertyValue.isString()) - calendarView.PressedForeground(BrushFrom(propertyValue)); - else if (propertyValue.isNull()) - calendarView.ClearValue(winrt::CalendarView::PressedForegroundProperty()); - else - assert(false); // pressedColor?: string - we don't expect anything but int after processColor conversion - } - else if (propertyName == "selectedBorderColor") - { - if (propertyValue.isString()) - calendarView.SelectedBorderBrush(BrushFrom(propertyValue)); - else if (propertyValue.isNull()) - calendarView.ClearValue(winrt::CalendarView::SelectedBorderBrushProperty()); - else - assert(false); // selectedBorderColor?: string - we don't expect anything but int after processColor conversion - } - else if (propertyName == "selectedColor") - { - if (propertyValue.isString()) - calendarView.SelectedForeground(BrushFrom(propertyValue)); - else if (propertyValue.isNull()) - calendarView.ClearValue(winrt::CalendarView::SelectedForegroundProperty()); - else - assert(false); // selectedColor?: string - we don't expect anything but int after processColor conversion - } - else if (propertyName == "selectedDate") - { - if (propertyValue.isInt()) - { - m_selectedTime = propertyValue.asInt(); - updateSelectedDate = true; - } - else if (propertyValue.isNull()) - { - calendarView.SelectedDates().Clear(); - } - else - { - assert(false); // selectedDate?: number - we don't expect anything but int - } - } - else if (propertyName == "selectedHoverBorderColor") - { - if (propertyValue.isString()) - calendarView.SelectedHoverBorderBrush(BrushFrom(propertyValue)); - else if (propertyValue.isNull()) - calendarView.ClearValue(winrt::CalendarView::SelectedHoverBorderBrushProperty()); - else - assert(false); // selectedHoverBorderColor?: string - we don't expect anything but int after processColor conversion - } - else if (propertyName == "selectedPressedBorderColor") - { - if (propertyValue.isString()) - calendarView.SelectedPressedBorderBrush(BrushFrom(propertyValue)); - else if (propertyValue.isNull()) - calendarView.ClearValue(winrt::CalendarView::SelectedPressedBorderBrushProperty()); - else - assert(false); // selectedPressedBorderColor?: string - we don't expect anything but int after processColor conversion - } - else if (propertyName.asString() == "timeZoneOffsetInSeconds") - { - if (propertyValue.isInt()) - m_timeZoneOffsetInSeconds = propertyValue.asInt(); - else if (propertyValue.isNull()) - m_timeZoneOffsetInSeconds = 0; - else - assert(false); // timeZoneOffsetInSeconds?: number - we don't expect anything but int - } - else if (propertyName == "todayColor") - { - if (propertyValue.isString()) - calendarView.TodayForeground(BrushFrom(propertyValue)); - else if (propertyValue.isNull()) - calendarView.ClearValue(winrt::CalendarView::TodayForegroundProperty()); - else - assert(false); // todayColor?: string - we don't expect anything but int after processColor conversion - } - else if (propertyName == "todayFontWeight") - { - if (propertyValue.isInt()) - { - winrt::FontWeight fontWeight; - fontWeight.Weight = propertyValue.asInt(); - calendarView.TodayFontWeight(fontWeight); - } - else if (propertyValue.isNull()) - { - calendarView.ClearValue(winrt::CalendarView::TodayFontWeightProperty()); - } - else - { - assert(false); // todayFontWeight?: number - we don't expect anything but int - } - } - else if (propertyName == "verticalDayItemAlignment") - { - if (propertyValue.isString()) - calendarView.VerticalDayItemAlignment(VerticalAlignmentFrom(propertyValue)); - else if (propertyValue.isNull()) - calendarView.ClearValue(winrt::CalendarView::VerticalDayItemAlignmentProperty()); - else - assert(false); // verticalDayItemAlignment?: "bottom" | "center" | "stretch" | "top" - we don't expect anything else - } - else if (propertyName == "verticalFirstOfMonthLabelAlignment") - { - if (propertyValue.isString()) - calendarView.VerticalFirstOfMonthLabelAlignment(VerticalAlignmentFrom(propertyValue)); - else if (propertyValue.isNull()) - calendarView.ClearValue(winrt::CalendarView::VerticalFirstOfMonthLabelAlignmentProperty()); - else - assert(false); // verticalFirstOfMonthLabelAlignment?: "bottom" | "center" | "stretch" | "top" - we don't expect anything else - } - } - - if (updateMaxDate) - calendarView.MaxDate(DateTimeFrom(m_maxTime, m_timeZoneOffsetInSeconds)); - - if (updateMinDate) - calendarView.MinDate(DateTimeFrom(m_minTime, m_timeZoneOffsetInSeconds)); - - if (updateSelectedDate) - { - winrt::DateTime value = DateTimeFrom(m_selectedTime, m_timeZoneOffsetInSeconds); - if (value != winrt::DateTime()) - { - calendarView.SelectedDates().Clear(); - calendarView.SelectedDates().InsertAt(0, value); - } - } - - Super::updateProperties(std::move(props)); - m_updating = false; -} - -void CalendarViewShadowNode::OnSelectedDateChanged(IReactInstance& instance, int64_t tag, winrt::DateTime const& selectedDate) -{ - auto timeInMilliseconds = DateTimeToDynamic(selectedDate, m_timeZoneOffsetInSeconds); - - if (!timeInMilliseconds.isNull()) - { - folly::dynamic eventData = folly::dynamic::object("target", tag)("selectedDate", timeInMilliseconds); - instance.DispatchEvent(tag, "topChange", std::move(eventData)); - } - else - { - assert(0); - } -} - -CalendarViewViewManager::CalendarViewViewManager(const std::shared_ptr& reactInstance) - : Super(reactInstance) -{ -} - -const char* CalendarViewViewManager::GetName() const -{ - return "RCTCalendarView"; -} - -folly::dynamic CalendarViewViewManager::GetNativeProps() const -{ - auto props = Super::GetNativeProps(); - - // For the sake of consistency, please keep expressions below in alphabetical order (on property names). - props.update(folly::dynamic::object - ("calendarIdentifier", "string") - ("calendarItemBackgroundColor", "number") - ("calendarItemBorderColor", "number") - ("calendarItemBorderThickness", "string") - ("calendarItemColor", "number") - ("dayItemFontFamily", "string") - ("dayItemFontSize", "number") - ("dayItemFontWeight", "number") - ("dayOfWeekFormat", "string") - ("firstDayOfWeek", "number") - ("firstOfMonthLabelFontFamily", "string") - ("firstOfMonthLabelFontSize", "number") - ("firstOfMonthLabelFontWeight", "number") - ("firstOfYearDecadeLabelFontFamily", "string") - ("firstOfYearDecadeLabelFontSize", "number") - ("firstOfYearDecadeLabelFontWeight", "number") - ("focusBorderColor", "number") - ("horizontalDayItemAlignment", "string") - ("horizontalFirstOfMonthLabelAlignment", "string") - ("hoverBorderColor", "number") - ("isGroupLabelVisible", "boolean") - ("isOutOfScopeEnabled", "boolean") - ("isTodayHighlighted", "boolean") - ("maxDate", "number") - ("minDate", "number") - ("monthYearItemFontFamily", "string") - ("monthYearItemFontSize", "number") - ("monthYearItemFontWeight", "number") - ("numberOfWeeksInView", "number") - ("outOfScopeColor", "number") - ("outOfScopeBackgroundColor", "number") - ("pressedBorderColor", "number") - ("pressedColor", "number") - ("selectedBorderColor", "number") - ("selectedColor", "number") - ("selectedDate", "number") - ("selectedHoverBorderColor", "number") - ("selectedPressedBorderColor", "number") - ("todayColor", "number") - ("todayFontWeight", "string") - ("timeZoneOffsetInSeconds", "number") - ("verticalDayItemAlignment", "string") - ("verticalFirstOfMonthLabelAlignment", "string") - ); - - return props; -} - -facebook::react::ShadowNode* CalendarViewViewManager::createShadow() const -{ - return new CalendarViewShadowNode(); -} - -XamlView CalendarViewViewManager::CreateViewCore(int64_t tag) -{ - auto calendarView = winrt::CalendarView(); - return calendarView; -} - -}} diff --git a/RNWCPP/ReactUWP/Views/CalendarViewViewManager.h b/RNWCPP/ReactUWP/Views/CalendarViewViewManager.h deleted file mode 100644 index cd0d409a908..00000000000 --- a/RNWCPP/ReactUWP/Views/CalendarViewViewManager.h +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#pragma once - -#include - -namespace react { namespace uwp { - -class CalendarViewViewManager : public ControlViewManager -{ - using Super = ControlViewManager; -public: - CalendarViewViewManager(const std::shared_ptr& reactInstance); - - const char* GetName() const override; - folly::dynamic GetNativeProps() const override; - - facebook::react::ShadowNode* createShadow() const; - -protected: - XamlView CreateViewCore(int64_t tag) override; - - friend class CalendarViewShadowNode; -}; - -} } diff --git a/RNWCPP/ReactUWP/Views/ViewControl.cpp b/RNWCPP/ReactUWP/Views/ViewControl.cpp new file mode 100644 index 00000000000..e3f1f34f509 --- /dev/null +++ b/RNWCPP/ReactUWP/Views/ViewControl.cpp @@ -0,0 +1,79 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#include "pch.h" + +#include "ViewControl.h" + +#include +#include +#include + +namespace winrt { +using namespace Windows::UI; +using namespace Windows::UI::Xaml; +using namespace Windows::UI::Xaml::Controls; +using namespace Windows::UI::Xaml::Interop; +using namespace Windows::UI::Xaml::Media; +using namespace Windows::Foundation; +} + +namespace react { namespace uwp { + +ViewControl::ViewControl() +{ +} + +/*static*/ winrt::com_ptr ViewControl::Create() +{ + return winrt::make_self(); +} + +winrt::Windows::UI::Xaml::Automation::Peers::AutomationPeer ViewControl::OnCreateAutomationPeer() +{ + auto dyn = winrt::make(*this); + return dyn; +} + +} } // namespace react::uwp + +namespace winrt::react::uwp::implementation +{ + DynamicAutomationPeer::DynamicAutomationPeer(Windows::UI::Xaml::FrameworkElement const& owner) + : Super(owner) + { + } + + Windows::UI::Xaml::Automation::Peers::AutomationControlType DynamicAutomationPeer::GetAutomationControlTypeCore() const + { + auto viewControl = Owner().as<::react::uwp::ViewControl>(); + + if (viewControl->AccessibilityRole() == ::react::uwp::AccessibilityRoles::Button) + return winrt::Windows::UI::Xaml::Automation::Peers::AutomationControlType::Button; + + return winrt::Windows::UI::Xaml::Automation::Peers::AutomationControlType::Group; + } + + Windows::Foundation::IInspectable DynamicAutomationPeer::GetPatternCore(Windows::UI::Xaml::Automation::Peers::PatternInterface const& patternInterface) const + { + auto viewControl = Owner().as<::react::uwp::ViewControl>(); + + if (patternInterface == Windows::UI::Xaml::Automation::Peers::PatternInterface::Invoke && + viewControl->AccessibilityRole() == ::react::uwp::AccessibilityRoles::Button) + { + return *this; + } + + return nullptr; + } + + + void DynamicAutomationPeer::Invoke() const + { + auto viewControl = Owner().as<::react::uwp::ViewControl>(); + auto invokeHandler = viewControl->AccessibilityInvoke(); + if (invokeHandler) + invokeHandler(); + } + +} diff --git a/RNWCPP/ReactUWP/Views/ViewControl.h b/RNWCPP/ReactUWP/Views/ViewControl.h new file mode 100644 index 00000000000..9f06c3432f8 --- /dev/null +++ b/RNWCPP/ReactUWP/Views/ViewControl.h @@ -0,0 +1,73 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once + +#include + +#include +#include +#include +#include +#include + +namespace react { +namespace uwp { + +// +// ViewControl is ViewViewManager's ContentControl but with a custom AutomationPeer +// using DynamicAutomationPeer (See below) +// +struct ViewControl : winrt::Windows::UI::Xaml::Controls::ContentControlT +{ + using Super = winrt::Windows::UI::Xaml::Controls::ContentControlT; +private: + // Constructors + ViewControl(); + +public: + static winrt::com_ptr Create(); + template friend auto winrt::make_self(Args&&... args); + + winrt::Windows::UI::Xaml::Automation::Peers::AutomationPeer OnCreateAutomationPeer(); + + // Public Methods + AccessibilityRoles AccessibilityRole() { return m_accessibilityRole; } + void AccessibilityRole(AccessibilityRoles role) { m_accessibilityRole = role; } + + using AccessibilityInvokeEventHandler = std::function; + const AccessibilityInvokeEventHandler& AccessibilityInvoke() { return m_accessibilityInvokeHandler; } + void AccessibilityInvoke(AccessibilityInvokeEventHandler&& handler) + { + m_accessibilityInvokeHandler = std::move(handler); + } + +private: + AccessibilityRoles m_accessibilityRole = AccessibilityRoles::None; + AccessibilityInvokeEventHandler m_accessibilityInvokeHandler = nullptr; +}; + +}} // namespace react::uwp + + +#include "cppwinrt/react.uwp.DynamicAutomationPeer.g.h" +namespace winrt::react::uwp::implementation +{ +// +// DynamicAutomationPeer refers to the owner ViewControl to determine what type control +// it appears to be for accessibility tools +// +struct DynamicAutomationPeer : DynamicAutomationPeerT +{ + using Super = DynamicAutomationPeerT; + + DynamicAutomationPeer() = delete; + DynamicAutomationPeer(Windows::UI::Xaml::FrameworkElement const& owner); + + Windows::UI::Xaml::Automation::Peers::AutomationControlType GetAutomationControlTypeCore() const; + Windows::Foundation::IInspectable GetPatternCore(Windows::UI::Xaml::Automation::Peers::PatternInterface const& patternInterface) const; + + void Invoke() const; +}; +} // namespace winrt::react::uwp::implementation + diff --git a/RNWCPP/ReactUWP/Views/ViewViewManager.cpp b/RNWCPP/ReactUWP/Views/ViewViewManager.cpp index ac507cc71a9..e0b9b9203e3 100644 --- a/RNWCPP/ReactUWP/Views/ViewViewManager.cpp +++ b/RNWCPP/ReactUWP/Views/ViewViewManager.cpp @@ -5,6 +5,7 @@ #include "ViewViewManager.h" +#include "ViewControl.h" #include "ViewPanel.h" #include @@ -48,7 +49,7 @@ class ViewShadowNode : public ShadowNodeBase m_enableFocusRing = enable; if (IsControl()) - GetControl().UseSystemFocusVisuals(m_enableFocusRing); + GetControl()->UseSystemFocusVisuals(m_enableFocusRing); } int32_t TabIndex() { return m_tabIndex; } @@ -57,12 +58,26 @@ class ViewShadowNode : public ShadowNodeBase m_tabIndex = tabIndex; if (IsControl()) - GetControl().TabIndex(m_tabIndex); + GetControl()->TabIndex(m_tabIndex); } bool OnClick() { return m_onClick; } void OnClick(bool isSet) { m_onClick = isSet; } + AccessibilityRoles AccessibilityRole() { return m_accessibilityRole; } + void AccessibilityRole(AccessibilityRoles role) + { + m_accessibilityRole = role; + if (IsControl()) + GetControl()->AccessibilityRole(role); + } + + bool AccessibilityState(AccessibilityStates state) { return m_accessibilityStates[state]; } + void AccessibilityState(AccessibilityStates state, bool value) + { + m_accessibilityStates[state] = value; + } + void AddView(ShadowNode& child, int64_t index) override { GetViewPanel()->InsertAt(static_cast(index), static_cast(child).GetView().as()); @@ -99,6 +114,9 @@ class ViewShadowNode : public ShadowNodeBase void RefreshProperties() { // The view may have been replaced, so transfer properties stored on the shadow node to the view + AccessibilityRole(AccessibilityRole()); + AccessibilityState(AccessibilityStates::Disabled, AccessibilityState(AccessibilityStates::Disabled)); + AccessibilityState(AccessibilityStates::Selected, AccessibilityState(AccessibilityStates::Selected)); EnableFocusRing(EnableFocusRing()); TabIndex(TabIndex()); } @@ -116,9 +134,9 @@ class ViewShadowNode : public ShadowNodeBase } } - winrt::ContentControl GetControl() + winrt::impl::com_ref GetControl() { - return IsControl() ? m_view.as() : winrt::ContentControl(nullptr); + return IsControl() ? m_view.as() : nullptr; } private: @@ -126,6 +144,8 @@ class ViewShadowNode : public ShadowNodeBase bool m_enableFocusRing = true; bool m_onClick = false; int32_t m_tabIndex = std::numeric_limits::max(); + AccessibilityRoles m_accessibilityRole = AccessibilityRoles::None; + bool m_accessibilityStates[AccessibilityStates::CountStates] = { false, false }; }; @@ -145,6 +165,7 @@ folly::dynamic ViewViewManager::GetExportedCustomDirectEventTypeConstants() cons directEvents["topTextInputFocus"] = folly::dynamic::object("registrationName", "onFocus"); directEvents["topTextInputBlur"] = folly::dynamic::object("registrationName", "onBlur"); directEvents["topClick"] = folly::dynamic::object("registrationName", "onClick"); + directEvents["topAccessibilityTap"] = folly::dynamic::object("registrationName", "onAccessibilityTap"); return directEvents; } @@ -185,7 +206,8 @@ XamlView ViewViewManager::CreateViewControl(int64_t tag) panel->VerticalAlignment(winrt::VerticalAlignment::Top); // Create the ContentControl as the outer/containing element, nest the ViewPanel, set default properties - winrt::ContentControl contentControl; + auto contentControlPtr = ViewControl::Create(); + auto contentControl = contentControlPtr.as(); contentControl.Content(newViewPanelXamlView); // TODO: Remove once existing clients stop using TouchableNativeFeedback.uwp @@ -225,6 +247,22 @@ XamlView ViewViewManager::CreateViewControl(int64_t tag) } }); + contentControlPtr->AccessibilityInvoke([=]() + { + auto instance = m_wkReactInstance.lock(); + if (instance != nullptr) + { + auto pNativeUiManager = static_cast(instance->NativeUIManager()); + facebook::react::INativeUIManagerHost* pUIManagerHost = pNativeUiManager->getHost(); + + auto pViewShadowNode = static_cast(pUIManagerHost->FindShadowNodeForTag(tag)); + if (pViewShadowNode != nullptr && pViewShadowNode->OnClick()) + DispatchEvent(tag, "topClick", std::move(folly::dynamic::object("target", tag))); + else + DispatchEvent(tag, "topAccessibilityTap", std::move(folly::dynamic::object("target", tag))); + } + }); + return contentControl.as(); } @@ -239,6 +277,8 @@ folly::dynamic ViewViewManager::GetNativeProps() const props.update(folly::dynamic::object ("accessible", "boolean") + ("accessibilityRole", "string") + ("accessibilityStates", "array") ("pointerEvents", "string") ("onClick", "function") ("onMouseEnter", "function") @@ -306,8 +346,49 @@ void ViewViewManager::UpdateProperties(ShadowNodeBase* nodeToUpdate, folly::dyna } else if (propertyName == "acceptsKeyboardFocus") { - if (pair.second.isBool()) - shouldBeControl = pair.second.asBool(); + if (propertyValue.isBool()) + shouldBeControl = propertyValue.asBool(); + } + else if (propertyName == "accessibilityRole") + { + // FUTURE having an accessibilityRole shouldBeControl to support + // non-Touchable scenarios + if (propertyValue.isString()) + { + auto role = propertyValue.asString(); + if (role == "none") + pViewShadowNode->AccessibilityRole(AccessibilityRoles::None); + else if (role == "button") + pViewShadowNode->AccessibilityRole(AccessibilityRoles::Button); + else + pViewShadowNode->AccessibilityRole(AccessibilityRoles::None); + } + else if (propertyValue.isNull()) + { + pViewShadowNode->AccessibilityRole(AccessibilityRoles::None); + } + } + else if (propertyName == "accessibilityStates") + { + // FUTURE having an accessibilityStates shouldBeControl to support + // non-Touchable scenarios + bool disabled = false; + bool selected = false; + if (propertyValue.isArray()) + { + for (const auto& state : propertyValue) + { + if (!state.isString()) + continue; + if (state.getString() == "disabled") + disabled = true; + else if (state.getString() == "selected") + selected = true; + } + } + + pViewShadowNode->AccessibilityState(AccessibilityStates::Disabled, disabled); + pViewShadowNode->AccessibilityState(AccessibilityStates::Selected, selected); } else if (propertyName == "enableFocusRing") { diff --git a/RNWCPP/ReactUWP/Views/cppwinrt/react.uwp.DynamicAutomationPeer.g.h b/RNWCPP/ReactUWP/Views/cppwinrt/react.uwp.DynamicAutomationPeer.g.h new file mode 100644 index 00000000000..d795f739ac8 --- /dev/null +++ b/RNWCPP/ReactUWP/Views/cppwinrt/react.uwp.DynamicAutomationPeer.g.h @@ -0,0 +1,101 @@ +// WARNING: Please don't edit this file. It was generated by C++/WinRT v1.0.180821.2 + +#pragma once + +#include "winrt/Windows.UI.Xaml.h" +#include "winrt/Windows.UI.Xaml.Automation.Peers.h" +#include "winrt/Windows.UI.Xaml.Automation.Provider.h" +#include "winrt/react.uwp.h" + +#if OLD_CPPWINRT +namespace winrt::impl +{ + template + using default_interface_t = typename default_interface::type; +} + +namespace winrt +{ + template + using default_interface = typename impl::default_interface::type; +} +#endif + +namespace winrt::react::uwp::implementation { + +template +struct WINRT_EBO DynamicAutomationPeer_base : implements, + impl::require, + impl::base, + Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverridesT, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides2T, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides3T, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides4T, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides5T, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides6T, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides8T, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides9T +{ + using base_type = DynamicAutomationPeer_base; + using class_type = react::uwp::DynamicAutomationPeer; + using implements_type = typename DynamicAutomationPeer_base::implements_type; + using implements_type::implements_type; + using composable_base = Windows::UI::Xaml::Automation::Peers::FrameworkElementAutomationPeer; +#if _MSC_VER < 1914 + operator class_type() const noexcept + { + static_assert(std::is_same_v::type, default_interface>); + class_type result{ nullptr }; + attach_abi(result, detach_abi(static_cast>(*this))); + return result; + } +#else + operator impl::producer_ref const() const noexcept + { + return { to_abi>(this) }; + } +#endif + + hstring GetRuntimeClassName() const + { + return L"react.uwp.DynamicAutomationPeer"; + } + DynamicAutomationPeer_base(Windows::UI::Xaml::FrameworkElement const& owner) + { + impl::call_factory([&](auto&& f) { f.CreateInstanceWithOwner(owner, *this, this->m_inner); }); + } +}; + +} + +namespace winrt::react::uwp::factory_implementation { + +template +struct WINRT_EBO DynamicAutomationPeerT : implements +{ + using instance_type = react::uwp::DynamicAutomationPeer; + + hstring GetRuntimeClassName() const + { + return L"react.uwp.DynamicAutomationPeer"; + } + + Windows::Foundation::IInspectable ActivateInstance() const + { + throw hresult_not_implemented(); + } + + react::uwp::DynamicAutomationPeer CreateInstance(Windows::UI::Xaml::FrameworkElement const& owner) + { + return make(owner); + } +}; + +} + +#if defined(WINRT_FORCE_INCLUDE_DYNAMICAUTOMATIONPEER_XAML_G_H) || __has_include("react.uwp.DynamicAutomationPeer.xaml.g.h") + +#include "react.uwp.DynamicAutomationPeer.xaml.g.h" + +#else + +namespace winrt::react::uwp::implementation +{ + template + using DynamicAutomationPeerT = DynamicAutomationPeer_base; +} + +#endif diff --git a/RNWCPP/ReactUWP/Views/cppwinrt/reactuwp.idl b/RNWCPP/ReactUWP/Views/cppwinrt/reactuwp.idl new file mode 100644 index 00000000000..72e9f702277 --- /dev/null +++ b/RNWCPP/ReactUWP/Views/cppwinrt/reactuwp.idl @@ -0,0 +1,18 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// This file was used to generate the files in the cppwinrt subfolders +// +// in the future this should be run through cppwinrt.exe but thats not currently +// possible with the multiple build systems react uwp needs to support. + +namespace react.uwp +{ + [default_interface] + runtimeclass DynamicAutomationPeer : + Windows.UI.Xaml.Automation.Peers.FrameworkElementAutomationPeer, + Windows.UI.Xaml.Automation.Provider.IInvokeProvider + { + DynamicAutomationPeer(Windows.UI.Xaml.FrameworkElement owner); + } +} diff --git a/RNWCPP/ReactUWP/Views/cppwinrt/winrt/impl/react.uwp.0.h b/RNWCPP/ReactUWP/Views/cppwinrt/winrt/impl/react.uwp.0.h new file mode 100644 index 00000000000..3c5a6abdf3e --- /dev/null +++ b/RNWCPP/ReactUWP/Views/cppwinrt/winrt/impl/react.uwp.0.h @@ -0,0 +1,53 @@ +// WARNING: Please don't edit this file. It was generated by C++/WinRT v1.0.180821.2 + +#pragma once + +WINRT_EXPORT namespace winrt::Windows::UI::Xaml { + +struct FrameworkElement; + +} + +WINRT_EXPORT namespace winrt::react::uwp { + +struct IDynamicAutomationPeer; +struct IDynamicAutomationPeerFactory; +struct DynamicAutomationPeer; + +} + +namespace winrt::impl { + +template <> struct category{ using type = interface_category; }; +template <> struct category{ using type = interface_category; }; +template <> struct category{ using type = class_category; }; +template <> struct name{ static constexpr auto & value{ L"react.uwp.IDynamicAutomationPeer" }; }; +template <> struct name{ static constexpr auto & value{ L"react.uwp.IDynamicAutomationPeerFactory" }; }; +template <> struct name{ static constexpr auto & value{ L"react.uwp.DynamicAutomationPeer" }; }; +template <> struct guid_storage{ static constexpr guid value{ 0x96D2FA46,0xD93B,0x5EB4,{ 0x9E,0xD8,0xFC,0x60,0x2C,0xB5,0xB7,0x8F } }; }; +template <> struct guid_storage{ static constexpr guid value{ 0x0F0A64B1,0xCCEF,0x54F1,{ 0xB9,0x05,0x0C,0x58,0x26,0xCB,0x6C,0xC4 } }; }; +template <> struct default_interface{ using type = react::uwp::IDynamicAutomationPeer; }; + +template <> struct abi{ struct type : IInspectable +{ +};}; + +template <> struct abi{ struct type : IInspectable +{ + virtual int32_t WINRT_CALL CreateInstance(void* owner, void** value) noexcept = 0; +};}; + +template +struct consume_react_uwp_IDynamicAutomationPeer +{ +}; +template <> struct consume { template using type = consume_react_uwp_IDynamicAutomationPeer; }; + +template +struct consume_react_uwp_IDynamicAutomationPeerFactory +{ + react::uwp::DynamicAutomationPeer CreateInstance(Windows::UI::Xaml::FrameworkElement const& owner) const; +}; +template <> struct consume { template using type = consume_react_uwp_IDynamicAutomationPeerFactory; }; + +} diff --git a/RNWCPP/ReactUWP/Views/cppwinrt/winrt/impl/react.uwp.1.h b/RNWCPP/ReactUWP/Views/cppwinrt/winrt/impl/react.uwp.1.h new file mode 100644 index 00000000000..554da7aca6d --- /dev/null +++ b/RNWCPP/ReactUWP/Views/cppwinrt/winrt/impl/react.uwp.1.h @@ -0,0 +1,25 @@ +// WARNING: Please don't edit this file. It was generated by C++/WinRT v1.0.180821.2 + +#pragma once +#include "winrt/impl/Windows.UI.Xaml.0.h" +#include "winrt/impl/Windows.UI.Xaml.Automation.Peers.0.h" +#include "winrt/impl/Windows.UI.Xaml.Automation.Provider.0.h" +#include "winrt/impl/react.uwp.0.h" + +WINRT_EXPORT namespace winrt::react::uwp { + +struct WINRT_EBO IDynamicAutomationPeer : + Windows::Foundation::IInspectable, + impl::consume_t +{ + IDynamicAutomationPeer(std::nullptr_t = nullptr) noexcept {} +}; + +struct WINRT_EBO IDynamicAutomationPeerFactory : + Windows::Foundation::IInspectable, + impl::consume_t +{ + IDynamicAutomationPeerFactory(std::nullptr_t = nullptr) noexcept {} +}; + +} diff --git a/RNWCPP/ReactUWP/Views/cppwinrt/winrt/impl/react.uwp.2.h b/RNWCPP/ReactUWP/Views/cppwinrt/winrt/impl/react.uwp.2.h new file mode 100644 index 00000000000..90dd61ed04f --- /dev/null +++ b/RNWCPP/ReactUWP/Views/cppwinrt/winrt/impl/react.uwp.2.h @@ -0,0 +1,28 @@ +// WARNING: Please don't edit this file. It was generated by C++/WinRT v1.0.180821.2 + +#pragma once +#include "winrt/impl/Windows.UI.Xaml.1.h" +#include "winrt/impl/Windows.UI.Xaml.Automation.Peers.1.h" +#include "winrt/impl/Windows.UI.Xaml.Automation.Provider.1.h" +#include "winrt/impl/react.uwp.1.h" + +WINRT_EXPORT namespace winrt::react::uwp { + +} + +namespace winrt::impl { + +} + +WINRT_EXPORT namespace winrt::react::uwp { + +struct WINRT_EBO DynamicAutomationPeer : + react::uwp::IDynamicAutomationPeer, + impl::base, + impl::require +{ + DynamicAutomationPeer(std::nullptr_t) noexcept {} + DynamicAutomationPeer(Windows::UI::Xaml::FrameworkElement const& owner); +}; + +} diff --git a/RNWCPP/ReactUWP/Views/cppwinrt/winrt/react.uwp.h b/RNWCPP/ReactUWP/Views/cppwinrt/winrt/react.uwp.h new file mode 100644 index 00000000000..ef33ee94c47 --- /dev/null +++ b/RNWCPP/ReactUWP/Views/cppwinrt/winrt/react.uwp.h @@ -0,0 +1,73 @@ +// WARNING: Please don't edit this file. It was generated by C++/WinRT v1.0.180821.2 + +#pragma once + +#include "winrt/base.h" + +#ifndef OLD_CPPWINRT +static_assert(winrt::check_version(CPPWINRT_VERSION, "1.0.180821.2"), "Mismatched component and base headers."); +#endif +#include "winrt/Windows.Foundation.h" +#include "winrt/Windows.Foundation.Collections.h" +#include "winrt/impl/Windows.UI.Xaml.2.h" +#include "winrt/impl/Windows.UI.Xaml.Automation.Peers.2.h" +#include "winrt/impl/Windows.UI.Xaml.Automation.Provider.2.h" +#include "winrt/impl/react.uwp.2.h" + +namespace winrt::impl { + +template react::uwp::DynamicAutomationPeer consume_react_uwp_IDynamicAutomationPeerFactory::CreateInstance(Windows::UI::Xaml::FrameworkElement const& owner) const +{ + react::uwp::DynamicAutomationPeer value{ nullptr }; + check_hresult(WINRT_SHIM(react::uwp::IDynamicAutomationPeerFactory)->CreateInstance(get_abi(owner), put_abi(value))); + return value; +} + +template +struct produce : produce_base +{}; + +template +struct produce : produce_base +{ + int32_t WINRT_CALL CreateInstance(void* owner, void** value) noexcept final + { + try + { + *value = nullptr; + typename D::abi_guard guard(this->shim()); + WINRT_ASSERT_DECLARATION(CreateInstance, WINRT_WRAP(react::uwp::DynamicAutomationPeer), Windows::UI::Xaml::FrameworkElement const&); + *value = detach_from(this->shim().CreateInstance(*reinterpret_cast(&owner))); + return 0; + } + catch (...) { return to_hresult(); } + } +}; + +} + +WINRT_EXPORT namespace winrt::react::uwp { + +inline DynamicAutomationPeer::DynamicAutomationPeer(Windows::UI::Xaml::FrameworkElement const& owner) : + DynamicAutomationPeer(impl::call_factory([&](auto&& f) { return f.CreateInstance(owner); })) +{} + +} + +namespace winrt::impl { + +} + +WINRT_EXPORT namespace winrt::experimental::reflect { + +template <> +struct base_type { using type = Windows::UI::Xaml::Automation::Peers::FrameworkElementAutomationPeer; }; +} + +WINRT_EXPORT namespace std { + +template<> struct hash : winrt::impl::hash_base {}; +template<> struct hash : winrt::impl::hash_base {}; +template<> struct hash : winrt::impl::hash_base {}; + +} diff --git a/RNWCPP/ReactUWP/Views/sources b/RNWCPP/ReactUWP/Views/sources index 9296d742ea2..4fe746ed39a 100644 --- a/RNWCPP/ReactUWP/Views/sources +++ b/RNWCPP/ReactUWP/Views/sources @@ -4,7 +4,6 @@ LIBLETNAME = ReactUWP_Views SOURCES = \ ActivityIndicatorViewManager.cpp \ - CalendarViewViewManager.cpp \ CheckboxViewManager.cpp \ DatePickerViewManager.cpp \ ControlViewManager.cpp \ @@ -23,7 +22,10 @@ SOURCES = \ TextViewManager.cpp \ ToucheventHandler.cpp \ ViewManagerBase.cpp \ + ViewControl.cpp \ ViewPanel.cpp \ ViewViewManager.cpp \ VirtualTextViewManager.cpp \ WebViewManager.cpp \ + +C_DEFINES = $(C_DEFINES) -DOLD_CPPWINRT=1 diff --git a/RNWCPP/Universal.SampleApp/index.uwp.js b/RNWCPP/Universal.SampleApp/index.uwp.js index f33564f684a..9ed2af432b8 100644 --- a/RNWCPP/Universal.SampleApp/index.uwp.js +++ b/RNWCPP/Universal.SampleApp/index.uwp.js @@ -16,7 +16,6 @@ import { TouchableHighlight } from 'react-native'; import { - CalendarView, CheckBox, DatePicker, Popup, @@ -117,7 +116,6 @@ export default class Bootstrap extends Component { pickerSelectedValue: "key1", pickerSelectedIndex: 0, datePickerSelectedValue: new Date(), - calendarViewSelectedDate: new Date(), }; render() { @@ -342,13 +340,6 @@ export default class Bootstrap extends Component { onDateChange={this.datePickerValueChange} /> - - Test CalendarView - Date selected: {this.state.calendarViewSelectedDate.toString()} - - ); @@ -426,10 +417,6 @@ export default class Bootstrap extends Component { datePickerValueChange = (date) => { this.setState({ datePickerSelectedValue: date }); } - - calendarViewSelectedDateChange = (date) => { - this.setState({ calendarViewSelectedDate: date }); - } } const styles = StyleSheet.create({ diff --git a/RNWCPP/include/ReactUWP/Views/ShadowNodeBase.h b/RNWCPP/include/ReactUWP/Views/ShadowNodeBase.h index 4a69bfa5e43..452a8e01d01 100644 --- a/RNWCPP/include/ReactUWP/Views/ShadowNodeBase.h +++ b/RNWCPP/include/ReactUWP/Views/ShadowNodeBase.h @@ -38,6 +38,31 @@ enum ShadowCorners : uint8_t CountCorners }; +enum AccessibilityRoles : uint8_t +{ + None = 0, + Button, + /* + Link, + Search, + Image, + KeyboardKey, + Text, + Adjustable, + ImageButton, + Header, + Summary, + */ + CountRoles +}; + +enum AccessibilityStates : uint8_t +{ + Selected = 0, + Disabled, + CountStates +}; + extern const DECLSPEC_SELECTANY double c_UndefinedEdge = -1; #define INIT_UNDEFINED_EDGES { c_UndefinedEdge, c_UndefinedEdge, c_UndefinedEdge, c_UndefinedEdge, c_UndefinedEdge, c_UndefinedEdge, c_UndefinedEdge, c_UndefinedEdge, c_UndefinedEdge } #define INIT_UNDEFINED_CORNERS { c_UndefinedEdge, c_UndefinedEdge, c_UndefinedEdge, c_UndefinedEdge, c_UndefinedEdge, c_UndefinedEdge, c_UndefinedEdge, c_UndefinedEdge, c_UndefinedEdge } @@ -82,6 +107,7 @@ struct REACTWINDOWS_EXPORT ShadowNodeBase : public facebook::react::ShadowNode double m_padding[ShadowEdges::CountEdges] = INIT_UNDEFINED_EDGES; double m_border[ShadowEdges::CountEdges] = INIT_UNDEFINED_EDGES; double m_cornerRadius[ShadowCorners::CountCorners] = INIT_UNDEFINED_CORNERS; + // Bound event types bool m_onLayout = false; bool m_onMouseEnter = false; diff --git a/RNWCPP/package.json b/RNWCPP/package.json index 401a2801593..1a265af459c 100644 --- a/RNWCPP/package.json +++ b/RNWCPP/package.json @@ -1,6 +1,6 @@ { "name": "react-native-windows", - "version": "0.57.0-vnext.9", + "version": "0.57.0-vnext.14", "license": "MIT", "description": "ReactNative Windows implementation using react-native's c++ ReactCommon bridge", "types": "lib/index.d.ts", @@ -33,7 +33,7 @@ } }, "dependencies": { - "react-native": "0.57.0-microsoft.6", + "react-native": "0.57.0-microsoft.9", "create-react-class": "^15.6.3", "fbjs": "0.8.17", "prop-types": "^15.5.8", diff --git a/RNWCPP/src/Libraries/Components/CalendarView/CalendarView.tsx b/RNWCPP/src/Libraries/Components/CalendarView/CalendarView.tsx deleted file mode 100644 index 920a4feb0a2..00000000000 --- a/RNWCPP/src/Libraries/Components/CalendarView/CalendarView.tsx +++ /dev/null @@ -1,13 +0,0 @@ -'use strict'; - -import * as React from 'react'; -import { ICalendarViewProps } from './CalendarViewProps'; - -export class CalendarView extends React.Component { - - public render(): JSX.Element | null { - return null; - } -} - -export default CalendarView; diff --git a/RNWCPP/src/Libraries/Components/CalendarView/CalendarView.uwp.tsx b/RNWCPP/src/Libraries/Components/CalendarView/CalendarView.uwp.tsx deleted file mode 100644 index 02fe01f55ce..00000000000 --- a/RNWCPP/src/Libraries/Components/CalendarView/CalendarView.uwp.tsx +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -'use strict'; - -import * as React from 'react'; -import { processColor, requireNativeComponent, StyleSheet } from 'react-native'; -import { ICalendarViewProps, ICalendarViewChangeEvent } from './CalendarViewProps'; - -const styles = StyleSheet.create({ - rctCalendarView: { - height: 340, - width: 280, - }, -}); - -const RCTCalendarView = requireNativeComponent('RCTCalendarView'); - -/** - * Renders a calendar view component. - * - * @keyword calendarview - * @keyword minicalendar - */ -export class CalendarView extends React.Component { - - // tslint:disable-next-line:no-any - private _rctCalendarView: any; - - public constructor(props: ICalendarViewProps) { - super(props); - this._rctCalendarView = React.createRef(); - } - - public render(): JSX.Element { - // Note: we don't use const props = { ...this.props } here because we need to convert string? color properties - // from ICalendarViewProps to number ? color properties(as needed on C++ side) - via processColor calls. - // For the sake of consistency, please keep properties below in alphabetical order (on property names). - const props = { - calendarIdentifier: this.props.calendarIdentifier, - calendarItemBackgroundColor: processColor(this.props.calendarItemBackgroundColor), - calendarItemBorderColor: processColor(this.props.calendarItemBorderColor), - calendarItemBorderThickness: this.props.calendarItemBorderThickness, - calendarItemColor: processColor(this.props.calendarItemColor), - dayItemFontFamily: this.props.dayItemFontFamily, - dayItemFontSize: this.props.dayItemFontSize, - dayItemFontWeight: this.props.dayItemFontWeight, - dayOfWeekFormat: this.props.dayOfWeekFormat, - firstDayOfWeek: this.props.firstDayOfWeek, - firstOfMonthLabelFontFamily: this.props.firstOfMonthLabelFontFamily, - firstOfMonthLabelFontSize: this.props.firstOfMonthLabelFontSize, - firstOfMonthLabelFontWeight: this.props.firstOfMonthLabelFontWeight, - firstOfYearDecadeLabelFontFamily: this.props.firstOfYearDecadeLabelFontFamily, - firstOfYearDecadeLabelFontSize: this.props.firstOfYearDecadeLabelFontSize, - firstOfYearDecadeLabelFontWeight: this.props.firstOfYearDecadeLabelFontWeight, - focusBorderColor: processColor(this.props.focusBorderColor), - horizontalDayItemAlignment: this.props.horizontalDayItemAlignment, - horizontalFirstOfMonthLabelAlignment: this.props.horizontalFirstOfMonthLabelAlignment, - hoverBorderColor: processColor(this.props.hoverBorderColor), - isGroupLabelVisible: this.props.isGroupLabelVisible, - isOutOfScopeEnabled: this.props.isOutOfScopeEnabled, - isTodayHighlighted: this.props.isTodayHighlighted, - maxDate: (this.props.maxDate ? this.props.maxDate.getTime() : undefined), // time in milliseconds - minDate: (this.props.minDate ? this.props.minDate.getTime() : undefined), // time in milliseconds - monthYearItemFontFamily: this.props.monthYearItemFontFamily, - monthYearItemFontSize: this.props.monthYearItemFontSize, - monthYearItemFontWeight: this.props.monthYearItemFontWeight, - numberOfWeeksInView: this.props.numberOfWeeksInView, - onChange: this.props.onChange, - onSelectedDateChange: this.props.onSelectedDateChange, - outOfScopeColor: processColor(this.props.outOfScopeColor), - outOfScopeBackgroundColor: processColor(this.props.outOfScopeBackgroundColor), - pressedBorderColor: processColor(this.props.pressedBorderColor), - pressedColor: processColor(this.props.pressedColor), - selectedBorderColor: processColor(this.props.selectedBorderColor), - selectedColor: processColor(this.props.selectedColor), - selectedDate: (this.props.selectedDate ? this.props.selectedDate.getTime() : undefined), // time in milliseconds - selectedHoverBorderColor: processColor(this.props.selectedHoverBorderColor), - selectedPressedBorderColor: processColor(this.props.selectedPressedBorderColor), - style: [styles.rctCalendarView, this.props.style], - todayColor: processColor(this.props.todayColor), - todayFontWeight: this.props.todayFontWeight, - verticalDayItemAlignment: this.props.verticalDayItemAlignment, - verticalFirstOfMonthLabelAlignment: this.props.verticalFirstOfMonthLabelAlignment, - }; - - // The Date object returns timezone in minutes. Convert that to seconds - // and multiply by -1 so that the offset can be added to GMT time to get - // the correct value on the native side. - const timeZoneOffsetInSeconds = - this.props.timeZoneOffsetInSeconds - ? this.props.timeZoneOffsetInSeconds - : this.props.selectedDate - ? (-1 * this.props.selectedDate.getTimezoneOffset() * 60) - : undefined; - - return ( - - ); - } - - private _setRef = (datepicker: CalendarView/*RCTCalendarView*/) => { - this._rctCalendarView = datepicker; - } - - private _onChange = (event: ICalendarViewChangeEvent) => { - if (this.props.selectedDate) { - const propsTimeStamp = this.props.selectedDate.getTime(); - if (this._rctCalendarView) { - this._rctCalendarView.setNativeProps({ selectedDate: propsTimeStamp }); - } - } - - // Change the props after the native props are set in case the props - // change removes the component - this.props.onChange && this.props.onChange(event); - - const nativeTimeStamp = event.nativeEvent.selectedDate; - this.props.onSelectedDateChange && - this.props.onSelectedDateChange(new Date(+nativeTimeStamp)); // Added the '+' operator to convert string to number - } -} - -export default CalendarView; diff --git a/RNWCPP/src/Libraries/Components/CalendarView/CalendarViewProps.ts b/RNWCPP/src/Libraries/Components/CalendarView/CalendarViewProps.ts deleted file mode 100644 index a75e8e70069..00000000000 --- a/RNWCPP/src/Libraries/Components/CalendarView/CalendarViewProps.ts +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -import { ViewProps } from 'react-native'; - -export interface ICalendarViewProps extends ViewProps { - // For the sake of consistency, please keep declarations below in alphabetical order (on property names). - calendarIdentifier?: string; - calendarItemBackgroundColor?: string; - calendarItemBorderColor?: string; - calendarItemBorderThickness?: number; - calendarItemColor?: string; - dayItemFontFamily?: string; - dayItemFontSize?: number; - dayItemFontWeight?: number; - dayOfWeekFormat?: '{dayofweek.abbreviated(2)}' | '{dayofweek.abbreviated(3)}' | '{dayofweek.full}'; - firstDayOfWeek?: 0 | 1 | 2 | 3 | 4 | 5 | 6; - firstOfMonthLabelFontFamily?: string; - firstOfMonthLabelFontSize?: number; - firstOfMonthLabelFontWeight?: number; - firstOfYearDecadeLabelFontFamily?: string; - firstOfYearDecadeLabelFontSize?: number; - firstOfYearDecadeLabelFontWeight?: number; - focusBorderColor?: string; - horizontalDayItemAlignment?: 'center' | 'left' | 'right' | 'stretch'; - horizontalFirstOfMonthLabelAlignment?: 'center' | 'left' | 'right' | 'stretch'; - hoverBorderColor?: string; - isGroupLabelVisible?: boolean; - isOutOfScopeEnabled?: boolean; - isTodayHighlighted?: boolean; - maxDate?: Date; - minDate?: Date; - monthYearItemFontFamily?: string; - monthYearItemFontSize?: number; - monthYearItemFontWeight?: number; - numberOfWeeksInView?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10; - onChange?: (event: ICalendarViewChangeEvent) => void; - onSelectedDateChange?: (selectedDate: Date) => void; - outOfScopeColor?: string; - outOfScopeBackgroundColor?: string; - pressedBorderColor?: string; - pressedColor?: string; - selectedBorderColor?: string; - selectedColor?: string; - selectedDate?: Date; - selectedHoverBorderColor?: string; - selectedPressedBorderColor?: string; - timeZoneOffsetInSeconds?: number; - todayColor?: string; - todayFontWeight?: number; - verticalDayItemAlignment?: 'bottom' | 'center' | 'stretch' | 'top'; - verticalFirstOfMonthLabelAlignment?: 'bottom' | 'center' | 'stretch' | 'top'; -} - -export interface ICalendarViewChangeEvent { - nativeEvent: { - selectedDate: number; - }; -} diff --git a/RNWCPP/src/RNTester/AccessibilityExample.tsx b/RNWCPP/src/RNTester/AccessibilityExample.tsx index f85dcf4fb67..f8e2720e967 100644 --- a/RNWCPP/src/RNTester/AccessibilityExample.tsx +++ b/RNWCPP/src/RNTester/AccessibilityExample.tsx @@ -27,22 +27,33 @@ class AccessibilityBaseExample extends React.Component { } } -class TouchableExamples extends React.Component { +class TouchableExamples extends React.Component<{}, any> { + public state = { + pressedCount: 0, + }; + public render() { return ( - The following has accessibilityLabel, accessibilityHint, toolip: + The following TouchableHighlight has accessibilityLabel, accessibilityHint, accessibilityRole, toolip: Blue + Pressed {this.state.pressedCount} times ); } + + private press = () => { + this.setState({pressedCount: this.state.pressedCount+1}); + } } diff --git a/RNWCPP/src/index.ts b/RNWCPP/src/index.ts index 5cf5e17fa94..43e9ff2c61a 100644 --- a/RNWCPP/src/index.ts +++ b/RNWCPP/src/index.ts @@ -1,8 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -export * from './Libraries/Components/CalendarView/CalendarView'; export * from './Libraries/Components/CheckBox/CheckBox'; -export * from './Libraries/Components/Picker/PickerUWP'; -export * from './Libraries/Components/Popup/Popup'; export * from './Libraries/Components/DatePicker/DatePicker'; export * from './Libraries/Components/DatePicker/DatePickerProps'; +export * from './Libraries/Components/Picker/PickerUWP'; +export * from './Libraries/Components/Popup/Popup'; diff --git a/RNWCPP/src/index.uwp.ts b/RNWCPP/src/index.uwp.ts index 82e226d900a..67ab6731e64 100644 --- a/RNWCPP/src/index.uwp.ts +++ b/RNWCPP/src/index.uwp.ts @@ -1,8 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -export * from './Libraries/Components/CalendarView/CalendarView.uwp'; export * from './Libraries/Components/CheckBox/CheckBox.uwp'; -export * from './Libraries/Components/Picker/PickerUWP.uwp'; -export * from './Libraries/Components/Popup/Popup.uwp'; export * from './Libraries/Components/DatePicker/DatePicker.uwp'; export * from './Libraries/Components/DatePicker/DatePickerProps'; +export * from './Libraries/Components/Picker/PickerUWP.uwp'; +export * from './Libraries/Components/Popup/Popup.uwp';