Adding Support for Select-Mode in Apps for taskbar 62/291262/1
authorShivam Varshney/Core S/W Group /SRI-Delhi/Engineer/Samsung Electronics <shivam.v2@samsung.com>
Wed, 12 Apr 2023 09:19:58 +0000 (14:49 +0530)
committerShivam Varshney/Core S/W Group /SRI-Delhi/Engineer/Samsung Electronics <shivam.v2@samsung.com>
Wed, 12 Apr 2023 09:19:58 +0000 (14:49 +0530)
Change-Id: I7bead366af4a8aaab4fa4d3998c7b805e34b8561
Signed-off-by: Shivam Varshney/Core S/W Group /SRI-Delhi/Engineer/Samsung Electronics <shivam.v2@samsung.com>
16 files changed:
Apps/Apps.cs
Apps/Models/AppInfoModel.cs
Apps/ViewManager.cs
Apps/ViewModels/AppViewModel.cs
Apps/Views/AppItemLayout.cs
Apps/Views/AppView.cs
Apps/Views/SelectAppItemLayout.cs [new file with mode: 0644]
Apps/Views/SelectAppsView.cs [new file with mode: 0644]
Apps/Views/SelectAppsViewHeader.cs [new file with mode: 0644]
Apps/res/images/dark/circle.png [new file with mode: 0644]
Apps/res/images/dark/circle_selected.png [new file with mode: 0644]
Apps/res/images/light/circle.png [new file with mode: 0644]
Apps/res/images/light/circle_selected.png [new file with mode: 0644]
Apps/res/themes/dark.xaml
Apps/res/themes/light.xaml
packaging/org.tizen.Apps-1.0.0.tpk

index 508452e518013b7cc28509661edd7840c0b93c7e..1fc110eac103758ef38dc1e13012f18e246bbac6 100755 (executable)
  *  limitations under the License
  */
 
+using System;
 using System.Collections.Generic;
+using Tizen.Applications;
 using Tizen.NUI;
 using Apps.Common;
 using Apps.Views;
+
 namespace Apps
 {
     public class Program : NUIApplication
@@ -54,10 +57,55 @@ namespace Apps
             window.KeyEvent += OnKeyEvent;
             window.Resized += OnWindowResized;
             window.OrientationChanged += OnWindowOrientationChanged;
-            viewManager = new ViewManager(window);
+            viewManager = new ViewManager();
             Tizen.Log.Info(Resources.LogTag, "Show Window");
         }
 
