private async void autoDetectExpiration(string name) { if (name == null) { return; } string[] names = name.Split(' '); bool detected = false; string key = ""; string keyTrimmed = ""; foreach (var n in names) { key = n.Trim().TrimStart(' '); keyTrimmed = key.TrimEnd('s'); detected = ContentManager.PresetExpirationBase.ContainsKey(key) || ContentManager.PresetExpirationBase.ContainsKey(keyTrimmed); if (detected) { break; } } if (detected && !autoDetectLabel.IsVisible) { autoDetectLabel.ScaleX = 0; autoDetectLabel.IsVisible = true; autoDetectLabel.Text = ContentManager.PresetExpirationBase.ContainsKey(key) ? ContentManager.PresetExpirationBase[key] : ContentManager.PresetExpirationBase[keyTrimmed]; await ViewExtensions.LinearInterpolator(autoDetectLabel, 1, 100, (v) => { Console.WriteLine("v " + v); autoDetectLabel.ScaleX = v; }); } else if (!detected) { autoDetectLabel.IsVisible = false; } }
private async void UpdateShelf(string name, ItemLayout itemLayout, int cellIndex) { // Update copies: Meta Item Base contains copies of items that should be updated ItemLayout metaItemLayout = ContentManager.MetaItemBase[itemLayout.ItemData.ID]; ItemLayout unplacedItemLayout = ContentManager.UnplacedItemBase[itemLayout.ItemData.ID]; itemLayout.iconImage.RemoveEffect(typeof(ScreenTouch)); itemLayout.IsVisible = false; metaItemLayout.ItemData.SetStorage(name, cellIndex, ContentManager.GetStorageType()); itemLayout.ItemData.SetStorage(name, cellIndex, ContentManager.GetStorageType()); ContentManager.UnplacedItemBase.Remove(itemLayout.ItemData.ID); GridManager.RemoveGridItem(ContentManager.unplacedGridName, unplacedItemLayout); // Weird fact: the animation actually allows the touchEffect cycle to complete without complaining that the item is disposed. var storage = ContentManager.GetSelectedStorage(name); var cellBackground = storage.GetGridCell(cellIndex).GetBackground(); await ViewExtensions.QuadraticInterpolator(cellBackground, 0.2, 250, d => cellBackground.Scale = d + 1, null); GridManager.RemoveGridItem(partialUnplacedGrid, itemLayout); storage.AddGridItems(cellIndex, new List <View>() { itemLayout }); if (ContentManager.isLocal) { LocalStorageController.UpdateItem(itemLayout.ItemData); } else { FireBaseController.SaveItem(itemLayout.ItemData); } }
public InfoView(Item item) { // Calculating sizes button_width = ContentManager.screenWidth * info_view_width_proportional / 3; Grid mainGrid = new Grid() { HeightRequest = ContentManager.screenHeight * info_view_height_proportional * 0.75, Margin = new Thickness(side_margin, 0), RowDefinitions = { new RowDefinition() { Height = GridLength.Star }, new RowDefinition() { Height = 1 }, new RowDefinition() { Height = GridLength.Star }, new RowDefinition() { Height = 1 }, new RowDefinition() { Height = GridLength.Star }, new RowDefinition() { Height = 1 }, new RowDefinition() { Height = GridLength.Star }, }, ColumnDefinitions = { new ColumnDefinition() { Width = GridLength.Star }, new ColumnDefinition() { Width = GridLength.Star }, } }; var closeButton = new Button() { BackgroundColor = Color.Gray, Text = "X", TextColor = Color.Black, HorizontalOptions = LayoutOptions.End, WidthRequest = close_button_size, HeightRequest = close_button_size, CornerRadius = 0, Padding = 0 }; closeButton.Clicked += (o, a) => ContentManager.pageController.RemoveInfoView(this); var itemName = new Label() { Text = item.Name, TextColor = Color.Black, FontSize = 25, HorizontalTextAlignment = TextAlignment.Center }; var itemNameDivider = new BoxView() { HeightRequest = 1, WidthRequest = ContentManager.screenWidth * 0.5, Color = Color.Gray }; var itemImage = new Image() { Source = item.Icon.Substring(6), WidthRequest = 120, HeightRequest = 120, Aspect = Aspect.Fill, HorizontalOptions = LayoutOptions.Center }; var expirationDateTitle = new Label() { Text = "Expiration Date:", TextColor = Color.Black, FontSize = grid_font_size }; var expDateText = item.daysUntilExp < 0 ? "?" : item.expMonth + "/" + item.expDay + "/" + item.expYear; var expirationDateLabel = new Label() { Text = expDateText, TextColor = Color.Black, FontSize = grid_font_size, HorizontalTextAlignment = TextAlignment.End }; var expirationDateDivider = new BoxView() { HeightRequest = 1, WidthRequest = ContentManager.screenWidth * 0.5, Color = Color.Gray }; var daysToExpString = item.daysUntilExp < 0 ? "?" : item.daysUntilExp.ToString(); var daysToExpirationTitle = new Label() { Text = "Days Until Expiration:", TextColor = Color.Black, FontSize = grid_font_size }; var daysToExpirationLabel = new Label() { Text = daysToExpString, TextColor = Color.Black, FontSize = grid_font_size, HorizontalTextAlignment = TextAlignment.End }; var expirationDayDivider = new BoxView() { HeightRequest = 1, WidthRequest = ContentManager.screenWidth * 0.5, Color = Color.Gray }; var amountTitle = new Label() { Text = "Amount: ", TextColor = Color.Black, FontSize = grid_font_size }; var amountLabel = new Label() { Text = item.Amount.ToString(), TextColor = Color.Black, FontSize = grid_font_size, WidthRequest = 30, HorizontalTextAlignment = TextAlignment.End }; var amountDivider = new BoxView() { HeightRequest = 1, WidthRequest = ContentManager.screenWidth * 0.5, Color = Color.Gray }; var locationTitle = new Label() { Text = "Location:", TextColor = Color.Black, FontSize = grid_font_size }; var locationLabel = new Label() { TextColor = Color.Black, FontSize = grid_font_size, HorizontalTextAlignment = TextAlignment.End }; locationLabel.Text = item.Stored ? item.StorageName : "Not Placed"; mainGrid.Children.Add(expirationDateTitle, 0, 0); mainGrid.Children.Add(expirationDateLabel, 1, 0); mainGrid.Children.Add(expirationDateDivider, 0, 1); Grid.SetColumnSpan(expirationDateDivider, 2); mainGrid.Children.Add(daysToExpirationTitle, 0, 2); mainGrid.Children.Add(daysToExpirationLabel, 1, 2); mainGrid.Children.Add(expirationDayDivider, 0, 3); Grid.SetColumnSpan(expirationDayDivider, 2); mainGrid.Children.Add(amountTitle, 0, 4); mainGrid.Children.Add(amountLabel, 1, 4); mainGrid.Children.Add(amountDivider, 0, 5); Grid.SetColumnSpan(amountDivider, 2); mainGrid.Children.Add(locationTitle, 0, 6); mainGrid.Children.Add(locationLabel, 1, 6); var toStorageViewButton = new Button() { BackgroundColor = Color.FromRgba(0, 100, 20, 80), Text = "View In Storage", TextColor = Color.Black, HorizontalOptions = LayoutOptions.CenterAndExpand, VerticalOptions = LayoutOptions.EndAndExpand, Margin = new Thickness(0, vertical_margin) }; var addButton = new Button() { BackgroundColor = Color.FromRgba(0, 100, 0, 80), Text = "Add", WidthRequest = button_width, TextColor = Color.Black, HorizontalOptions = LayoutOptions.CenterAndExpand, VerticalOptions = LayoutOptions.EndAndExpand, Margin = new Thickness(0, 0, 0, vertical_margin) }; var consumeButton = new Button() { BackgroundColor = Color.FromRgba(100, 20, 0, 80), Text = "Consume", WidthRequest = button_width, TextColor = Color.Black, HorizontalOptions = LayoutOptions.CenterAndExpand, VerticalOptions = LayoutOptions.EndAndExpand, Margin = new Thickness(0, 0, 0, vertical_margin) }; toStorageViewButton.BackgroundColor = item.Stored ? Color.FromRgba(0, 100, 20, 80) : Color.Gray; toStorageViewButton.Clicked += (obj, args) => { if (item.Stored) { ContentManager.pageController.RemoveInfoView(this); if (!ContentManager.pageController.IsOnPage <CabinetViewPage>()) { ContentManager.pageController.ToViewItemPage(item.StorageName, item.StorageCellIndex, item.StorageType); } } }; var gradientLineBrush = new LinearGradientBrush(new GradientStopCollection() { new GradientStop(Color.Transparent, 0.1f), new GradientStop(Color.FromRgba(0, 255, 0, 80), 0.5f), new GradientStop(Color.Transparent, 1) }, new Point(0, 0), new Point(0, 1)); var gradientLine = new BoxView() { Background = gradientLineBrush, HeightRequest = 200, }; void animateAmountChange(bool add) { // Get x, y, w, h in proprotional terms. var dhGradientLine = ContentManager.screenHeight - gradientLine.HeightRequest; var y = ContentManager.screenHeight * info_view_height_proportional / 2 + ContentManager.screenHeight / 2 - gradientLine.HeightRequest; y /= dhGradientLine; var h = gradientLine.HeightRequest / ContentManager.screenHeight; var gradientLineY = add ? y : 0; ContentManager.pageController.OverlayAnimation(gradientLine, new Rect(0.5, gradientLineY, info_view_width_proportional, h), ViewExtensions.LinearInterpolator(gradientLine, ContentManager.screenHeight * info_view_height_proportional - gradientLine.HeightRequest, 500, t => gradientLine.TranslationY = add ? -t : t, Easing.CubicInOut)); var amountLabelBounds = amountLabel.Bounds; var amountChangeLabel = new Label() { TextColor = Color.Gray, FontSize = 40, FontAttributes = FontAttributes.Bold, WidthRequest = 50, HeightRequest = 50, HorizontalTextAlignment = TextAlignment.End }; amountChangeLabel.Text = add ? "+1" : "-1"; var dwAmount = ContentManager.screenWidth - amountChangeLabel.WidthRequest; var dhAmount = ContentManager.screenHeight - amountChangeLabel.HeightRequest; ContentManager.pageController.OverlayAnimation(amountChangeLabel, new Rect(amountLabel.GetAbsolutePosition().X / dwAmount, amountLabel.GetAbsolutePosition().Y / dhAmount, amountChangeLabel.WidthRequest / ContentManager.screenWidth, amountChangeLabel.HeightRequest / ContentManager.screenHeight), amountChangeLabel.LinearInterpolator(80, 2000, t => { amountChangeLabel.TranslationY = -t; amountChangeLabel.Opacity = 1 - t / 100; }, Easing.CubicOut), () => { amountChangeLabel.TranslationY = 0; }); } addButton.Clicked += (obj, args) => { // add amount item.Amount++; // animate animateAmountChange(true); amountLabel.Text = item.Amount.ToString(); // Save data locally or to cloud if (ContentManager.isLocal) { LocalStorageController.UpdateItem(item); } else { FireBaseController.SaveItem(item); } }; consumeButton.Clicked += (obj, args) => { // Subtract amount item.Amount--; // If not fully consumed, keep track of it if (item.Amount > 0) { animateAmountChange(false); amountLabel.Text = item.Amount.ToString(); // Save data locally or to cloud if (ContentManager.isLocal) { LocalStorageController.UpdateItem(item); } else { FireBaseController.SaveItem(item); } } // If fully consumed, remove it. else { // If item not stored, remove it from unplaced grid if (!item.Stored) { var itemLayoutUnplaced = ContentManager.UnplacedItemBase[item.ID]; var unplacedGrid = GridManager.GetGrid(ContentManager.unplacedGridName); if (unplacedGrid.Children.Contains(itemLayoutUnplaced)) { unplacedGrid.Children.Remove(itemLayoutUnplaced); } } ContentManager.UnplacedItemBase.Remove(item.ID); // Remove item from meta grid var itemLayoutMeta = ContentManager.MetaItemBase[item.ID]; var metaGrid = GridManager.GetGrid(ContentManager.metaGridName); ContentManager.MetaItemBase.Remove(item.ID); GridManager.AddGridItem(metaGrid, ContentManager.MetaItemBase.Values, true); // Exit out of infoView ContentManager.pageController.RemoveInfoView(this); // Save data locally and to cloud if (ContentManager.isLocal) { LocalStorageController.DeleteItem(item); } else { FireBaseController.DeleteItem(item); } // If item is stored, delete it from storage if (item.Stored) { // Delete item from storage cell var gridCell = item.StorageType == ContentManager.fridgeStorageType ? ContentManager.FridgeMetaBase[item.StorageName].GetGridCell(item.StorageCellIndex) : ContentManager.CabinetMetaBase[item.StorageName].GetGridCell(item.StorageCellIndex); var cellGrid = gridCell.GetItemGrid(); List <View> childList = cellGrid.Children.ToList(); foreach (ItemLayout child in cellGrid.Children) { if (item.ID == child.ItemData.ID) { gridCell.RemoveItem(child); break; } } //Update storage cell children //gridCell.AddItem(childList); } } }; pageContainer = new StackLayout() { BackgroundColor = Color.Beige, Children = { closeButton, itemName, itemNameDivider, itemImage, mainGrid, toStorageViewButton, addButton, new StackLayout() { Orientation = StackOrientation.Horizontal, Children = { addButton, consumeButton } } } }; }
public void UpdateLayout() { mainGridChildren.Clear(); // Need to clear children to prevent the same children to be assigned to two different views, causing invisibility bugs mainGrid.Children.Clear(); var itemBase = new List <string>(); var expiredStorages = new List <string>(); var expiredItems = new List <int>(); if (currentStorageSelection == ContentManager.StorageSelection.cabinet) { itemBase = ContentManager.CabinetMetaBase.Keys.ToList(); ContentManager.GetItemExpirationInfo(expiredStorages, null, expiredItems); } else { itemBase = ContentManager.FridgeMetaBase.Keys.ToList(); ContentManager.GetItemExpirationInfo(null, expiredStorages, expiredItems); } foreach (var key in itemBase) { var metaName = key; var name = new Label() { Text = key.ToString(), TextColor = Color.Black, FontSize = 25, Margin = new Thickness(0, storage_name_margin), HorizontalTextAlignment = TextAlignment.Center }; var model = ContentManager.GetStorageView(currentStorageSelection, key); var button = new ImageButton() { Source = ContentManager.transIcon, Aspect = Aspect.Fill, BorderColor = Color.Black, BorderWidth = 1, BackgroundColor = Color.Transparent }; AbsoluteLayout preview = new AbsoluteLayout() { HorizontalOptions = LayoutOptions.Center, }; preview.Children.Add(name, new Rectangle(.5, 0, 1, .2), AbsoluteLayoutFlags.All); preview.Children.Add(model, new Rectangle(0, 1, 1, .8), AbsoluteLayoutFlags.All); var addButton = new Button() { BackgroundColor = Color.WhiteSmoke, Text = "Add", CornerRadius = button_radius, TextColor = Color.Black, WidthRequest = add_view_button_width, HeightRequest = 40, TranslationX = -add_view_button_width / 3 * 2, HorizontalOptions = LayoutOptions.CenterAndExpand, VerticalOptions = LayoutOptions.CenterAndExpand, IsVisible = false }; var viewButton = new Button() { BackgroundColor = Color.WhiteSmoke, Text = "View", BorderColor = Color.Black, BorderWidth = 2, CornerRadius = button_radius, TextColor = Color.Black, WidthRequest = add_view_button_width, HeightRequest = 40, TranslationX = add_view_button_width / 3 * 2, HorizontalOptions = LayoutOptions.CenterAndExpand, VerticalOptions = LayoutOptions.CenterAndExpand, IsVisible = false }; var deleteButton = new Button() { Text = "X", FontAttributes = FontAttributes.Bold, BorderWidth = 2, TextColor = Color.WhiteSmoke, BackgroundColor = Color.Transparent, FontSize = 20, FontFamily = "oswald-medium", Padding = 0, WidthRequest = 30, HeightRequest = 30, HorizontalOptions = LayoutOptions.EndAndExpand, VerticalOptions = LayoutOptions.StartAndExpand, IsVisible = false }; var changeNameButton = new ImageButton() { Source = ContentManager.changeNameIcon, BackgroundColor = Color.Transparent, HeightRequest = change_name_field_height, WidthRequest = change_name_field_height, Aspect = Aspect.AspectFill, Padding = 0, HorizontalOptions = LayoutOptions.EndAndExpand, VerticalOptions = LayoutOptions.StartAndExpand, TranslationX = -40, IsVisible = false }; var changeNameField = new Entry() { VerticalOptions = LayoutOptions.StartAndExpand, BackgroundColor = Color.White, HeightRequest = change_name_field_height, ScaleX = 0, IsEnabled = false }; deleteButton.Clicked += (obj, args) => { ContentManager.pageController.ShowAlert("Caution", "Are you sure you want to delete this layout? All of its items will be unplaced.", "Delete", "Cancel", () => { if (ContentManager.isLocal) { deleteStorageLocal?.Invoke(key); } else { deleteStorageBase?.Invoke(key); } foreach (var cell in ContentManager.GetSelectedStorage(key).GetGridCells()) { foreach (var child in cell.GetChildren()) { if (child.GetType() == typeof(ItemLayout)) { Item item = (child as ItemLayout).ItemData; item.RemoveFromStorage(); ContentManager.UnplacedItemBase.Add(item.ID, (ItemLayout)child); } } } ContentManager.RemoveSelectedStorage(key); mainGrid.Children.Clear(); mainGridChildren.Remove(key); var gridChildrenList = mainGridChildren.Values.ToList(); gridChildrenList.Insert(0, new List <View>() { newButton }); // Re-layout grid after deletion mainGrid.OrganizeGrid(gridChildrenList, GridOrganizer.OrganizeMode.HorizontalLeft); }, () => { }); }; changeNameButton.Clicked += async(obj, args) => { changeNameField.IsEnabled = true; await ViewExtensions.LinearInterpolator(changeNameField, 1, 100, i => changeNameField.ScaleX = i); changeNameField.Focus(); }; void onNameChanged() { if (changeNameField.Text != null && !itemBase.Contains(changeNameField.Text)) { var itemStorage = ContentManager.GetSelectedStorage(metaName); ContentManager.RemoveSelectedStorage(metaName); metaName = changeNameField.Text; ContentManager.AddSelectedStorage(metaName, itemStorage); name.Text = metaName; } changeNameField.ScaleX = 0; changeNameField.IsEnabled = false; } changeNameField.Completed += (obj, args) => onNameChanged(); changeNameField.Unfocused += (obj, args) => onNameChanged(); addButton.Clicked += (obj, args) => ContentManager.pageController.ToAddItemPage(metaName); viewButton.Clicked += (obj, args) => ContentManager.pageController.ToViewItemPage(metaName); button.Clicked += (object obj, EventArgs args) => button.ToggleEffects(new ImageTint() { tint = Color.FromRgba(0, 0, 0, 180), ImagePath = ContentManager.buttonTintImage }, new List <VisualElement>() { addButton, viewButton, deleteButton, changeNameButton }); List <View> views = new List <View>() { preview, button, addButton, viewButton, deleteButton, changeNameButton, changeNameField }; //expiration warning and animation if (expiredStorages.Contains(key)) { var expWarningImage = new Image() { Source = ContentManager.expWarningIcon, WidthRequest = ContentManager.exp_warning_size, HeightRequest = ContentManager.exp_warning_size, HorizontalOptions = LayoutOptions.Start, VerticalOptions = LayoutOptions.End, }; views.Add(expWarningImage); expWarningImage.QuadraticInterpolator(1.3, 2000, (t) => { if (t >= 1) { expWarningImage.Scale = t; } }, null, true); } if (!mainGridChildren.ContainsKey(metaName)) { mainGridChildren.Add(metaName, views); } } var gridChildren = mainGridChildren.Values.ToList(); gridChildren.Insert(0, new List <View>() { newButton }); mainGrid.OrganizeGrid(gridChildren, GridOrganizer.OrganizeMode.HorizontalLeft); Console.WriteLine("SIngle Selection 275 main grid children length " + mainGridChildren.Values.Count); }