diff --git a/MessageTextPage.xaml.cpp b/MessageTextPage.xaml.cpp index 5094ae7a4557130ffa0263becf207076380bec16..9700db0acacfa8c7e10c3e8f1e881cd2e7862bb3 100644 --- a/MessageTextPage.xaml.cpp +++ b/MessageTextPage.xaml.cpp @@ -149,7 +149,7 @@ RingClientUWP::Views::MessageTextPage::sendMessage() Object ^ RingClientUWP::Views::BubbleBackground::Convert(Object ^ value, Windows::UI::Xaml::Interop::TypeName targetType, Object ^ parameter, String ^ language) { auto color1 = Windows::UI::ColorHelper::FromArgb(255, 0, 76, 96); - auto color2 = Windows::UI::ColorHelper::FromArgb(255, 58, 192, 210); + auto color2 = Windows::UI::ColorHelper::FromArgb(255, 58, 192, 210); // refacto : defines colors used by the application as globals return ((bool)value) ? ref new SolidColorBrush(color1) : ref new SolidColorBrush(color2); } diff --git a/RingD.cpp b/RingD.cpp index 07a3c3f1b73d9e9985261c4774876a3162f44dfb..fdb45dd62a1c6e60f5d435100a97455c2ac8628a 100644 --- a/RingD.cpp +++ b/RingD.cpp @@ -518,7 +518,11 @@ RingD::registerCallbacks() auto from2 = toPlatformString(from); auto item = SmartPanelItemsViewModel::instance->findItem(callId2); - auto contact = item->_contact; + Contact^ contact; + if (item) + contact = item->_contact; + else + WNG_("item not found!"); static const unsigned int profileSize = VCardUtils::PROFILE_VCF.size(); for (auto i : payloads) { diff --git a/SmartPanel.xaml b/SmartPanel.xaml index 019d21f3f6d347843151c2ad27f914e75748ea7b..c1a1635a9363b69b4208e407f15215897554bf04 100644 --- a/SmartPanel.xaml +++ b/SmartPanel.xaml @@ -37,6 +37,7 @@ <views:AccountSelectedToVisibility x:Key="_AccountSelectedToVisibility_" /> <views:CollapseEmptyString x:Key="_CollapseEmptyString_" /> <views:ContactStatusNotification x:Key="_ContactStatusNotification_" /> + <views:boolToVisibility x:Key="_boolToVisibility_" /> <!-- template for contacts. --> <DataTemplate x:Key="ContactTemplate" @@ -144,7 +145,10 @@ <!-- template for smartpanelitems. --> <DataTemplate x:Key="SmartPanelItemsTemplate" x:DataType="controls:SmartPanelItem"> - <Grid PointerEntered="Grid_PointerEntered" PointerExited="Grid_PointerExited" PointerMoved="Grid_PointerMoved" + <Grid PointerReleased="Grid_PointerReleased" + PointerEntered="Grid_PointerEntered" + PointerExited="Grid_PointerExited" + PointerMoved="Grid_PointerMoved" Visibility="{x:Bind _showMe, Mode=OneWay}"> <Grid.RowDefinitions> <!-- row definition for the contact. --> @@ -152,9 +156,19 @@ <!-- row definition for the incoming call bar. --> <RowDefinition Height="auto"/> </Grid.RowDefinitions> - <!--helper to detect mouse overing--> + <!-- the first rectangle helps to detect mouse overing--> <Rectangle Fill="Transparent" Grid.Row="0"/> + <!-- the two next rectangles offer a better visibility correlation between the call button and the + backgrounds. Using them, avoid some visual bugs --> + <!-- the second rectangle controls the background for a selected item --> + <Rectangle Fill="#3bc1d3" + Visibility="{x:Bind _isSelected, Converter={StaticResource _boolToVisibility_}, Mode=OneWay}" + Grid.Row="0"/> + <!-- the thirs rectangle controls the background for an hovered item --> + <Rectangle Fill="#ced9e1" + Visibility="{x:Bind _isHovered, Converter={StaticResource _boolToVisibility_}, Mode=OneWay}" + Grid.Row="0"/> <!-- curtain over item with contact not ready (e.g. lookup is in progress) --> <Rectangle Fill="White" Grid.Row="0" @@ -218,7 +232,6 @@ <RowDefinition Height="30"/> </Grid.RowDefinitions> <!-- name of the contact. --> - <!-- (XXX) Foreground="{x:Bind _contact._contactStatus, Converter={StaticResource _ContactStatusNotification_}, Mode=OneWay}"--> <TextBlock x:Name="_contactName_" Grid.Row="0" Text="{x:Bind _contact._name, Mode=OneWay}" @@ -226,7 +239,7 @@ </TextBlock> <!-- call button. --> <Button Grid.Row="0" - Visibility="{x:Bind _hovered, Mode=OneWay}" + Visibility="{x:Bind _isCallable, Converter={StaticResource _boolToVisibility_}, Mode=OneWay}" Click="_callContact__Click" VerticalAlignment="Bottom" HorizontalAlignment="Left" @@ -398,7 +411,8 @@ </Grid> <!-- smartList and settings. --> - <Grid Grid.Row="1"> + <Grid Grid.Row="1" + Background="#FFE4F1F9"> <!-- accounts menu. --> <Grid x:Name="_accountsMenuGrid_" Grid.Row="0" @@ -1140,9 +1154,10 @@ </Grid> <ListBox x:Name="_smartList_" Grid.Row="2" + Background="Transparent" Margin="0" - Padding="0" SelectionChanged="_smartList__SelectionChanged" + Padding="0" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.HorizontalScrollMode="Enabled" ItemContainerStyle="{StaticResource contactsListBoxStyle}" diff --git a/SmartPanel.xaml.cpp b/SmartPanel.xaml.cpp index 3a82cb8b3cda829616e6a8c318c91f6464ce98d7..5df2299affa9ccb1e6331abdca86240bcfbf4ad8 100644 --- a/SmartPanel.xaml.cpp +++ b/SmartPanel.xaml.cpp @@ -417,45 +417,14 @@ void RingClientUWP::Views::SmartPanel::_createAccountNo__Click(Platform::Object^ _accountsMenuButton__Unchecked(nullptr,nullptr); } +/* using the usual selection behaviour doesn't allow us to deselect by simple click. The selection is managed + by Grid_PointerReleased */ void SmartPanel::_smartList__SelectionChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::SelectionChangedEventArgs^ e) { - auto listbox = dynamic_cast<ListBox^>(sender); - auto item = dynamic_cast<SmartPanelItem^>(listbox->SelectedItem); - - if (item) - if (item->_contact->_contactStatus == ContactStatus::WAITING_FOR_ACTIVATION) { - listbox->SelectedItem = nullptr; - return; - } - - SmartPanelItemsViewModel::instance->_selectedItem = item; - - if (!item) { - summonWelcomePage(); - return; - } - - auto contact = item->_contact; - - if (item->_callStatus == CallStatus::IN_PROGRESS - || item->_callStatus == CallStatus::PAUSED - || item->_callStatus == CallStatus::PEER_PAUSED) { - if (contact) { - contact->_unreadMessages = 0; - ContactsViewModel::instance->saveContactsToFile(); - } - - summonVideoPage(); - return; - } - - if (contact) { - summonMessageTextPage(); - contact->_unreadMessages = 0; - ContactsViewModel::instance->saveContactsToFile(); - return; - } + auto listbox = dynamic_cast<ListBox^>(sender); // same as _smartList_ + listbox->SelectedItem = nullptr; + return; } void @@ -561,7 +530,11 @@ SmartPanel::_callContact__Click(Platform::Object^ sender, Windows::UI::Xaml::Rou if (it->_callStatus == CallStatus::IN_PROGRESS) RingD::instance->pauseCall(Utils::toString(it->_callId)); - RingD::instance->placeCall(contact); + if (item->_callStatus == CallStatus::ENDED || item->_callStatus == CallStatus::NONE) { + item->_callStatus == CallStatus::OUTGOING_REQUESTED; + RingD::instance->placeCall(contact); + } + } } } @@ -585,24 +558,11 @@ void RingClientUWP::Views::SmartPanel::Grid_PointerEntered(Platform::Object^ sen auto grid = dynamic_cast<Grid^>(sender); auto item = dynamic_cast<SmartPanelItem^>(grid->DataContext); - for (auto it : SmartPanelItemsViewModel::instance->itemsList) - it->_hovered = Windows::UI::Xaml::Visibility::Collapsed; - - /// to keep for future use, when we will be able to do several calls. - ///if (item->_callStatus == CallStatus::NONE || item->_callStatus == CallStatus::ENDED) - /// item->_hovered = Windows::UI::Xaml::Visibility::Visible; - - /// for now use this, do not merge with the for loop above, to make easier to remove that part later - /*bool anyCall = false; for (auto it : SmartPanelItemsViewModel::instance->itemsList) { - if (it->_callStatus != CallStatus::NONE && it->_callStatus != CallStatus::ENDED) - anyCall = true; + it->_isHovered = false; } - if (anyCall == false)*/ - item->_hovered = Windows::UI::Xaml::Visibility::Visible; - - + item->_isHovered = true; } @@ -611,8 +571,10 @@ void RingClientUWP::Views::SmartPanel::Grid_PointerExited(Platform::Object^ send auto grid = dynamic_cast<Grid^>(sender); auto item = dynamic_cast<SmartPanelItem^>(grid->DataContext); - for each (auto it in SmartPanelItemsViewModel::instance->itemsList) - item->_hovered = Windows::UI::Xaml::Visibility::Collapsed; + // to avoid visual bug, do it on the whole list + for each (auto it in SmartPanelItemsViewModel::instance->itemsList) { + it->_isHovered = false; + } } @@ -1311,23 +1273,9 @@ void RingClientUWP::Views::SmartPanel::Grid_PointerMoved(Platform::Object^ sende auto item = dynamic_cast<SmartPanelItem^>(grid->DataContext); for (auto it : SmartPanelItemsViewModel::instance->itemsList) - it->_hovered = Windows::UI::Xaml::Visibility::Collapsed; - - /// to keep for future use, when we will be able to do several calls. - ///if (item->_callStatus == CallStatus::NONE || item->_callStatus == CallStatus::ENDED) - /// item->_hovered = Windows::UI::Xaml::Visibility::Visible; - - /// for now use this, do not merge with the for loop above, to make easier to remove that part later - /*bool anyCall = false; - for (auto it : SmartPanelItemsViewModel::instance->itemsList) { - if (it->_callStatus != CallStatus::NONE && it->_callStatus != CallStatus::ENDED) - anyCall = true; - } - - if (anyCall == false)*/ - item->_hovered = Windows::UI::Xaml::Visibility::Visible; - + it->_isHovered = false; + item->_isHovered = true; } // NAME SERVICE @@ -1816,3 +1764,73 @@ Object ^ RingClientUWP::Views::ContactStatusNotification::ConvertBack(Object ^ v RingClientUWP::Views::ContactStatusNotification::ContactStatusNotification() {} + + +/* if you changed the name of Grid_PointerReleased, be sure to change it in the comment about the selection */ +void RingClientUWP::Views::SmartPanel::Grid_PointerReleased(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ e) +{ + auto grid = dynamic_cast<Grid^>(sender); + auto item = dynamic_cast<SmartPanelItem^>(grid->DataContext); + + if (item) { + /* if the contact is not yet ready to be used, typically when we are waiting a lookup from the blockachin*/ + auto contact = item->_contact; + + if (contact == nullptr) + { + ERR_("SmartPanelIem without contact"); + return; + } + + if (contact->_contactStatus == ContactStatus::WAITING_FOR_ACTIVATION) { + //_smartList_->SelectedItem = nullptr; + return; + } + + /* if the contact was already selected, just do a deselection and live the message text page*/ + if (item == SmartPanelItemsViewModel::instance->_selectedItem) + { + //_smartList_->SelectedItem = nullptr; + SmartPanelItemsViewModel::instance->_selectedItem = nullptr; + summonWelcomePage(); + return; + } + + /* we set the current selected item */ + SmartPanelItemsViewModel::instance->_selectedItem = item; + + /* at this point we check if a call is in progress with the current selected contact*/ + if (item->_callStatus == CallStatus::IN_PROGRESS + || item->_callStatus == CallStatus::PAUSED + || item->_callStatus == CallStatus::PEER_PAUSED) { + if (contact) { + contact->_unreadMessages = 0; + ContactsViewModel::instance->saveContactsToFile(); + } + + summonVideoPage(); + return; + } + + /* else, summont the message text page*/ + summonMessageTextPage(); + contact->_unreadMessages = 0; + ContactsViewModel::instance->saveContactsToFile(); + } +} + +Object ^ RingClientUWP::Views::boolToVisibility::Convert(Object ^ value, Windows::UI::Xaml::Interop::TypeName targetType, Object ^ parameter, String ^ language) +{ + if (static_cast<bool>(value)) + return Windows::UI::Xaml::Visibility::Visible; + + return Windows::UI::Xaml::Visibility::Collapsed; +} + +Object ^ RingClientUWP::Views::boolToVisibility::ConvertBack(Object ^ value, Windows::UI::Xaml::Interop::TypeName targetType, Object ^ parameter, String ^ language) +{ + throw ref new Platform::NotImplementedException(); +} + +RingClientUWP::Views::boolToVisibility::boolToVisibility() +{} diff --git a/SmartPanel.xaml.h b/SmartPanel.xaml.h index ec1cc2f4126d3a6f9619e5849118268af55680c2..93926ce108165d0a6241d9ffaa8ca6d1d4abba9e 100644 --- a/SmartPanel.xaml.h +++ b/SmartPanel.xaml.h @@ -87,6 +87,13 @@ public: ContactStatusNotification(); }; +public ref class boolToVisibility sealed : IValueConverter { +public: + virtual Object^ Convert(Object^ value, Windows::UI::Xaml::Interop::TypeName targetType, Object^ parameter, String^ language); + virtual Object^ ConvertBack(Object^ value, Windows::UI::Xaml::Interop::TypeName targetType, Object^ parameter, String^ language); + boolToVisibility(); +}; + public ref class SmartPanel sealed { public: @@ -189,6 +196,7 @@ private: }; MenuOpen menuOpen; + void Grid_PointerReleased(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ e); }; } } diff --git a/SmartPanelItem.cpp b/SmartPanelItem.cpp index be4254ba73a743632b904019bbec57206fdc2697..e093cca82eea4b342665d3bff5be44e8dae4b8be 100644 --- a/SmartPanelItem.cpp +++ b/SmartPanelItem.cpp @@ -33,6 +33,8 @@ SmartPanelItem::SmartPanelItem() { _callId = ""; videoMuted_ = false; + isSelected_ = false; + isHovered_ = false; RingD::instance->callPlaced += ref new RingClientUWP::CallPlaced(this, &RingClientUWP::Controls::SmartPanelItem::OncallPlaced); } diff --git a/SmartPanelItem.h b/SmartPanelItem.h index 1f5b34db2198c5e317a67bf3c493d2315b048f85..463f10b4956736d766b1edc7ad8fc15c80b47114 100644 --- a/SmartPanelItem.h +++ b/SmartPanelItem.h @@ -33,30 +33,6 @@ public: virtual event PropertyChangedEventHandler^ PropertyChanged; property Contact^ _contact; - /*property Call^ _call - { - Call^ get() - { - return call_; - } - void set(Call^ value) - { - call_ = value; - PropertyChanged(this, ref new PropertyChangedEventArgs("_call")); - } - }*/ - property Visibility _hovered - { - Visibility get() - { - return hovered_; - } - void set(Visibility value) - { - hovered_ = value; - NotifyPropertyChanged("_hovered"); - } - } property String^ _callId; /*{ String^ get() { @@ -98,15 +74,52 @@ public: } } + property bool _isSelected + { + bool get() + { + return isSelected_; + } + void set(bool value) + { + isSelected_ = value; + NotifyPropertyChanged("_isSelected"); + } + } + + property bool _isHovered + { + bool get() + { + return isHovered_; + } + void set(bool value) + { + isHovered_ = value; + NotifyPropertyChanged("_isHovered"); + NotifyPropertyChanged("_isCallable"); + } + } + + property bool _isCallable + { + bool get() + { + return ((callStatus_ == CallStatus::ENDED || callStatus_ == CallStatus::NONE) && isHovered_)? true : false; + } + } + + protected: void NotifyPropertyChanged(String^ propertyName); private: - Visibility hovered_ = Visibility::Collapsed; Visibility showMe_ = Visibility::Visible; CallStatus callStatus_; String^ callId_; bool videoMuted_; + bool isSelected_; + bool isHovered_; void OncallPlaced(Platform::String ^callId); }; diff --git a/SmartPanelItemsViewModel.h b/SmartPanelItemsViewModel.h index 184120b73e3b849df6a129ce7ae16390f772f534..e3656999068f14e50d48e5a62dcebebf38d0dcde 100644 --- a/SmartPanelItemsViewModel.h +++ b/SmartPanelItemsViewModel.h @@ -66,6 +66,12 @@ internal: { oldItem_ = currentItem_; currentItem_ = value; + + if (oldItem_ != nullptr) + oldItem_->_isSelected = false; + + if (currentItem_ != nullptr) + currentItem_->_isSelected = true; } } diff --git a/Styles.xaml b/Styles.xaml index 70f9b1a984327de21c764afee86b533b00cf9f2b..5a14e5d64a6accdf6fb572b59346acfb42c7f554 100644 --- a/Styles.xaml +++ b/Styles.xaml @@ -364,6 +364,10 @@ </Style> <!-- smartlist --> + <!--<Style x:Key="smartListStyle" TargetType="ListBox"> + <Setter Property="Background" Value="#FFE4F1F9"/> + <Setter Property="" Value="#FFE4F1F9"/> + </Style>--> <Style x:Key="contactsListBoxStyle" TargetType="ListBoxItem"> <Setter Property="MinWidth" Value="{StaticResource SplitViewCompactPaneThemeLength}"/> <Setter Property="Height" Value="auto"/> @@ -456,7 +460,7 @@ <Setter.Value> <ControlTemplate TargetType ="Button"> <Grid> - <Ellipse Name ="OuterRing" Width ="30" Height ="30" Fill ="#3bc1d3"/> + <Ellipse Name ="OuterRing" Width ="30" Height ="30" Fill ="#004c60"/> <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White"/> </Grid> </ControlTemplate> diff --git a/VideoPage.xaml.cpp b/VideoPage.xaml.cpp index 0798d2fbfadd6f7d84271e75a3552a8b624b74f3..67dc210c22aa157a27c395924b2f021d9a1bdde3 100644 --- a/VideoPage.xaml.cpp +++ b/VideoPage.xaml.cpp @@ -243,9 +243,13 @@ void RingClientUWP::Views::VideoPage::_btnCancel__Click(Platform::Object^ sender void RingClientUWP::Views::VideoPage::_btnHangUp__Tapped(Platform::Object^ sender, Windows::UI::Xaml::Input::TappedRoutedEventArgs^ e) { auto item = SmartPanelItemsViewModel::instance->_selectedItem; - RingD::instance->hangUpCall2(item->_callId); - pressHangUpCall(); + if (item) { + RingD::instance->hangUpCall2(item->_callId); + pressHangUpCall(); + } + else + WNG_("item not found, cannot hang up"); }