+        protected override void OnAppControlReceived(AppControlReceivedEventArgs e)
+        {
+            base.OnAppControlReceived(e);
+            if (e.ReceivedAppControl.ExtraData != null)
+            {
+                try
+                {
+                    string mode = (string)e.ReceivedAppControl.ExtraData.Get("taskBar");
+                    if (mode != "SelectApps")
+                    {
+                        Exit();
+                    }
+                    Tizen.Log.Debug(Resources.LogTag, "appControl Received from taskBar");
+                    if (e.ReceivedAppControl.ExtraData.TryGet("taskBarPinnedApps", out IEnumerable<string> receivedValue))
+                    {
+                        viewManager.LaunchSelectMode((List<string>)receivedValue);
+                    }
+                    else
+                    {
+                        viewManager.LaunchSelectMode(null);
+                    }
+
+                    viewManager.AppsSelected += (object sender, List<string> selectedApps) =>
+                    {
+                        if (e.ReceivedAppControl.IsReplyRequest == true)
+                        {
+                            AppControl appControl = new AppControl()
+                            {
+                                ApplicationId = "org.tizen.Apps",
+                                Operation = AppControlOperations.Send
+                            };
+                            appControl.ExtraData.Add("SelectedApps", selectedApps);
+                            e.ReceivedAppControl.ReplyToLaunchRequest(appControl, AppControlReplyResult.Succeeded);
+                            Exit();
+                        }
+                    };
+                }
+                catch(Exception ex)
+                {
+                    Tizen.Log.Debug(Resources.LogTag, ex.Message);
+                }
+
+            }
+        }
+
         private void OnWindowOrientationChanged(object sender, WindowOrientationChangedEventArgs e)
         {
             Tizen.Log.Debug(Resources.LogTag, "orientation changed" + e.WindowOrientation);
index 49e8a4aa2b0ecd6d3ca92920d565ff543c92c6dc..27fe83244f2f25100dfb54bbc0b5595e085e6ca0 100755 (executable)
@@ -15,7 +15,6 @@
  */
 
 using System;
-using System.Collections.Generic;
 using System.Windows.Input;
 using Tizen.NUI;
 using Tizen.NUI.Binding;
@@ -26,15 +25,13 @@ namespace Apps.Models
 {
     class AppInfoModel : PropertyNotifier
     {
-        private ImageVisual defaultVisual;
-        private GradientVisual gradientVisual;
-
         public AppInfoModel(string name, string applicationId, string url)
         {
             Name = name;
             ApplicationId = applicationId;
             IconUrl = url;
-            SetExtractedBackground(url);
+            SetBackgroundColor(url);
+            IsSelected = false;
             AppSelectCommand = new Command(OnAppSelect);
         }
 
@@ -50,12 +47,20 @@ namespace Apps.Models
             set => SetProperty(ref iconUrl, value);
         }
 
-        private PropertyMap iconBackground;
+        private bool isSelected;
+
+        public bool IsSelected
+        {
+            get => isSelected;
+            set => SetProperty(ref isSelected, value);
+        }
+
+        private Color iconBackgroundColor;
 
-        public PropertyMap IconBackground
+        public Color IconBackgroundColor
         {
-            get => iconBackground;
-            set => SetProperty(ref iconBackground, value);
+            get => iconBackgroundColor;
+            set => SetProperty(ref iconBackgroundColor, value);
         }
 
         private ICommand appSelectCommand;
@@ -71,79 +76,7 @@ namespace Apps.Models
             NUIApplication.Current.Exit();
         }
 
-        private void SetDefaultImageVisual()
-        {
-            defaultVisual = new ImageVisual()
-            {
-                URL = Resources.GetImagePath() + "default_gradient.png",
-                CornerRadius = new Vector4(12, 12, 12, 12),
-            };
-        }
-
-        private void SetGradientVisual(PropertyArray stopColor)
-        {
-            gradientVisual = new GradientVisual()
-            {
-                StartPosition = new Vector2(0.0f, -1.0f),
-                EndPosition = new Vector2(0.0f, 1.0f),
-                StopColor = stopColor,
-                SpreadMethod = GradientVisualSpreadMethodType.Pad,
-                CornerRadius = new Vector4(12, 12, 12, 12),
-            };
-        }
-
-        private PropertyArray GetGradientStopColors(Palette palette)
-        {
-            PropertyArray propertyArray = new PropertyArray();
-            if (palette == null)
-            {
-                Tizen.Log.Error(Resources.LogTag, "Color palette from background is null");
-                return propertyArray;
-            }
-
-            Palette.Swatch lightMutedSwatch = palette.GetLightMutedSwatch();
-            Palette.Swatch darkMutedSwatch = palette.GetDarkMutedSwatch();
-            if (lightMutedSwatch != null && darkMutedSwatch != null)
-            {
-                propertyArray.PushBack(new PropertyValue(lightMutedSwatch.GetRgb()));
-                propertyArray.PushBack(new PropertyValue(darkMutedSwatch.GetRgb()));
-                return propertyArray;
-            }
-
-            Palette.Swatch lightVibrantSwatch = palette.GetLightVibrantSwatch();
-            Palette.Swatch darkVibrantSwatch = palette.GetDarkVibrantSwatch();
-            if (lightVibrantSwatch != null && darkVibrantSwatch != null)
-            {
-                propertyArray.PushBack(new PropertyValue(lightVibrantSwatch.GetRgb()));
-                propertyArray.PushBack(new PropertyValue(darkVibrantSwatch.GetRgb()));
-                return propertyArray;
-            }
-
-            Palette.Swatch mutedSwatch = palette.GetMutedSwatch();
-            Palette.Swatch vibrantSwatch = palette.GetVibrantSwatch();
-            if (mutedSwatch != null && vibrantSwatch != null)
-            {
-                propertyArray.PushBack(new PropertyValue(mutedSwatch.GetRgb()));
-                propertyArray.PushBack(new PropertyValue(vibrantSwatch.GetRgb()));
-                return propertyArray;
-            }
-
-            IReadOnlyCollection<Palette.Swatch> swatches = palette.GetSwatches();
-            foreach (Palette.Swatch swatch in swatches)
-            {
-                if (propertyArray.Count() >= 2)
-                {
-                    return propertyArray;
-                }
-                if (swatch != null)
-                {
-                    propertyArray.PushBack(new PropertyValue(swatch.GetRgb()));
-                }
-            }
-            return propertyArray;
-        }
-
-        public void SetExtractedBackground(string path)
+        public void SetBackgroundColor(string path)
         {
             Tizen.Log.Debug(Resources.LogTag, "Path for the color image thumbnail" + path);
             PixelBuffer pixelBuffer = ImageLoader.LoadImageFromFile(path);
@@ -156,30 +89,15 @@ namespace Apps.Models
             {
                 Tizen.Log.Error(Resources.LogTag, "ArgumentNullException: " + e.Message);
             }
-            PropertyArray stopColor = GetGradientStopColors(palette);
-            if (stopColor.Count() < 2)
+            if (palette == null || palette.GetDominantSwatch() == null)
             {
-                Tizen.Log.Info(Resources.LogTag, "Palette or palatte values not valid, adding default gradient");
-                SetDefaultImageVisual();
-                IconBackground = defaultVisual.OutputVisualMap;
+                IconBackgroundColor = Color.Transparent;
             }
             else
             {
-                Tizen.Log.Info(Resources.LogTag, "setting palette color");
-                SetGradientVisual(stopColor);
-                IconBackground = gradientVisual.OutputVisualMap;
+                IconBackgroundColor = palette.GetDominantSwatch().GetRgb();
             }
-        }
-
-        ~AppInfoModel()
-        {
-            Tizen.Log.Info(Resources.LogTag, "Clearing NUI PropertyMap resources");
-            defaultVisual?.Dispose();
-            defaultVisual = null;
-            gradientVisual?.Dispose();
-            gradientVisual = null;
-            IconBackground?.Dispose();
-            IconBackground = null;
+            pixelBuffer.Dispose();
         }
     }
 }
