diff --git a/IoT/UI/AppCommon/AppCommon.png b/IoT/UI/AppCommon/AppCommon.png
new file mode 100755
index 000000000..a38504b74
Binary files /dev/null and b/IoT/UI/AppCommon/AppCommon.png differ
diff --git a/IoT/UI/AppCommon/AppCommon.sln b/IoT/UI/AppCommon/AppCommon.sln
new file mode 100755
index 000000000..d8af4e2df
--- /dev/null
+++ b/IoT/UI/AppCommon/AppCommon.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.14.36414.22 d17.14
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AppCommon", "AppCommon\AppCommon.csproj", "{E4FE2ADD-EAF4-4152-BC2F-3DFF44C2443E}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {E4FE2ADD-EAF4-4152-BC2F-3DFF44C2443E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E4FE2ADD-EAF4-4152-BC2F-3DFF44C2443E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E4FE2ADD-EAF4-4152-BC2F-3DFF44C2443E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E4FE2ADD-EAF4-4152-BC2F-3DFF44C2443E}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {DC210600-66CB-4C43-94CE-4713D9FA403A}
+ EndGlobalSection
+EndGlobal
diff --git a/IoT/UI/AppCommon/AppCommon/AppCommon.cs b/IoT/UI/AppCommon/AppCommon/AppCommon.cs
new file mode 100755
index 000000000..30014e5d2
--- /dev/null
+++ b/IoT/UI/AppCommon/AppCommon/AppCommon.cs
@@ -0,0 +1,112 @@
+using AppCommon.Services;
+using System;
+using Tizen.Applications;
+using Tizen.NUI;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Components;
+using AppCommon.Models;
+using AppCommon.Pages;
+using AppCommon.Services;
+
+namespace AppCommon
+{
+ class Program : NUIApplication
+ {
+ private Window window;
+ private Navigator navigator;
+ private MainPage mainPage;
+
+ protected override void OnCreate()
+ {
+ base.OnCreate();
+ Initialize();
+ }
+
+ void Initialize()
+ {
+ // Set IsUsingXaml to false as per migration requirements
+ NUIApplication.IsUsingXaml = false;
+
+ // Initialize service locator
+ ServiceLocator.Initialize();
+
+ window = NUIApplication.GetDefaultWindow();
+ window.BackgroundColor = Color.White;
+
+ // Get window size
+ var windowSize = window.WindowSize;
+ int screenWidth = (int)windowSize.Width;
+ int screenHeight = (int)windowSize.Height;
+
+ // Get default navigator for page-based navigation
+ navigator = window.GetDefaultNavigator();
+
+ // Push main page with tabs
+ mainPage = new MainPage(screenWidth, screenHeight);
+ navigator.Push(mainPage);
+ }
+
+ ///
+ /// Handle LowMemory event
+ ///
+ /// Low memory event arguments
+ protected override void OnLowMemory(LowMemoryEventArgs e)
+ {
+ base.OnLowMemory(e);
+
+ // Convert Tizen.Applications.LowMemoryStatus to our LowMemoryStatus enum
+ var status = Models.LowMemoryStatus.None;
+ switch (e.LowMemoryStatus)
+ {
+ case Tizen.Applications.LowMemoryStatus.Normal:
+ status = Models.LowMemoryStatus.Normal;
+ break;
+ case Tizen.Applications.LowMemoryStatus.SoftWarning:
+ status = Models.LowMemoryStatus.SoftWarning;
+ break;
+ case Tizen.Applications.LowMemoryStatus.HardWarning:
+ status = Models.LowMemoryStatus.HardWarning;
+ break;
+ }
+
+ // Update ViewModel
+ mainPage?.AppInfoPage?.ViewModel?.UpdateLowMemoryLEDColor(status);
+ }
+
+ ///
+ /// Handle DeviceOrientation event
+ ///
+ /// Device orientation event arguments
+ protected override void OnDeviceOrientationChanged(DeviceOrientationEventArgs e)
+ {
+ base.OnDeviceOrientationChanged(e);
+
+ // Convert Tizen.Applications.DeviceOrientation to our DeviceOrientationStatus enum
+ var orientation = Models.DeviceOrientationStatus.Orientation_0;
+ switch (e.DeviceOrientation)
+ {
+ case Tizen.Applications.DeviceOrientation.Orientation_0:
+ orientation = Models.DeviceOrientationStatus.Orientation_0;
+ break;
+ case Tizen.Applications.DeviceOrientation.Orientation_90:
+ orientation = Models.DeviceOrientationStatus.Orientation_90;
+ break;
+ case Tizen.Applications.DeviceOrientation.Orientation_180:
+ orientation = Models.DeviceOrientationStatus.Orientation_180;
+ break;
+ case Tizen.Applications.DeviceOrientation.Orientation_270:
+ orientation = Models.DeviceOrientationStatus.Orientation_270;
+ break;
+ }
+
+ // Update ViewModel
+ mainPage?.AppInfoPage?.ViewModel?.UpdateDeviceOrientation(orientation);
+ }
+
+ static void Main(string[] args)
+ {
+ var app = new Program();
+ app.Run(args);
+ }
+ }
+}
diff --git a/IoT/UI/AppCommon/AppCommon/AppCommon.csproj b/IoT/UI/AppCommon/AppCommon/AppCommon.csproj
new file mode 100755
index 000000000..8ecc55db0
--- /dev/null
+++ b/IoT/UI/AppCommon/AppCommon/AppCommon.csproj
@@ -0,0 +1,23 @@
+
+
+
+ Exe
+ net6.0-tizen
+
+
+
+ portable
+
+
+ None
+
+
+
+
+
+
+
+
+
+
+
diff --git a/IoT/UI/AppCommon/AppCommon/Models/Enums.cs b/IoT/UI/AppCommon/AppCommon/Models/Enums.cs
new file mode 100755
index 000000000..eaf82ae38
--- /dev/null
+++ b/IoT/UI/AppCommon/AppCommon/Models/Enums.cs
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ */
+
+namespace AppCommon.Models
+{
+ ///
+ /// Low battery status enumeration
+ ///
+ public enum LowBatteryStatus
+ {
+ None,
+ PowerOff,
+ CriticalLow
+ }
+
+ ///
+ /// Low memory status enumeration
+ ///
+ public enum LowMemoryStatus
+ {
+ None,
+ Normal,
+ SoftWarning,
+ HardWarning
+ }
+
+ ///
+ /// Device orientation status enumeration
+ ///
+ public enum DeviceOrientationStatus
+ {
+ Orientation_0,
+ Orientation_90,
+ Orientation_180,
+ Orientation_270
+ }
+}
diff --git a/IoT/UI/AppCommon/AppCommon/Models/PathInformation.cs b/IoT/UI/AppCommon/AppCommon/Models/PathInformation.cs
new file mode 100755
index 000000000..da94f1c7e
--- /dev/null
+++ b/IoT/UI/AppCommon/AppCommon/Models/PathInformation.cs
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ */
+
+namespace AppCommon.Models
+{
+ ///
+ /// A class to define each path information
+ ///
+ public class PathInformation
+ {
+ public string Title { get; set; }
+ public string Path { get; set; }
+ }
+}
diff --git a/IoT/UI/AppCommon/AppCommon/Pages/ApplicationInformationPage.cs b/IoT/UI/AppCommon/AppCommon/Pages/ApplicationInformationPage.cs
new file mode 100755
index 000000000..e24c61171
--- /dev/null
+++ b/IoT/UI/AppCommon/AppCommon/Pages/ApplicationInformationPage.cs
@@ -0,0 +1,392 @@
+/*
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.NUI;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Components;
+using AppCommon.ViewModels;
+
+namespace AppCommon.Pages
+{
+ ///
+ /// Application information page
+ ///
+ public class ApplicationInformationPage : ContentPage
+ {
+ private ApplicationInformationViewModel _viewModel;
+
+ // UI Elements
+ private ImageView _icon;
+ private TextLabel _applicationName;
+ private TextLabel _applicationID;
+ private TextLabel _applicationVersion;
+ private ImageView _memoryLED;
+ private ImageView _batteryLED;
+ private TextLabel _language;
+ private TextLabel _regionFormat;
+ private TextLabel _deviceOrientation;
+ private TextLabel _rotationDegree;
+
+ private int _screenWidth;
+ private int _screenHeight;
+ private bool _isLandscape;
+
+ public ApplicationInformationViewModel ViewModel => _viewModel;
+
+ public ApplicationInformationPage(int screenWidth = 720, int screenHeight = 1280)
+ {
+ _screenWidth = screenWidth;
+ _screenHeight = screenHeight;
+ _isLandscape = screenWidth > screenHeight;
+
+ // Create ViewModel
+ _viewModel = new ApplicationInformationViewModel();
+
+ InitializeComponent();
+ SetupDataBinding();
+ }
+
+ private void InitializeComponent()
+ {
+ // Set page properties
+ AppBar = new AppBar
+ {
+ Title = "Application Information"
+ };
+
+ // Create main layout with simple background
+ var mainLayout = new View
+ {
+ Layout = new AbsoluteLayout(),
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.MatchParent,
+ BackgroundColor = new Color(0.95f, 0.95f, 0.95f, 1.0f) // Light gray background
+ };
+
+ // Adaptive layout calculations
+ float iconSize = _isLandscape ? 100f : 150f;
+ float margin = _isLandscape ? 20f : 30f;
+ float topOffset = _isLandscape ? 20f : 80f;
+ float ledSize = _isLandscape ? 15f : 20f;
+
+ // Application Icon
+ _icon = new ImageView
+ {
+ Size = new Size(iconSize, iconSize),
+ Position = new Position(margin, topOffset)
+ };
+ mainLayout.Add(_icon);
+
+ // Application Name Label
+ var nameLabel = new TextLabel
+ {
+ Text = "Name:",
+ PixelSize = Resources.SmallFontSize,
+ TextColor = Resources.Black,
+ HorizontalAlignment = HorizontalAlignment.Begin,
+ VerticalAlignment = VerticalAlignment.Top,
+ Position = new Position(margin, topOffset + iconSize + 15)
+ };
+ mainLayout.Add(nameLabel);
+
+ // Application Name
+ _applicationName = new TextLabel
+ {
+ PixelSize = Resources.NormalFontSize,
+ TextColor = Resources.DarkGray,
+ HorizontalAlignment = HorizontalAlignment.Begin,
+ VerticalAlignment = VerticalAlignment.Top,
+ MultiLine = true,
+ Size = new Size(_screenWidth - margin * 2, 40),
+ Position = new Position(margin, topOffset + iconSize + 35)
+ };
+ mainLayout.Add(_applicationName);
+
+ // Application ID Label
+ var idLabel = new TextLabel
+ {
+ Text = "ID:",
+ PixelSize = Resources.SmallFontSize,
+ TextColor = Resources.Black,
+ HorizontalAlignment = HorizontalAlignment.Begin,
+ VerticalAlignment = VerticalAlignment.Top,
+ Position = new Position(margin, topOffset + iconSize + 80)
+ };
+ mainLayout.Add(idLabel);
+
+ // Application ID
+ _applicationID = new TextLabel
+ {
+ PixelSize = Resources.NormalFontSize,
+ TextColor = Resources.DarkGray,
+ HorizontalAlignment = HorizontalAlignment.Begin,
+ VerticalAlignment = VerticalAlignment.Top,
+ MultiLine = true,
+ Size = new Size((_screenWidth - margin * 3) / 2, 50),
+ Position = new Position(margin, topOffset + iconSize + 100)
+ };
+ mainLayout.Add(_applicationID);
+
+ // Application Version Label
+ var versionLabel = new TextLabel
+ {
+ Text = "Version:",
+ PixelSize = Resources.SmallFontSize,
+ TextColor = Resources.Black,
+ HorizontalAlignment = HorizontalAlignment.Begin,
+ VerticalAlignment = VerticalAlignment.Top,
+ Position = new Position(_screenWidth / 2 + margin / 2, topOffset + iconSize + 80)
+ };
+ mainLayout.Add(versionLabel);
+
+ // Application Version
+ _applicationVersion = new TextLabel
+ {
+ PixelSize = Resources.NormalFontSize,
+ TextColor = Resources.DarkGray,
+ HorizontalAlignment = HorizontalAlignment.Begin,
+ VerticalAlignment = VerticalAlignment.Top,
+ MultiLine = true,
+ Size = new Size((_screenWidth - margin * 3) / 2, 40),
+ Position = new Position(_screenWidth / 2 + margin / 2, topOffset + iconSize + 100)
+ };
+ mainLayout.Add(_applicationVersion);
+
+ // Memory LED (simple colored circle)
+ float ledYPos = topOffset + iconSize + 170;
+ _memoryLED = new ImageView
+ {
+ Size = new Size(ledSize, ledSize),
+ Position = new Position(margin, ledYPos),
+ BackgroundColor = Resources.LightGray,
+ CornerRadius = ledSize / 2.0f
+ };
+ mainLayout.Add(_memoryLED);
+
+ // Memory LED Label
+ var memoryLabel = new TextLabel
+ {
+ Text = "Memory:",
+ PixelSize = Resources.SmallFontSize,
+ TextColor = Resources.DarkGray,
+ Position = new Position(margin + ledSize + 10, ledYPos - 5),
+ Size = new Size(150, 30)
+ };
+ mainLayout.Add(memoryLabel);
+
+ // Battery LED (simple colored circle)
+ _batteryLED = new ImageView
+ {
+ Size = new Size(ledSize, ledSize),
+ Position = new Position(_screenWidth / 2 + margin / 2, ledYPos),
+ BackgroundColor = Resources.LightGray,
+ CornerRadius = ledSize / 2.0f
+ };
+ mainLayout.Add(_batteryLED);
+
+ // Battery LED Label
+ var batteryLabel = new TextLabel
+ {
+ Text = "Battery:",
+ PixelSize = Resources.SmallFontSize,
+ TextColor = Resources.DarkGray,
+ Position = new Position(_screenWidth / 2 + margin / 2 + ledSize + 10, ledYPos - 5),
+ Size = new Size(150, 30)
+ };
+ mainLayout.Add(batteryLabel);
+
+ // Language Label
+ float langYPos = ledYPos + 60;
+ var languageLabel = new TextLabel
+ {
+ Text = "Language:",
+ PixelSize = Resources.SmallFontSize,
+ TextColor = Resources.Black,
+ HorizontalAlignment = HorizontalAlignment.Begin,
+ VerticalAlignment = VerticalAlignment.Top,
+ Position = new Position(margin, langYPos)
+ };
+ mainLayout.Add(languageLabel);
+
+ // Language
+ _language = new TextLabel
+ {
+ PixelSize = Resources.NormalFontSize,
+ TextColor = Resources.DarkGray,
+ HorizontalAlignment = HorizontalAlignment.Begin,
+ VerticalAlignment = VerticalAlignment.Top,
+ MultiLine = true,
+ Size = new Size((_screenWidth - margin * 3) / 2, 40),
+ Position = new Position(margin, langYPos + 20)
+ };
+ mainLayout.Add(_language);
+
+ // Region Format Label
+ var regionLabel = new TextLabel
+ {
+ Text = "Region:",
+ PixelSize = Resources.SmallFontSize,
+ TextColor = Resources.Black,
+ HorizontalAlignment = HorizontalAlignment.Begin,
+ VerticalAlignment = VerticalAlignment.Top,
+ Position = new Position(_screenWidth / 2 + margin / 2, langYPos)
+ };
+ mainLayout.Add(regionLabel);
+
+ // Region Format
+ _regionFormat = new TextLabel
+ {
+ PixelSize = Resources.NormalFontSize,
+ TextColor = Resources.DarkGray,
+ HorizontalAlignment = HorizontalAlignment.Begin,
+ VerticalAlignment = VerticalAlignment.Top,
+ MultiLine = true,
+ Size = new Size((_screenWidth - margin * 3) / 2, 40),
+ Position = new Position(_screenWidth / 2 + margin / 2, langYPos + 20)
+ };
+ mainLayout.Add(_regionFormat);
+
+ // Device Orientation Label
+ float orientYPos = _isLandscape ? langYPos + 80 : _screenHeight - 120;
+ var orientationLabel = new TextLabel
+ {
+ Text = "Orientation:",
+ PixelSize = Resources.SmallFontSize,
+ TextColor = Resources.Black,
+ HorizontalAlignment = HorizontalAlignment.Begin,
+ VerticalAlignment = VerticalAlignment.Top,
+ Position = new Position(margin, orientYPos)
+ };
+ mainLayout.Add(orientationLabel);
+
+ // Device Orientation
+ _deviceOrientation = new TextLabel
+ {
+ PixelSize = Resources.NormalFontSize,
+ TextColor = Resources.DarkGray,
+ HorizontalAlignment = HorizontalAlignment.Begin,
+ VerticalAlignment = VerticalAlignment.Top,
+ MultiLine = true,
+ Size = new Size((_screenWidth - margin * 3) / 2, 40),
+ Position = new Position(margin, orientYPos + 20)
+ };
+ mainLayout.Add(_deviceOrientation);
+
+ // Rotation Degree Label
+ var degreeLabel = new TextLabel
+ {
+ Text = "Rotation:",
+ PixelSize = Resources.SmallFontSize,
+ TextColor = Resources.Black,
+ HorizontalAlignment = HorizontalAlignment.Begin,
+ VerticalAlignment = VerticalAlignment.Top,
+ Position = new Position(_screenWidth / 2 + margin / 2, orientYPos)
+ };
+ mainLayout.Add(degreeLabel);
+
+ // Rotation Degree
+ _rotationDegree = new TextLabel
+ {
+ PixelSize = _isLandscape ? 80.0f : Resources.LargeFontSize,
+ TextColor = Resources.Black,
+ HorizontalAlignment = HorizontalAlignment.Begin,
+ VerticalAlignment = VerticalAlignment.Top,
+ Size = new Size((_screenWidth - margin * 3) / 2, _isLandscape ? 100 : 150),
+ Position = new Position(_screenWidth / 2 + margin / 2, _isLandscape ? orientYPos + 20 : orientYPos - 30)
+ };
+ mainLayout.Add(_rotationDegree);
+
+ // Set content
+ Content = mainLayout;
+ }
+
+ private void SetupDataBinding()
+ {
+ // Subscribe to PropertyChanged events for manual data binding
+ _viewModel.PropertyChanged += OnViewModelPropertyChanged;
+
+ // Initialize UI with current ViewModel values
+ UpdateUI();
+ }
+
+ private void OnViewModelPropertyChanged(object sender, PropertyChangedEventArgs e)
+ {
+ // Update UI directly (NUI is already on UI thread)
+ switch (e.PropertyName)
+ {
+ case nameof(_viewModel.IconPath):
+ _icon.ResourceUrl = _viewModel.IconPath;
+ break;
+ case nameof(_viewModel.Name):
+ _applicationName.Text = _viewModel.Name;
+ break;
+ case nameof(_viewModel.ID):
+ _applicationID.Text = _viewModel.ID;
+ break;
+ case nameof(_viewModel.Version):
+ _applicationVersion.Text = _viewModel.Version;
+ break;
+ case nameof(_viewModel.LowMemoryLEDColor):
+ _memoryLED.BackgroundColor = _viewModel.LowMemoryLEDColor;
+ break;
+ case nameof(_viewModel.LowBatteryLEDColor):
+ _batteryLED.BackgroundColor = _viewModel.LowBatteryLEDColor;
+ break;
+ case nameof(_viewModel.Language):
+ _language.Text = _viewModel.Language;
+ break;
+ case nameof(_viewModel.RegionFormat):
+ _regionFormat.Text = _viewModel.RegionFormat;
+ break;
+ case nameof(_viewModel.DeviceOrientation):
+ _deviceOrientation.Text = _viewModel.DeviceOrientation;
+ break;
+ case nameof(_viewModel.RotationDegree):
+ _rotationDegree.Text = _viewModel.RotationDegree;
+ break;
+ }
+ }
+
+ private void UpdateUI()
+ {
+ _icon.ResourceUrl = _viewModel.IconPath;
+ _applicationName.Text = _viewModel.Name;
+ _applicationID.Text = _viewModel.ID;
+ _applicationVersion.Text = _viewModel.Version;
+ _memoryLED.BackgroundColor = _viewModel.LowMemoryLEDColor;
+ _batteryLED.BackgroundColor = _viewModel.LowBatteryLEDColor;
+ _language.Text = _viewModel.Language;
+ _regionFormat.Text = _viewModel.RegionFormat;
+ _deviceOrientation.Text = _viewModel.DeviceOrientation;
+ _rotationDegree.Text = _viewModel.RotationDegree;
+ }
+
+ protected override void Dispose(DisposeTypes type)
+ {
+ if (type == DisposeTypes.Explicit)
+ {
+ // Unsubscribe from events
+ if (_viewModel != null)
+ {
+ _viewModel.PropertyChanged -= OnViewModelPropertyChanged;
+ }
+ }
+ base.Dispose(type);
+ }
+ }
+}
diff --git a/IoT/UI/AppCommon/AppCommon/Pages/MainPage.cs b/IoT/UI/AppCommon/AppCommon/Pages/MainPage.cs
new file mode 100755
index 000000000..af4a8c229
--- /dev/null
+++ b/IoT/UI/AppCommon/AppCommon/Pages/MainPage.cs
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 Tizen.NUI;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Components;
+
+namespace AppCommon.Pages
+{
+ ///
+ /// Main page with tab navigation (simulating ColoredTabbedPage)
+ ///
+ public class MainPage : ContentPage
+ {
+ private View _currentPageContent;
+ private ApplicationInformationPage _appInfoPage;
+ private PathsPage _pathsPage;
+ private Button _appInfoTab;
+ private Button _pathsTab;
+ private View _tabBar;
+
+ private int _screenWidth;
+ private int _screenHeight;
+ private bool _isLandscape;
+
+ public ApplicationInformationPage AppInfoPage => _appInfoPage;
+
+ public MainPage(int screenWidth = 720, int screenHeight = 1280)
+ {
+ _screenWidth = screenWidth;
+ _screenHeight = screenHeight;
+ _isLandscape = screenWidth > screenHeight;
+
+ InitializeComponent();
+ ShowPage(0); // Show first page by default
+ }
+
+ private void InitializeComponent()
+ {
+ // Create main layout
+ var mainLayout = new View
+ {
+ Layout = new LinearLayout
+ {
+ LinearOrientation = LinearLayout.Orientation.Vertical
+ },
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.MatchParent
+ };
+
+ // Create tab bar (adaptive height based on orientation)
+ int tabBarHeight = _isLandscape ? 60 : 80;
+ _tabBar = new View
+ {
+ Layout = new LinearLayout
+ {
+ LinearOrientation = LinearLayout.Orientation.Horizontal,
+ HorizontalAlignment = HorizontalAlignment.Center,
+ VerticalAlignment = VerticalAlignment.Center
+ },
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = tabBarHeight,
+ BackgroundColor = Resources.TabbedPageBarColor
+ };
+
+ // Create tab buttons
+ _appInfoTab = new Button
+ {
+ Text = "Application Information",
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.MatchParent,
+ Weight = 1.0f,
+ BackgroundColor = Resources.TabbedPageBarColor,
+ TextColor = Resources.White
+ };
+ _appInfoTab.Clicked += (s, e) => ShowPage(0);
+
+ _pathsTab = new Button
+ {
+ Text = "Paths",
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.MatchParent,
+ Weight = 1.0f,
+ BackgroundColor = Resources.TabbedPageBarColor,
+ TextColor = Resources.White
+ };
+ _pathsTab.Clicked += (s, e) => ShowPage(1);
+
+ _tabBar.Add(_appInfoTab);
+ _tabBar.Add(_pathsTab);
+
+ // Create content container
+ _currentPageContent = new View
+ {
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.MatchParent
+ };
+
+ // Add tab bar and content to main layout
+ mainLayout.Add(_tabBar);
+ mainLayout.Add(_currentPageContent);
+
+ // Set content
+ Content = mainLayout;
+
+ // Create pages
+ _appInfoPage = new ApplicationInformationPage(_screenWidth, _screenHeight);
+ _pathsPage = new PathsPage(_screenWidth, _screenHeight);
+ }
+
+ private void ShowPage(int index)
+ {
+ // Clear current content
+ if (_currentPageContent.ChildCount > 0)
+ {
+ _currentPageContent.Remove(_currentPageContent.GetChildAt(0));
+ }
+
+ // Update tab button states
+ _appInfoTab.BackgroundColor = (index == 0)
+ ? new Color(0.6f, 0.15f, 0.4f, 1.0f) // Darker shade for selected
+ : Resources.TabbedPageBarColor;
+
+ _pathsTab.BackgroundColor = (index == 1)
+ ? new Color(0.6f, 0.15f, 0.4f, 1.0f) // Darker shade for selected
+ : Resources.TabbedPageBarColor;
+
+ // Show selected page content
+ switch (index)
+ {
+ case 0:
+ if (_appInfoPage.Content != null)
+ {
+ _currentPageContent.Add(_appInfoPage.Content);
+ }
+ break;
+ case 1:
+ if (_pathsPage.Content != null)
+ {
+ _currentPageContent.Add(_pathsPage.Content);
+ }
+ break;
+ }
+ }
+
+ protected override void Dispose(DisposeTypes type)
+ {
+ if (type == DisposeTypes.Explicit)
+ {
+ _appInfoPage?.Dispose();
+ _pathsPage?.Dispose();
+ }
+ base.Dispose(type);
+ }
+ }
+}
diff --git a/IoT/UI/AppCommon/AppCommon/Pages/PathsPage.cs b/IoT/UI/AppCommon/AppCommon/Pages/PathsPage.cs
new file mode 100755
index 000000000..62ac409a9
--- /dev/null
+++ b/IoT/UI/AppCommon/AppCommon/Pages/PathsPage.cs
@@ -0,0 +1,283 @@
+/*
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.Collections.Generic;
+using Tizen.NUI;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Components;
+using AppCommon.Models;
+using AppCommon.ViewModels;
+
+namespace AppCommon.Pages
+{
+ ///
+ /// Paths information page
+ ///
+ public class PathsPage : ContentPage
+ {
+ private PathsPageViewModel _viewModel;
+ private ScrollableBase _scrollView;
+ private View _listContainer;
+ private Button _floatingButton;
+ private AlertDialog _popup;
+
+ private int _screenWidth;
+ private int _screenHeight;
+ private double _horizontalScale;
+ private bool _isLandscape;
+
+ public PathsPage(int screenWidth = 720, int screenHeight = 1280)
+ {
+ _screenWidth = screenWidth;
+ _screenHeight = screenHeight;
+ _isLandscape = screenWidth > screenHeight;
+ _horizontalScale = (double)screenWidth / 720.0;
+
+ // Create ViewModel
+ _viewModel = new PathsPageViewModel();
+
+ InitializeComponent();
+ }
+
+ private void InitializeComponent()
+ {
+ // Set page properties
+ AppBar = new AppBar
+ {
+ Title = "Paths"
+ };
+
+ // Create main layout with simple background
+ var mainLayout = new View
+ {
+ Layout = new AbsoluteLayout(),
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.MatchParent,
+ BackgroundColor = new Color(0.95f, 0.95f, 0.95f, 1.0f) // Light gray background
+ };
+
+ // Create scrollable list container
+ _scrollView = new ScrollableBase
+ {
+ ScrollingDirection = ScrollableBase.Direction.Vertical,
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.MatchParent,
+ HideScrollbar = false
+ };
+
+ _listContainer = new View
+ {
+ Layout = new LinearLayout
+ {
+ LinearOrientation = LinearLayout.Orientation.Vertical,
+ },
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.WrapContent,
+ };
+
+ // Add path items to list
+ foreach (var pathInfo in _viewModel.Paths)
+ {
+ var itemView = CreatePathItemView(pathInfo);
+ _listContainer.Add(itemView);
+ }
+
+ _scrollView.Add(_listContainer);
+ mainLayout.Add(_scrollView);
+
+ // Create floating button (simple text button)
+ _floatingButton = new Button
+ {
+ Text = "↑",
+ Size = new Size((float)(100 * _horizontalScale), (float)(100 * _horizontalScale)),
+ Position = new Position(_screenWidth * 0.8194f, _screenHeight * 0.8948f),
+ BackgroundColor = Resources.TabbedPageBarColor,
+ TextColor = Color.White,
+ CornerRadius = (float)(50 * _horizontalScale)
+ };
+ _floatingButton.Clicked += OnFloatingButtonClicked;
+ mainLayout.Add(_floatingButton);
+
+ // Set content
+ Content = mainLayout;
+ }
+
+ private View CreatePathItemView(PathInformation pathInfo)
+ {
+ int itemHeight = (int)(227.0 * _horizontalScale);
+
+ var itemView = new View
+ {
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = itemHeight,
+ BackgroundColor = Color.White,
+ Margin = new Extents(0, 0, 2, 2),
+ Focusable = true,
+ FocusableInTouch = true,
+ BoxShadow = new Shadow(5.0f, new Color(0, 0, 0, 0.2f), new Vector2(0, 2))
+ };
+
+ var itemLayout = new View
+ {
+ Layout = new LinearLayout
+ {
+ LinearOrientation = LinearLayout.Orientation.Vertical,
+ CellPadding = new Size2D(10, 10),
+ HorizontalAlignment = HorizontalAlignment.Begin,
+ VerticalAlignment = VerticalAlignment.Top
+ },
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.MatchParent,
+ Padding = new Extents(20, 20, 10, 10)
+ };
+
+ // Title
+ var titleLabel = new TextLabel
+ {
+ Text = pathInfo.Title,
+ PixelSize = 30.0f,
+ TextColor = Resources.Black,
+ FontStyle = new PropertyMap().Add("weight", new PropertyValue("bold")),
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.WrapContent
+ };
+ itemLayout.Add(titleLabel);
+
+ // Path
+ var pathLabel = new TextLabel
+ {
+ Text = pathInfo.Path,
+ PixelSize = Resources.NormalFontSize,
+ TextColor = Resources.DarkGray,
+ MultiLine = true,
+ Ellipsis = true,
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.WrapContent
+ };
+ itemLayout.Add(pathLabel);
+
+ itemView.Add(itemLayout);
+
+ // Add touch event
+ itemView.TouchEvent += (sender, e) =>
+ {
+ if (e.Touch.GetState(0) == PointStateType.Up)
+ {
+ OnListItemSelected(pathInfo);
+ return true;
+ }
+ return false;
+ };
+
+ return itemView;
+ }
+
+ private void OnListItemSelected(PathInformation selectedItem)
+ {
+ var title = selectedItem.Title;
+ var path = selectedItem.Path;
+ var count = 0;
+
+ try
+ {
+ count = _viewModel.GetFilesCount(path);
+ }
+ catch
+ {
+ count = 0;
+ }
+
+ // Create popup dialog
+ ShowPathDetailsDialog(title, path, count);
+ }
+
+ private void ShowPathDetailsDialog(string title, string path, int count)
+ {
+ _popup = new AlertDialog
+ {
+ Title = title,
+ };
+
+ var contentView = new View
+ {
+ Layout = new LinearLayout
+ {
+ LinearOrientation = LinearLayout.Orientation.Vertical,
+ CellPadding = new Size2D(10, 10)
+ },
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.WrapContent,
+ Padding = new Extents(20, 20, 20, 20)
+ };
+
+ var pathLabel = new TextLabel
+ {
+ Text = path,
+ PixelSize = Resources.NormalFontSize,
+ TextColor = Resources.Black,
+ HorizontalAlignment = HorizontalAlignment.Center,
+ MultiLine = true,
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.WrapContent
+ };
+ contentView.Add(pathLabel);
+
+ var countLabel = new TextLabel
+ {
+ Text = $"File count: {count}",
+ PixelSize = Resources.NormalFontSize,
+ TextColor = Resources.Black,
+ HorizontalAlignment = HorizontalAlignment.Center,
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.WrapContent
+ };
+ contentView.Add(countLabel);
+
+ _popup.Content = contentView;
+
+ var closeButton = new Button
+ {
+ Text = "CLOSE",
+ };
+ closeButton.Clicked += (sender, e) =>
+ {
+ _popup.Hide();
+ };
+
+ _popup.Actions = new View[] { closeButton };
+ _popup.Show();
+ }
+
+ private void OnFloatingButtonClicked(object sender, ClickedEventArgs e)
+ {
+ // Scroll to top
+ _scrollView.ScrollTo(0, true);
+ }
+
+ protected override void Dispose(DisposeTypes type)
+ {
+ if (type == DisposeTypes.Explicit)
+ {
+ if (_floatingButton != null)
+ {
+ _floatingButton.Clicked -= OnFloatingButtonClicked;
+ }
+ }
+ base.Dispose(type);
+ }
+ }
+}
diff --git a/IoT/UI/AppCommon/AppCommon/Resources.cs b/IoT/UI/AppCommon/AppCommon/Resources.cs
new file mode 100755
index 000000000..e4e1a483f
--- /dev/null
+++ b/IoT/UI/AppCommon/AppCommon/Resources.cs
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 Tizen.NUI;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Components;
+
+namespace AppCommon
+{
+ ///
+ /// Common resources for the application (colors, styles, etc.)
+ ///
+ internal static class Resources
+ {
+ // Colors
+ public static readonly Color White = new Color(1.0f, 1.0f, 1.0f, 1.0f);
+ public static readonly Color Black = new Color(0.0f, 0.0f, 0.0f, 1.0f);
+ public static readonly Color Gray = new Color(0.5f, 0.5f, 0.5f, 1.0f);
+ public static readonly Color LightGray = new Color(0.875f, 0.875f, 0.875f, 1.0f); // RGB(223, 223, 223)
+ public static readonly Color DarkGray = new Color(0.573f, 0.573f, 0.573f, 1.0f); // RGB(146, 146, 146)
+ public static readonly Color TabbedPageBarColor = new Color(0.706f, 0.204f, 0.498f, 1.0f); // RGB(180, 52, 127)
+ public static readonly Color Red = new Color(1.0f, 0.0f, 0.0f, 1.0f);
+ public static readonly Color Green = new Color(0.0f, 1.0f, 0.0f, 1.0f);
+ public static readonly Color Yellow = new Color(1.0f, 1.0f, 0.0f, 1.0f);
+
+ // Font sizes
+ public const float SmallFontSize = 20.0f;
+ public const float NormalFontSize = 25.0f;
+ public const float LargeFontSize = 130.0f;
+
+ // TextLabel Styles
+ public static readonly TextLabelStyle ContentTextStyle = new TextLabelStyle
+ {
+ PixelSize = NormalFontSize,
+ TextColor = DarkGray,
+ VerticalAlignment = VerticalAlignment.Top,
+ HorizontalAlignment = HorizontalAlignment.Begin,
+ MultiLine = true,
+ Ellipsis = false,
+ };
+
+ public static readonly TextLabelStyle LargeContentTextStyle = new TextLabelStyle
+ {
+ PixelSize = LargeFontSize,
+ TextColor = Black,
+ VerticalAlignment = VerticalAlignment.Top,
+ HorizontalAlignment = HorizontalAlignment.Begin,
+ };
+
+ // Button Styles
+ public static readonly ButtonStyle PrimaryButtonStyle = new ButtonStyle
+ {
+ BackgroundColor = new Selector
+ {
+ Normal = TabbedPageBarColor,
+ Pressed = new Color(0.6f, 0.15f, 0.4f, 1.0f),
+ },
+ Text = new TextLabelStyle
+ {
+ TextColor = White,
+ PixelSize = NormalFontSize,
+ }
+ };
+
+ // Helper method to create TextLabel with content style
+ public static TextLabel CreateContentLabel(string text)
+ {
+ return new TextLabel
+ {
+ Text = text,
+ PixelSize = NormalFontSize,
+ TextColor = DarkGray,
+ VerticalAlignment = VerticalAlignment.Top,
+ HorizontalAlignment = HorizontalAlignment.Begin,
+ MultiLine = true,
+ Ellipsis = false,
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.WrapContent,
+ };
+ }
+
+ // Helper method to create TextLabel with large content style
+ public static TextLabel CreateLargeContentLabel(string text)
+ {
+ return new TextLabel
+ {
+ Text = text,
+ PixelSize = LargeFontSize,
+ TextColor = Black,
+ VerticalAlignment = VerticalAlignment.Top,
+ HorizontalAlignment = HorizontalAlignment.Begin,
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.WrapContent,
+ };
+ }
+ }
+}
diff --git a/IoT/UI/AppCommon/AppCommon/Services/AppInformationService.cs b/IoT/UI/AppCommon/AppCommon/Services/AppInformationService.cs
new file mode 100755
index 000000000..be62cd576
--- /dev/null
+++ b/IoT/UI/AppCommon/AppCommon/Services/AppInformationService.cs
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 Tizen.Applications;
+
+namespace AppCommon.Services
+{
+ ///
+ /// Implementation of application information service
+ ///
+ public class AppInformationService : IAppInformationService
+ {
+ private static readonly Application Current = Application.Current;
+
+ public string ID
+ {
+ get { return Current.ApplicationInfo.ApplicationId; }
+ }
+
+ public string Name
+ {
+ get { return Current.ApplicationInfo.Label; }
+ }
+
+ public string IconPath
+ {
+ get { return Current.ApplicationInfo.IconPath; }
+ }
+
+ public string CachePath
+ {
+ get { return Current.DirectoryInfo.Cache; }
+ }
+
+ public string ExternalCachePath
+ {
+ get { return Current.DirectoryInfo.ExternalCache; }
+ }
+
+ public string ExternalDataPath
+ {
+ get { return Current.DirectoryInfo.ExternalData; }
+ }
+
+ public string ExternalSharedDataPath
+ {
+ get { return Current.DirectoryInfo.ExternalSharedData; }
+ }
+
+ public string ResourcePath
+ {
+ get { return Current.DirectoryInfo.Resource; }
+ }
+
+ public string ResourcesPath
+ {
+ get { return Current.DirectoryInfo.Resource; }
+ }
+
+ public string SharedDataPath
+ {
+ get { return Current.ApplicationInfo.SharedDataPath; }
+ }
+
+ public string SharedResourcePath
+ {
+ get { return Current.ApplicationInfo.SharedResourcePath; }
+ }
+
+ public string SharedTrustedPath
+ {
+ get { return Current.ApplicationInfo.SharedTrustedPath; }
+ }
+ }
+}
diff --git a/IoT/UI/AppCommon/AppCommon/Services/BatteryInformationService.cs b/IoT/UI/AppCommon/AppCommon/Services/BatteryInformationService.cs
new file mode 100755
index 000000000..031d3cfc1
--- /dev/null
+++ b/IoT/UI/AppCommon/AppCommon/Services/BatteryInformationService.cs
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 AppCommon.Models;
+using TBattery = Tizen.System.Battery;
+
+namespace AppCommon.Services
+{
+ ///
+ /// Implementation of battery information service
+ ///
+ public class BatteryInformationService : IBatteryInformationService
+ {
+ public BatteryInformationService()
+ {
+ TBattery.PercentChanged += (s, e) =>
+ {
+ var status = LowBatteryStatus.None;
+ if (e.Percent > 5)
+ {
+ status = LowBatteryStatus.None;
+ }
+ else if (e.Percent > 0)
+ {
+ status = LowBatteryStatus.CriticalLow;
+ }
+ else
+ {
+ status = LowBatteryStatus.PowerOff;
+ }
+ OnLevelChanged(new BatteryLevelChangedEventArgs(status));
+ };
+ }
+
+ public event EventHandler LevelChanged;
+
+ void OnLevelChanged(BatteryLevelChangedEventArgs e)
+ {
+ LevelChanged?.Invoke(this, e);
+ }
+ }
+}
diff --git a/IoT/UI/AppCommon/AppCommon/Services/DirectoryService.cs b/IoT/UI/AppCommon/AppCommon/Services/DirectoryService.cs
new file mode 100755
index 000000000..c9499589b
--- /dev/null
+++ b/IoT/UI/AppCommon/AppCommon/Services/DirectoryService.cs
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.IO;
+
+namespace AppCommon.Services
+{
+ ///
+ /// Implementation of directory service
+ ///
+ public class DirectoryService : IDirectoryService
+ {
+ public bool Exists(string path)
+ {
+ return Directory.Exists(path);
+ }
+
+ public string[] GetFiles(string path)
+ {
+ return Directory.GetFiles(path);
+ }
+ }
+}
diff --git a/IoT/UI/AppCommon/AppCommon/Services/IAppInformationService.cs b/IoT/UI/AppCommon/AppCommon/Services/IAppInformationService.cs
new file mode 100755
index 000000000..73aa7ab1f
--- /dev/null
+++ b/IoT/UI/AppCommon/AppCommon/Services/IAppInformationService.cs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ */
+
+namespace AppCommon.Services
+{
+ ///
+ /// Interface for application information service
+ ///
+ public interface IAppInformationService
+ {
+ string ID { get; }
+ string Name { get; }
+ string IconPath { get; }
+ string CachePath { get; }
+ string ExternalCachePath { get; }
+ string ExternalDataPath { get; }
+ string ExternalSharedDataPath { get; }
+ string ResourcePath { get; }
+ string ResourcesPath { get; }
+ string SharedDataPath { get; }
+ string SharedResourcePath { get; }
+ string SharedTrustedPath { get; }
+ }
+}
diff --git a/IoT/UI/AppCommon/AppCommon/Services/IBatteryInformationService.cs b/IoT/UI/AppCommon/AppCommon/Services/IBatteryInformationService.cs
new file mode 100755
index 000000000..949442195
--- /dev/null
+++ b/IoT/UI/AppCommon/AppCommon/Services/IBatteryInformationService.cs
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 AppCommon.Models;
+
+namespace AppCommon.Services
+{
+ public class BatteryLevelChangedEventArgs : EventArgs
+ {
+ public BatteryLevelChangedEventArgs(LowBatteryStatus level)
+ {
+ LowBatteryStatus = level;
+ }
+
+ public LowBatteryStatus LowBatteryStatus { get; private set; }
+ }
+
+ ///
+ /// Interface for battery information service
+ ///
+ public interface IBatteryInformationService
+ {
+ event EventHandler LevelChanged;
+ }
+}
diff --git a/IoT/UI/AppCommon/AppCommon/Services/IDirectoryService.cs b/IoT/UI/AppCommon/AppCommon/Services/IDirectoryService.cs
new file mode 100755
index 000000000..1302a1bed
--- /dev/null
+++ b/IoT/UI/AppCommon/AppCommon/Services/IDirectoryService.cs
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ */
+
+namespace AppCommon.Services
+{
+ ///
+ /// Directory service interface
+ ///
+ public interface IDirectoryService
+ {
+ ///
+ /// Returns the names of files (including their paths) in the specified directory.
+ ///
+ string[] GetFiles(string path);
+
+ ///
+ /// Determines whether the given path refers to an existing directory on disk.
+ ///
+ bool Exists(string path);
+ }
+}
diff --git a/IoT/UI/AppCommon/AppCommon/Services/ISystemSettingsService.cs b/IoT/UI/AppCommon/AppCommon/Services/ISystemSettingsService.cs
new file mode 100755
index 000000000..665aaeb48
--- /dev/null
+++ b/IoT/UI/AppCommon/AppCommon/Services/ISystemSettingsService.cs
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ */
+
+namespace AppCommon.Services
+{
+ ///
+ /// System settings service interface
+ ///
+ public interface ISystemSettingsService
+ {
+ string Language { get; }
+ }
+}
diff --git a/IoT/UI/AppCommon/AppCommon/Services/ServiceLocator.cs b/IoT/UI/AppCommon/AppCommon/Services/ServiceLocator.cs
new file mode 100755
index 000000000..674ea3d81
--- /dev/null
+++ b/IoT/UI/AppCommon/AppCommon/Services/ServiceLocator.cs
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.Collections.Generic;
+
+namespace AppCommon.Services
+{
+ ///
+ /// Simple service locator to replace Xamarin.Forms DependencyService
+ ///
+ public static class ServiceLocator
+ {
+ private static readonly Dictionary _services = new Dictionary();
+
+ ///
+ /// Register a service implementation
+ ///
+ public static void Register(TInterface implementation)
+ {
+ _services[typeof(TInterface)] = implementation;
+ }
+
+ ///
+ /// Get a registered service
+ ///
+ public static TInterface Get()
+ {
+ if (_services.TryGetValue(typeof(TInterface), out var service))
+ {
+ return (TInterface)service;
+ }
+ throw new InvalidOperationException($"Service {typeof(TInterface).Name} not registered");
+ }
+
+ ///
+ /// Initialize all services
+ ///
+ public static void Initialize()
+ {
+ Register(new AppInformationService());
+ Register(new BatteryInformationService());
+ Register(new DirectoryService());
+ Register(new SystemSettingsService());
+ }
+ }
+}
diff --git a/IoT/UI/AppCommon/AppCommon/Services/SystemSettingsService.cs b/IoT/UI/AppCommon/AppCommon/Services/SystemSettingsService.cs
new file mode 100755
index 000000000..5f21e2b38
--- /dev/null
+++ b/IoT/UI/AppCommon/AppCommon/Services/SystemSettingsService.cs
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.Globalization;
+using TSystem = Tizen.System;
+
+namespace AppCommon.Services
+{
+ ///
+ /// Implementation of system settings service
+ ///
+ public class SystemSettingsService : ISystemSettingsService
+ {
+ public string Language
+ {
+ get
+ {
+ return new CultureInfo(TSystem.SystemSettings.LocaleLanguage).DisplayName;
+ }
+ }
+ }
+}
diff --git a/IoT/UI/AppCommon/AppCommon/ViewModels/ApplicationInformationViewModel.cs b/IoT/UI/AppCommon/AppCommon/ViewModels/ApplicationInformationViewModel.cs
new file mode 100755
index 000000000..749a0cf5a
--- /dev/null
+++ b/IoT/UI/AppCommon/AppCommon/ViewModels/ApplicationInformationViewModel.cs
@@ -0,0 +1,269 @@
+/*
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.ComponentModel;
+using Tizen.NUI;
+using AppCommon.Models;
+using AppCommon.Services;
+
+namespace AppCommon.ViewModels
+{
+ ///
+ /// ViewModel for application information page
+ ///
+ public class ApplicationInformationViewModel : INotifyPropertyChanged
+ {
+ private const string degree = "\u00b0";
+
+ private string _id;
+ private string _name;
+ private string _iconPath;
+ private string _version;
+ private Color _lowBatteryLEDColor;
+ private Color _lowMemoryLEDColor;
+ private string _language;
+ private string _regionFormat;
+ private string _deviceOrientation;
+ private string _rotationDegree;
+
+ public ApplicationInformationViewModel()
+ {
+ Initialize();
+ }
+
+ public string ID
+ {
+ get => _id;
+ set
+ {
+ if (_id != value)
+ {
+ _id = value;
+ OnPropertyChanged(nameof(ID));
+ }
+ }
+ }
+
+ public string Name
+ {
+ get => _name;
+ set
+ {
+ if (_name != value)
+ {
+ _name = value;
+ OnPropertyChanged(nameof(Name));
+ }
+ }
+ }
+
+ public string IconPath
+ {
+ get => _iconPath;
+ set
+ {
+ if (_iconPath != value)
+ {
+ _iconPath = value;
+ OnPropertyChanged(nameof(IconPath));
+ }
+ }
+ }
+
+ public string Version
+ {
+ get => _version;
+ set
+ {
+ if (_version != value)
+ {
+ _version = value;
+ OnPropertyChanged(nameof(Version));
+ }
+ }
+ }
+
+ public Color LowBatteryLEDColor
+ {
+ get => _lowBatteryLEDColor;
+ set
+ {
+ if (_lowBatteryLEDColor != value)
+ {
+ _lowBatteryLEDColor = value;
+ OnPropertyChanged(nameof(LowBatteryLEDColor));
+ }
+ }
+ }
+
+ public Color LowMemoryLEDColor
+ {
+ get => _lowMemoryLEDColor;
+ set
+ {
+ if (_lowMemoryLEDColor != value)
+ {
+ _lowMemoryLEDColor = value;
+ OnPropertyChanged(nameof(LowMemoryLEDColor));
+ }
+ }
+ }
+
+ public string Language
+ {
+ get => _language;
+ set
+ {
+ if (_language != value)
+ {
+ _language = value;
+ OnPropertyChanged(nameof(Language));
+ }
+ }
+ }
+
+ public string RegionFormat
+ {
+ get => _regionFormat;
+ set
+ {
+ if (_regionFormat != value)
+ {
+ _regionFormat = value;
+ OnPropertyChanged(nameof(RegionFormat));
+ }
+ }
+ }
+
+ public string DeviceOrientation
+ {
+ get => _deviceOrientation;
+ set
+ {
+ if (_deviceOrientation != value)
+ {
+ _deviceOrientation = value;
+ OnPropertyChanged(nameof(DeviceOrientation));
+ }
+ }
+ }
+
+ public string RotationDegree
+ {
+ get => _rotationDegree;
+ set
+ {
+ if (_rotationDegree != value)
+ {
+ _rotationDegree = value;
+ OnPropertyChanged(nameof(RotationDegree));
+ }
+ }
+ }
+
+ public void UpdateLowBatteryLEDColor(LowBatteryStatus status)
+ {
+ switch (status)
+ {
+ case LowBatteryStatus.PowerOff:
+ LowBatteryLEDColor = Resources.Red;
+ return;
+ case LowBatteryStatus.CriticalLow:
+ LowBatteryLEDColor = Resources.Yellow;
+ return;
+ case LowBatteryStatus.None:
+ default:
+ LowBatteryLEDColor = Resources.LightGray;
+ return;
+ }
+ }
+
+ public void UpdateLowMemoryLEDColor(LowMemoryStatus status)
+ {
+ switch (status)
+ {
+ case LowMemoryStatus.HardWarning:
+ LowMemoryLEDColor = Resources.Red;
+ return;
+ case LowMemoryStatus.SoftWarning:
+ LowMemoryLEDColor = Resources.Yellow;
+ return;
+ case LowMemoryStatus.Normal:
+ LowMemoryLEDColor = Resources.Green;
+ return;
+ case LowMemoryStatus.None:
+ default:
+ LowMemoryLEDColor = Resources.LightGray;
+ return;
+ }
+ }
+
+ public void UpdateDeviceOrientation(DeviceOrientationStatus orientation)
+ {
+ switch (orientation)
+ {
+ case DeviceOrientationStatus.Orientation_0:
+ DeviceOrientation = "Natural position";
+ RotationDegree = "0" + degree;
+ return;
+ case DeviceOrientationStatus.Orientation_90:
+ DeviceOrientation = "Right-side up";
+ RotationDegree = "90" + degree;
+ return;
+ case DeviceOrientationStatus.Orientation_180:
+ DeviceOrientation = "Up-side down";
+ RotationDegree = "180" + degree;
+ return;
+ case DeviceOrientationStatus.Orientation_270:
+ DeviceOrientation = "Left-side up";
+ RotationDegree = "270" + degree;
+ return;
+ }
+ }
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ protected virtual void OnPropertyChanged(string propertyName)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ }
+
+ void Initialize()
+ {
+ var appInfo = ServiceLocator.Get();
+ var systemSettings = ServiceLocator.Get();
+ var batteryInfo = ServiceLocator.Get();
+
+ batteryInfo.LevelChanged += (s, e) =>
+ {
+ UpdateLowBatteryLEDColor(e.LowBatteryStatus);
+ };
+
+ ID = appInfo.ID;
+ Name = appInfo.Name;
+ IconPath = appInfo.IconPath;
+
+ Version = "0.0.0.1";
+ LowBatteryLEDColor = Resources.LightGray;
+ LowMemoryLEDColor = Resources.LightGray;
+ Language = systemSettings.Language;
+ RegionFormat = systemSettings.Language;
+
+ DeviceOrientation = "Natural position";
+ RotationDegree = "0" + degree;
+ }
+ }
+}
diff --git a/IoT/UI/AppCommon/AppCommon/ViewModels/PathsPageViewModel.cs b/IoT/UI/AppCommon/AppCommon/ViewModels/PathsPageViewModel.cs
new file mode 100755
index 000000000..b09ef1fff
--- /dev/null
+++ b/IoT/UI/AppCommon/AppCommon/ViewModels/PathsPageViewModel.cs
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.Collections.Generic;
+using AppCommon.Models;
+using AppCommon.Services;
+
+namespace AppCommon.ViewModels
+{
+ ///
+ /// ViewModel for paths page
+ ///
+ public class PathsPageViewModel
+ {
+ private IAppInformationService _appInfo;
+ private IDirectoryService _directory;
+
+ public PathsPageViewModel()
+ {
+ Initialize();
+ }
+
+ public List Paths { get; set; }
+
+ public int GetFilesCount(string path)
+ {
+ try
+ {
+ return _directory.GetFiles(path).Length;
+ }
+ catch
+ {
+ return 0;
+ }
+ }
+
+ void Initialize()
+ {
+ Paths = new List();
+ _appInfo = ServiceLocator.Get();
+ _directory = ServiceLocator.Get();
+
+ SetListItems();
+ }
+
+ private void SetListItems()
+ {
+ Paths.Add(new PathInformation
+ {
+ Title = "Resources",
+ Path = _appInfo.ResourcesPath
+ });
+
+ Paths.Add(new PathInformation
+ {
+ Title = "Cache",
+ Path = _appInfo.CachePath
+ });
+
+ Paths.Add(new PathInformation
+ {
+ Title = "Shared Data",
+ Path = _appInfo.SharedDataPath
+ });
+
+ Paths.Add(new PathInformation
+ {
+ Title = "Shared Resource",
+ Path = _appInfo.SharedResourcePath
+ });
+
+ Paths.Add(new PathInformation
+ {
+ Title = "Shared Trusted",
+ Path = _appInfo.SharedTrustedPath
+ });
+
+ Paths.Add(new PathInformation
+ {
+ Title = "External Data",
+ Path = _appInfo.ExternalDataPath
+ });
+
+ Paths.Add(new PathInformation
+ {
+ Title = "External Cache",
+ Path = _appInfo.ExternalCachePath
+ });
+
+ Paths.Add(new PathInformation
+ {
+ Title = "External Shared Data",
+ Path = _appInfo.ExternalSharedDataPath
+ });
+ }
+ }
+}
diff --git a/IoT/UI/AppCommon/AppCommon/res/background_app.png b/IoT/UI/AppCommon/AppCommon/res/background_app.png
new file mode 100755
index 000000000..7795f2c15
Binary files /dev/null and b/IoT/UI/AppCommon/AppCommon/res/background_app.png differ
diff --git a/IoT/UI/AppCommon/AppCommon/res/led.png b/IoT/UI/AppCommon/AppCommon/res/led.png
new file mode 100755
index 000000000..963545874
Binary files /dev/null and b/IoT/UI/AppCommon/AppCommon/res/led.png differ
diff --git a/IoT/UI/AppCommon/AppCommon/res/list_item_bg.png b/IoT/UI/AppCommon/AppCommon/res/list_item_bg.png
new file mode 100755
index 000000000..5f1e601fe
Binary files /dev/null and b/IoT/UI/AppCommon/AppCommon/res/list_item_bg.png differ
diff --git a/IoT/UI/AppCommon/AppCommon/res/list_top_icon.png b/IoT/UI/AppCommon/AppCommon/res/list_top_icon.png
new file mode 100755
index 000000000..008059c87
Binary files /dev/null and b/IoT/UI/AppCommon/AppCommon/res/list_top_icon.png differ
diff --git a/IoT/UI/AppCommon/AppCommon/shared/res/AppCommon.png b/IoT/UI/AppCommon/AppCommon/shared/res/AppCommon.png
new file mode 100755
index 000000000..9f3cb9860
Binary files /dev/null and b/IoT/UI/AppCommon/AppCommon/shared/res/AppCommon.png differ
diff --git a/IoT/UI/AppCommon/AppCommon/tizen-manifest.xml b/IoT/UI/AppCommon/AppCommon/tizen-manifest.xml
new file mode 100755
index 000000000..9aae38fa6
--- /dev/null
+++ b/IoT/UI/AppCommon/AppCommon/tizen-manifest.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+ AppCommon.png
+
+
diff --git a/IoT/UI/ApplicationControl/ApplicationControl.png b/IoT/UI/ApplicationControl/ApplicationControl.png
new file mode 100755
index 000000000..2b1b85287
Binary files /dev/null and b/IoT/UI/ApplicationControl/ApplicationControl.png differ
diff --git a/IoT/UI/ApplicationControl/ApplicationControl.sln b/IoT/UI/ApplicationControl/ApplicationControl.sln
new file mode 100755
index 000000000..0833907cf
--- /dev/null
+++ b/IoT/UI/ApplicationControl/ApplicationControl.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.14.36414.22 d17.14
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ApplicationControl", "ApplicationControl\ApplicationControl.csproj", "{ECC6B993-E617-4D8E-8789-026A99CE3C86}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {ECC6B993-E617-4D8E-8789-026A99CE3C86}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {ECC6B993-E617-4D8E-8789-026A99CE3C86}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {ECC6B993-E617-4D8E-8789-026A99CE3C86}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {ECC6B993-E617-4D8E-8789-026A99CE3C86}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {A37209D3-A9C7-4D51-A0C2-4F7F760481F4}
+ EndGlobalSection
+EndGlobal
diff --git a/IoT/UI/ApplicationControl/ApplicationControl/ApplicationControl.cs b/IoT/UI/ApplicationControl/ApplicationControl/ApplicationControl.cs
new file mode 100755
index 000000000..b6dbd1eb5
--- /dev/null
+++ b/IoT/UI/ApplicationControl/ApplicationControl/ApplicationControl.cs
@@ -0,0 +1,39 @@
+using System;
+using Tizen.NUI;
+using Tizen.NUI.Components;
+using Tizen.NUI.BaseComponents;
+using ApplicationControl.Pages;
+
+namespace ApplicationControl
+{
+ class Program : NUIApplication
+ {
+ private Window window;
+ private Navigator navigator;
+
+ protected override void OnCreate()
+ {
+ base.OnCreate();
+ // Disable XAML usage
+ IsUsingXaml = false;
+ Initialize();
+ }
+
+ void Initialize()
+ {
+ window = NUIApplication.GetDefaultWindow();
+ window.BackgroundColor = Color.White;
+
+ // Get default navigator and push MainPage
+ navigator = window.GetDefaultNavigator();
+ var mainPage = new MainPage();
+ navigator.Push(mainPage);
+ }
+
+ static void Main(string[] args)
+ {
+ var app = new Program();
+ app.Run(args);
+ }
+ }
+}
diff --git a/IoT/UI/ApplicationControl/ApplicationControl/ApplicationControl.csproj b/IoT/UI/ApplicationControl/ApplicationControl/ApplicationControl.csproj
new file mode 100755
index 000000000..0aae0055f
--- /dev/null
+++ b/IoT/UI/ApplicationControl/ApplicationControl/ApplicationControl.csproj
@@ -0,0 +1,27 @@
+
+
+
+
+ Exe
+ net6.0-tizen
+
+
+
+ portable
+
+
+ None
+
+
+
+
+
+
+
+
+ True
+
+
+
+
+
diff --git a/IoT/UI/ApplicationControl/ApplicationControl/Helpers/AppControlType.cs b/IoT/UI/ApplicationControl/ApplicationControl/Helpers/AppControlType.cs
new file mode 100755
index 000000000..80ca95033
--- /dev/null
+++ b/IoT/UI/ApplicationControl/ApplicationControl/Helpers/AppControlType.cs
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ */
+
+namespace ApplicationControl.Helpers
+{
+ ///
+ /// An enumeration for appcontrol type
+ ///
+ public enum AppControlType
+ {
+ View,
+ Pick,
+ Compose,
+ Send,
+ Unknown,
+ }
+}
diff --git a/IoT/UI/ApplicationControl/ApplicationControl/Helpers/ApplicationControlHelper.cs b/IoT/UI/ApplicationControl/ApplicationControl/Helpers/ApplicationControlHelper.cs
new file mode 100755
index 000000000..44692496f
--- /dev/null
+++ b/IoT/UI/ApplicationControl/ApplicationControl/Helpers/ApplicationControlHelper.cs
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.Collections.Generic;
+using System.Diagnostics;
+using Tizen.Applications;
+using ApplicationControl.Models;
+
+namespace ApplicationControl.Helpers
+{
+ ///
+ /// A singleton class to manipulate application operation
+ ///
+ public class ApplicationOperations
+ {
+ static ApplicationOperations _instance;
+ Dictionary _launchedAppControl;
+
+ ApplicationOperations()
+ {
+ _launchedAppControl = new Dictionary();
+ }
+
+ static public ApplicationOperations Instance
+ {
+ get
+ {
+ if (_instance == null)
+ {
+ _instance = new ApplicationOperations();
+ }
+
+ return _instance;
+ }
+ }
+
+ ///
+ /// To get the selected operation id
+ ///
+ /// selected operation name
+ /// selected operation id
+ public IEnumerable GetMatchedApplicationIds(string operation)
+ {
+ AppControl appControl = new AppControl
+ {
+ Operation = operation,
+ LaunchMode = AppControlLaunchMode.Group
+ };
+ if (operation.Equals(AppControlOperations.View))
+ {
+ appControl.Uri = "http";
+ }
+
+ return AppControl.GetMatchedApplicationIds(appControl);
+ }
+
+ ///
+ /// To send launch request
+ ///
+ /// selected operation
+ /// selected operation app
+ /// a message to send
+ public void SendLaunchRequest(string operation, string id, Message data = null)
+ {
+ var appCon = new AppControl
+ {
+ Operation = operation,
+ LaunchMode = AppControlLaunchMode.Group
+ };
+
+ if (data != null)
+ {
+ if (!String.IsNullOrEmpty(data.To))
+ {
+ appCon.ExtraData.Add(AppControlData.To, data.To);
+ }
+
+ appCon.ExtraData.Add(AppControlData.Subject, data.Subject);
+ appCon.ExtraData.Add(AppControlData.Text, data.Text);
+ }
+
+ if (!string.IsNullOrEmpty(id))
+ {
+ appCon.ApplicationId = id;
+ SaveLaunchedAppControl(appCon);
+ }
+
+ try
+ {
+ AppControl.SendLaunchRequest(appCon);
+ }
+ catch
+ {
+ /// Error Handling Codes
+ }
+ }
+
+ ///
+ /// To send a terminate request
+ ///
+ /// a selected application ID
+ public void SendTerminateRequest(string id)
+ {
+ var appCon = GetLaunchedAppControl(id);
+ if (appCon == null)
+ {
+ return;
+ }
+
+ try
+ {
+ AppControl.SendTerminateRequest(appCon);
+ RemoveLaunchedAppControl(appCon.ApplicationId);
+ }
+ catch (Exception e)
+ {
+ Debug.WriteLine(e.Message);
+ }
+ }
+
+ ///
+ /// To get the application icon path
+ ///
+ /// An application ID
+ /// The application icon path
+ public string GetApplicationIconPath(string id)
+ {
+ var info = new ApplicationInfo(id);
+ string iconPath = info.IconPath;
+ info.Dispose();
+ return iconPath;
+ }
+
+ ///
+ /// The view operation
+ ///
+ public string View => AppControlOperations.View;
+
+ ///
+ /// The pick operation
+ ///
+ public string Pick => AppControlOperations.Pick;
+
+ ///
+ /// The compose operation
+ ///
+ public string Compose => AppControlOperations.Compose;
+
+ ///
+ /// The send operation
+ ///
+ public string Send => AppControlOperations.Send;
+
+ ///
+ /// To save a launched appcontrol that it will be used to send a kill request later
+ ///
+ /// An application control to save
+ void SaveLaunchedAppControl(AppControl appCon)
+ {
+ if (!_launchedAppControl.ContainsKey(appCon.ApplicationId))
+ {
+ _launchedAppControl.Add(appCon.ApplicationId, appCon);
+ }
+ }
+
+ ///
+ /// To get the application control by an application ID
+ ///
+ /// An application ID
+ /// An application control
+ AppControl GetLaunchedAppControl(string id)
+ {
+ if (!_launchedAppControl.ContainsKey(id))
+ {
+ return null;
+ }
+
+ return _launchedAppControl[id];
+ }
+
+ ///
+ /// To remove an application control by an application ID
+ ///
+ /// An application ID
+ void RemoveLaunchedAppControl(string id)
+ {
+ _launchedAppControl.Remove(id);
+ }
+ }
+
+ ///
+ /// A static class to manipulate the application control and the application information functionalities
+ ///
+ static public class ApplicationControlHelper
+ {
+ ///
+ /// To get application IDs matched a specific appcontrol type
+ ///
+ /// an appcontrol type
+ /// application IDs
+ public static IEnumerable GetApplicationIdsForSpecificAppControlType(AppControlType type)
+ {
+ return ApplicationOperations.Instance.GetMatchedApplicationIds(IntToString(type));
+ }
+
+ ///
+ /// To get the application icon path for an application
+ ///
+ /// an application ID
+ /// the application icon path
+ public static string GetApplicationIconPath(string id)
+ {
+ return ApplicationOperations.Instance.GetApplicationIconPath(id);
+ }
+
+ ///
+ /// To send a launch request
+ ///
+ /// an appcontrol type
+ /// an application ID
+ /// a message to pass with an appcontrol
+ public static void ExecuteApplication(AppControlType type, string id, Message data = null)
+ {
+ ApplicationOperations.Instance.SendLaunchRequest(IntToString(type), id, data);
+ }
+
+ ///
+ /// To send a terminate request
+ ///
+ /// an application ID
+ public static void KillApplication(string id)
+ {
+ ApplicationOperations.Instance.SendTerminateRequest(id);
+ }
+
+ ///
+ /// To change an enumeration to a matched string
+ ///
+ /// An enumeration
+ /// A matched string
+ static string IntToString(AppControlType type)
+ {
+ var operation = ApplicationOperations.Instance;
+ switch (type)
+ {
+ case AppControlType.View:
+ {
+ return operation.View;
+ }
+
+ case AppControlType.Pick:
+ {
+ return operation.Pick;
+ }
+
+ case AppControlType.Compose:
+ {
+ return operation.Compose;
+ }
+
+ case AppControlType.Send:
+ {
+ return operation.Send;
+ }
+
+ default:
+ {
+ return "Unknown";
+ }
+ }
+ }
+ }
+}
diff --git a/IoT/UI/ApplicationControl/ApplicationControl/Models/ApplicationListItem.cs b/IoT/UI/ApplicationControl/ApplicationControl/Models/ApplicationListItem.cs
new file mode 100755
index 000000000..c13853fe7
--- /dev/null
+++ b/IoT/UI/ApplicationControl/ApplicationControl/Models/ApplicationListItem.cs
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.ComponentModel;
+using Tizen.NUI;
+
+namespace ApplicationControl.Models
+{
+ ///
+ /// A class for an application list item
+ ///
+ public class ApplicationListItem : INotifyPropertyChanged
+ {
+ Color _blendColor;
+
+ ///
+ /// The application ID
+ ///
+ public string Id { get; set; }
+
+ ///
+ /// The icon path
+ ///
+ public string IconPath { get; set; }
+
+ ///
+ /// The color be blended with an image
+ ///
+ public Color BlendColor
+ {
+ get
+ {
+ return _blendColor;
+ }
+
+ set
+ {
+ if (_blendColor == value)
+ {
+ return;
+ }
+
+ _blendColor = value;
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("BlendColor"));
+ }
+ }
+
+ public event PropertyChangedEventHandler PropertyChanged;
+ }
+}
diff --git a/IoT/UI/ApplicationControl/ApplicationControl/Models/Message.cs b/IoT/UI/ApplicationControl/ApplicationControl/Models/Message.cs
new file mode 100755
index 000000000..bb41e7863
--- /dev/null
+++ b/IoT/UI/ApplicationControl/ApplicationControl/Models/Message.cs
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ */
+
+namespace ApplicationControl.Models
+{
+ ///
+ /// A class for a composed message will be sent
+ ///
+ public class Message
+ {
+ ///
+ /// A constructor for the Message class
+ ///
+ public Message()
+ {
+ Initialize();
+ }
+
+ ///
+ /// An email address to send
+ ///
+ public string To { get; set; }
+
+ ///
+ /// An Subject for the message
+ ///
+ public string Subject { get; set; }
+
+ ///
+ /// An text content to send
+ ///
+ public string Text { get; set; }
+
+ void Initialize()
+ {
+ Subject = "Message from appcontrol";
+ Text = "Dear Developer,\n\nThis is the default message sent from\nappcontrol sample application.\nFeel free to modify this text message in email composer.\n\nBest Regards.";
+ }
+ }
+}
diff --git a/IoT/UI/ApplicationControl/ApplicationControl/Pages/MainPage.cs b/IoT/UI/ApplicationControl/ApplicationControl/Pages/MainPage.cs
new file mode 100755
index 000000000..fdfcccf59
--- /dev/null
+++ b/IoT/UI/ApplicationControl/ApplicationControl/Pages/MainPage.cs
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 Tizen.NUI;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Components;
+using ApplicationControl.ViewModels;
+using ApplicationControl.Views;
+
+namespace ApplicationControl.Pages
+{
+ ///
+ /// Main page for ApplicationControl
+ ///
+ public class MainPage : ContentPage
+ {
+ private MainViewModel _viewModel;
+ private OperationLayout _operationLayout;
+ private ApplicationLayout _applicationLayout;
+ private ComposeLayout _composeLayout;
+
+ public MainPage()
+ {
+ _viewModel = new MainViewModel();
+ InitializeComponent();
+ }
+
+ void InitializeComponent()
+ {
+ // Set page background
+ BackgroundColor = Resources.BackgroundLight;
+
+ // Get screen dimensions
+ var window = NUIApplication.GetDefaultWindow();
+ var screenWidth = (int)window.WindowSize.Width;
+ var screenHeight = (int)window.WindowSize.Height;
+
+ // Horizontal layout for landscape view
+ // Left panel: Operation selection (30%)
+ // Right panel: Application list and compose (70%)
+ var mainLayout = new View
+ {
+ Layout = new LinearLayout
+ {
+ LinearOrientation = LinearLayout.Orientation.Horizontal,
+ CellPadding = new Size2D(Resources.Dimensions.Padding, 0)
+ },
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.MatchParent,
+ Padding = new Extents((ushort)Resources.Dimensions.Padding, (ushort)Resources.Dimensions.Padding,
+ (ushort)Resources.Dimensions.Padding, (ushort)Resources.Dimensions.Padding)
+ };
+
+ // Left Panel: Operation Selection
+ _operationLayout = new OperationLayout(_viewModel)
+ {
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.MatchParent,
+ Weight = 0.3f
+ };
+
+ // Right Panel Container
+ var rightPanel = new View
+ {
+ Layout = new LinearLayout
+ {
+ LinearOrientation = LinearLayout.Orientation.Vertical,
+ CellPadding = new Size2D(0, Resources.Dimensions.Padding)
+ },
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.MatchParent,
+ Weight = 0.7f
+ };
+
+ // Application List (60% of right panel)
+ _applicationLayout = new ApplicationLayout(_viewModel, screenWidth, screenHeight)
+ {
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.MatchParent,
+ Weight = 0.6f
+ };
+
+ // Compose Section (40% of right panel)
+ _composeLayout = new ComposeLayout(_viewModel)
+ {
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.MatchParent,
+ Weight = 0.4f
+ };
+
+ rightPanel.Add(_applicationLayout);
+ rightPanel.Add(_composeLayout);
+
+ // Add panels to main layout
+ mainLayout.Add(_operationLayout);
+ mainLayout.Add(rightPanel);
+
+ // Set content
+ Content = mainLayout;
+
+ // Set AppBar
+ AppBar = new AppBar
+ {
+ Title = "Application Control",
+ AutoNavigationContent = false
+ };
+ }
+ }
+}
diff --git a/IoT/UI/ApplicationControl/ApplicationControl/Resources.cs b/IoT/UI/ApplicationControl/ApplicationControl/Resources.cs
new file mode 100755
index 000000000..cd77c6ea1
--- /dev/null
+++ b/IoT/UI/ApplicationControl/ApplicationControl/Resources.cs
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 Tizen.NUI;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Components;
+
+namespace ApplicationControl
+{
+ ///
+ /// Static resource class for ApplicationControl
+ ///
+ internal static class Resources
+ {
+ // Colors - Modern Color Scheme
+ public static readonly Color White = new Color(1.0f, 1.0f, 1.0f, 1.0f);
+ public static readonly Color Black = new Color(0.0f, 0.0f, 0.0f, 1.0f);
+ public static readonly Color Gray = new Color(0.5f, 0.5f, 0.5f, 1.0f);
+ public static readonly Color LightGray = new Color(0.95f, 0.95f, 0.95f, 1.0f);
+ public static readonly Color DarkGray = new Color(0.3f, 0.3f, 0.3f, 1.0f);
+ public static readonly Color Transparent = new Color(0.0f, 0.0f, 0.0f, 0.0f);
+
+ // Primary Colors
+ public static readonly Color PrimaryBlue = new Color(0.26f, 0.52f, 0.96f, 1.0f); // #4285F4
+ public static readonly Color PrimaryBlueDark = new Color(0.2f, 0.4f, 0.8f, 1.0f);
+ public static readonly Color PrimaryBlueLight = new Color(0.67f, 0.8f, 0.98f, 1.0f);
+
+ // Accent Colors
+ public static readonly Color AccentGreen = new Color(0.2f, 0.73f, 0.29f, 1.0f); // #34BA52
+ public static readonly Color AccentRed = new Color(0.92f, 0.26f, 0.21f, 1.0f); // #EA4335
+ public static readonly Color AccentOrange = new Color(1.0f, 0.67f, 0.0f, 1.0f); // #FFAB00
+
+ // Background Colors
+ public static readonly Color BackgroundLight = new Color(0.98f, 0.98f, 0.98f, 1.0f);
+ public static readonly Color CardBackground = new Color(1.0f, 1.0f, 1.0f, 1.0f);
+ public static readonly Color SectionBackground = new Color(0.96f, 0.96f, 0.96f, 1.0f);
+
+ // Text Colors
+ public static readonly Color TextPrimary = new Color(0.13f, 0.13f, 0.13f, 1.0f);
+ public static readonly Color TextSecondary = new Color(0.45f, 0.45f, 0.45f, 1.0f);
+ public static readonly Color TextHint = new Color(0.62f, 0.62f, 0.62f, 1.0f);
+
+ // State Colors
+ public static readonly Color PressedColor = new Color(0.0f, 0.0f, 0.0f, 0.1f);
+ public static readonly Color SelectedColor = new Color(0.26f, 0.52f, 0.96f, 0.15f);
+ public static readonly Color HoverColor = new Color(0.0f, 0.0f, 0.0f, 0.05f);
+
+ // Dimensions
+ public static class Dimensions
+ {
+ public const int Padding = 16;
+ public const int PaddingSmall = 8;
+ public const int PaddingLarge = 24;
+ public const int CornerRadius = 8;
+ public const int ButtonHeight = 48;
+ public const int CardElevation = 4;
+ }
+
+ // Font Sizes
+ public static class FontSizes
+ {
+ public const float Title = 24.0f;
+ public const float Subtitle = 18.0f;
+ public const float Body = 16.0f;
+ public const float Caption = 14.0f;
+ public const float Small = 12.0f;
+ }
+
+ // Helper Methods
+ public static Shadow CreateShadow()
+ {
+ return new Shadow(2.0f, new Color(0, 0, 0, 0.2f), new Vector2(0, 2));
+ }
+
+ public static View CreateCard()
+ {
+ return new View
+ {
+ BackgroundColor = CardBackground,
+ CornerRadius = Dimensions.CornerRadius,
+ BoxShadow = new Shadow(Dimensions.CardElevation, new Color(0, 0, 0, 0.1f), new Vector2(0, 2))
+ };
+ }
+
+ public static Button CreatePrimaryButton(string text)
+ {
+ return new Button
+ {
+ Text = text,
+ BackgroundColor = PrimaryBlue,
+ TextColor = White,
+ CornerRadius = Dimensions.CornerRadius / 2,
+ HeightSpecification = Dimensions.ButtonHeight,
+ PointSize = FontSizes.Caption,
+ };
+ }
+
+ public static Button CreateSecondaryButton(string text, Color color)
+ {
+ return new Button
+ {
+ Text = text,
+ BackgroundColor = color,
+ TextColor = White,
+ CornerRadius = Dimensions.CornerRadius / 2,
+ HeightSpecification = Dimensions.ButtonHeight,
+ PointSize = FontSizes.Body
+ };
+ }
+ }
+}
diff --git a/IoT/UI/ApplicationControl/ApplicationControl/ViewModels/MainViewModel.cs b/IoT/UI/ApplicationControl/ApplicationControl/ViewModels/MainViewModel.cs
new file mode 100755
index 000000000..a08c095fb
--- /dev/null
+++ b/IoT/UI/ApplicationControl/ApplicationControl/ViewModels/MainViewModel.cs
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.Collections.ObjectModel;
+using System.ComponentModel;
+using Tizen.NUI;
+using ApplicationControl.Models;
+using ApplicationControl.Helpers;
+
+namespace ApplicationControl.ViewModels
+{
+ ///
+ /// A class for main view model
+ ///
+ public class MainViewModel : INotifyPropertyChanged
+ {
+ ObservableCollection _applications;
+ Message _message;
+ AppControlType _selectedAppControlType;
+ ApplicationListItem _selectedItem;
+
+ ///
+ /// A constructor for the MainViewModel class
+ ///
+ public MainViewModel()
+ {
+ Initialize();
+ }
+
+ ///
+ /// To execute the selected application
+ ///
+ public void ExecuteSelectedApplication()
+ {
+ if (SelectedItem == null || SelectedItem?.Id == null || SelectedAppControlType == AppControlType.Unknown)
+ {
+ return;
+ }
+
+ Console.WriteLine($"Execute id:{SelectedItem.Id}, type:{SelectedAppControlType}");
+ ApplicationControlHelper.ExecuteApplication(SelectedAppControlType, SelectedItem.Id);
+ }
+
+ ///
+ /// To kill the selected application
+ ///
+ public void KillSelectedApplication()
+ {
+ if (SelectedItem == null || SelectedItem?.Id == null)
+ {
+ return;
+ }
+
+ ApplicationControlHelper.KillApplication(SelectedItem.Id);
+ }
+
+ ///
+ /// To send a message
+ ///
+ public void SendMessage()
+ {
+ ApplicationControlHelper.ExecuteApplication(AppControlType.Send, null, Message);
+ }
+
+ ///
+ /// The selected application control type
+ ///
+ public AppControlType SelectedAppControlType
+ {
+ get
+ {
+ return _selectedAppControlType;
+ }
+
+ set
+ {
+ if (_selectedAppControlType == value)
+ {
+ return;
+ }
+
+ _selectedAppControlType = value;
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("SelectedAppControlType"));
+ }
+ }
+
+ ///
+ /// Applications information for a specific application control
+ ///
+ public ObservableCollection Applications
+ {
+ get
+ {
+ return _applications;
+ }
+ }
+
+ ///
+ /// The selected application item on the application list
+ ///
+ public ApplicationListItem SelectedItem
+ {
+ get
+ {
+ return _selectedItem;
+ }
+
+ set
+ {
+ if (_selectedItem == value)
+ {
+ return;
+ }
+
+ if (_selectedItem != null)
+ {
+ _selectedItem.BlendColor = Resources.Gray;
+ }
+
+ _selectedItem = value;
+ if (_selectedItem != null)
+ {
+ _selectedItem.BlendColor = Resources.Transparent;
+ }
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("SelectedItem"));
+ }
+ }
+
+ ///
+ /// A Message to send
+ ///
+ public Message Message
+ {
+ get
+ {
+ return _message;
+ }
+ }
+
+ ///
+ /// To initialize some fields when the class is instantiated
+ ///
+ void Initialize()
+ {
+ _applications = new ObservableCollection();
+ _message = new Message { };
+ _selectedAppControlType = AppControlType.Unknown;
+ _selectedItem = new ApplicationListItem { Id = null };
+ }
+
+ public event PropertyChangedEventHandler PropertyChanged;
+ }
+}
diff --git a/IoT/UI/ApplicationControl/ApplicationControl/Views/ApplicationLayout.cs b/IoT/UI/ApplicationControl/ApplicationControl/Views/ApplicationLayout.cs
new file mode 100755
index 000000000..e0d8434e6
--- /dev/null
+++ b/IoT/UI/ApplicationControl/ApplicationControl/Views/ApplicationLayout.cs
@@ -0,0 +1,311 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 System.Threading.Tasks;
+using Tizen.NUI;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Components;
+using ApplicationControl.ViewModels;
+using ApplicationControl.Helpers;
+using ApplicationControl.Models;
+
+namespace ApplicationControl.Views
+{
+ ///
+ /// A class for an application list layout as a part of the main layout
+ ///
+ public class ApplicationLayout : View
+ {
+ private MainViewModel _viewModel;
+ private ScrollableBase _scrollView;
+ private View _applicationsContainer;
+ private TextLabel _emptyStateLabel;
+
+ public ApplicationLayout(MainViewModel viewModel, int screenWidth, int screenHeight)
+ {
+ _viewModel = viewModel;
+
+ BackgroundColor = Resources.CardBackground;
+ CornerRadius = Resources.Dimensions.CornerRadius;
+ BoxShadow = new Shadow(Resources.Dimensions.CardElevation, new Color(0, 0, 0, 0.1f), new Vector2(0, 2));
+
+ Layout = new LinearLayout
+ {
+ LinearOrientation = LinearLayout.Orientation.Vertical,
+ CellPadding = new Size2D(0, Resources.Dimensions.Padding)
+ };
+
+ Padding = new Extents((ushort)Resources.Dimensions.Padding, (ushort)Resources.Dimensions.Padding,
+ (ushort)Resources.Dimensions.Padding, (ushort)Resources.Dimensions.Padding);
+
+ SetPropertyChangeListener();
+ InitializeComponent();
+ }
+
+ void InitializeComponent()
+ {
+ // Header
+ var header = new View
+ {
+ Layout = new LinearLayout
+ {
+ LinearOrientation = LinearLayout.Orientation.Horizontal,
+ VerticalAlignment = VerticalAlignment.Center,
+ },
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.WrapContent
+ };
+
+ var title = new TextLabel
+ {
+ Text = "Applications",
+ PointSize = Resources.FontSizes.Title,
+ TextColor = Resources.TextPrimary,
+ FontStyle = new PropertyMap().Add("weight", new PropertyValue("bold")),
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.WrapContent,
+ Weight = 1.0f
+ };
+ header.Add(title);
+ Add(header);
+
+ // Scrollable container for applications
+ _scrollView = new ScrollableBase
+ {
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.MatchParent,
+ Weight = 1.0f,
+ ScrollingDirection = ScrollableBase.Direction.Vertical,
+ HideScrollbar = false
+ };
+
+ _applicationsContainer = new View
+ {
+ Layout = new LinearLayout
+ {
+ LinearOrientation = LinearLayout.Orientation.Vertical,
+ CellPadding = new Size2D(0, Resources.Dimensions.PaddingSmall)
+ },
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.WrapContent
+ };
+
+ _scrollView.Add(_applicationsContainer);
+ Add(_scrollView);
+
+ // Empty state
+ _emptyStateLabel = new TextLabel
+ {
+ Text = "Select an operation type to view applications",
+ PointSize = Resources.FontSizes.Body,
+ TextColor = Resources.TextHint,
+ HorizontalAlignment = HorizontalAlignment.Center,
+ VerticalAlignment = VerticalAlignment.Center,
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.MatchParent,
+ MultiLine = true
+ };
+ _applicationsContainer.Add(_emptyStateLabel);
+
+ // Action buttons
+ var buttonContainer = new View
+ {
+ Layout = new LinearLayout
+ {
+ LinearOrientation = LinearLayout.Orientation.Horizontal,
+ CellPadding = new Size2D(Resources.Dimensions.Padding, 0)
+ },
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.WrapContent
+ };
+
+ var executeButton = Resources.CreateSecondaryButton("Execute", Resources.AccentGreen);
+ executeButton.Weight = 1.0f;
+ executeButton.Clicked += (s, e) =>
+ {
+ _viewModel.ExecuteSelectedApplication();
+ };
+
+ var killButton = Resources.CreateSecondaryButton("Kill", Resources.AccentRed);
+ killButton.Weight = 1.0f;
+ killButton.Clicked += (s, e) =>
+ {
+ _viewModel.KillSelectedApplication();
+ };
+
+ buttonContainer.Add(executeButton);
+ buttonContainer.Add(killButton);
+ Add(buttonContainer);
+ }
+
+ void SetPropertyChangeListener()
+ {
+ _viewModel.PropertyChanged += OnPropertyChanged;
+ }
+
+ async void OnPropertyChanged(object s, PropertyChangedEventArgs e)
+ {
+ if (e.PropertyName == "SelectedAppControlType")
+ {
+ _viewModel.Applications.Clear();
+ await UpdateContentLayout();
+ }
+ }
+
+ Task UpdateContentLayout()
+ {
+ return Task.Run(() =>
+ {
+ // Clear existing items
+ _applicationsContainer.Children.Clear();
+
+ var selected = _viewModel.SelectedAppControlType;
+ if (selected == AppControlType.Unknown)
+ {
+ // Show empty state
+ _applicationsContainer.Add(_emptyStateLabel);
+ return;
+ }
+
+ var apps = ApplicationControlHelper.GetApplicationIdsForSpecificAppControlType(selected);
+
+ foreach (var app in apps)
+ {
+ var iconPath = ApplicationControlHelper.GetApplicationIconPath(app);
+
+ var appItem = new ApplicationListItem
+ {
+ Id = app,
+ IconPath = iconPath,
+ BlendColor = Resources.Gray,
+ };
+ _viewModel.Applications.Add(appItem);
+
+ var appLayoutItem = CreateApplicationLayoutItem(appItem);
+ _applicationsContainer.Add(appLayoutItem);
+ }
+ });
+ }
+
+ View CreateApplicationLayoutItem(ApplicationListItem item)
+ {
+ var container = new View
+ {
+ Layout = new LinearLayout
+ {
+ LinearOrientation = LinearLayout.Orientation.Horizontal,
+ LinearAlignment = LinearLayout.Alignment.CenterVertical,
+ CellPadding = new Size2D(Resources.Dimensions.Padding, 0)
+ },
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = 72,
+ BackgroundColor = Resources.CardBackground,
+ Padding = new Extents((ushort)Resources.Dimensions.Padding, (ushort)Resources.Dimensions.Padding,
+ (ushort)Resources.Dimensions.PaddingSmall, (ushort)Resources.Dimensions.PaddingSmall)
+ };
+
+ // Icon
+ View iconContainer;
+ if (!string.IsNullOrEmpty(item.IconPath))
+ {
+ iconContainer = new ImageView
+ {
+ ResourceUrl = item.IconPath,
+ WidthSpecification = 48,
+ HeightSpecification = 48,
+ CornerRadius = 24
+ };
+ }
+ else
+ {
+ // Placeholder icon
+ iconContainer = new View
+ {
+ BackgroundColor = Resources.LightGray,
+ WidthSpecification = 48,
+ HeightSpecification = 48,
+ CornerRadius = 24
+ };
+ }
+
+ // Text container
+ var textContainer = new View
+ {
+ Layout = new LinearLayout
+ {
+ LinearOrientation = LinearLayout.Orientation.Vertical,
+ CellPadding = new Size2D(0, 2)
+ },
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.WrapContent,
+ Weight = 1.0f
+ };
+
+ var appIdLabel = new TextLabel
+ {
+ Text = item.Id ?? "Unknown",
+ PointSize = Resources.FontSizes.Body,
+ TextColor = Resources.TextPrimary,
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.WrapContent,
+ Ellipsis = true
+ };
+
+ textContainer.Add(appIdLabel);
+
+ container.Add(iconContainer);
+ container.Add(textContainer);
+
+ // Selection indicator
+ var indicator = new View
+ {
+ BackgroundColor = Resources.Transparent,
+ WidthSpecification = 4,
+ HeightSpecification = LayoutParamPolicies.MatchParent,
+ CornerRadius = 2
+ };
+ container.Add(indicator);
+
+ // Touch handling
+ container.TouchEvent += (sender, e) =>
+ {
+ if (e.Touch.GetState(0) == PointStateType.Down)
+ {
+ container.BackgroundColor = Resources.HoverColor;
+ }
+ else if (e.Touch.GetState(0) == PointStateType.Up)
+ {
+ container.BackgroundColor = Resources.CardBackground;
+
+ // Update selection
+ foreach (var app in _viewModel.Applications)
+ {
+ if (app.Id == item.Id)
+ {
+ _viewModel.SelectedItem = app;
+ indicator.BackgroundColor = Resources.PrimaryBlue;
+ }
+ }
+ }
+ return false;
+ };
+
+ return container;
+ }
+ }
+}
diff --git a/IoT/UI/ApplicationControl/ApplicationControl/Views/ComposeLayout.cs b/IoT/UI/ApplicationControl/ApplicationControl/Views/ComposeLayout.cs
new file mode 100755
index 000000000..abff76fe7
--- /dev/null
+++ b/IoT/UI/ApplicationControl/ApplicationControl/Views/ComposeLayout.cs
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 Tizen.NUI;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Components;
+using ApplicationControl.ViewModels;
+
+namespace ApplicationControl.Views
+{
+ ///
+ /// A class for a compose layout as a part of the main layout
+ ///
+ public class ComposeLayout : View
+ {
+ private MainViewModel _viewModel;
+
+ public ComposeLayout(MainViewModel viewModel)
+ {
+ _viewModel = viewModel;
+
+ BackgroundColor = Resources.CardBackground;
+ CornerRadius = Resources.Dimensions.CornerRadius;
+ BoxShadow = new Shadow(Resources.Dimensions.CardElevation, new Color(0, 0, 0, 0.1f), new Vector2(0, 2));
+
+ Layout = new LinearLayout
+ {
+ LinearOrientation = LinearLayout.Orientation.Vertical,
+ CellPadding = new Size2D(0, Resources.Dimensions.Padding)
+ };
+
+ Padding = new Extents((ushort)Resources.Dimensions.Padding, (ushort)Resources.Dimensions.Padding,
+ (ushort)Resources.Dimensions.Padding, (ushort)Resources.Dimensions.Padding);
+
+ InitializeComponent();
+ }
+
+ void InitializeComponent()
+ {
+ // Header
+ var title = new TextLabel
+ {
+ Text = "Compose Message",
+ PointSize = Resources.FontSizes.Title,
+ TextColor = Resources.TextPrimary,
+ FontStyle = new PropertyMap().Add("weight", new PropertyValue("bold")),
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.WrapContent
+ };
+ Add(title);
+
+ // Message preview
+ var messageContainer = new View
+ {
+ BackgroundColor = Resources.SectionBackground,
+ CornerRadius = Resources.Dimensions.CornerRadius / 2,
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.MatchParent,
+ Weight = 1.0f,
+ Padding = new Extents((ushort)Resources.Dimensions.Padding, (ushort)Resources.Dimensions.Padding,
+ (ushort)Resources.Dimensions.Padding, (ushort)Resources.Dimensions.Padding)
+ };
+
+ var messageLabel = new TextLabel
+ {
+ Text = _viewModel.Message.Text,
+ TextColor = Resources.TextSecondary,
+ PointSize = Resources.FontSizes.Caption,
+ MultiLine = true,
+ LineWrapMode = LineWrapMode.Word,
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.MatchParent
+ };
+ messageContainer.Add(messageLabel);
+ Add(messageContainer);
+
+ // Input section
+ var inputContainer = new View
+ {
+ Layout = new LinearLayout
+ {
+ LinearOrientation = LinearLayout.Orientation.Horizontal,
+ CellPadding = new Size2D(Resources.Dimensions.Padding, 0)
+ },
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.WrapContent
+ };
+
+ var addressEntry = new TextField
+ {
+ PlaceholderText = "Recipient email address",
+ BackgroundColor = Resources.LightGray,
+ TextColor = Resources.TextPrimary,
+ PlaceholderTextColor = Resources.TextHint,
+ PointSize = Resources.FontSizes.Body,
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = Resources.Dimensions.ButtonHeight,
+ Weight = 1.0f,
+ Padding = new Extents((ushort)Resources.Dimensions.Padding, (ushort)Resources.Dimensions.Padding, 0, 0),
+ CornerRadius = Resources.Dimensions.CornerRadius / 2
+ };
+
+ addressEntry.TextChanged += (s, e) =>
+ {
+ _viewModel.Message.To = e.TextField.Text;
+ };
+
+ var sendButton = Resources.CreatePrimaryButton("Send");
+ sendButton.WidthSpecification = 120;
+ sendButton.Clicked += (s, e) =>
+ {
+ _viewModel.SendMessage();
+ };
+
+ inputContainer.Add(addressEntry);
+ inputContainer.Add(sendButton);
+ Add(inputContainer);
+ }
+ }
+}
diff --git a/IoT/UI/ApplicationControl/ApplicationControl/Views/OperationLayout.cs b/IoT/UI/ApplicationControl/ApplicationControl/Views/OperationLayout.cs
new file mode 100755
index 000000000..d9b278c45
--- /dev/null
+++ b/IoT/UI/ApplicationControl/ApplicationControl/Views/OperationLayout.cs
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 Tizen.NUI;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Components;
+using ApplicationControl.ViewModels;
+using ApplicationControl.Helpers;
+
+namespace ApplicationControl.Views
+{
+ ///
+ /// A class for an operation layout as a part of the main layout
+ ///
+ public class OperationLayout : View
+ {
+ private MainViewModel _viewModel;
+ private RadioButtonGroup _radioGroup;
+
+ public OperationLayout(MainViewModel viewModel)
+ {
+ _viewModel = viewModel;
+ BackgroundColor = Resources.CardBackground;
+ CornerRadius = Resources.Dimensions.CornerRadius;
+ BoxShadow = new Shadow(Resources.Dimensions.CardElevation, new Color(0, 0, 0, 0.1f), new Vector2(0, 2));
+
+ Layout = new LinearLayout
+ {
+ LinearOrientation = LinearLayout.Orientation.Vertical,
+ CellPadding = new Size2D(0, Resources.Dimensions.PaddingSmall)
+ };
+
+ Padding = new Extents((ushort)Resources.Dimensions.Padding, (ushort)Resources.Dimensions.Padding,
+ (ushort)Resources.Dimensions.Padding, (ushort)Resources.Dimensions.Padding);
+
+ // Create RadioButtonGroup for mutual exclusion
+ _radioGroup = new RadioButtonGroup();
+
+ InitializeComponent();
+ }
+
+ void InitializeComponent()
+ {
+ // Title
+ var title = new TextLabel
+ {
+ Text = "Operation Type",
+ PointSize = Resources.FontSizes.Title,
+ TextColor = Resources.TextPrimary,
+ FontStyle = new PropertyMap().Add("weight", new PropertyValue("bold")),
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.WrapContent,
+ Margin = new Extents(0, 0, 0, (ushort)Resources.Dimensions.Padding)
+ };
+ Add(title);
+
+ // Subtitle
+ var subtitle = new TextLabel
+ {
+ Text = "Select an operation to view matching applications",
+ PointSize = Resources.FontSizes.Caption,
+ TextColor = Resources.TextSecondary,
+ MultiLine = true,
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.WrapContent,
+ Margin = new Extents(0, 0, 0, (ushort)Resources.Dimensions.PaddingLarge)
+ };
+ Add(subtitle);
+
+ // Create operation items
+ Add(CreateOperationItem("View", "Open and view content", AppControlType.View, Resources.PrimaryBlue));
+ Add(CreateOperationItem("Pick", "Select files or data", AppControlType.Pick, Resources.AccentOrange));
+ Add(CreateOperationItem("Compose", "Create new content", AppControlType.Compose, Resources.AccentGreen));
+ }
+
+ View CreateOperationItem(string title, string description, AppControlType type, Color accentColor)
+ {
+ var container = new View
+ {
+ Layout = new LinearLayout
+ {
+ LinearOrientation = LinearLayout.Orientation.Horizontal,
+ LinearAlignment = LinearLayout.Alignment.CenterVertical,
+ CellPadding = new Size2D(Resources.Dimensions.Padding, 0)
+ },
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.WrapContent,
+ Margin = new Extents(0, 0, 0, (ushort)Resources.Dimensions.PaddingSmall)
+ };
+
+ // Radio Button
+ var radioButton = new RadioButton
+ {
+ IsSelected = false,
+ WidthSpecification = 24,
+ HeightSpecification = 24
+ };
+
+ // Add to RadioButtonGroup for mutual exclusion
+ _radioGroup.Add(radioButton);
+
+ radioButton.SelectedChanged += (s, e) =>
+ {
+ if (e.IsSelected == false)
+ {
+ return;
+ }
+
+ // Update selected item if type changes
+ if (type != _viewModel.SelectedAppControlType)
+ {
+ if (_viewModel.SelectedItem != null)
+ {
+ _viewModel.SelectedItem.Id = null;
+ }
+ }
+
+ _viewModel.SelectedAppControlType = type;
+ };
+
+ // Text container
+ var textContainer = new View
+ {
+ Layout = new LinearLayout
+ {
+ LinearOrientation = LinearLayout.Orientation.Vertical,
+ CellPadding = new Size2D(0, 4)
+ },
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.WrapContent,
+ Weight = 1.0f
+ };
+
+ // Title
+ var titleLabel = new TextLabel
+ {
+ Text = title,
+ PointSize = Resources.FontSizes.Body,
+ TextColor = Resources.TextPrimary,
+ FontStyle = new PropertyMap().Add("weight", new PropertyValue("medium")),
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.WrapContent
+ };
+
+ // Description
+ var descLabel = new TextLabel
+ {
+ Text = description,
+ PointSize = Resources.FontSizes.Small,
+ TextColor = Resources.TextSecondary,
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.WrapContent
+ };
+
+ textContainer.Add(titleLabel);
+ textContainer.Add(descLabel);
+
+ // Accent indicator
+ var indicator = new View
+ {
+ BackgroundColor = accentColor,
+ WidthSpecification = 4,
+ HeightSpecification = LayoutParamPolicies.MatchParent,
+ CornerRadius = 2
+ };
+
+ container.Add(radioButton);
+ container.Add(textContainer);
+ container.Add(indicator);
+
+ // Add touch feedback
+ container.TouchEvent += (sender, e) =>
+ {
+ if (e.Touch.GetState(0) == PointStateType.Down)
+ {
+ container.BackgroundColor = Resources.HoverColor;
+ }
+ else if (e.Touch.GetState(0) == PointStateType.Up)
+ {
+ container.BackgroundColor = Resources.Transparent;
+ radioButton.IsSelected = true;
+ }
+ return false;
+ };
+
+ return container;
+ }
+ }
+}
diff --git a/IoT/UI/ApplicationControl/ApplicationControl/shared/res/ApplicationControl.png b/IoT/UI/ApplicationControl/ApplicationControl/shared/res/ApplicationControl.png
new file mode 100755
index 000000000..9f3cb9860
Binary files /dev/null and b/IoT/UI/ApplicationControl/ApplicationControl/shared/res/ApplicationControl.png differ
diff --git a/IoT/UI/ApplicationControl/ApplicationControl/tizen-manifest.xml b/IoT/UI/ApplicationControl/ApplicationControl/tizen-manifest.xml
new file mode 100755
index 000000000..2ed4429ed
--- /dev/null
+++ b/IoT/UI/ApplicationControl/ApplicationControl/tizen-manifest.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+ ApplicationControl.png
+
+
+
+ http://tizen.org/privilege/appmanager.launch
+ http://tizen.org/privilege/appmanager.kill
+ http://tizen.org/privilege/packagemanager.info
+
+