-
Notifications
You must be signed in to change notification settings - Fork 32
Add ContentPopup #276
base: master
Are you sure you want to change the base?
Add ContentPopup #276
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -48,6 +48,7 @@ public static void Init() | |||||
{ | ||||||
if (IsInitialized) return; | ||||||
IsInitialized = true; | ||||||
ContentPopup.RendererFunc = () => new ContentPopupRenderer(); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
} | ||||||
|
||||||
public static void Init(string apiKey) | ||||||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,141 @@ | ||||||
/* | ||||||
* Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved | ||||||
* | ||||||
* Licensed under the Flora License, Version 1.1 (the "License"); | ||||||
* you may not use this file except in compliance with the License. | ||||||
* You may obtain a copy of the License at | ||||||
* | ||||||
* http://floralicense.org/license/ | ||||||
* | ||||||
* Unless required by applicable law or agreed to in writing, software | ||||||
* distributed under the License is distributed on an "AS IS" BASIS, | ||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
* See the License for the specific language governing permissions and | ||||||
* limitations under the License. | ||||||
*/ | ||||||
|
||||||
using System; | ||||||
using System.ComponentModel; | ||||||
using Tizen.Wearable.CircularUI.Forms; | ||||||
using Tizen.Wearable.CircularUI.Forms.Renderer; | ||||||
using Xamarin.Forms; | ||||||
using Xamarin.Forms.Platform.Tizen; | ||||||
using XForms = Xamarin.Forms.Forms; | ||||||
|
||||||
[assembly: ExportRenderer(typeof(ContentPopup), typeof(ContentPopupRenderer))] | ||||||
|
||||||
namespace Tizen.Wearable.CircularUI.Forms.Renderer | ||||||
{ | ||||||
public class ContentPopupRenderer : IContentPopupRenderer | ||||||
{ | ||||||
ElmSharp.Popup _popup; | ||||||
ContentPopup _element; | ||||||
|
||||||
public void SetElement(Element element) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Because it is |
||||||
{ | ||||||
if (element.Parent == null) | ||||||
element.Parent = Application.Current; | ||||||
element.PropertyChanged += OnElementPropertyChanged; | ||||||
_element = element as ContentPopup; | ||||||
|
||||||
UpdateContent(); | ||||||
UpdateIsShow(); | ||||||
} | ||||||
|
||||||
public ContentPopupRenderer() | ||||||
myroot marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
{ | ||||||
_popup = new ElmSharp.Popup(XForms.NativeParent); | ||||||
_popup.Style = "circle"; | ||||||
|
||||||
_popup.BackButtonPressed += OnBackButtonPressed; | ||||||
_popup.Dismissed += OnDismissed; | ||||||
} | ||||||
|
||||||
~ContentPopupRenderer() | ||||||
{ | ||||||
Dispose(false); | ||||||
} | ||||||
|
||||||
public void Dispose() | ||||||
{ | ||||||
Dispose(true); | ||||||
GC.SuppressFinalize(this); | ||||||
} | ||||||
|
||||||
public void Dismiss() | ||||||
{ | ||||||
_popup?.Hide(); | ||||||
} | ||||||
|
||||||
public void Show() | ||||||
{ | ||||||
_popup?.Show(); | ||||||
} | ||||||
|
||||||
protected void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) | ||||||
{ | ||||||
if (e.PropertyName == ContentPopup.ContentProperty.PropertyName) | ||||||
{ | ||||||
UpdateContent(); | ||||||
} | ||||||
if (e.PropertyName == ContentPopup.IsShowProperty.PropertyName) | ||||||
{ | ||||||
UpdateIsShow(); | ||||||
} | ||||||
} | ||||||
|
||||||
protected virtual void Dispose(bool disposing) | ||||||
{ | ||||||
if (disposing) | ||||||
{ | ||||||
if (_popup != null) | ||||||
{ | ||||||
_popup.BackButtonPressed -= OnBackButtonPressed; | ||||||
_popup.Dismissed -= OnDismissed; | ||||||
_popup.Unrealize(); | ||||||
_popup = null; | ||||||
} | ||||||
if (_element != null) | ||||||
{ | ||||||
_element.PropertyChanged -= OnElementPropertyChanged; | ||||||
_element = null; | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
void OnBackButtonPressed(object sender, EventArgs e) | ||||||
myroot marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
{ | ||||||
_element.SendBackButtonPressed(); | ||||||
} | ||||||
|
||||||
void OnDismissed(object sender, EventArgs e) | ||||||
{ | ||||||
_element.SendDismissed(); | ||||||
Dispose(); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do you dispose it? |
||||||
} | ||||||
|
||||||
void UpdateContent() | ||||||
{ | ||||||
if (_element.Content != null) | ||||||
{ | ||||||
var renderer = Platform.GetOrCreateRenderer(_element.Content); | ||||||
(renderer as LayoutRenderer)?.RegisterOnLayoutUpdated(); | ||||||
var native = renderer.NativeView; | ||||||
native.MinimumHeight = 360; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do not use static value native.AlignmentX= -1;
native.AlignmentY= -1;
native.WeightX = 1;
native.WeightY = 1; |
||||||
_popup.SetContent(native, false); | ||||||
} | ||||||
else | ||||||
{ | ||||||
_popup.SetContent(null, false); | ||||||
} | ||||||
} | ||||||
|
||||||
void UpdateIsShow() | ||||||
{ | ||||||
if (_element.IsShow) | ||||||
Show(); | ||||||
else | ||||||
Dismiss(); | ||||||
} | ||||||
} | ||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
/* | ||
* Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved | ||
* | ||
* Licensed under the Flora License, Version 1.1 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://floralicense.org/license/ | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
using System; | ||
using System.ComponentModel; | ||
using Xamarin.Forms; | ||
|
||
namespace Tizen.Wearable.CircularUI.Forms | ||
{ | ||
/// <summary> | ||
/// The ContentPopup is a Popup, which allows you to customize the View to be displayed. | ||
/// </summary> | ||
/// <since_tizen> 4 </since_tizen> | ||
public class ContentPopup : Element, IDisposable | ||
{ | ||
IContentPopupRenderer _renderer; | ||
|
||
/// <summary> | ||
/// For internal use. | ||
/// </summary> | ||
[EditorBrowsable(EditorBrowsableState.Never)] | ||
public static Func<IContentPopupRenderer> RendererFunc { get; set; } = null; | ||
|
||
/// <summary> | ||
/// BindableProperty. Identifies the Content bindable property. | ||
/// </summary> | ||
/// <since_tizen> 4 </since_tizen> | ||
public static readonly BindableProperty ContentProperty = BindableProperty.Create(nameof(Content), typeof(View), typeof(ContentPopup), null, propertyChanged: (b, o, n) => ((ContentPopup)b).UpdateContent()); | ||
|
||
/// <summary> | ||
/// BindableProperty. Identifies the IsShow bindable property. | ||
/// </summary> | ||
/// <since_tizen> 4 </since_tizen> | ||
public static readonly BindableProperty IsShowProperty = BindableProperty.Create(nameof(IsShow), typeof(bool), typeof(ContentPopup), false, propertyChanged:(b, o, n) => ((ContentPopup)b).UpdateRenderer()); | ||
|
||
/// <summary> | ||
/// Occurs when the device's back button is pressed. | ||
/// </summary> | ||
/// <since_tizen> 4 </since_tizen> | ||
public event EventHandler BackButtonPressed; | ||
|
||
/// <summary> | ||
/// Occurs when the popup is dismissed. | ||
/// </summary> | ||
/// <since_tizen> 4 </since_tizen> | ||
public event EventHandler Dismissed; | ||
|
||
/// <summary> | ||
/// Gets or sets content view of the Popup. | ||
/// </summary> | ||
/// <since_tizen> 4 </since_tizen> | ||
public View Content | ||
{ | ||
get { return (View)GetValue(ContentProperty); } | ||
set { SetValue(ContentProperty, value); } | ||
} | ||
|
||
/// <summary> | ||
/// Gets or sets the popup is shown. | ||
/// </summary> | ||
/// <since_tizen> 4 </since_tizen> | ||
public bool IsShow | ||
{ | ||
get { return (bool)GetValue(IsShowProperty); } | ||
set { SetValue(IsShowProperty, value); } | ||
} | ||
|
||
/// <summary> | ||
/// Shows the popup. | ||
/// </summary> | ||
/// <since_tizen> 4 </since_tizen> | ||
public void Show() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about rename to TaskCompletionSource<bool> _tcsForDismiss;
public Task Open()
{
IsShow = true;
_tcsForDismiss = new TaskCompletionSource<bool>();
return _tcsForDismiss.Task;
}
public void SendDismissed()
{
Dismissed?.Invoke(this, EventArgs.Empty);
_tcsForDismiss?.TrySetResult(true);
} If you provide using (var popup = new ContentPopup()) {
poup.Content = new StackLayout { ... };
_ = await popup.Open();
} |
||
{ | ||
IsShow = true; | ||
} | ||
|
||
/// <summary> | ||
/// Dismisses the popup. | ||
/// </summary> | ||
/// <since_tizen> 4 </since_tizen> | ||
public void Dismiss() | ||
{ | ||
IsShow = false; | ||
} | ||
|
||
/// <summary> | ||
/// For internal use. | ||
/// </summary> | ||
[EditorBrowsable(EditorBrowsableState.Never)] | ||
public void SendDismissed() | ||
{ | ||
Dismissed?.Invoke(this, EventArgs.Empty); | ||
} | ||
|
||
/// <summary> | ||
/// For internal use. | ||
/// </summary> | ||
[EditorBrowsable(EditorBrowsableState.Never)] | ||
public void SendBackButtonPressed() | ||
{ | ||
BackButtonPressed?.Invoke(this, EventArgs.Empty); | ||
} | ||
|
||
/// <summary> | ||
/// Dispose the popup. | ||
/// </summary> | ||
/// <since_tizen> 4 </since_tizen> | ||
public void Dispose() | ||
{ | ||
Dispose(true); | ||
} | ||
|
||
protected virtual void Dispose(bool disposing) | ||
{ | ||
if (disposing && _renderer != null) | ||
{ | ||
_renderer.Dispose(); | ||
_renderer = null; | ||
} | ||
} | ||
|
||
protected override void OnBindingContextChanged() | ||
{ | ||
base.OnBindingContextChanged(); | ||
if (Content != null) | ||
SetInheritedBindingContext(Content, BindingContext); | ||
} | ||
|
||
void UpdateContent() | ||
{ | ||
if (Content != null) | ||
OnChildAdded(Content); | ||
} | ||
|
||
void UpdateRenderer() | ||
{ | ||
if (_renderer == null) | ||
{ | ||
_renderer = RendererFunc(); | ||
_renderer.SetElement(this); | ||
} | ||
} | ||
|
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/* | ||
* Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved | ||
* | ||
* Licensed under the Flora License, Version 1.1 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://floralicense.org/license/ | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
using System; | ||
using Xamarin.Forms; | ||
|
||
namespace Tizen.Wearable.CircularUI.Forms | ||
{ | ||
/// <summary> | ||
/// Base interface for ContentPopup renderer. | ||
/// </summary> | ||
/// <since_tizen> 4 </since_tizen> | ||
public interface IContentPopupRenderer : IDisposable | ||
{ | ||
/// <summary> | ||
/// Sets the Element associated with this renderer. | ||
/// </summary> | ||
/// <param name="element">New element.</param> | ||
void SetElement(Element element); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -72,4 +72,4 @@ internal interface ITwoButtonPopup | |
/// <since_tizen> 4 </since_tizen> | ||
void Dismiss(); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
<?xml version="1.0" encoding="utf-8" ?> | ||
<ContentPage | ||
x:Class="WearableUIGallery.TC.TCContentPopupTest" | ||
xmlns="http://xamarin.com/schemas/2014/forms" | ||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" | ||
xmlns:local="clr-namespace:WearableUIGallery" | ||
xmlns:w="clr-namespace:Tizen.Wearable.CircularUI.Forms;assembly=Tizen.Wearable.CircularUI.Forms" | ||
w:CircleSurfaceEffectBehavior.RotaryFocusObject="{x:Reference myscroller}"> | ||
<ContentPage.Behaviors> | ||
<w:CircleSurfaceEffectBehavior/> | ||
</ContentPage.Behaviors> | ||
<ContentPage.Content> | ||
<w:CircleScrollView x:Name="myscroller" Orientation="Vertical"> | ||
<StackLayout Padding="0,50,0,50"> | ||
<Label | ||
x:Name="label1" | ||
HorizontalOptions="CenterAndExpand" | ||
Text="ContentPopup test" | ||
VerticalOptions="Start" /> | ||
<Button | ||
AutomationId="dismisstest1" | ||
x:Name="button1" | ||
Clicked="OnContentPopupDismissBackKeyClicked" | ||
FontSize="Small" | ||
HeightRequest="50" | ||
HorizontalOptions="Center" | ||
Text="Dismiss test 1" | ||
VerticalOptions="CenterAndExpand" | ||
WidthRequest="300" /> | ||
<Button | ||
AutomationId="dismisstest2" | ||
x:Name="button2" | ||
Clicked="OnContentPopupDismissButtonClicked" | ||
FontSize="Small" | ||
HeightRequest="50" | ||
HorizontalOptions="Center" | ||
Text="Dismiss test 2" | ||
VerticalOptions="CenterAndExpand" | ||
WidthRequest="300" /> | ||
</StackLayout> | ||
</w:CircleScrollView> | ||
</ContentPage.Content> | ||
</ContentPage> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where this technique come from?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
come from me 😉