index 0f60d8b15926ca41fda85484ac87a066cc4a4393..404072bf555973182548d40bf11ade181e02df4a 100755 (executable)
@@ -20,6 +20,7 @@ using System.Threading.Tasks;
 using System.Collections.Generic;
 using System.IO;
 using Tizen.NUI;
+using Tizen.NUI.Binding;
 using Tizen.NUI.Xaml;
 using Tizen.NUI.Components;
 using Tizen.Applications;
@@ -31,19 +32,25 @@ namespace Apps
 {
     class ViewManager
     {
+        public event EventHandler<List<string>> AppsSelected;
+
         private IEnumerable<ApplicationInfo> appList;
         private AppViewModel appViewModel;
         private AppView appView;
+        private SelectAppsView selectAppsView;
 
-        public ViewManager(Window window)
+        public ViewManager()
         {
             Task<IEnumerable<ApplicationInfo>> appListTask = CreateAppList();
 
             UpdateTheme(ThemeManager.PlatformThemeId);
 
             appViewModel = new AppViewModel();
-            appView = new AppView(appViewModel);
-            window.Add(appView);
+            appView = new AppView();
+            appView.BindingContext = appViewModel;
+            appView.SetBinding(AppView.AppRemoveCommandProperty, "AppRemoveCommand");
+            appView.SetBinding(RecyclerView.ItemsSourceProperty, "AppListSource");
+            Window.Instance.Add(appView);
             UpdateViewModel(appListTask);
 
             PackageManager.InstallProgressChanged += OnInstallProgressChanged;
@@ -54,7 +61,14 @@ namespace Apps
 
         public void UpdateAppView()
         {
-            appView.Size2D = new Size2D(Window.Instance.Size.Width, Window.Instance.Size.Height);
+            if (appView != null)
+            {
+                appView.Size2D = new Size2D(Window.Instance.Size.Width, Window.Instance.Size.Height);
+            }
+            if(selectAppsView != null)
+            {
+                selectAppsView.Size2D = new Size2D(Window.Instance.Size.Width, Window.Instance.Size.Height);
+            }
         }
         public void CleanUp()
         {
@@ -62,6 +76,31 @@ namespace Apps
             PackageManager.UninstallProgressChanged -= OnUninstallProgressChanged;
             ThemeManager.ThemeChanged -= OnThemeChanged;
             appView?.Dispose();
+            selectAppsView?.Dispose();
+        }
+
+        public void LaunchSelectMode(List<string> invalidApps)
+        {
+            Window.Instance.Remove(appView);
+            appView?.Dispose();
+            if (invalidApps != null)
+            {
+                Task<IEnumerable<ApplicationInfo>> appListTask = CreateAppList();
+                UpdateViewModel(appListTask, invalidApps);
+            }
+            if (selectAppsView == null)
+            {
+                selectAppsView = new SelectAppsView();
+            }
+            appViewModel.CreateSelectModeFields();
+            selectAppsView.BindingContext = appViewModel;
+            selectAppsView.SetBinding(RecyclerView.ItemsSourceProperty, "AppListSource");
+            selectAppsView.SetBinding(CollectionView.SelectionChangedCommandProperty, "SelectionChangedCommand");
+            appViewModel.AppsSelected += (object sender, List<string> e) =>
+            {
+                AppsSelected.Invoke(this, e);
+            };
+            Window.Instance.Add(selectAppsView);
         }
 
         private void OnThemeChanged(object sender, ThemeChangedEventArgs e)
@@ -88,6 +127,18 @@ namespace Apps
             appViewModel.CreateData(appList);
         }
 
+        private void UpdateViewModel(Task<IEnumerable<ApplicationInfo>> appListTask, List<string> invalidApps)
+        {
+            appListTask.Wait();
+            appList = appListTask.Result;
+            appList = appList.OrderBy(c => c.Label);
+            foreach (string appId in invalidApps)
+            {
+                appList = appList.Where(c => c.ApplicationId != appId);
+            }
+            appViewModel.CreateData(appList);
+        }
+
         private void OnInstallProgressChanged(object sender, PackageManagerEventArgs e)
         {
             if (e.State == PackageEventState.Completed)
index c643b2e13be15e30800f623d0f9644d38853e39e..167773b7c434c51763ecd314c7ef6b4d9b6342ce 100755 (executable)
  *  See the License for the specific language governing permissions and
  *  limitations under the License
  */
+using System;
 using System.Collections;
 using System.Collections.Generic;
 using System.Windows.Input;
 using Tizen.Applications;
 using Tizen.NUI.Binding;
 using Apps.Common;
+using Apps.Models;
 
 namespace Apps.ViewModels
 {
     class AppViewModel : PropertyNotifier
     {
+        public event EventHandler<List<string>> AppsSelected;
+        private List<object> selectedApps;
         public AppViewModel()
         {
             AppListSource = new AppInfoViewModel();
@@ -46,6 +50,22 @@ namespace Apps.ViewModels
             set => SetProperty(ref appRemoveCommand, value);
         }
 
+        private ICommand selectionChangedCommand;
+
+        public ICommand SelectionChangedCommand
+        {
+            get => selectionChangedCommand;
+            set => SetProperty(ref selectionChangedCommand, value);
+        }
+
+        private ICommand appsSelectedCommand;
+
+        public ICommand AppsSelectedCommand
+        {
+            get => appsSelectedCommand;
+            set => SetProperty(ref appsSelectedCommand, value);
+        }
+
         public void CreateData(IEnumerable<ApplicationInfo> list)
         {
             ((AppInfoViewModel)AppListSource).CreateData(list);
@@ -53,8 +73,52 @@ namespace Apps.ViewModels
 
         private void OnAppRemove(object selectedItem)
         {
-            Models.AppInfoModel appInfo = (Models.AppInfoModel)selectedItem;
+            AppInfoModel appInfo = (AppInfoModel)selectedItem;
             Core.AppLauncher.UninstallApplication(appInfo.ApplicationId);
         }
+
+        public void CreateSelectModeFields()
+        {
+            selectedApps = new List<object>();
+            SelectionChangedCommand = new Command(OnSelectionChanged);
+            AppsSelectedCommand = new Command(OnAppsSelected);
+        }
+
+        private void OnAppsSelected(object parameter)
+        {
+            if (selectedApps?.Count > 0)
+            {
+                List<string> apps = new List<string>();
+                foreach (object item in selectedApps)
+                {
+                    if (item is AppInfoModel appInfoModel)
+                    {
+                        apps.Add(appInfoModel.ApplicationId);
+                    }
+                }
+                AppsSelected?.Invoke(this, apps);
+            }
+        }
+
+        private void OnSelectionChanged(object changedItem)
+        {
+            if (changedItem == null)
+            {
+                return;
+            }
+            Tizen.Log.Info(Resources.LogTag, ((AppInfoModel)changedItem).ApplicationId);
+            if (selectedApps.Contains(changedItem) == false)
+            {
+                Tizen.Log.Info(Resources.LogTag, "Add App");
+                selectedApps.Add(changedItem);
+                ((AppInfoModel)changedItem).IsSelected = true;
+            }
+            else
+            {
+                Tizen.Log.Info(Resources.LogTag, "Remove App");
+                selectedApps.Remove(changedItem);
+                ((AppInfoModel)changedItem).IsSelected = false;
+            }
+        }
     }
 }
index 06946e9c655b0b83cace5692116aabd55c23f5d1..976dc86e99e6a19f180751bfe2e7692a8743438f 100644 (file)
@@ -92,7 +92,7 @@ namespace Apps.Views
 
             appIcon = new ImageView()
             {
-                MaximumSize = new Size2D(96, 96).SpToPx(),
+                Size2D = new Size2D(102, 102).SpToPx(),
             };
             iconBackgroundView.Add(appIcon);
 
@@ -242,6 +242,7 @@ namespace Apps.Views
             if (type == DisposeTypes.Explicit)
             {
                 DisposeTimer();
+                ThemeManager.ThemeChanged -= OnThemeUpdated;
 
                 baseView.Remove(appLabel);
                 appLabel?.Dispose();
index 8b482ade8b64d0f5d7594d2872e4dc38182023f3..e433d8d54d6eb0d3aa29df150445cef4097d2b64 100755 (executable)
@@ -42,7 +42,7 @@ namespace Apps.Views
         },
         defaultValueCreator: (bindable) => ((AppView)bindable).appRemoveCommand);
 
-        public AppView(object viewModel) : base()
+        public AppView() : base()
         {
             Name = "AppView";
             StyleName = "TrayBackGround";
@@ -52,12 +52,9 @@ namespace Apps.Views
             ItemsLayouter = new GridLayouter();
             ScrollingDirection = Direction.Vertical;
             SelectionMode = ItemSelectionMode.Single;
-            BindingContext = viewModel;
             removeMode = false;
             UpdateItemTemplate(removeMode);
             Header = GetHeader();
-            this.SetBinding(AppRemoveCommandProperty, "AppRemoveCommand");
-            this.SetBinding(ItemsSourceProperty, "AppListSource");
             Tizen.Log.Info(Resources.LogTag, "AppView");
         }
 
@@ -74,7 +71,7 @@ namespace Apps.Views
                 AppItemLayout item = new AppItemLayout(removeMode);
                 item.Label.SetBinding(TextLabel.TextProperty, "Name");
                 item.Icon.SetBinding(ImageView.ResourceUrlProperty, "IconUrl");
-                item.IconBackground.SetBinding(BackgroundProperty, "IconBackground");
+                item.IconBackground.SetBinding(BackgroundColorProperty, "IconBackgroundColor");
                 item.SetBinding(AppItemLayout.AppSelectCommandProperty, "AppSelectCommand");
                 item.LongPressed += OnLongPressed;
                 if (removeMode && item.CrossButton != null)
diff --git a/Apps/Views/SelectAppItemLayout.cs b/Apps/Views/SelectAppItemLayout.cs
new file mode 100644 (file)
index 0000000..d7c8086
--- /dev/null
@@ -0,0 +1,149 @@
+using Tizen.NUI;
+using Tizen.NUI.Components;
+using Tizen.NUI.BaseComponents;
+using Apps.Common;
+
+namespace Apps.Views
+{
+    class SelectAppItemLayout : RecyclerViewItem
+    {
+        private View baseView;
+
+        public SelectAppItemLayout() : base()
+        {
+            BackgroundColor = Color.Transparent;
+            WidthSpecification = 154.SpToPx();
+            HeightSpecification = 162.SpToPx();
+            Layout = new LinearLayout()
+            {
+                Padding = new Extents(8, 8, 12, 12).SpToPx(),
+                VerticalAlignment = VerticalAlignment.Center,
+                HorizontalAlignment = HorizontalAlignment.Center,
+            };
+
+            baseView = new View()
+            {
+                ThemeChangeSensitive = true,
+                StyleName = "TrayBackGround",
+                WidthSpecification = 138.SpToPx(),
+                HeightSpecification = 138.SpToPx(),
+                CornerRadius = new Vector4(12, 12, 12, 12),
+                BoxShadow = new Shadow(4.0f, new Color(0, 0, 0, 0.10f), new Vector2(2, 2)),
+                Layout = new RelativeLayout()
+                {
+                    Padding = new Extents(0, 0, 8, 0).SpToPx(),
+                }
+            };
+            Add(baseView);
+
+            IconBackground = new View()
+            {
+                CornerRadius = new Vector4(12, 12, 12, 12),
+                WidthSpecification = 122.SpToPx(),
+                HeightSpecification = 102.SpToPx(),
+                Layout = new LinearLayout()
+                {
+                    VerticalAlignment = VerticalAlignment.Center,
+                    HorizontalAlignment = HorizontalAlignment.Center,
+                },
+            };
+            baseView.Add(IconBackground);
+            RelativeLayout.SetHorizontalAlignment(IconBackground, RelativeLayout.Alignment.Center);
+            RelativeLayout.SetVerticalAlignment(IconBackground, RelativeLayout.Alignment.Start);
+
+            Icon = new ImageView()
+            {
+                Size2D = new Size2D(102, 102).SpToPx(),
+            };
+            IconBackground.Add(Icon);
+
+            Label = new TextLabel()
+            {
+                StyleName = "ItemTitle",
+                FontFamily = "BreezeSans",
+                ThemeChangeSensitive = true,
+                HeightSpecification = 24.SpToPx(),
+                WidthSpecification = LayoutParamPolicies.MatchParent,
+                HorizontalAlignment = HorizontalAlignment.Center,
+                VerticalAlignment = VerticalAlignment.Center,
+            };
+            baseView.Add(Label);
+            RelativeLayout.SetHorizontalAlignment(Label, RelativeLayout.Alignment.Center);
+            RelativeLayout.SetVerticalAlignment(Label, RelativeLayout.Alignment.End);
+
+
+            SelectButton = new CheckBox("CheckBox");
+            baseView.Add(SelectButton);
+            RelativeLayout.SetRightTarget(SelectButton, IconBackground);
+            RelativeLayout.SetRightRelativeOffset(SelectButton, 1.0f);
+            RelativeLayout.SetHorizontalAlignment(SelectButton, RelativeLayout.Alignment.End);
+
+            UpdateTheme(ThemeManager.PlatformThemeId);
+            ThemeManager.ThemeChanged += OnThemeUpdated;
+            AllowOnlyOwnTouch = true;
+        }
+
+        public TextLabel Label { get; private set; }
+
+        public ImageView Icon { get; private set; }
+
+        public View IconBackground { get; private set; }
+
+        public CheckBox SelectButton { get; private set; }
+
+        private void OnThemeUpdated(object sender, ThemeChangedEventArgs e)
+        {
+            if (e.IsPlatformThemeChanged)
+            {
+                UpdateTheme(e.PlatformThemeId);
+            }
+        }
+
+        private void UpdateTheme(string currentPlatformThemeId)
+        {
+            if (currentPlatformThemeId.Equals(Resources.LightPlatformThemeId))
+            {
+                baseView.BoxShadow = new Shadow(4.0f, new Color(0, 0, 0, 0.20f), new Vector2(2, 2));
+            }
+            else if (currentPlatformThemeId.Equals(Resources.DarkPlatformThemeId))
+            {
+                baseView.BoxShadow = new Shadow(4.0f, new Color(1.0f, 1.0f, 1.0f, 0.20f), new Vector2(2, 2));
+            }
+        }
+
+        protected override void Dispose(DisposeTypes type)
+        {
+            if (Disposed)
+            {
+                return;
+            }
+            if (type == DisposeTypes.Explicit)
+            {
+                ThemeManager.ThemeChanged -= OnThemeUpdated;
+
+                baseView.Remove(Label);
+                Label?.Dispose();
+                Label = null;
+
+                baseView.Remove(SelectButton);
+                SelectButton.Dispose();
+                SelectButton = null;
+
+                IconBackground.Remove(Icon);
+                Icon?.Dispose();
+                Icon = null;
+
+                baseView.Remove(IconBackground);
+                IconBackground?.Dispose();
+                IconBackground = null;
+
+                Remove(baseView);
+                baseView?.Dispose();
+                baseView = null;
+
+            }
+            Tizen.Log.Info(Resources.LogTag, "Dispose SelectAppItemLayout");
+            base.Dispose(type);
+        }
+    }
+}
diff --git a/Apps/Views/SelectAppsView.cs b/Apps/Views/SelectAppsView.cs
new file mode 100644 (file)
index 0000000..6be4cdf
--- /dev/null
@@ -0,0 +1,99 @@
+using System.Collections.Generic;
+using System.Windows.Input;
+using Tizen.NUI;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Binding;
+using Tizen.NUI.Components;
+using Apps.Common;
+
+namespace Apps.Views
+{
+    class SelectAppsView : CollectionView
+    {
+        public static readonly BindableProperty AddSelectedAppsCommandProperty = BindableProperty.Create(nameof(AddSelectedAppsCommand), typeof(ICommand), typeof(SelectAppsView), null, propertyChanged: (bindable, oldValue, newValue) =>
+        {
+            var instance = (SelectAppsView)bindable;
+            if (oldValue != newValue)
+            {
+                instance.addSelectedAppsCommand = (ICommand)newValue;
+            }
+        },
+        defaultValueCreator: (bindable) => ((SelectAppsView)bindable).addSelectedAppsCommand);
+
+        public SelectAppsView() : base()
+        {
+            Name = "SelectAppsView";
+            StyleName = "TrayBackGround";
+            ThemeChangeSensitive = true;
+            CornerRadius = new Vector4(24, 24, 24, 24);
+            Size2D = new Size2D(Window.Instance.Size.Width, Window.Instance.Size.Height);
+            ItemsLayouter = new GridLayouter();
+            ScrollingDirection = Direction.Vertical;
+            SelectionMode = ItemSelectionMode.Multiple;
+            Header = new SelectAppsViewHeader();
+            ItemTemplate = new DataTemplate(() =>
+            {
+                SelectAppItemLayout item = new SelectAppItemLayout();
+                item.Label.SetBinding(TextLabel.TextProperty, "Name");
+                item.Icon.SetBinding(ImageView.ResourceUrlProperty, "IconUrl");
+                item.IconBackground.SetBinding(BackgroundColorProperty, "IconBackgroundColor");
+                item.SelectButton.SetBinding(Button.IsSelectedProperty, "IsSelected");
+                return item;
+            });
+            SelectionChanged += OnSelectionChanged;
+            ((SelectAppsViewHeader)Header).AddButton.SetBinding(CommandProperty, "AppsSelectedCommand");
+            Tizen.Log.Info(Resources.LogTag, "SelectAppsView");
+        }
+
+        private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
+        {
+            List<object> oldSel = (List<object>)e.PreviousSelection;
+            List<object> newSel = (List<object>)e.CurrentSelection;
+            object changedObject = null;
+            if (oldSel != null)
+            {
+                foreach (object item in oldSel)
+                {
+                    if (item != null && newSel.Contains(item) == false)
+                    {
+                        changedObject = item;
+                    }
+                }
+            }
+            if (newSel != null)
+            {
+                foreach (object item in newSel)
+                {
+                    if (item != null && oldSel.Contains(item) == false)
+                    {
+                        changedObject = item;
+                    }
+                }
+            }
+            SelectionChangedCommand.Execute(changedObject);
+            ((SelectAppsViewHeader)Header).AddButton.IsEnabled = newSel.Count > 0;
+        }
+
+        protected override void Dispose(DisposeTypes type)
+        {
+            if (Disposed)
+            {
+                return;
+            }
+            if (type == DisposeTypes.Explicit)
+            {
+                SelectionChanged -= OnSelectionChanged;
+                Header.Dispose();
+            }
+            Tizen.Log.Info(Resources.LogTag, "Dispose SelectAppsView");
+            base.Dispose(type);
+        }
+
+        private ICommand addSelectedAppsCommand;
+        public ICommand AddSelectedAppsCommand
+        {
+            get => (ICommand)GetValue(AddSelectedAppsCommandProperty);
+            set => SetValue(AddSelectedAppsCommandProperty, value);
+        }
+    }
+}
diff --git a/Apps/Views/SelectAppsViewHeader.cs b/Apps/Views/SelectAppsViewHeader.cs
new file mode 100644 (file)
index 0000000..674ed67
--- /dev/null
@@ -0,0 +1,69 @@
+using Tizen.NUI;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Components;
+using Apps.Common;
+
+namespace Apps.Views
+{
+    class SelectAppsViewHeader : RecyclerViewItem
+    {
+        private TextLabel label;
+
+        public SelectAppsViewHeader() : base()
+        {
+            ThemeChangeSensitive = true;
+            WidthSpecification = LayoutParamPolicies.MatchParent;
+            HeightSpecification = 64.SpToPx();
+            Padding = new Extents(40, 40, 0, 0).SpToPx();
+            BackgroundColor = Color.Transparent;
+            CornerRadius = new Vector4(24, 24, 0, 0);
+            Layout = new RelativeLayout();
+
+            label = new TextLabel()
+            {
+                StyleName = "HeaderTitle",
+                Text = "All Apps",
+                FontStyle = new PropertyMap().Add("width", new PropertyValue("normal")).
+                                                Add("weight", new PropertyValue("normal")).
+                                                Add("slant", new PropertyValue("normal")),
+            };
+            Add(label);
+            RelativeLayout.SetVerticalAlignment(label, RelativeLayout.Alignment.Center);
+            RelativeLayout.SetHorizontalAlignment(label, RelativeLayout.Alignment.Start);
+
+            AddButton = new Button("TextButton")
+            {
+                Text = "Add",
+                IsEnabled = false,
+            };
+            Add(AddButton);
+            RelativeLayout.SetVerticalAlignment(AddButton, RelativeLayout.Alignment.Center);
+            RelativeLayout.SetHorizontalAlignment(AddButton, RelativeLayout.Alignment.End);
+            Tizen.Log.Info(Resources.LogTag, "SelectAppsViewHeader");
+            IsEnabled = false;
+        }
+
+        public Button AddButton { get; private set; }
+
+        protected override void Dispose(DisposeTypes type)
+        {
+            if (Disposed)
+            {
+                return;
+            }
+            if (type == DisposeTypes.Explicit)
+            {
+
+                Remove(label);
+                label?.Dispose();
+                label = null;
+
+                Remove(AddButton);
+                AddButton.Dispose();
+                AddButton = null;
+            }
+            Tizen.Log.Info(Resources.LogTag, "Dispose SelectAppsViewHeader");
+            base.Dispose(type);
+        }
+    }
+}
diff --git a/Apps/res/images/dark/circle.png b/Apps/res/images/dark/circle.png
new file mode 100644 (file)
index 0000000..01e7703
Binary files /dev/null and b/Apps/res/images/dark/circle.png differ
diff --git a/Apps/res/images/dark/circle_selected.png b/Apps/res/images/dark/circle_selected.png
new file mode 100644 (file)
index 0000000..b64302c
Binary files /dev/null and b/Apps/res/images/dark/circle_selected.png differ
diff --git a/Apps/res/images/light/circle.png b/Apps/res/images/light/circle.png
new file mode 100644 (file)
index 0000000..14020e8
Binary files /dev/null and b/Apps/res/images/light/circle.png differ
diff --git a/Apps/res/images/light/circle_selected.png b/Apps/res/images/light/circle_selected.png
new file mode 100644 (file)
index 0000000..a277c64
Binary files /dev/null and b/Apps/res/images/light/circle_selected.png differ
index 8ffff0b2d2d9cdc4c9be70888fceb4cfb53754ca..be9f6e046a109062dd2cbd6cb575329c882b15c2 100644 (file)
@@ -6,11 +6,13 @@ xmlns:c="clr-namespace:Tizen.NUI.Components;assembly=Tizen.NUI.Components"
 Id="DarkTheme">
 
     <ViewStyle x:Key="TrayBackGround" BackgroundColor="#16131A" />
+
     <c:DefaultTitleItemStyle x:Key="Header" ThemeChangeSensitive="True" >
         <c:DefaultTitleItemStyle.Label>
-            <TextLabelStyle PixelSize ="24sp" TextColor ="#FDFDFD" />
+            <TextLabelStyle PixelSize ="24sp" TextColor ="#FDFDFD" FontFamily="BreezeSans" />
         </c:DefaultTitleItemStyle.Label>
     </c:DefaultTitleItemStyle>
+
     <c:ButtonStyle x:Key="CrossButton" ThemeChangeSensitive="true" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
         <c:ButtonStyle.Icon>
             <ImageViewStyle Size="48sp, 48sp">
@@ -20,6 +22,7 @@ Id="DarkTheme">
             </ImageViewStyle>
         </c:ButtonStyle.Icon>
     </c:ButtonStyle>
+
     <c:AlertDialogStyle x:Key="AlertDialogBackground" ThemeChangeSensitive="true" BackgroundColor="#16131A">
         <c:AlertDialogStyle.TitleTextLabel>
             <TextLabelStyle TextColor="#FDFDFD" FontFamily="BreezeSans" PixelSize="24sp" />
@@ -28,6 +31,7 @@ Id="DarkTheme">
             <TextLabelStyle TextColor="#FDFDFD" FontFamily="BreezeSans" PixelSize="24sp" />
         </c:AlertDialogStyle.MessageTextLabel>
     </c:AlertDialogStyle>
+
     <c:ButtonStyle x:Key="CancelButton" ThemeChangeSensitive="true" Size="252sp, 48sp" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent" >
         <c:ButtonStyle.Icon>
             <ImageViewStyle Size="252sp, 48sp">
@@ -37,5 +41,28 @@ Id="DarkTheme">
             </ImageViewStyle>
         </c:ButtonStyle.Icon>
     </c:ButtonStyle>
-    <TextLabelStyle x:Key="ItemTitle" TextColor="#FDFDFD" FontFamily="BreezeSans" PixelSize="16sp"/>
+
+    <TextLabelStyle x:Key="ItemTitle" ThemeChangeSensitive="true" TextColor="#FDFDFD" FontFamily="BreezeSans" PixelSize="16sp"/>
+
+    <TextLabelStyle x:Key="HeaderTitle" ThemeChangeSensitive="true" TextColor="#FDFDFD" FontFamily="BreezeSans" PixelSize="24sp"/>
+
+    <c:ButtonStyle x:Key="TextButton" ThemeChangeSensitive="true" Size="110sp, 48sp" BackgroundColor="Transparent" >
+        <c:ButtonStyle.Text>
+            <TextLabelStyle FontFamily="BreezeSans" PixelSize="24sp" VerticalAlignment ="Center" HorizontalAlignment ="Center">
+                <TextLabelStyle.TextColor>
+                    <Selector x:TypeArguments="Color" Normal="#FF8A00" Pressed="#CC6E00" Disabled="#666666" />
+                </TextLabelStyle.TextColor>
+            </TextLabelStyle>
+        </c:ButtonStyle.Text>
+    </c:ButtonStyle>
+
+    <c:ButtonStyle x:Key="CheckBox" ThemeChangeSensitive="true" Size="32sp, 32sp" IsSelected="false" IsEnabled="false" BackgroundColor="Transparent">
+        <c:ButtonStyle.Icon>
+            <ImageViewStyle Size="32sp, 32sp">
+                <ImageViewStyle.ResourceUrl>
+                    <Selector x:TypeArguments="x:String" Disabled="*Resource*/images/dark/circle.png" DisabledSelected="*Resource*/images/dark/circle_selected.png" />
+                </ImageViewStyle.ResourceUrl>
+            </ImageViewStyle>
+        </c:ButtonStyle.Icon>
+    </c:ButtonStyle>
 </Theme>
\ No newline at end of file
index cbd7a3906589c2760da864baf16d229cdb6e265c..34aee607323e43d3a3e8757275833e46dd9f7147 100644 (file)
@@ -6,11 +6,13 @@ xmlns:c="clr-namespace:Tizen.NUI.Components;assembly=Tizen.NUI.Components"
 Id="LightTheme">
 
     <ViewStyle x:Key="TrayBackGround" BackgroundColor="#FAFAFA" />
+
     <c:DefaultTitleItemStyle x:Key="Header" ThemeChangeSensitive="True">
         <c:DefaultTitleItemStyle.Label>
-            <TextLabelStyle PixelSize ="24sp" TextColor ="#090E21" />
+            <TextLabelStyle PixelSize ="24sp" TextColor ="#090E21" FontFamily="BreezeSans" />
         </c:DefaultTitleItemStyle.Label>
     </c:DefaultTitleItemStyle>
+
     <c:ButtonStyle x:Key="CrossButton" ThemeChangeSensitive="true" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
         <c:ButtonStyle.Icon>
             <ImageViewStyle Size="48sp, 48sp">
@@ -20,6 +22,7 @@ Id="LightTheme">
             </ImageViewStyle>
         </c:ButtonStyle.Icon>
     </c:ButtonStyle>
+
     <c:AlertDialogStyle x:Key="AlertDialogBackground" ThemeChangeSensitive="true" BackgroundColor="#FAFAFA">
         <c:AlertDialogStyle.TitleTextLabel>
             <TextLabelStyle TextColor="#090E21" FontFamily="BreezeSans" PixelSize="24sp" />
@@ -28,6 +31,7 @@ Id="LightTheme">
             <TextLabelStyle TextColor="#090E21" FontFamily="BreezeSans" PixelSize="24sp" />
         </c:AlertDialogStyle.MessageTextLabel>
     </c:AlertDialogStyle>
+
     <c:ButtonStyle x:Key="CancelButton" ThemeChangeSensitive="true" Size="252sp, 48sp" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent" >
         <c:ButtonStyle.Icon>
             <ImageViewStyle Size="252sp, 48sp">
@@ -37,5 +41,28 @@ Id="LightTheme">
             </ImageViewStyle>
         </c:ButtonStyle.Icon>
     </c:ButtonStyle>
-    <TextLabelStyle x:Key="ItemTitle" TextColor="#090E21" FontFamily="BreezeSans" PixelSize="16sp"/>
+
+    <TextLabelStyle x:Key="ItemTitle" ThemeChangeSensitive="true" TextColor="#090E21" FontFamily="BreezeSans" PixelSize="16sp"/>
+
+    <TextLabelStyle x:Key="HeaderTitle" ThemeChangeSensitive="true" TextColor="#090E21" FontFamily="BreezeSans" PixelSize="24sp"/>
+
+    <c:ButtonStyle x:Key="TextButton" ThemeChangeSensitive="true" Size="110sp, 48sp" BackgroundColor="Transparent" >
+        <c:ButtonStyle.Text>
+            <TextLabelStyle FontFamily="BreezeSans" PixelSize="24sp" VerticalAlignment ="Center" HorizontalAlignment ="Center">
+                <TextLabelStyle.TextColor>
+                    <Selector x:TypeArguments="Color" Normal="#FF6200" Pressed="#FFA166" Disabled="#CACACA" />
+                </TextLabelStyle.TextColor>
+            </TextLabelStyle>
+        </c:ButtonStyle.Text>
+    </c:ButtonStyle>
+
+    <c:ButtonStyle x:Key="CheckBox" ThemeChangeSensitive="true" Size="32sp, 32sp" IsSelected="false" IsEnabled="false" BackgroundColor="Transparent">
+        <c:ButtonStyle.Icon>
+            <ImageViewStyle Size="32sp, 32sp">
+                <ImageViewStyle.ResourceUrl>
+                    <Selector x:TypeArguments="x:String" Disabled="*Resource*/images/light/circle.png" DisabledSelected="*Resource*/images/light/circle_selected.png" />
+                </ImageViewStyle.ResourceUrl>
+            </ImageViewStyle>
+        </c:ButtonStyle.Icon>
+    </c:ButtonStyle>
 </Theme>
\ No newline at end of file
index d3480a56321f7e488b7ff1cbf0a6a6c9a48f6c89..e270ec31b112ebdfdbc3a8e4aa88192783b87c12 100755 (executable)
Binary files a/packaging/org.tizen.Apps-1.0.0.tpk and b/packaging/org.tizen.Apps-1.0.0.tpk differ