private void InputOnLeftMouseButtonReleased(object sender, Blish_HUD.Input.MouseEventArgs e) { if (_screenshotPickerActive && Control.ActiveControl != null) { GameService.Graphics.QueueMainThreadRender((graphicsDevice) => { var activeControl = Control.ActiveControl; var absoluteBounds = activeControl.AbsoluteBounds; var bounds = absoluteBounds.WithPadding(activeControl.Padding); var screenshotTarget = new RenderTarget2D(graphicsDevice, GameService.Graphics.SpriteScreen.Width, GameService.Graphics.SpriteScreen.Height, false, graphicsDevice.PresentationParameters.BackBufferFormat, DepthFormat.Depth24); graphicsDevice.SetRenderTarget(screenshotTarget); graphicsDevice.Clear(Color.Transparent); using (var screenshotSpriteBatch = new SpriteBatch(graphicsDevice)) { //GameService.Graphics.SpriteScreen.Draw(screenshotSpriteBatch, new Rectangle(Point.Zero, GameService.Graphics.SpriteScreen.Size), new Rectangle(Point.Zero, GameService.Graphics.SpriteScreen.Size)); activeControl.Draw(screenshotSpriteBatch, new Rectangle(Point.Zero, activeControl.Size), new Rectangle(Point.Zero, GameService.Graphics.SpriteScreen.Size)); } using (var pngStream = new MemoryStream()) { var croppedTarget = screenshotTarget.GetRegion(bounds); croppedTarget.SaveAsPng(pngStream, screenshotTarget.Width, screenshotTarget.Height); pngStream.Seek(0, SeekOrigin.Begin); var sysImg = System.Drawing.Image.FromStream(pngStream); ClipboardUtils.SetClipboardImage(new Bitmap(sysImg), null, null); } ScreenNotification.ShowNotification("Screenshot copied to clipboard!"); graphicsDevice.SetRenderTarget(null); }); _screenshotPickerActive = false; } else if (_magentaPickerActive && Control.ActiveControl != null) { Control.ActiveControl.BackgroundColor = Color.Magenta; _magentaPickerActive = false; } else if (_runtimeViewerPickerActive && Control.ActiveControl != null) { _toolboxForm?.SetActiveControl(Control.ActiveControl); _runtimeViewerPickerActive = false; } _controlHighlighter.Hide(); }
/// <summary> /// Allows your module to run logic such as updating UI elements, /// checking for conditions, playing audio, calculating changes, etc. /// This method will block the primary Blish HUD loop, so any long /// running tasks should be executed on a separate thread to prevent /// slowing down the overlay. /// </summary> protected override void Update(GameTime gameTime) { _runningTime += gameTime.ElapsedGameTime.TotalMilliseconds; if (_runningTime > 60000) { _runningTime -= 60000; ScreenNotification.ShowNotification("The examples module shows this message every 60 seconds!", ScreenNotification.NotificationType.Warning); } }
private EventNotification(string title, AsyncTexture2D icon, string message, string waypoint) { const string TOOLTIP_TEXT = "Left click to copy waypoint.\nRight click to dismiss."; _icon = icon; this.Opacity = 0f; this.Size = new Point(NOTIFICATION_WIDTH, NOTIFICATION_HEIGHT); this.Location = new Point(180, 60 + (NOTIFICATION_HEIGHT + 15) * _visibleNotifications); this.BasicTooltipText = TOOLTIP_TEXT; string wrappedTitle = DrawUtil.WrapText(Content.DefaultFont14, title, this.Width - NOTIFICATION_HEIGHT - 20 - 32); var titleLbl = new Label() { Parent = this, Location = new Point(NOTIFICATION_HEIGHT + 10, 5), Size = new Point(this.Width - NOTIFICATION_HEIGHT - 10 - 32, this.Height / 2), Font = Content.DefaultFont14, BasicTooltipText = TOOLTIP_TEXT, Text = wrappedTitle, }; string wrapped = DrawUtil.WrapText(Content.DefaultFont14, message, this.Width - NOTIFICATION_HEIGHT - 20 - 32); var messageLbl = new Label() { Parent = this, Location = new Point(NOTIFICATION_HEIGHT + 10, this.Height / 2), Size = new Point(this.Width - NOTIFICATION_HEIGHT - 10 - 32, this.Height / 2), BasicTooltipText = TOOLTIP_TEXT, Text = wrapped, }; _visibleNotifications++; this.RightMouseButtonReleased += delegate { this.Dispose(); }; this.LeftMouseButtonReleased += delegate { ClipboardUtil.WindowsClipboardService.SetTextAsync(waypoint) .ContinueWith((clipboardResult) => { if (clipboardResult.IsFaulted) { ScreenNotification.ShowNotification("Failed to copy waypoint to clipboard. Try again.", ScreenNotification.NotificationType.Red, duration: 2); } else { ScreenNotification.ShowNotification("Copied waypoint to clipboard!", duration: 2); } }); this.Dispose(); }; }
/// <summary> /// Allows you to perform an action once your module has finished loading (once /// <see cref="LoadAsync"/> has completed). You must call "base.OnModuleLoaded(e)" at the /// end for the <see cref="Module.ModuleLoaded"/> event to fire and for /// <see cref="Module.Loaded" /> to update correctly. /// </summary> protected override void OnModuleLoaded(EventArgs e) { // Add a mug icon in the top left next to the other icons _exampleIcon = new CornerIcon() { Icon = _mugTexture, BasicTooltipText = $"{this.Name} [{this.Namespace}]", Parent = GameService.Graphics.SpriteScreen }; // Show a notification in the middle of the screen when the icon is clicked _exampleIcon.Click += delegate(object sender, MouseEventArgs args) { ScreenNotification.ShowNotification("Hello from Blish HUD!"); }; // Add a right click menu to the icon that shows each Revenant legend (pulled from the API) _dungeonContextMenuStrip = new ContextMenuStrip(); foreach (var dungeon in _dungeons) { var dungeonItem = _dungeonContextMenuStrip.AddMenuItem(dungeon.Id); var dungeonMenu = new ContextMenuStrip(); foreach (var path in dungeon.Paths) { dungeonMenu.AddMenuItem($"{path.Id} ({path.Type})"); } dungeonItem.Submenu = dungeonMenu; } _exampleIcon.Menu = _dungeonContextMenuStrip; base.OnModuleLoaded(e); }
private Panel BuildSettingPanel(Rectangle panelBounds) { var etPanel = new Panel() { CanScroll = false, Size = panelBounds.Size }; var ddSortMethod = new Dropdown() { Location = new Point(etPanel.Right - 150 - Dropdown.Standard.ControlOffset.X, Dropdown.Standard.ControlOffset.Y), Width = 150, Parent = etPanel, }; int topOffset = ddSortMethod.Bottom + Panel.MenuStandard.ControlOffset.Y; var menuSection = new Panel { Title = "Event Categories", ShowBorder = true, Size = Panel.MenuStandard.Size - new Point(0, topOffset + Panel.MenuStandard.ControlOffset.Y), Location = new Point(Panel.MenuStandard.PanelOffset.X, topOffset), Parent = etPanel }; var eventPanel = new FlowPanel() { FlowDirection = ControlFlowDirection.LeftToRight, ControlPadding = new Vector2(8, 8), Location = new Point(menuSection.Right + Panel.MenuStandard.ControlOffset.X, menuSection.Top), Size = new Point(ddSortMethod.Right - menuSection.Right - Control.ControlStandard.ControlOffset.X, menuSection.Height), CanScroll = true, Parent = etPanel }; GameService.Overlay.QueueMainThreadUpdate((gameTime) => { var searchBox = new TextBox() { PlaceholderText = "Event Search", Width = menuSection.Width, Location = new Point(ddSortMethod.Top, menuSection.Left), Parent = etPanel }; searchBox.TextChanged += delegate(object sender, EventArgs args) { eventPanel.FilterChildren <DetailsButton>(db => db.Text.ToLower().Contains(searchBox.Text.ToLower())); }; }); foreach (var meta in Meta.Events) { var setting = _watchCollection.DefineSetting("watchEvent:" + meta.Name, true); meta.IsWatched = setting.Value; var es2 = new DetailsButton { Parent = eventPanel, BasicTooltipText = meta.Category, Text = meta.Name, IconSize = DetailsIconSize.Small, ShowVignette = false, HighlightType = DetailsHighlightType.LightHighlight, ShowToggleButton = true }; if (meta.Texture.HasTexture) { es2.Icon = meta.Texture; } var nextTimeLabel = new Label() { Size = new Point(65, es2.ContentRegion.Height), Text = meta.NextTime.ToShortTimeString(), BasicTooltipText = GetTimeDetails(meta), HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Middle, Parent = es2, }; Adhesive.Binding.CreateOneWayBinding(() => nextTimeLabel.Height, () => es2.ContentRegion, (rectangle => rectangle.Height), true); if (!string.IsNullOrEmpty(meta.Wiki)) { var glowWikiBttn = new GlowButton { Icon = GameService.Content.GetTexture("102530"), ActiveIcon = GameService.Content.GetTexture("glow-wiki"), BasicTooltipText = "Read about this event on the wiki.", Parent = es2, GlowColor = Color.White * 0.1f }; glowWikiBttn.Click += delegate { if (UrlIsValid(meta.Wiki)) { Process.Start(meta.Wiki); } }; } if (!string.IsNullOrEmpty(meta.Waypoint)) { var glowWaypointBttn = new GlowButton { Icon = GameService.Content.GetTexture("waypoint"), ActiveIcon = GameService.Content.GetTexture("glow-waypoint"), BasicTooltipText = $"Nearby waypoint: {meta.Waypoint}", Parent = es2, GlowColor = Color.White * 0.1f }; glowWaypointBttn.Click += delegate { System.Windows.Forms.Clipboard.SetText(meta.Waypoint); ScreenNotification.ShowNotification("Waypoint copied to clipboard."); }; } var toggleFollowBttn = new GlowButton() { Icon = _textureWatch, ActiveIcon = _textureWatchActive, BasicTooltipText = "Click to toggle tracking for this event.", ToggleGlow = true, Checked = meta.IsWatched, Parent = es2, }; toggleFollowBttn.Click += delegate { meta.IsWatched = toggleFollowBttn.Checked; setting.Value = toggleFollowBttn.Checked; }; meta.OnNextRunTimeChanged += delegate { UpdateSort(ddSortMethod, EventArgs.Empty); nextTimeLabel.Text = meta.NextTime.ToShortTimeString(); nextTimeLabel.BasicTooltipText = GetTimeDetails(meta); }; _displayedEvents.Add(es2); } // Add menu items for each category (and built-in categories) var eventCategories = new Menu { Size = menuSection.ContentRegion.Size, MenuItemHeight = 40, Parent = menuSection, CanSelect = true }; List <IGrouping <string, Meta> > submetas = Meta.Events.GroupBy(e => e.Category).ToList(); var evAll = eventCategories.AddMenuItem(EC_ALLEVENTS); evAll.Select(); evAll.Click += delegate { eventPanel.FilterChildren <DetailsButton>(db => true); }; foreach (IGrouping <string, Meta> e in submetas) { var ev = eventCategories.AddMenuItem(e.Key); ev.Click += delegate { eventPanel.FilterChildren <DetailsButton>(db => string.Equals(db.BasicTooltipText, e.Key)); }; } // TODO: Hidden events/timers to be added later //eventCategories.AddMenuItem(EC_HIDDEN); // Add dropdown for sorting events ddSortMethod.Items.Add(DD_ALPHABETICAL); ddSortMethod.Items.Add(DD_NEXTUP); ddSortMethod.ValueChanged += delegate(object sender, ValueChangedEventArgs args) { switch (args.CurrentValue) { case DD_ALPHABETICAL: eventPanel.SortChildren <DetailsButton>((db1, db2) => string.Compare(db1.Text, db2.Text, StringComparison.CurrentCultureIgnoreCase)); break; case DD_NEXTUP: break; } }; ddSortMethod.SelectedItem = DD_NEXTUP; //UpdateSort(ddSortMethod, EventArgs.Empty); return(etPanel); }
private void AddThumbnail(string filePath) { if (modulePanel == null || displayedThumbnails.ContainsKey(filePath)) { return; } var texture = GetThumbnail(filePath); if (texture == null) { return; } var thumbnail = new Panel { Parent = thumbnailFlowPanel, Size = new Point(_thumbnailSize.X + 6, _thumbnailSize.Y + 6), BackgroundColor = Color.Black, BasicTooltipText = filePath }; var tImage = new Blish_HUD.Controls.Image { Parent = thumbnail, Location = new Point(3, 3), Size = _thumbnailSize, Texture = texture, Opacity = 0.8f }; var inspectButton = new Blish_HUD.Controls.Image { Parent = thumbnail, Texture = _inspectIcon, Size = new Point(64, 64), Location = new Point(thumbnail.Width / 2 - 32, thumbnail.Height / 2 - 32), Opacity = 0.0f }; var deleteBackgroundTint = new Panel { Parent = thumbnail, Size = thumbnail.Size, BackgroundColor = Color.Black, Opacity = 0.0f }; var deleteLabel = new Label { Parent = thumbnail, Size = thumbnail.Size, TextColor = Color.White, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Middle, Font = GameService.Content.GetFont(ContentService.FontFace.Menomonia, ContentService.FontSize.Size24, ContentService.FontStyle.Regular), Text = FileDeletionPrompt, BasicTooltipText = ZoomInThumbnailTooltipText, StrokeText = true, ShowShadow = true, Opacity = 0.0f }; var favoriteMarker = new Blish_HUD.Controls.Image { Parent = thumbnail, Location = new Point(thumbnail.Size.X - 30 - PanelMargin, PanelMargin), Size = new Point(30, 30), BasicTooltipText = favorites.Value.Contains(filePath) ? UnfavoriteMarkerTooltip : FavoriteMarkerTooltip, Texture = favorites.Value.Contains(filePath) ? _completeHeartIcon : _incompleteHeartIcon, Opacity = 0.5f }; favoriteMarker.Click += delegate { var currentFilePath = thumbnail.BasicTooltipText; if (favorites.Value.Contains(currentFilePath)) { var copy = new List <string>(favorites.Value); copy.Remove(currentFilePath); favorites.Value = copy; favoriteMarker.Texture = _incompleteHeartIcon; favoriteMarker.BasicTooltipText = FavoriteMarkerTooltip; } else { var copy = new List <string>(favorites.Value) { currentFilePath }; favorites.Value = copy; favoriteMarker.Texture = _completeHeartIcon; favoriteMarker.BasicTooltipText = UnfavoriteMarkerTooltip; } SortThumbnails(); }; favoriteMarker.MouseEntered += delegate { GameService.Animation.Tweener.Tween(favoriteMarker, new { Opacity = 1.0f }, 0.2f); }; favoriteMarker.MouseLeft += delegate { GameService.Animation.Tweener.Tween(favoriteMarker, new { Opacity = 0.5f }, 0.2f); favoriteMarker.Location = new Point(thumbnail.Size.X - 30 - PanelMargin, PanelMargin); favoriteMarker.Size = new Point(30, 30); }; favoriteMarker.LeftMouseButtonPressed += delegate { favoriteMarker.Width -= 2; favoriteMarker.Height -= 2; favoriteMarker.Location = new Point(favoriteMarker.Location.X + 2, favoriteMarker.Location.Y + 2); }; favoriteMarker.LeftMouseButtonReleased += delegate { favoriteMarker.Location = new Point(thumbnail.Size.X - 30 - PanelMargin, PanelMargin); favoriteMarker.Size = new Point(30, 30); }; var fileNameTextBox = new TextBox { Parent = thumbnail, Size = new Point(thumbnail.Width / 2 + 20, 30), Location = new Point(PanelMargin, thumbnail.Height - 30 - PanelMargin), PlaceholderText = Path.GetFileNameWithoutExtension(filePath), MaxLength = MaxFileNameLength, BackgroundColor = Color.DarkBlue, BasicTooltipText = Path.GetFileNameWithoutExtension(filePath), Text = "", Opacity = 0.8f }; var fileNameLengthLabel = new Label { Parent = thumbnail, Size = fileNameTextBox.Size, Location = new Point(fileNameTextBox.Location.X, fileNameTextBox.Location.Y - fileNameTextBox.Height), HorizontalAlignment = HorizontalAlignment.Right, VerticalAlignment = VerticalAlignment.Bottom, Text = "0/" + MaxFileNameLength, Font = GameService.Content.GetFont(ContentService.FontFace.Menomonia, ContentService.FontSize.Size11, ContentService.FontStyle.Regular), TextColor = Color.Yellow, StrokeText = true, Visible = false }; fileNameTextBox.TextChanged += delegate { fileNameLengthLabel.Text = fileNameTextBox.Text.Length + "/" + MaxFileNameLength; }; fileNameTextBox.MouseEntered += delegate { GameService.Animation.Tweener.Tween(fileNameTextBox, new { Opacity = 1.0f }, 0.2f); }; fileNameTextBox.MouseLeft += delegate { if (!fileNameTextBox.Focused) { GameService.Animation.Tweener.Tween(fileNameTextBox, new { Opacity = 0.8f }, 0.2f); } }; var enterPressed = false; fileNameTextBox.EnterPressed += delegate { enterPressed = true; var oldFilePath = thumbnail.BasicTooltipText; var newFileName = fileNameTextBox.Text.Trim(); if (newFileName.Equals(string.Empty)) { ScreenNotification.ShowNotification(ReasonEmptyFileName, ScreenNotification.NotificationType.Error); } else if (_invalidFileNameCharacters.Any(x => newFileName.Contains(x))) { ScreenNotification.ShowNotification(ReasonInvalidFileName + "\n" + PromptChangeFileName + "\n" + InvalidFileNameCharactersHint + "\n" + string.Join(" ", _invalidFileNameCharacters), ScreenNotification.NotificationType.Error, null, 10); } else { var newPath = Path.Combine(Directory.GetParent(Path.GetFullPath(oldFilePath)).FullName, newFileName + Path.GetExtension(oldFilePath)); if (newPath.Equals(oldFilePath, StringComparison.InvariantCultureIgnoreCase)) { } else if (File.Exists(newPath)) { ScreenNotification.ShowNotification( FailedToRenameFileNotification + " " + ReasonDublicateFileName, ScreenNotification.NotificationType.Error); } else if (!File.Exists(oldFilePath)) { ScreenNotification.ShowNotification( FailedToRenameFileNotification + " " + ReasonFileNotExisting, ScreenNotification.NotificationType.Error); thumbnail?.Dispose(); } else { var renameCompleted = false; var renameTimeout = DateTime.Now.AddMilliseconds(FileTimeOutMilliseconds); while (!renameCompleted) { try { File.Move(oldFilePath, newPath); renameCompleted = true; } catch (IOException e) { if (DateTime.Now < renameTimeout) { continue; } Logger.Error(e.Message + e.StackTrace); } } } } if (!fileNameTextBox.MouseOver) { GameService.Animation.Tweener.Tween(fileNameTextBox, new { Opacity = 0.6f }, 0.2f); } fileNameTextBox.Text = ""; enterPressed = false; }; fileNameTextBox.InputFocusChanged += delegate { fileNameLengthLabel.Visible = fileNameTextBox.Focused; fileNameLengthLabel.Text = "0/" + MaxFileNameLength; fileNameTextBox.InputFocusChanged += delegate { Task.Run(async delegate { //InputFocusChanged needs to wait to not interfere with EnterPressed. await Task.Delay(1).ContinueWith(delegate { if (!enterPressed) { fileNameTextBox.Text = ""; } }); }); }; }; deleteLabel.MouseEntered += delegate { GameService.Animation.Tweener.Tween(inspectButton, new { Opacity = 1.0f }, 0.2f); GameService.Animation.Tweener.Tween(tImage, new { Opacity = 1.0f }, 0.45f); }; deleteLabel.MouseLeft += delegate { GameService.Animation.Tweener.Tween(inspectButton, new { Opacity = 0.0f }, 0.2f); GameService.Animation.Tweener.Tween(tImage, new { Opacity = 0.8f }, 0.45f); }; Panel inspectPanel = null; deleteLabel.Click += delegate { inspectPanel?.Dispose(); inspectPanel = CreateInspectionPanel(filePath); }; var deleteButton = new Blish_HUD.Controls.Image { Parent = thumbnail, Texture = _trashcanClosedIcon64, Size = new Point(45, 45), Location = new Point(thumbnail.Width - 45 - PanelMargin, thumbnail.Height - 45 - PanelMargin), Opacity = 0.5f }; deleteButton.MouseEntered += delegate { deleteButton.Texture = _trashcanOpenIcon64; GameService.Animation.Tweener.Tween(deleteButton, new { Opacity = 1.0f }, 0.2f); GameService.Animation.Tweener.Tween(deleteLabel, new { Opacity = 1.0f }, 0.2f); GameService.Animation.Tweener.Tween(deleteBackgroundTint, new { Opacity = 0.6f }, 0.35f); GameService.Animation.Tweener.Tween(fileNameTextBox, new { Opacity = 0.0f }, 0.2f); }; deleteButton.MouseLeft += delegate { deleteButton.Texture = _trashcanClosedIcon64; GameService.Animation.Tweener.Tween(deleteButton, new { Opacity = 0.8f }, 0.2f); GameService.Animation.Tweener.Tween(deleteLabel, new { Opacity = 0.0f }, 0.2f); GameService.Animation.Tweener.Tween(deleteBackgroundTint, new { Opacity = 0.0f }, 0.2f); GameService.Animation.Tweener.Tween(fileNameTextBox, new { Opacity = 0.8f }, 0.2f); }; deleteButton.LeftMouseButtonReleased += delegate { var oldFilePath = thumbnail.BasicTooltipText; if (!File.Exists(oldFilePath)) { thumbnail?.Dispose(); } else { var deletionCompleted = false; var deletionTimeout = DateTime.Now.AddMilliseconds(FileTimeOutMilliseconds); while (!deletionCompleted) { try { fileNameTextBox.Text = ""; File.Delete(oldFilePath); deletionCompleted = true; } catch (IOException e) { if (DateTime.Now < deletionTimeout) { continue; } Logger.Error(e.Message + e.StackTrace); ScreenNotification.ShowNotification(FailedToDeleteFileNotification + " " + ReasonFileInUse, ScreenNotification.NotificationType.Error); } } } }; thumbnail.Disposed += delegate { var oldFilePath = thumbnail.BasicTooltipText; if (displayedThumbnails.ContainsKey(oldFilePath)) { displayedThumbnails.Remove(oldFilePath); } if (!favorites.Value.Contains(oldFilePath)) { return; } var copy = new List <string>(favorites.Value); copy.Remove(oldFilePath); favorites.Value = copy; }; try { displayedThumbnails.Add(filePath, thumbnail); SortThumbnails(); } catch (ArgumentException e) { Logger.Error(e.Message + e.StackTrace); thumbnail.Dispose(); } }