Repository: cyotek/Cyotek.Windows.Forms.ImageBox
Branch: master
Commit: eaf19705e0b6
Files: 110
Total size: 809.5 KB
Directory structure:
gitextract_n7bu3m8j/
├── .editorconfig
├── .github/
│ └── workflows/
│ └── codeql-analysis.yml
├── .gitignore
├── .markdownlint.json
├── CHANGELOG.md
├── Cyotek.Windows.Forms.ImageBox/
│ ├── Cyotek.Windows.Forms.ImageBox.csproj
│ ├── Cyotek.Windows.Forms.ImageBox.nuspec
│ ├── ImageBox.cs
│ ├── ImageBoxActionSources.cs
│ ├── ImageBoxBorderStyle.cs
│ ├── ImageBoxCancelEventArgs.cs
│ ├── ImageBoxGridDisplayMode.cs
│ ├── ImageBoxGridScale.cs
│ ├── ImageBoxMouseWheelMessageFilter.cs
│ ├── ImageBoxMouseWheelMode.cs
│ ├── ImageBoxNativeMethods.cs
│ ├── ImageBoxPanDirection.cs
│ ├── ImageBoxPanMode.cs
│ ├── ImageBoxPanStyle.cs
│ ├── ImageBoxSelectionMode.cs
│ ├── ImageBoxSizeMode.cs
│ ├── ImageBoxZoomActions.cs
│ ├── ImageBoxZoomEventArgs.cs
│ ├── Properties/
│ │ └── AssemblyInfo.cs
│ ├── ScrollControl.cs
│ ├── ScrollProperties.cs
│ ├── VirtualScrollableControl.cs
│ ├── ZoomLevelCollection.cs
│ ├── ZoomLevelCollectionConverter.cs
│ └── cyopublic.snk
├── Cyotek.Windows.Forms.ImageBox.Demo/
│ ├── AboutDialog.cs
│ ├── AboutDialog.designer.cs
│ ├── AboutDialog.resx
│ ├── AnimatedGifDemoForm.Designer.cs
│ ├── AnimatedGifDemoForm.cs
│ ├── AnimatedGifDemoForm.resx
│ ├── BaseForm.Designer.cs
│ ├── BaseForm.cs
│ ├── BaseForm.resx
│ ├── Cyotek.Windows.Forms.ImageBox.Demo.csproj
│ ├── DisposedImageDemoForm.Designer.cs
│ ├── DisposedImageDemoForm.cs
│ ├── DisposedImageDemoForm.resx
│ ├── DragHandle.cs
│ ├── DragHandleAnchor.cs
│ ├── DragHandleCollection.cs
│ ├── DragTestForm.Designer.cs
│ ├── DragTestForm.cs
│ ├── DragTestForm.resx
│ ├── EventsListBox.cs
│ ├── FilteredPropertyGrid.cs
│ ├── GeneralDemoForm.Designer.cs
│ ├── GeneralDemoForm.cs
│ ├── GeneralDemoForm.resx
│ ├── GroupBox.cs
│ ├── ImageBoxEx.cs
│ ├── MainMenuForm.cs
│ ├── MainMenuForm.designer.cs
│ ├── MainMenuForm.resx
│ ├── MiniMapDemoForm.cs
│ ├── MiniMapDemoForm.designer.cs
│ ├── MiniMapDemoForm.resx
│ ├── OpenUrlDialog.Designer.cs
│ ├── OpenUrlDialog.cs
│ ├── OpenUrlDialog.resx
│ ├── PanStylesDemoForm.Designer.cs
│ ├── PanStylesDemoForm.cs
│ ├── PanStylesDemoForm.resx
│ ├── PixelGridForm.Designer.cs
│ ├── PixelGridForm.cs
│ ├── PixelGridForm.resx
│ ├── Program.cs
│ ├── Properties/
│ │ ├── AssemblyInfo.cs
│ │ ├── Resources.Designer.cs
│ │ └── Resources.resx
│ ├── PropertyGrid.cs
│ ├── ResizableSelectionDemoForm.Designer.cs
│ ├── ResizableSelectionDemoForm.cs
│ ├── ResizableSelectionDemoForm.resx
│ ├── Resources/
│ │ └── markdownpad-github.css
│ ├── ScaledAdornmentsDemoForm.Designer.cs
│ ├── ScaledAdornmentsDemoForm.cs
│ ├── ScaledAdornmentsDemoForm.resx
│ ├── SizeModeDemoForm.Designer.cs
│ ├── SizeModeDemoForm.cs
│ ├── SizeModeDemoForm.resx
│ ├── SwitchImageDuringZoomDemoForm.Designer.cs
│ ├── SwitchImageDuringZoomDemoForm.cs
│ ├── SwitchImageDuringZoomDemoForm.resx
│ ├── TextDemoForm.Designer.cs
│ ├── TextDemoForm.cs
│ ├── TextDemoForm.resx
│ ├── VirtualModeDemonstrationForm.Designer.cs
│ ├── VirtualModeDemonstrationForm.cs
│ ├── VirtualModeDemonstrationForm.resx
│ ├── app.manifest
│ ├── cyopublic.snk
│ └── packages.config
├── Cyotek.Windows.Forms.ImageBox.Design/
│ ├── Cyotek.Windows.Forms.ImageBox.Design.csproj
│ ├── ImageBoxDesigner.cs
│ └── Properties/
│ └── AssemblyInfo.cs
├── Cyotek.Windows.Forms.ImageBox.sln
├── LICENSE.txt
├── README.md
├── acknowledgements.md
├── build.cmd
├── nuget.config
└── res/
├── PanAll.cur
├── icon-16.pdn
└── icon-32.pdn
================================================
FILE CONTENTS
================================================
================================================
FILE: .editorconfig
================================================
; http://editorconfig.org/
; https://visualstudiogallery.msdn.microsoft.com/c8bccfe2-650c-4b42-bc5c-845e21f96328
root=true
[*]
end_of_line = crlf
trim_trailing_whitespace = true
insert_final_newline = true
charset = utf-8
[*.cs]
indent_style = space
indent_size = 2
================================================
FILE: .github/workflows/codeql-analysis.yml
================================================
name: "CodeQL"
on:
push:
branches: [master]
pull_request:
# The branches below must be a subset of the branches above
branches: [master]
schedule:
- cron: '0 7 * * 3'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
# Override automatic language detection by changing the below list
# Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
language: ['csharp']
# Learn more...
# https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection
steps:
- name: Checkout repository
uses: actions/checkout@v2
with:
# We must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head.
fetch-depth: 2
# If this run was triggered by a pull request event, then checkout
# the head of the pull request instead of the merge commit.
- run: git checkout HEAD^2
if: ${{ github.event_name == 'pull_request' }}
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
# ℹ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
================================================
FILE: .gitignore
================================================
.vs/
bin/
obj/
_NCrunch_*
nuget/
packages/
maps/
*.ncrunch*
*.user
push.cmd
*.suo
*.ncrunchproject
================================================
FILE: .markdownlint.json
================================================
{
"MD001": false,
"MD024": false
}
================================================
FILE: CHANGELOG.md
================================================
# Cyotek ImageBox Change Log
## 1.4.0
### Added
* Added new `MouseWheelMode` property to control how the mouse
wheel is used to interact with the control. When set to `Zoom`
(default), the wheel will scroll the control in and out. When
set to `ScrollAndZoom`, the wheel scrolls the control
vertically. Holding down `Shift` will scroll horizontally, or
`Control` to zoom (#18).
## 1.3.1
### Fixed
* Panning only worked if the horizontal scrollbar was present (#45)
## 1.3
### Added
* Added `PanMode` property. This property allows you to determine if panning can be triggered by the left mouse button, the middle mouse button or both. This property replaces the `AutoPan` property.
* Added `AllowFreePan` property. This property determines if panning only occurs when the mouse button is pressed, or if pressing the mouse button starts free panning and pressing any other button cancels the pan. Free panning only applies when using the middle mouse button.
### Deprecated
* The `AutoPan` property has been deprecated and will be removed in a future version
## 1.2.2
### Fixed
* Any exception during image painting will now be caught, and the error text printed
in lieu of the image
* Fixed a crash that could occur when dragging a selection if the selection was empty
## 1.2
### Changed
* Reworked events to have less overhead
* Switched to semantic versioning
## 1.1.5.1
### Fixed
* Fixes the `FitRectangle` method from increasing the width or height of the
source rectangle if `X` or `Y` were negative (generally seen when the
`SelectionMode` is set to `Rectangle` and you draw outside the bounds of the
image area)
* Resizing the selection in the `ImageBoxEx` control now works correctly even if
the mouse passes outside the bounds of the image
## 1.1.5.0
### Added
* Added `AllowUnfocusedMouseWheel` property. If set to `true` the control will
support mouse wheel zooming even when it does not have focus
### Fixed
* The `fitToBounds` parameter of the `PointToImage` wasn't being used correctly
## 1.1.4.6
### Added
* Added new `MaximumSelectionSize` property to the demonstration `ImageBoxEx`
control that allows for more control over default selection
* Added new overloads to `ZoomIn` and `ZoomOut` to determine if the center point
should be preserved
### Changed
* Refactored zoom handling for mouse and keyboard to avoid duplicate
calculations
* Updated copyright year
### Fixed
* Zooming in or out using the default keybinds now preserves the center point
relative to the new zoom
* Fixed the **About** dialog in the demonstration program not loading the
default tab correctly
## 1.1.4.5
### Added
* `ImageBoxEx` example control now correctly allows you to move and resize
selection regions even when the control is zoomed
### Changed
* If the `InterpolationMode` property is set to `Default`, the `ImageBox`
control will now choose an appropriate mode based on the current zoom levels
## 1.1.4.4
### Added
* Added new `DrawBackground` virtual method. This allows you to override how the
`ImageBox` draws the image background without having to override the entire
`OnPaint` method
## 1.1.4.3
### Added
* Added a new `TextPadding` property and corresponding `DrawLabel` overload.
When this property is set, rendered text from the `Text` and `TextAlign`
properties is drawn with the appropriate padding. If the `TextBackColor`
property is set to something not fully transparent, then the background will
be filled in the original render spot, excluding the padding, allowing for
labels with wider background borders
## 1.1.4.2
### Added
* Added a new **Resizable Selection** demo. This demo makes use of a subclass of
the `ImageBox` to add native dragging and resizing of the region defined by
the `SelectionRegion` property
### Changed
* `DrawImage` now also ignores `OutOfMemoryException` exceptions
* Removed requirement for .NET 3.5 thanks to a commit from
[dahmage](https://github.com/dahmage)
* Added `GetScaledRectangle` overloads using `Point` and `Size` (and the float
variant) parameters
### Fixed
* Calling `SelectAll` caused a crash if a backing image wasn't present (even if
`VirtualMode` was set)
## 1.1.4.1
### Fixed
* Removed unnecessary `UpdateStyles` calls
* Changed the `ViewSize` property and `DrawImage` methods to handle disposed
images rather than bringing down an entire application
* Added `TextFormatFlags.NoPadding` to the flags used by `DrawLabel` to avoid a
slight gap on left aligned text
* Fixed a potential crash calling `GetSelectedImage`. Thanks to MutStarburst for
finding this bug
## 1.1.4.0
### Added
* Added NuGet package
* Added a new `SizeMode` property. This allows you to switch between `Normal`,
`Fit` and `Stretch` modes. Stretch is a new mode for the `ImageBox`, and acts
similar to existing `Fit` functionality except the aspect ratio is not
preserved
* Added a license file to hopefully cut down on questions about usage. The
`ImageBox` control is licensed under the MIT license, allowing you free reign
to use it in your projects, commercial or otherwise. See `license.txt` for the
full text
* Added a new `CenterPoint` property. This property returns the pixel at the
center of the current image viewport
* Added a bunch of missing XML comments documentation.
* Added new overloads for most methods that accepted a source `Rectangle`,
`Point` or `Size` to also accept `float` and `int` arguments.
* Added a new `Zoomed` method that uses new `ImageBoxZoomEventArgs` arguments.
This new event allows you to tell if the zoom was in or out, how it was
raised, and current and previous zoom values. Not hugely thrilled with how
aspects of this change has been internally implemented, so implementation
methods are private rather than virtual so I can change them without affecting
the signature
* Added new `CenterToImage` method which resets the viewport to be centered of
the image, in the same way as zooming via the keyboard used to work.
* Added support for animated GIF's, thanks to a contribution from
[Eggy](https://github.com/teamalpha5441). Note animations only play at
runtime, not design time
* The `Text` and `Font` properties are now available and, if set, will be
displayed in the control. You can use the `ForeColor`, `TextBackColor`,
`TextAlign`, `TextDisplayMode` and `ScaleText` properties to determine how the
text will be rendered
* A new `DrawLabel` method that performs text drawing is available for use by
custom implementations or virtual modes
* Added a new *Scaled Adornments* demonstration, showing how easy it is to add
custom drawing that is scaled and positioned appropriately
* Added a new *Switch Image During Zoom* demonstration, a demo with an unwieldy
name that shows how to switch out a low resolution image with a higher
detailed one as you zoom into an `ImageBox`
* Added new *Text* and *Size Mode* demonstrations
### Fixed
* Zooming in and out with the keyboard now keeps the view centered to the same
pixel that was centered prior to the zoom
* Zooming in and out with the keyboard is now correctly disabled if the
`AllowZoom` property is `False`, or the `SizeMode` property is a value other
than `Normal`. This means keyboard behaviour now matches mouse behaviour
* If the mouse wheel was rapidly spun (thus having a multiple of the base
delta), the `Zoom` property was only adjusted once
* Setting the `GridScale` property to `None` rendered the default `Small` grid.
Using a scale of `None` now correctly just fills the grid area with a solid
brush from the `GridColor` property
* The `MouseWheel` event is now available
* Layout changes no longer occur if the `AllowPainting` property is `false`
through use of the `BeginUpdate` method
* Fixed various documentation errors
### Removed
* The `SizeToFit` property has been marked as deprecated and should no longer be
used. The `SizeMode` property has a `Fit` value that should be used instead.
Setting the `SizeToFit` property will now manipulate `SizeMode` instead
## 1.1.3.0
### Added
* Added new *DragTestForm* demo
* Added new `Tiny` setting for `ImageBoxGridScale` which is half the size of
`Small`
### Changed
* The `Selecting` event now uses `ImageBoxCancelEventArgs` in order to provide
further information
### Fixed
* If the `Selecting` event was cancelled, it would continue to be re-raised with
every movement of the mouse while the button was pressed. Now the event is
only raised once, and if cancelled will not be raised again until the button
is released and a new drag initiated
## 1.1.2.2
### Changed
* Changed `PixelGridThreshold` into an instance property, and changed default
value to `5`
## 1.1.2.1
### Added
* Added missing `GetOffsetRectangle` overload which supports `Rectangle`
structs
### Fixed
* The `ZoomToFit` method didn't support virtual mode and crashed if called
## 1.1.2.0
### Added
* Added `IsPointInImage` method. This function returns if a given point is
within the image viewport, and is useful for combining with `PointToImage`
* Added `ImageBorderColor` property, allowing you to customize the color of the
image border
* Added a new `ImageBoxBorderStyle`, `FixedSingleGlowShadow`. This style allows
for a more smoother outer glow shadow instead of the existing clunky drop
shadow
* Added `ShowPixelGrid` and `PixelGridColor` properties. When set, a dotted
grid is displayed around pixels when zooming in on an image
* Added new overload to `PointToImage` which allows you to specify if the
function should map the given point to the nearest available edge(s) if the
point is outside the image boundaries
* Added `AllowDoubleClick` property. When set, the normal double click events
and overrides work as expected
* Additional documentation added via XML comments
### Fixed
* If the `GridDisplayMode` property is set to `Image` an explicit image border
is no longer drawn, instead the `ImageBorder` property is correctly honoured
* Fixes a problem where half the pixels of the first row/column were lost when
zooming. Thanks to Rotem for the fix
* The `GetImageViewport` method now correctly returns a width and height that
accounts for control size, padding and zoom levels
* Fixed incorrect attributes on `AutoSize` property
* Fixes "see also" documentation errors for events
## 1.1.1.0
### Changed
* Added `VirtualMode` and `VirtualSize` properties. These new properties allow
you to use all functionality of the ImageBox control without having to set
the `Image` property. You can also use the new `VirtualDraw` event to provide
custom drawing without having to override existing drawing functionality
### Fixed
* Fixed the image viewport sometimes being the incorrect size when zoomed in.
Thanks to WMJ for the fix
## 1.1.0.0
### Added
* Added a `ZoomLevels` property which allows you to configure the different zoom
levels supported by the control. Now instead of the control trying to guess
the next zoom level, it cycles appropriately through the defined levels.
*Currently ZoomLevels (apart from the default series) can only be set at runtime*
* New `CenterAt` and `ScrollTo` methods allow you to scroll to a given location
in the source image
* Split shortcut handling into two methods `ProcessScrollingShortcuts` for
handling arrow keys and `ProcessImageShortcuts` for handling pretty much
anything else
* Added `EnableShortcuts` property, allowing the built in keyboard support to be
disabled. When this property is true, `ProcessImageShortcuts` is not called,
allowing the control to still be scrolled via the keyboard, but not zoomed etc
* Added a new `GetSelectedImage` method which creates a new `Bitmap` based on
the current selection
* Added new `FitRectangle` method which takes a given rectangle and ensure it
fits within the image boundaries
* Added a new `ZoomToRegion` method. This will caculate and appropriate zoom
level and scrollbar positions to fit a given rectangle
* Added new `SelectionMode.Zoom`. When this mode is selected, drawing a region
will automatically zoom and position the control to fit the region, after
which the region is automatically cleared
### Changed
* Zooming with the mouse is now smoother, and the control attempts to keep the
area under the mouse before the zoom in the same area after the zoon.
* The `ZoomIncrement` property has been removed due to the introduction of the
new zoom levels
* Zooming can now be performed by the -/+ keys (`OemMinus` and `Oemplus`)
* When zooming (except via mouse action), if the `AutoCenter` property is set,
the control will always center the image even when scrollbars are present
* Nestable `BeginUpdate` and `EndUpdate` methods allow you to disable and enable
painting of the control, for example when changing multiple properties at once
* The `AllowClickZoom` property now defaults to `false`
* The `PointToImage` function no longer adds +1 to the result of the function
### Fixed
* Panning no longer tries to activate if no scrollbars are visible
* A new base class, `VirtualScrollableControl` is now used instead of
`ScrollableControl`. This removes completely the flicker issues present in
previous versions of the control
* The BorderStyle property has been moved to the `ScrollControl` class, so that
borders now correctly surround the control (including scrollbars) rather than
just the client area
* If the `AllowZoomClick` property is `true`, the control no longer magically
zooms after panning or selecting a region. Code previously in the
`OnMouseClick` override is now in `OnMouseUp`
* If both `AutoPan` and a valid `SelectionMode` are set, only selections are
processed, instead of the control tying to do both. As a result of this fix,
setting the `SelectionMode` property no longer resets `AutoPan`
* With the introduction of the `VirtualScrollableControl`, the `MouseWheel`
event is now raised as expected
### Known issues
* The `ScrollProperties` class hasn't been fully integrated with the
`ScrollControl`, setting properties on this class won't update the owner control
## 1.0.0.5
* Initial GitHub release
================================================
FILE: Cyotek.Windows.Forms.ImageBox/Cyotek.Windows.Forms.ImageBox.csproj
================================================
Debug
AnyCPU
{4159C8D3-C18D-4BED-8BE6-9BAD1B0CA4F6}
Library
Properties
Cyotek.Windows.Forms
Cyotek.Windows.Forms.ImageBox
v2.0
512
true
full
false
bin\Debug\
DEBUG;TRACE
prompt
4
pdbonly
true
bin\Release\
TRACE
prompt
4
bin\Release\Cyotek.Windows.Forms.ImageBox.xml
true
cyopublic.snk
Component
Component
Component
Component
PanAll.cur
PanAllSymbol.png
================================================
FILE: Cyotek.Windows.Forms.ImageBox/Cyotek.Windows.Forms.ImageBox.nuspec
================================================
CyotekImageBox
$version$-beta.1
Cyotek ImageBox Control
Cyotek
Cyotek
https://raw.githubusercontent.com/cyotek/Cyotek.Windows.Forms.ImageBox/master/license.txt
http://cyotek.com/blog/tag/imagebox
http://static.cyotek.com/files/packageicons/imagebox-32x32.png
false
The ImageBox is a custom control for displaying images. It supports zooming, scrolling, panning, region selection, virtual modes, and much more.
The ImageBox is a custom control for displaying images with built in support for zooming, scrolling, panning, region selection, virtual modes, and much more.
$copyright$
en-GB
image picturebox form control imagebox cyotek
================================================
FILE: Cyotek.Windows.Forms.ImageBox/ImageBox.cs
================================================
// Cyotek ImageBox
// http://cyotek.com/blog/tag/imagebox
// Copyright (c) 2010-2021 Cyotek Ltd.
// This work is licensed under the MIT License.
// See LICENSE.TXT for the full text
// Found this code useful?
// https://www.cyotek.com/contribute
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Windows.Forms;
namespace Cyotek.Windows.Forms
{
///
/// Component for displaying images with support for scrolling and zooming.
///
[DefaultProperty("Image")]
[ToolboxBitmap(typeof(ImageBox), "ImageBox.bmp")]
[ToolboxItem(true)]
/* [Designer("Cyotek.Windows.Forms.Design.ImageBoxDesigner", Cyotek.Windows.Forms.ImageBox.Design.dll, PublicKeyToken=58daa28b0b2de221")] */
public class ImageBox : VirtualScrollableControl
{
#region Constants
private static readonly object _eventAllowClickZoomChanged = new object();
private static readonly object _eventAllowDoubleClickChanged = new object();
private static readonly object _eventAllowFreePanChanged = new object();
private static readonly object _eventAllowUnfocusedMouseWheelChanged = new object();
private static readonly object _eventAllowZoomChanged = new object();
private static readonly object _eventAutoCenterChanged = new object();
private static readonly object _eventAutoPanChanged = new object();
private static readonly object _eventDropShadowSizeChanged = new object();
private static readonly object _eventGridCellSizeChanged = new object();
private static readonly object _eventGridColorAlternateChanged = new object();
private static readonly object _eventGridColorChanged = new object();
private static readonly object _eventGridDisplayModeChanged = new object();
private static readonly object _eventGridScaleChanged = new object();
private static readonly object _eventImageBorderColorChanged = new object();
private static readonly object _eventImageBorderStyleChanged = new object();
private static readonly object _eventImageChanged = new object();
private static readonly object _eventInterpolationModeChanged = new object();
private static readonly object _eventInvertMouseChanged = new object();
private static readonly object _eventLimitSelectionToImageChanged = new object();
private static readonly object _eventMouseWheelModeChanged = new object();
private static readonly object _eventPanEnd = new object();
private static readonly object _eventPanModeChanged = new object();
private static readonly object _eventPanStart = new object();
private static readonly object _eventPixelGridColorChanged = new object();
private static readonly object _eventPixelGridThresholdChanged = new object();
private static readonly object _eventScaleTextChanged = new object();
private static readonly object _eventSelected = new object();
private static readonly object _eventSelecting = new object();
private static readonly object _eventSelectionColorChanged = new object();
private static readonly object _eventSelectionModeChanged = new object();
private static readonly object _eventSelectionRegionChanged = new object();
private static readonly object _eventShortcutsEnabledChanged = new object();
private static readonly object _eventShowPixelGridChanged = new object();
private static readonly object _eventSizeModeChanged = new object();
private static readonly object _eventSizeToFitChanged = new object();
private static readonly object _eventTextAlignChanged = new object();
private static readonly object _eventTextBackColorChanged = new object();
private static readonly object _eventTextDisplayModeChanged = new object();
private static readonly object _eventTextPaddingChanged = new object();
private static readonly object _eventVirtualDraw = new object();
private static readonly object _eventVirtualModeChanged = new object();
private static readonly object _eventVirtualSizeChanged = new object();
private static readonly object _eventZoomChanged = new object();
private static readonly object _eventZoomed = new object();
private static readonly object _eventZoomLevelsChanged = new object();
private const int _freePanTimerInterval = 250;
private const int _panAllDeadSize = 32;
private const int MaxZoom = 3500;
private const int MinZoom = 1;
private const int SelectionDeadZone = 5;
#endregion
#region Fields
private bool _allowClickZoom;
private bool _allowDoubleClick;
private bool _allowFreePan;
private bool _allowUnfocusedMouseWheel;
private bool _allowZoom;
private bool _autoCenter;
private Cursor _currentCursor;
private int _dropShadowSize;
private Timer _freePanTimer;
private int _gridCellSize;
private Color _gridColor;
private Color _gridColorAlternate;
private ImageBoxGridDisplayMode _gridDisplayMode;
private ImageBoxGridScale _gridScale;
private Bitmap _gridTile;
private Image _image;
private Color _imageBorderColor;
private ImageBoxBorderStyle _imageBorderStyle;
private InterpolationMode _interpolationMode;
private bool _invertMouse;
private bool _limitSelectionToImage;
private double _mouseDownStart;
private ImageBoxMouseWheelMode _mouseWheelMode;
private ImageBoxPanMode _panMode;
private ImageBoxPanStyle _panStyle;
private Color _pixelGridColor;
private int _pixelGridThreshold;
private bool _scaleText;
private Color _selectionColor;
private ImageBoxSelectionMode _selectionMode;
private RectangleF _selectionRegion;
private bool _shortcutsEnabled;
private bool _showPixelGrid;
private ImageBoxSizeMode _sizeMode;
private Point _startMousePosition;
private Point _startScrollPosition;
private ContentAlignment _textAlign;
private Color _textBackColor;
private ImageBoxGridDisplayMode _textDisplayMode;
private Padding _textPadding;
private Brush _texture;
private int _updateCount;
private bool _virtualMode;
private Size _virtualSize;
private int _zoom;
private ZoomLevelCollection _zoomLevels;
private bool _isSelecting;
#endregion
#region Constructors
///
/// Initializes a new instance of the class.
///
public ImageBox()
{
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw, true);
this.SetStyle(ControlStyles.StandardDoubleClick, false);
// ReSharper disable DoNotCallOverridableMethodsInConstructor
this.BeginUpdate();
_panMode = ImageBoxPanMode.Both;
_allowFreePan = true;
this.WheelScrollsControl = false;
this.AllowZoom = true;
this.MouseWheelMode = ImageBoxMouseWheelMode.Zoom;
this.LimitSelectionToImage = true;
this.DropShadowSize = 3;
this.ImageBorderStyle = ImageBoxBorderStyle.None;
this.BackColor = Color.White;
this.AutoSize = false;
this.AutoScroll = true;
this.GridScale = ImageBoxGridScale.Small;
this.GridDisplayMode = ImageBoxGridDisplayMode.Client;
this.GridColor = Color.Gainsboro;
this.GridColorAlternate = Color.White;
this.GridCellSize = 8;
this.InterpolationMode = InterpolationMode.NearestNeighbor;
this.AutoCenter = true;
this.SelectionColor = SystemColors.Highlight;
this.ActualSize();
this.ShortcutsEnabled = true;
this.ZoomLevels = ZoomLevelCollection.Default;
this.ImageBorderColor = SystemColors.ControlDark;
this.PixelGridColor = Color.DimGray;
this.PixelGridThreshold = 5;
this.TextAlign = ContentAlignment.MiddleCenter;
this.TextBackColor = Color.Transparent;
this.TextDisplayMode = ImageBoxGridDisplayMode.Client;
this.EndUpdate();
// ReSharper restore DoNotCallOverridableMethodsInConstructor
}
#endregion
#region Events
///
/// Occurs when the AllowClickZoom property is changed.
///
[Category("Property Changed")]
public event EventHandler AllowClickZoomChanged
{
add { this.Events.AddHandler(_eventAllowClickZoomChanged, value); }
remove { this.Events.RemoveHandler(_eventAllowClickZoomChanged, value); }
}
///
/// Occurs when the AllowDoubleClick property value changes
///
[Category("Property Changed")]
public event EventHandler AllowDoubleClickChanged
{
add { this.Events.AddHandler(_eventAllowDoubleClickChanged, value); }
remove { this.Events.RemoveHandler(_eventAllowDoubleClickChanged, value); }
}
///
/// Occurs when the AllowFreePan property value changes
///
[Category("Property Changed")]
public event EventHandler AllowFreePanChanged
{
add { this.Events.AddHandler(_eventAllowFreePanChanged, value); }
remove { this.Events.RemoveHandler(_eventAllowFreePanChanged, value); }
}
///
/// Occurs when the AllowUnfocusedMouseWheel property value changes
///
[Category("Property Changed")]
public event EventHandler AllowUnfocusedMouseWheelChanged
{
add { this.Events.AddHandler(_eventAllowUnfocusedMouseWheelChanged, value); }
remove { this.Events.RemoveHandler(_eventAllowUnfocusedMouseWheelChanged, value); }
}
///
/// Occurs when the AllowZoom property is changed.
///
[Category("Property Changed")]
public event EventHandler AllowZoomChanged
{
add { this.Events.AddHandler(_eventAllowZoomChanged, value); }
remove { this.Events.RemoveHandler(_eventAllowZoomChanged, value); }
}
///
/// Occurs when the AutoCenter property is changed.
///
[Category("Property Changed")]
public event EventHandler AutoCenterChanged
{
add { this.Events.AddHandler(_eventAutoCenterChanged, value); }
remove { this.Events.RemoveHandler(_eventAutoCenterChanged, value); }
}
///
/// Occurs when the AutoPan property is changed.
///
[Category("Property Changed")]
public event EventHandler AutoPanChanged
{
add { this.Events.AddHandler(_eventAutoPanChanged, value); }
remove { this.Events.RemoveHandler(_eventAutoPanChanged, value); }
}
///
/// Occurs when the DropShadowSize property is changed.
///
[Category("Property Changed")]
public event EventHandler DropShadowSizeChanged
{
add { this.Events.AddHandler(_eventDropShadowSizeChanged, value); }
remove { this.Events.RemoveHandler(_eventDropShadowSizeChanged, value); }
}
///
/// Occurs when the GridSizeCell property is changed.
///
[Category("Property Changed")]
public event EventHandler GridCellSizeChanged
{
add { this.Events.AddHandler(_eventGridCellSizeChanged, value); }
remove { this.Events.RemoveHandler(_eventGridCellSizeChanged, value); }
}
///
/// Occurs when the GridColorAlternate property is changed.
///
[Category("Property Changed")]
public event EventHandler GridColorAlternateChanged
{
add { this.Events.AddHandler(_eventGridColorAlternateChanged, value); }
remove { this.Events.RemoveHandler(_eventGridColorAlternateChanged, value); }
}
///
/// Occurs when the GridColor property is changed.
///
[Category("Property Changed")]
public event EventHandler GridColorChanged
{
add { this.Events.AddHandler(_eventGridColorChanged, value); }
remove { this.Events.RemoveHandler(_eventGridColorChanged, value); }
}
///
/// Occurs when the GridDisplayMode property is changed.
///
[Category("Property Changed")]
public event EventHandler GridDisplayModeChanged
{
add { this.Events.AddHandler(_eventGridDisplayModeChanged, value); }
remove { this.Events.RemoveHandler(_eventGridDisplayModeChanged, value); }
}
///
/// Occurs when the GridScale property is changed.
///
[Category("Property Changed")]
public event EventHandler GridScaleChanged
{
add { this.Events.AddHandler(_eventGridScaleChanged, value); }
remove { this.Events.RemoveHandler(_eventGridScaleChanged, value); }
}
///
/// Occurs when the ImageBorderColor property value changes
///
[Category("Property Changed")]
public event EventHandler ImageBorderColorChanged
{
add { this.Events.AddHandler(_eventImageBorderColorChanged, value); }
remove { this.Events.RemoveHandler(_eventImageBorderColorChanged, value); }
}
///
/// Occurs when the ImageBorderStyle property is changed.
///
[Category("Property Changed")]
public event EventHandler ImageBorderStyleChanged
{
add { this.Events.AddHandler(_eventImageBorderStyleChanged, value); }
remove { this.Events.RemoveHandler(_eventImageBorderStyleChanged, value); }
}
///
/// Occurs when the Image property is changed.
///
[Category("Property Changed")]
public event EventHandler ImageChanged
{
add { this.Events.AddHandler(_eventImageChanged, value); }
remove { this.Events.RemoveHandler(_eventImageChanged, value); }
}
///
/// Occurs when the InterpolationMode property is changed.
///
[Category("Property Changed")]
public event EventHandler InterpolationModeChanged
{
add { this.Events.AddHandler(_eventInterpolationModeChanged, value); }
remove { this.Events.RemoveHandler(_eventInterpolationModeChanged, value); }
}
///
/// Occurs when the InvertMouse property is changed.
///
[Category("Property Changed")]
public event EventHandler InvertMouseChanged
{
add { this.Events.AddHandler(_eventInvertMouseChanged, value); }
remove { this.Events.RemoveHandler(_eventInvertMouseChanged, value); }
}
///
/// Occurs when the LimitSelectionToImage property is changed.
///
[Category("Property Changed")]
public event EventHandler LimitSelectionToImageChanged
{
add { this.Events.AddHandler(_eventLimitSelectionToImageChanged, value); }
remove { this.Events.RemoveHandler(_eventLimitSelectionToImageChanged, value); }
}
///
/// Occurs when the MouseWheelMode property value changes
///
[Category("Property Changed")]
public event EventHandler MouseWheelModeChanged
{
add { this.Events.AddHandler(_eventMouseWheelModeChanged, value); }
remove { this.Events.RemoveHandler(_eventMouseWheelModeChanged, value); }
}
///
/// Occurs when panning the control completes.
///
[Category("Action")]
public event EventHandler PanEnd
{
add { this.Events.AddHandler(_eventPanEnd, value); }
remove { this.Events.RemoveHandler(_eventPanEnd, value); }
}
///
/// Occurs when the PanMode property value changes
///
[Category("Property Changed")]
public event EventHandler PanModeChanged
{
add { this.Events.AddHandler(_eventPanModeChanged, value); }
remove { this.Events.RemoveHandler(_eventPanModeChanged, value); }
}
///
/// Occurs when panning the control starts.
///
[Category("Action")]
public event EventHandler PanStart
{
add { this.Events.AddHandler(_eventPanStart, value); }
remove { this.Events.RemoveHandler(_eventPanStart, value); }
}
///
/// Occurs when the PixelGridColor property value changes
///
[Category("Property Changed")]
public event EventHandler PixelGridColorChanged
{
add { this.Events.AddHandler(_eventPixelGridColorChanged, value); }
remove { this.Events.RemoveHandler(_eventPixelGridColorChanged, value); }
}
///
/// Occurs when the PixelGridThreshold property value changes
///
[Category("Property Changed")]
public event EventHandler PixelGridThresholdChanged
{
add { this.Events.AddHandler(_eventPixelGridThresholdChanged, value); }
remove { this.Events.RemoveHandler(_eventPixelGridThresholdChanged, value); }
}
///
/// Occurs when the ScaleText property value changes
///
[Category("Property Changed")]
public event EventHandler ScaleTextChanged
{
add { this.Events.AddHandler(_eventScaleTextChanged, value); }
remove { this.Events.RemoveHandler(_eventScaleTextChanged, value); }
}
///
/// Occurs when a selection region has been defined
///
[Category("Action")]
public event EventHandler Selected
{
// TODO: The event signature is wrong and should just be EventHandler - breaking change however. Do in the 2.0 scroll changes branch.
add { this.Events.AddHandler(_eventSelected, value); }
remove { this.Events.RemoveHandler(_eventSelected, value); }
}
///
/// Occurs when the user starts to define a selection region.
///
[Category("Action")]
public event EventHandler Selecting
{
add { this.Events.AddHandler(_eventSelecting, value); }
remove { this.Events.RemoveHandler(_eventSelecting, value); }
}
///
/// Occurs when the SelectionColor property is changed.
///
[Category("Property Changed")]
public event EventHandler SelectionColorChanged
{
add { this.Events.AddHandler(_eventSelectionColorChanged, value); }
remove { this.Events.RemoveHandler(_eventSelectionColorChanged, value); }
}
///
/// Occurs when the SelectionMode property is changed.
///
[Category("Property Changed")]
public event EventHandler SelectionModeChanged
{
add { this.Events.AddHandler(_eventSelectionModeChanged, value); }
remove { this.Events.RemoveHandler(_eventSelectionModeChanged, value); }
}
///
/// Occurs when the SelectionRegion property is changed.
///
[Category("Property Changed")]
public event EventHandler SelectionRegionChanged
{
add { this.Events.AddHandler(_eventSelectionRegionChanged, value); }
remove { this.Events.RemoveHandler(_eventSelectionRegionChanged, value); }
}
///
/// Occurs when the ShortcutsEnabled property value changes
///
[Category("Property Changed")]
public event EventHandler ShortcutsEnabledChanged
{
add { this.Events.AddHandler(_eventShortcutsEnabledChanged, value); }
remove { this.Events.RemoveHandler(_eventShortcutsEnabledChanged, value); }
}
///
/// Occurs when the ShowPixelGrid property value changes
///
[Category("Property Changed")]
public event EventHandler ShowPixelGridChanged
{
add { this.Events.AddHandler(_eventShowPixelGridChanged, value); }
remove { this.Events.RemoveHandler(_eventShowPixelGridChanged, value); }
}
///
/// Occurs when the SizeMode property value changes
///
[Category("Property Changed")]
public event EventHandler SizeModeChanged
{
add { this.Events.AddHandler(_eventSizeModeChanged, value); }
remove { this.Events.RemoveHandler(_eventSizeModeChanged, value); }
}
///
/// Occurs when the SizeToFit property is changed.
///
[Category("Property Changed")]
public event EventHandler SizeToFitChanged
{
add { this.Events.AddHandler(_eventSizeToFitChanged, value); }
remove { this.Events.RemoveHandler(_eventSizeToFitChanged, value); }
}
///
/// Occurs when the TextAlign property value changes
///
[Category("Property Changed")]
public event EventHandler TextAlignChanged
{
add { this.Events.AddHandler(_eventTextAlignChanged, value); }
remove { this.Events.RemoveHandler(_eventTextAlignChanged, value); }
}
///
/// Occurs when the TextBackColor property value changes
///
[Category("Property Changed")]
public event EventHandler TextBackColorChanged
{
add { this.Events.AddHandler(_eventTextBackColorChanged, value); }
remove { this.Events.RemoveHandler(_eventTextBackColorChanged, value); }
}
///
/// Occurs when the TextDisplayMode property value changes
///
[Category("Property Changed")]
public event EventHandler TextDisplayModeChanged
{
add { this.Events.AddHandler(_eventTextDisplayModeChanged, value); }
remove { this.Events.RemoveHandler(_eventTextDisplayModeChanged, value); }
}
///
/// Occurs when the TextPadding property value changes
///
[Category("Property Changed")]
public event EventHandler TextPaddingChanged
{
add { this.Events.AddHandler(_eventTextPaddingChanged, value); }
remove { this.Events.RemoveHandler(_eventTextPaddingChanged, value); }
}
///
/// Occurs when virtual painting should occur
///
[Category("Appearance")]
public event PaintEventHandler VirtualDraw
{
add { this.Events.AddHandler(_eventVirtualDraw, value); }
remove { this.Events.RemoveHandler(_eventVirtualDraw, value); }
}
///
/// Occurs when the VirtualMode property value changes
///
[Category("Property Changed")]
public event EventHandler VirtualModeChanged
{
add { this.Events.AddHandler(_eventVirtualModeChanged, value); }
remove { this.Events.RemoveHandler(_eventVirtualModeChanged, value); }
}
///
/// Occurs when the VirtualSize property value changes
///
[Category("Property Changed")]
public event EventHandler VirtualSizeChanged
{
add { this.Events.AddHandler(_eventVirtualSizeChanged, value); }
remove { this.Events.RemoveHandler(_eventVirtualSizeChanged, value); }
}
///
/// Occurs when the Zoom property is changed.
///
[Category("Property Changed")]
public event EventHandler ZoomChanged
{
add { this.Events.AddHandler(_eventZoomChanged, value); }
remove { this.Events.RemoveHandler(_eventZoomChanged, value); }
}
///
/// Occurs when then a zoom action is performed.
///
[Category("Action")]
public event EventHandler Zoomed
{
add { this.Events.AddHandler(_eventZoomed, value); }
remove { this.Events.RemoveHandler(_eventZoomed, value); }
}
///
/// Occurs when the ZoomLevels property is changed
///
[Category("Property Changed")]
public event EventHandler ZoomLevelsChanged
{
add { this.Events.AddHandler(_eventZoomLevelsChanged, value); }
remove { this.Events.RemoveHandler(_eventZoomLevelsChanged, value); }
}
#endregion
#region Static Methods
///
/// Creates a bitmap image containing a 2x2 grid using the specified cell size and colors.
///
/// Size of the cell.
/// Cell color.
/// Alternate cell color.
///
public static Bitmap CreateCheckerBoxTile(int cellSize, Color cellColor, Color alternateCellColor)
{
Bitmap result;
int width;
int height;
// draw the tile
width = cellSize * 2;
height = cellSize * 2;
result = new Bitmap(width, height);
using (Graphics g = Graphics.FromImage(result))
{
using (Brush brush = new SolidBrush(cellColor))
{
g.FillRectangle(brush, new Rectangle(cellSize, 0, cellSize, cellSize));
g.FillRectangle(brush, new Rectangle(0, cellSize, cellSize, cellSize));
}
using (Brush brush = new SolidBrush(alternateCellColor))
{
g.FillRectangle(brush, new Rectangle(0, 0, cellSize, cellSize));
g.FillRectangle(brush, new Rectangle(cellSize, cellSize, cellSize, cellSize));
}
}
return result;
}
///
/// Creates a checked tile texture using default values.
///
///
public static Bitmap CreateCheckerBoxTile()
{
return CreateCheckerBoxTile(8, Color.Gainsboro, Color.WhiteSmoke);
}
private static Cursor GetPanAllCursor()
{
Type type;
type = typeof(ImageBox);
return new Cursor(type.Assembly.GetManifestResourceStream(type.Namespace + ".PanAll.cur"));
}
private static Bitmap GetPanAllSymbol()
{
Type type;
type = typeof(ImageBox);
using (Stream stream = type.Assembly.GetManifestResourceStream(type.Namespace + ".PanAllSymbol.png"))
{
return new Bitmap(stream);
}
}
private static void LoadPanResources()
{
if (_panAllCursor == null)
{
_panAllCursor = GetPanAllCursor();
}
if (_panAllSymbol == null)
{
_panAllSymbol = GetPanAllSymbol();
}
}
#endregion
#region Properties
///
/// Gets or sets a value indicating whether clicking the control with the mouse will automatically zoom in or out.
///
///
/// true if clicking the control allows zooming; otherwise, false.
///
[DefaultValue(false)]
[Category("Behavior")]
public virtual bool AllowClickZoom
{
get { return _allowClickZoom; }
set
{
if (_allowClickZoom != value)
{
_allowClickZoom = value;
this.OnAllowClickZoomChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets a value indicating whether the DoubleClick event can be raised.
///
/// true if the DoubleClick event can be raised; otherwise, false.
[Category("Behavior")]
[DefaultValue(false)]
public virtual bool AllowDoubleClick
{
get { return _allowDoubleClick; }
set
{
if (this.AllowDoubleClick != value)
{
_allowDoubleClick = value;
this.OnAllowDoubleClickChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets a value indicating whether free panning can be used
///
///
/// true if free panning can be used, otherwise false.
///
[Category("Behavior")]
[DefaultValue(true)]
public virtual bool AllowFreePan
{
get { return _allowFreePan; }
set
{
if (_allowFreePan != value)
{
_allowFreePan = value;
this.OnAllowFreePanChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets a value indicating whether the mouse wheel is processed event if the doesn't have focus.
///
///
/// true if the mouse wheel is processed regardless of focus, otherwise false to only process the mouse wheel when the control has focus.
///
/// Setting this problem to true could cause conflicting behavior with other controls that also make use of the mouse wheel.
[Category("Behavior")]
[DefaultValue(false)]
public virtual bool AllowUnfocusedMouseWheel
{
get { return _allowUnfocusedMouseWheel; }
set
{
if (this.AllowUnfocusedMouseWheel != value)
{
_allowUnfocusedMouseWheel = value;
this.OnAllowUnfocusedMouseWheelChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets a value indicating whether the user can change the zoom level.
///
///
/// true if the zoom level can be changed; otherwise, false.
///
[Category("Behavior")]
[DefaultValue(true)]
public virtual bool AllowZoom
{
get { return _allowZoom; }
set
{
if (this.AllowZoom != value)
{
_allowZoom = value;
this.OnAllowZoomChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets a value indicating whether the image is centered where possible.
///
///
/// true if the image should be centered where possible; otherwise, false.
///
[DefaultValue(true)]
[Category("Appearance")]
public virtual bool AutoCenter
{
get { return _autoCenter; }
set
{
if (_autoCenter != value)
{
_autoCenter = value;
this.OnAutoCenterChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets if the mouse can be used to pan the control.
///
///
/// true if the control can be auto panned; otherwise, false.
///
/// If this property is set, the SizeToFit property cannot be used.
[DefaultValue(true)]
[Category("Behavior")]
[Obsolete("Use the PanMode property instead", false)]
//[Browsable(false)]
public virtual bool AutoPan
{
get { return (_panMode & ImageBoxPanMode.Left) != 0; }
set
{
if (this.AutoPan != value)
{
this.PanMode = value ? _panMode & ImageBoxPanMode.Left : _panMode & ~ImageBoxPanMode.Left;
this.OnAutoPanChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets a value indicating whether the container enables the user to scroll to any content placed outside of its visible boundaries.
///
///
/// true if the container enables auto-scrolling; otherwise, false.
///
[DefaultValue(true)]
public override bool AutoScroll
{
get { return base.AutoScroll; }
set { base.AutoScroll = value; }
}
///
/// Gets or sets the minimum size of the auto-scroll.
///
///
///
/// A that determines the minimum size of the virtual area through which the user can scroll.
///
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new Size AutoScrollMinSize
{
get { return base.AutoScrollMinSize; }
set { base.AutoScrollMinSize = value; }
}
///
/// Specifies if the control should auto size to fit the image contents.
///
///
///
/// true if enabled; otherwise, false
///
[Browsable(true)]
[EditorBrowsable(EditorBrowsableState.Always)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[DefaultValue(false)]
public override bool AutoSize
{
get { return base.AutoSize; }
set
{
if (base.AutoSize != value)
{
base.AutoSize = value;
this.AdjustLayout();
}
}
}
///
/// Gets or sets the background color for the control.
///
///
///
/// A that represents the background color of the control. The default is the value of the
///
/// property.
///
[DefaultValue(typeof(Color), "White")]
public override Color BackColor
{
get { return base.BackColor; }
set { base.BackColor = value; }
}
///
/// Gets or sets the background image displayed in the control.
///
///
///
/// An that represents the image to display in the background of the control.
///
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public override Image BackgroundImage
{
get { return base.BackgroundImage; }
set { base.BackgroundImage = value; }
}
///
/// Gets or sets the background image layout as defined in the enumeration.
///
/// The background image layout.
///
/// One of the values of (
///
/// , ,
///
/// , , or
///
/// ). is the default value.
///
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public override ImageLayout BackgroundImageLayout
{
get { return base.BackgroundImageLayout; }
set { base.BackgroundImageLayout = value; }
}
///
/// Gets the point at the center of the currently displayed image viewport.
///
/// The point at the center of the current image viewport.
[Browsable(false)]
public Point CenterPoint
{
get
{
Rectangle viewport;
viewport = this.GetImageViewPort();
return new Point(viewport.Width / 2, viewport.Height / 2);
}
}
///
/// Gets or sets the cursor that is displayed when the mouse pointer is over the control.
///
///
/// A that represents the cursor to display when the
/// mouse pointer is over the control.
///
///
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public override Cursor Cursor
{
get { return base.Cursor; }
set { base.Cursor = value; }
}
///
/// Gets or sets the size of the drop shadow.
///
/// The size of the drop shadow.
[Category("Appearance")]
[DefaultValue(3)]
public virtual int DropShadowSize
{
get { return _dropShadowSize; }
set
{
if (this.DropShadowSize != value)
{
_dropShadowSize = value;
this.OnDropShadowSizeChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets the size of the grid cells.
///
/// The size of the grid cells.
[Category("Appearance")]
[DefaultValue(8)]
public virtual int GridCellSize
{
get { return _gridCellSize; }
set
{
if (_gridCellSize != value)
{
_gridCellSize = value;
this.OnGridCellSizeChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets the color of primary cells in the grid.
///
/// The color of primary cells in the grid.
[Category("Appearance")]
[DefaultValue(typeof(Color), "Gainsboro")]
public virtual Color GridColor
{
get { return _gridColor; }
set
{
if (_gridColor != value)
{
_gridColor = value;
this.OnGridColorChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets the color of alternate cells in the grid.
///
/// The color of alternate cells in the grid.
[Category("Appearance")]
[DefaultValue(typeof(Color), "White")]
public virtual Color GridColorAlternate
{
get { return _gridColorAlternate; }
set
{
if (_gridColorAlternate != value)
{
_gridColorAlternate = value;
this.OnGridColorAlternateChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets the grid display mode.
///
/// The grid display mode.
[DefaultValue(ImageBoxGridDisplayMode.Client)]
[Category("Appearance")]
public virtual ImageBoxGridDisplayMode GridDisplayMode
{
get { return _gridDisplayMode; }
set
{
if (_gridDisplayMode != value)
{
_gridDisplayMode = value;
this.OnGridDisplayModeChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets the grid scale.
///
/// The grid scale.
[DefaultValue(typeof(ImageBoxGridScale), "Small")]
[Category("Appearance")]
public virtual ImageBoxGridScale GridScale
{
get { return _gridScale; }
set
{
if (_gridScale != value)
{
_gridScale = value;
this.OnGridScaleChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets the image.
///
/// The image.
[Category("Appearance")]
[DefaultValue(null)]
public virtual Image Image
{
get { return _image; }
set
{
if (_image != value)
{
// disable animations
if (this.IsAnimating)
{
ImageAnimator.StopAnimate(this.Image, this.OnFrameChangedHandler);
}
_image = value;
this.OnImageChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets the color of the image border.
///
/// The color of the image border.
[Category("Appearance")]
[DefaultValue(typeof(Color), "ControlDark")]
public virtual Color ImageBorderColor
{
get { return _imageBorderColor; }
set
{
if (this.ImageBorderColor != value)
{
_imageBorderColor = value;
this.OnImageBorderColorChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets the image border style.
///
/// The image border style.
[Category("Appearance")]
[DefaultValue(typeof(ImageBoxBorderStyle), "None")]
public virtual ImageBoxBorderStyle ImageBorderStyle
{
get { return _imageBorderStyle; }
set
{
if (this.ImageBorderStyle != value)
{
_imageBorderStyle = value;
this.OnImageBorderStyleChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets the interpolation mode.
///
/// The interpolation mode.
[Category("Appearance")]
[DefaultValue(InterpolationMode.NearestNeighbor)]
public virtual InterpolationMode InterpolationMode
{
get { return _interpolationMode; }
set
{
if (value == InterpolationMode.Invalid)
{
value = InterpolationMode.Default;
}
if (_interpolationMode != value)
{
_interpolationMode = value;
this.OnInterpolationModeChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets a value indicating whether the mouse should be inverted when panning the control.
///
///
/// true if the mouse should be inverted when panning the control; otherwise, false.
///
[DefaultValue(false)]
[Category("Behavior")]
public virtual bool InvertMouse
{
get { return _invertMouse; }
set
{
if (_invertMouse != value)
{
_invertMouse = value;
this.OnInvertMouseChanged(EventArgs.Empty);
}
}
}
///
/// Gets a value indicating whether the image is currently being displayed at 100% zoom
///
/// true if the image is currently being displayed at 100% zoom; otherwise, false.
[Browsable(false)]
public virtual bool IsActualSize
{
get { return this.Zoom == 100; }
}
///
/// Gets a value indicating whether this control is panning.
///
///
/// true if this control is panning; otherwise, false.
///
[DefaultValue(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Browsable(false)]
public virtual bool IsPanning
{
get { return _panStyle != ImageBoxPanStyle.None; }
protected set { this.ProcessPanEvents(value ? ImageBoxPanStyle.Standard : ImageBoxPanStyle.None); }
}
///
/// Gets or sets a value indicating whether this a selection region is currently being drawn.
///
///
/// true if a selection region is currently being drawn; otherwise, false.
///
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public virtual bool IsSelecting
{
get
{
return _isSelecting;
}
protected set
{
_isSelecting = value;
}
}
///
/// Gets or sets a value indicating whether selection regions should be limited to the image boundaries.
///
///
/// true if selection regions should be limited to image boundaries; otherwise, false.
///
[Category("Behavior")]
[DefaultValue(true)]
public virtual bool LimitSelectionToImage
{
get { return _limitSelectionToImage; }
set
{
if (this.LimitSelectionToImage != value)
{
_limitSelectionToImage = value;
this.OnLimitSelectionToImageChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets the how the mouse wheel is handled
///
///
/// The mouse wheel mode.
///
[Category("Behavior")]
[DefaultValue(typeof(ImageBoxMouseWheelMode), "Zoom")]
public virtual ImageBoxMouseWheelMode MouseWheelMode
{
get { return _mouseWheelMode; }
set
{
if (_mouseWheelMode != value)
{
_mouseWheelMode = value;
this.OnMouseWheelModeChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets the how panning is initiated using the mouse
///
///
/// The pan mode.
///
[Category("Behavior")]
[DefaultValue(typeof(ImageBoxPanMode), "Both")]
public virtual ImageBoxPanMode PanMode
{
get { return _panMode; }
set
{
if (_panMode != value)
{
_panMode = value;
this.OnPanModeChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets the color of the pixel grid.
///
/// The color of the pixel grid.
[Category("Appearance")]
[DefaultValue(typeof(Color), "DimGray")]
public virtual Color PixelGridColor
{
get { return _pixelGridColor; }
set
{
if (this.PixelGridColor != value)
{
_pixelGridColor = value;
this.OnPixelGridColorChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets the minimum size of zoomed pixel's before the pixel grid will be drawn
///
/// The pixel grid threshold.
[Category("Behavior")]
[DefaultValue(5)]
public virtual int PixelGridThreshold
{
get { return _pixelGridThreshold; }
set
{
if (this.PixelGridThreshold != value)
{
_pixelGridThreshold = value;
this.OnPixelGridThresholdChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets a value indicating whether the font size of text is scaled according to the current zoom level.
///
/// true if the size of text is scaled according to the current zoom level; otherwise, false.
[Category("Appearance")]
[DefaultValue(false)]
public virtual bool ScaleText
{
get { return _scaleText; }
set
{
if (this.ScaleText != value)
{
_scaleText = value;
this.OnScaleTextChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets the color of selection regions.
///
///
/// The color of selection regions.
///
[Category("Appearance")]
[DefaultValue(typeof(Color), "Highlight")]
public virtual Color SelectionColor
{
get { return _selectionColor; }
set
{
if (this.SelectionColor != value)
{
_selectionColor = value;
this.OnSelectionColorChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets the selection mode.
///
///
/// The selection mode.
///
[Category("Behavior")]
[DefaultValue(typeof(ImageBoxSelectionMode), "None")]
public virtual ImageBoxSelectionMode SelectionMode
{
get { return _selectionMode; }
set
{
if (this.SelectionMode != value)
{
_selectionMode = value;
this.OnSelectionModeChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets the selection region.
///
///
/// The selection region.
///
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public virtual RectangleF SelectionRegion
{
get { return _selectionRegion; }
set
{
if (this.SelectionRegion != value)
{
_selectionRegion = value;
this.OnSelectionRegionChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets a value indicating whether the defined shortcuts are enabled.
///
///
/// true to enable the shortcuts; otherwise, false.
///
[Category("Behavior")]
[DefaultValue(true)]
public virtual bool ShortcutsEnabled
{
get { return _shortcutsEnabled; }
set
{
if (this.ShortcutsEnabled != value)
{
_shortcutsEnabled = value;
this.OnShortcutsEnabledChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets a value indicating whether a pixel grid is displayed when the control is zoomed.
///
/// true if a pixel grid is displayed when the control is zoomed; otherwise, false.
[Category("Appearance")]
[DefaultValue(false)]
public virtual bool ShowPixelGrid
{
get { return _showPixelGrid; }
set
{
if (this.ShowPixelGrid != value)
{
_showPixelGrid = value;
this.OnShowPixelGridChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets the size mode of images hosted in the control.
///
/// The size mode.
[Category("Behavior")]
[DefaultValue(typeof(ImageBoxSizeMode), "Normal")]
public virtual ImageBoxSizeMode SizeMode
{
get { return _sizeMode; }
set
{
if (this.SizeMode != value)
{
_sizeMode = value;
this.OnSizeModeChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets a value indicating whether the control should automatically size to fit the image contents.
///
///
/// true if the control should size to fit the image contents; otherwise, false.
///
[DefaultValue(false)]
[Category("Appearance")]
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Obsolete("This property is deprecated and will be removed in a future version of the component. Implementors should use the SizeMode property instead.")]
public virtual bool SizeToFit
{
get { return this.SizeMode == ImageBoxSizeMode.Fit; }
set
{
if (this.SizeMode == ImageBoxSizeMode.Fit != value)
{
this.SizeMode = value ? ImageBoxSizeMode.Fit : ImageBoxSizeMode.Normal;
this.OnSizeToFitChanged(EventArgs.Empty);
if (value)
{
this.AutoPan = false;
}
else
{
this.ActualSize();
}
}
}
}
///
/// Gets or sets the alignment of the text on the control.
///
/// One of the values. The default is MiddleCenter.
[Category("Appearance")]
[DefaultValue(typeof(ContentAlignment), "MiddleCenter")]
public virtual ContentAlignment TextAlign
{
get { return _textAlign; }
set
{
if (this.TextAlign != value)
{
_textAlign = value;
this.OnTextAlignChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets the color of the text background.
///
/// The color of the text background.
[Category("Appearance")]
[DefaultValue(typeof(Color), "Transparent")]
public virtual Color TextBackColor
{
get { return _textBackColor; }
set
{
if (this.TextBackColor != value)
{
_textBackColor = value;
this.OnTextBackColorChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets the text display mode.
///
/// The text display mode.
[Category("Appearance")]
[DefaultValue(typeof(ImageBoxGridDisplayMode), "Client")]
public virtual ImageBoxGridDisplayMode TextDisplayMode
{
get { return _textDisplayMode; }
set
{
if (this.TextDisplayMode != value)
{
_textDisplayMode = value;
this.OnTextDisplayModeChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets the text padding.
///
///
/// The text padding.
///
[Category("Appearance")]
[DefaultValue(typeof(Padding), "0, 0, 0, 0")]
public virtual Padding TextPadding
{
get { return _textPadding; }
set
{
if (this.TextPadding != value)
{
_textPadding = value;
this.OnTextPaddingChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets a value indicating whether the control acts as a virtual image box.
///
///
/// true if the control acts as a virtual image box; otherwise, false.
///
///
/// When this property is set to true, the Image property is ignored in favor of the VirtualSize property. In addition, the VirtualDraw event is raised to allow custom painting of the image area.
///
[Category("Behavior")]
[DefaultValue(false)]
public virtual bool VirtualMode
{
get { return _virtualMode; }
set
{
if (this.VirtualMode != value)
{
_virtualMode = value;
this.OnVirtualModeChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets the size of the virtual image.
///
/// The size of the virtual image.
[Category("Appearance")]
[DefaultValue(typeof(Size), "0, 0")]
public virtual Size VirtualSize
{
get { return _virtualSize; }
set
{
if (this.VirtualSize != value)
{
_virtualSize = value;
this.OnVirtualSizeChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets the zoom.
///
/// The zoom.
[DefaultValue(100)]
[Category("Appearance")]
public virtual int Zoom
{
get { return _zoom; }
set { this.SetZoom(value, value > this.Zoom ? ImageBoxZoomActions.ZoomIn : ImageBoxZoomActions.ZoomOut, ImageBoxActionSources.Unknown); }
}
///
/// Gets the zoom factor.
///
/// The zoom factor.
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public virtual double ZoomFactor
{
get { return (double)this.Zoom / 100; }
}
///
/// Gets or sets the zoom levels.
///
/// The zoom levels.
[Browsable(false) /*Category("Behavior"), DefaultValue(typeof(ZoomLevelCollection), "7, 10, 15, 20, 25, 30, 50, 70, 100, 150, 200, 300, 400, 500, 600, 700, 800, 1200, 1600")*/]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public virtual ZoomLevelCollection ZoomLevels
{
get { return _zoomLevels; }
set
{
if (this.ZoomLevels != value)
{
_zoomLevels = value;
this.OnZoomLevelsChanged(EventArgs.Empty);
}
}
}
///
/// Gets a value indicating whether painting of the control is allowed.
///
///
/// true if painting of the control is allowed; otherwise, false.
///
protected virtual bool AllowPainting
{
get { return _updateCount == 0; }
}
///
/// Gets or sets a value indicating whether the current image is animated.
///
/// true if the current image is animated; otherwise, false.
protected bool IsAnimating { get; set; }
///
/// Gets the height of the scaled image.
///
/// The height of the scaled image.
protected virtual int ScaledImageHeight
{
get { return Convert.ToInt32(this.ViewSize.Height * this.ZoomFactor); }
}
///
/// Gets the width of the scaled image.
///
/// The width of the scaled image.
protected virtual int ScaledImageWidth
{
get { return Convert.ToInt32(this.ViewSize.Width * this.ZoomFactor); }
}
///
/// Gets the size of the view.
///
/// The size of the view.
protected virtual Size ViewSize
{
get { return this.VirtualMode ? this.VirtualSize : this.GetImageSize(); }
}
///
/// Gets or sets a value indicating whether a drag operation was cancelled.
///
/// true if the drag operation was cancelled; otherwise, false.
protected bool WasDragCancelled { get; set; }
#endregion
#region Methods
///
/// Resets the zoom to 100%.
///
public virtual void ActualSize()
{
this.PerformActualSize(ImageBoxActionSources.Unknown);
}
///
/// Disables any redrawing of the image box
///
public virtual void BeginUpdate()
{
_updateCount++;
}
///
/// Centers the given point in the image in the center of the control
///
/// The point of the image to attempt to center.
public virtual void CenterAt(Point imageLocation)
{
this.ScrollTo(imageLocation, new Point(this.ClientSize.Width / 2, this.ClientSize.Height / 2));
}
///
/// Centers the given point in the image in the center of the control
///
/// The X co-ordinate of the point to center.
/// The Y co-ordinate of the point to center.
public void CenterAt(int x, int y)
{
this.CenterAt(new Point(x, y));
}
///
/// Centers the given point in the image in the center of the control
///
/// The X co-ordinate of the point to center.
/// The Y co-ordinate of the point to center.
public void CenterAt(float x, float y)
{
this.CenterAt(new Point((int)x, (int)y));
}
///
/// Resets the viewport to show the center of the image.
///
public virtual void CenterToImage()
{
this.AutoScrollPosition = new Point((this.AutoScrollMinSize.Width - this.ClientSize.Width) / 2, (this.AutoScrollMinSize.Height - this.ClientSize.Height) / 2);
}
///
/// Enables the redrawing of the image box
///
public virtual void EndUpdate()
{
if (_updateCount > 0)
{
_updateCount--;
}
if (this.AllowPainting)
{
this.Invalidate();
}
}
///
/// Fits a given to match image boundaries
///
/// The rectangle.
///
/// A structure remapped to fit the image boundaries
///
public Rectangle FitRectangle(Rectangle rectangle)
{
int x;
int y;
int w;
int h;
x = rectangle.X;
y = rectangle.Y;
w = rectangle.Width;
h = rectangle.Height;
if (x < 0)
{
x = 0;
}
if (y < 0)
{
y = 0;
}
if (x + w > this.ViewSize.Width)
{
w = this.ViewSize.Width - x;
}
if (y + h > this.ViewSize.Height)
{
h = this.ViewSize.Height - y;
}
return new Rectangle(x, y, w, h);
}
///
/// Fits a given to match image boundaries
///
/// The rectangle.
///
/// A structure remapped to fit the image boundaries
///
public RectangleF FitRectangle(RectangleF rectangle)
{
float x;
float y;
float w;
float h;
x = rectangle.X;
y = rectangle.Y;
w = rectangle.Width;
h = rectangle.Height;
if (x < 0)
{
w -= -x;
x = 0;
}
if (y < 0)
{
h -= -y;
y = 0;
}
if (x + w > this.ViewSize.Width)
{
w = this.ViewSize.Width - x;
}
if (y + h > this.ViewSize.Height)
{
h = this.ViewSize.Height - y;
}
return new RectangleF(x, y, w, h);
}
///
/// Gets the image view port.
///
///
public virtual Rectangle GetImageViewPort()
{
Rectangle viewPort;
if (!this.ViewSize.IsEmpty)
{
Rectangle innerRectangle;
Point offset;
int width;
int height;
innerRectangle = this.GetInsideViewPort(true);
if (!this.HScroll && !this.VScroll) // if no scrolling is present, tinker the view port so that the image and any applicable borders all fit inside
{
innerRectangle.Inflate(-this.GetImageBorderOffset(), -this.GetImageBorderOffset());
}
if (this.SizeMode != ImageBoxSizeMode.Stretch)
{
if (this.AutoCenter)
{
int x;
int y;
x = !this.HScroll ? (innerRectangle.Width - (this.ScaledImageWidth + this.Padding.Horizontal)) / 2 : 0;
y = !this.VScroll ? (innerRectangle.Height - (this.ScaledImageHeight + this.Padding.Vertical)) / 2 : 0;
offset = new Point(x, y);
}
else
{
offset = Point.Empty;
}
width = Math.Min(this.ScaledImageWidth - Math.Abs(this.AutoScrollPosition.X), innerRectangle.Width);
height = Math.Min(this.ScaledImageHeight - Math.Abs(this.AutoScrollPosition.Y), innerRectangle.Height);
}
else
{
offset = Point.Empty;
width = innerRectangle.Width;
height = innerRectangle.Height;
}
viewPort = new Rectangle(offset.X + innerRectangle.Left, offset.Y + innerRectangle.Top, width, height);
}
else
{
viewPort = Rectangle.Empty;
}
return viewPort;
}
///
/// Gets the inside view port, excluding any padding.
///
///
public Rectangle GetInsideViewPort()
{
return this.GetInsideViewPort(false);
}
///
/// Gets the inside view port.
///
///
/// if set to true [include padding].
///
///
public virtual Rectangle GetInsideViewPort(bool includePadding)
{
int left;
int top;
int width;
int height;
left = 0;
top = 0;
width = this.ClientSize.Width;
height = this.ClientSize.Height;
if (includePadding)
{
left += this.Padding.Left;
top += this.Padding.Top;
width -= this.Padding.Horizontal;
height -= this.Padding.Vertical;
}
return new Rectangle(left, top, width, height);
}
///
/// Returns the source repositioned to include the current image offset and scaled by the current zoom level
///
/// The source to offset.
/// A which has been repositioned to match the current zoom level and image offset
public virtual Point GetOffsetPoint(Point source)
{
PointF offset;
offset = this.GetOffsetPoint(new PointF(source.X, source.Y));
return new Point((int)offset.X, (int)offset.Y);
}
///
/// Returns the source co-ordinates repositioned to include the current image offset and scaled by the current zoom level
///
/// The source X co-ordinate.
/// The source Y co-ordinate.
/// A which has been repositioned to match the current zoom level and image offset
public Point GetOffsetPoint(int x, int y)
{
return this.GetOffsetPoint(new Point(x, y));
}
///
/// Returns the source co-ordinates repositioned to include the current image offset and scaled by the current zoom level
///
/// The source X co-ordinate.
/// The source Y co-ordinate.
/// A which has been repositioned to match the current zoom level and image offset
public PointF GetOffsetPoint(float x, float y)
{
return this.GetOffsetPoint(new PointF(x, y));
}
///
/// Returns the source repositioned to include the current image offset and scaled by the current zoom level
///
/// The source to offset.
/// A which has been repositioned to match the current zoom level and image offset
public virtual PointF GetOffsetPoint(PointF source)
{
Rectangle viewport;
PointF scaled;
int offsetX;
int offsetY;
viewport = this.GetImageViewPort();
scaled = this.GetScaledPoint(source);
offsetX = viewport.Left + this.Padding.Left + this.AutoScrollPosition.X;
offsetY = viewport.Top + this.Padding.Top + this.AutoScrollPosition.Y;
return new PointF(scaled.X + offsetX, scaled.Y + offsetY);
}
///
/// Returns the source scaled according to the current zoom level and repositioned to include the current image offset
///
/// The source to offset.
/// A which has been resized and repositioned to match the current zoom level and image offset
public virtual RectangleF GetOffsetRectangle(RectangleF source)
{
RectangleF viewport;
RectangleF scaled;
float offsetX;
float offsetY;
viewport = this.GetImageViewPort();
scaled = this.GetScaledRectangle(source);
offsetX = viewport.Left + this.Padding.Left + this.AutoScrollPosition.X;
offsetY = viewport.Top + this.Padding.Top + this.AutoScrollPosition.Y;
return new RectangleF(new PointF(scaled.Left + offsetX, scaled.Top + offsetY), scaled.Size);
}
///
/// Returns the source rectangle scaled according to the current zoom level and repositioned to include the current image offset
///
/// The X co-ordinate of the source rectangle.
/// The Y co-ordinate of the source rectangle.
/// The width of the rectangle.
/// The height of the rectangle.
/// A which has been resized and repositioned to match the current zoom level and image offset
public Rectangle GetOffsetRectangle(int x, int y, int width, int height)
{
return this.GetOffsetRectangle(new Rectangle(x, y, width, height));
}
///
/// Returns the source rectangle scaled according to the current zoom level and repositioned to include the current image offset
///
/// The X co-ordinate of the source rectangle.
/// The Y co-ordinate of the source rectangle.
/// The width of the rectangle.
/// The height of the rectangle.
/// A which has been resized and repositioned to match the current zoom level and image offset
public RectangleF GetOffsetRectangle(float x, float y, float width, float height)
{
return this.GetOffsetRectangle(new RectangleF(x, y, width, height));
}
///
/// Returns the source scaled according to the current zoom level and repositioned to include the current image offset
///
/// The source to offset.
/// A which has been resized and repositioned to match the current zoom level and image offset
public virtual Rectangle GetOffsetRectangle(Rectangle source)
{
Rectangle viewport;
Rectangle scaled;
int offsetX;
int offsetY;
viewport = this.GetImageViewPort();
scaled = this.GetScaledRectangle(source);
offsetX = viewport.Left + this.Padding.Left + this.AutoScrollPosition.X;
offsetY = viewport.Top + this.Padding.Top + this.AutoScrollPosition.Y;
return new Rectangle(new Point(scaled.Left + offsetX, scaled.Top + offsetY), scaled.Size);
}
///
/// Retrieves the size of a rectangular area into which a control can be fitted.
///
/// The custom-sized area for a control.
///
/// An ordered pair of type representing the width and height of a rectangle.
///
public override Size GetPreferredSize(Size proposedSize)
{
Size size;
if (!this.ViewSize.IsEmpty)
{
int width;
int height;
// get the size of the image
width = this.ScaledImageWidth;
height = this.ScaledImageHeight;
// add an offset based on padding
width += this.Padding.Horizontal;
height += this.Padding.Vertical;
// add an offset based on the border style
width += this.GetImageBorderOffset();
height += this.GetImageBorderOffset();
size = new Size(width, height);
}
else
{
size = base.GetPreferredSize(proposedSize);
}
return size;
}
///
/// Returns the source scaled according to the current zoom level
///
/// The X co-ordinate of the point to scale.
/// The Y co-ordinate of the point to scale.
/// A which has been scaled to match the current zoom level
public Point GetScaledPoint(int x, int y)
{
return this.GetScaledPoint(new Point(x, y));
}
///
/// Returns the source scaled according to the current zoom level
///
/// The X co-ordinate of the point to scale.
/// The Y co-ordinate of the point to scale.
/// A which has been scaled to match the current zoom level
public PointF GetScaledPoint(float x, float y)
{
return this.GetScaledPoint(new PointF(x, y));
}
///
/// Returns the source scaled according to the current zoom level
///
/// The source to scale.
/// A which has been scaled to match the current zoom level
public virtual Point GetScaledPoint(Point source)
{
return new Point((int)(source.X * this.ZoomFactor), (int)(source.Y * this.ZoomFactor));
}
///
/// Returns the source scaled according to the current zoom level
///
/// The source to scale.
/// A which has been scaled to match the current zoom level
public virtual PointF GetScaledPoint(PointF source)
{
return new PointF((float)(source.X * this.ZoomFactor), (float)(source.Y * this.ZoomFactor));
}
///
/// Returns the source rectangle scaled according to the current zoom level
///
/// The X co-ordinate of the source rectangle.
/// The Y co-ordinate of the source rectangle.
/// The width of the rectangle.
/// The height of the rectangle.
/// A which has been scaled to match the current zoom level
public Rectangle GetScaledRectangle(int x, int y, int width, int height)
{
return this.GetScaledRectangle(new Rectangle(x, y, width, height));
}
///
/// Returns the source rectangle scaled according to the current zoom level
///
/// The X co-ordinate of the source rectangle.
/// The Y co-ordinate of the source rectangle.
/// The width of the rectangle.
/// The height of the rectangle.
/// A which has been scaled to match the current zoom level
public RectangleF GetScaledRectangle(float x, float y, float width, float height)
{
return this.GetScaledRectangle(new RectangleF(x, y, width, height));
}
///
/// Returns the source rectangle scaled according to the current zoom level
///
/// The location of the source rectangle.
/// The size of the source rectangle.
/// A which has been scaled to match the current zoom level
public Rectangle GetScaledRectangle(Point location, Size size)
{
return this.GetScaledRectangle(new Rectangle(location, size));
}
///
/// Returns the source rectangle scaled according to the current zoom level
///
/// The location of the source rectangle.
/// The size of the source rectangle.
/// A which has been scaled to match the current zoom level
public RectangleF GetScaledRectangle(PointF location, SizeF size)
{
return this.GetScaledRectangle(new RectangleF(location, size));
}
///
/// Returns the source scaled according to the current zoom level
///
/// The source to scale.
/// A which has been scaled to match the current zoom level
public virtual Rectangle GetScaledRectangle(Rectangle source)
{
return new Rectangle((int)(source.Left * this.ZoomFactor), (int)(source.Top * this.ZoomFactor), (int)(source.Width * this.ZoomFactor), (int)(source.Height * this.ZoomFactor));
}
///
/// Returns the source scaled according to the current zoom level
///
/// The source to scale.
/// A which has been scaled to match the current zoom level
public virtual RectangleF GetScaledRectangle(RectangleF source)
{
return new RectangleF((float)(source.Left * this.ZoomFactor), (float)(source.Top * this.ZoomFactor), (float)(source.Width * this.ZoomFactor), (float)(source.Height * this.ZoomFactor));
}
///
/// Returns the source size scaled according to the current zoom level
///
/// The width of the size to scale.
/// The height of the size to scale.
/// A which has been resized to match the current zoom level
public SizeF GetScaledSize(float width, float height)
{
return this.GetScaledSize(new SizeF(width, height));
}
///
/// Returns the source size scaled according to the current zoom level
///
/// The width of the size to scale.
/// The height of the size to scale.
/// A which has been resized to match the current zoom level
public Size GetScaledSize(int width, int height)
{
return this.GetScaledSize(new Size(width, height));
}
///
/// Returns the source scaled according to the current zoom level
///
/// The source to scale.
/// A which has been resized to match the current zoom level
public virtual SizeF GetScaledSize(SizeF source)
{
return new SizeF((float)(source.Width * this.ZoomFactor), (float)(source.Height * this.ZoomFactor));
}
///
/// Returns the source scaled according to the current zoom level
///
/// The source to scale.
/// A which has been resized to match the current zoom level
public virtual Size GetScaledSize(Size source)
{
return new Size((int)(source.Width * this.ZoomFactor), (int)(source.Height * this.ZoomFactor));
}
///
/// Creates an image based on the current selection region
///
/// An image containing the selection contents if a selection if present, otherwise null
/// The caller is responsible for disposing of the returned image
public Image GetSelectedImage()
{
Image result;
result = null;
if (!this.SelectionRegion.IsEmpty)
{
Rectangle rect;
rect = this.FitRectangle(new Rectangle((int)this.SelectionRegion.X, (int)this.SelectionRegion.Y, (int)this.SelectionRegion.Width, (int)this.SelectionRegion.Height));
if (rect.Width > 0 && rect.Height > 0)
{
result = new Bitmap(rect.Width, rect.Height);
using (Graphics g = Graphics.FromImage(result))
{
g.DrawImage(this.Image, new Rectangle(Point.Empty, rect.Size), rect, GraphicsUnit.Pixel);
}
}
}
return result;
}
///
/// Gets the source image region.
///
///
public virtual RectangleF GetSourceImageRegion()
{
RectangleF region;
if (!this.ViewSize.IsEmpty)
{
if (this.SizeMode != ImageBoxSizeMode.Stretch)
{
float sourceLeft;
float sourceTop;
float sourceWidth;
float sourceHeight;
Rectangle viewPort;
viewPort = this.GetImageViewPort();
sourceLeft = (float)(-this.AutoScrollPosition.X / this.ZoomFactor);
sourceTop = (float)(-this.AutoScrollPosition.Y / this.ZoomFactor);
sourceWidth = (float)(viewPort.Width / this.ZoomFactor);
sourceHeight = (float)(viewPort.Height / this.ZoomFactor);
region = new RectangleF(sourceLeft, sourceTop, sourceWidth, sourceHeight);
}
else
{
region = new RectangleF(PointF.Empty, this.ViewSize);
}
}
else
{
region = RectangleF.Empty;
}
return region;
}
///
/// Determines whether the specified point is located within the image view port
///
/// The point.
///
/// true if the specified point is located within the image view port; otherwise, false.
///
public virtual bool IsPointInImage(Point point)
{
return this.GetImageViewPort().
Contains(point);
}
///
/// Determines whether the specified point is located within the image view port
///
/// The X co-ordinate of the point to check.
/// The Y co-ordinate of the point to check.
///
/// true if the specified point is located within the image view port; otherwise, false.
///
public bool IsPointInImage(int x, int y)
{
return this.IsPointInImage(new Point(x, y));
}
///
/// Determines whether the specified point is located within the image view port
///
/// The X co-ordinate of the point to check.
/// The Y co-ordinate of the point to check.
///
/// true if the specified point is located within the image view port; otherwise, false.
///
public bool IsPointInImage(float x, float y)
{
return this.IsPointInImage(new Point((int)x, (int)y));
}
///
/// Converts the given client size point to represent a coordinate on the source image.
///
/// The source point.
/// Point.Empty if the point could not be matched to the source image, otherwise the new translated point
public Point PointToImage(Point point)
{
return this.PointToImage(point, false);
}
///
/// Converts the given client size point to represent a coordinate on the source image.
///
/// The X co-ordinate of the point to convert.
/// The Y co-ordinate of the point to convert.
/// Point.Empty if the point could not be matched to the source image, otherwise the new translated point
public Point PointToImage(float x, float y)
{
return this.PointToImage(x, y, false);
}
///
/// Converts the given client size point to represent a coordinate on the source image.
///
/// The X co-ordinate of the point to convert.
/// The Y co-ordinate of the point to convert.
///
/// if set to true and the point is outside the bounds of the source image, it will be mapped to the nearest edge.
///
/// Point.Empty if the point could not be matched to the source image, otherwise the new translated point
public Point PointToImage(float x, float y, bool fitToBounds)
{
return this.PointToImage(new Point((int)x, (int)y), fitToBounds);
}
///
/// Converts the given client size point to represent a coordinate on the source image.
///
/// The X co-ordinate of the point to convert.
/// The Y co-ordinate of the point to convert.
/// Point.Empty if the point could not be matched to the source image, otherwise the new translated point
public Point PointToImage(int x, int y)
{
return this.PointToImage(x, y, false);
}
///
/// Converts the given client size point to represent a coordinate on the source image.
///
/// The X co-ordinate of the point to convert.
/// The Y co-ordinate of the point to convert.
///
/// if set to true and the point is outside the bounds of the source image, it will be mapped to the nearest edge.
///
/// Point.Empty if the point could not be matched to the source image, otherwise the new translated point
public Point PointToImage(int x, int y, bool fitToBounds)
{
return this.PointToImage(new Point(x, y), fitToBounds);
}
///
/// Converts the given client size point to represent a coordinate on the source image.
///
/// The source point.
///
/// if set to true and the point is outside the bounds of the source image, it will be mapped to the nearest edge.
///
/// Point.Empty if the point could not be matched to the source image, otherwise the new translated point
public virtual Point PointToImage(Point point, bool fitToBounds)
{
Rectangle viewport;
int x;
int y;
viewport = this.GetImageViewPort();
if (!fitToBounds || viewport.Contains(point))
{
if (this.AutoScrollPosition != Point.Empty)
{
point = new Point(point.X - this.AutoScrollPosition.X, point.Y - this.AutoScrollPosition.Y);
}
x = (int)((point.X - viewport.X) / this.ZoomFactor);
y = (int)((point.Y - viewport.Y) / this.ZoomFactor);
if (fitToBounds)
{
if (x < 0)
{
x = 0;
}
else if (x > this.ViewSize.Width)
{
x = this.ViewSize.Width;
}
if (y < 0)
{
y = 0;
}
else if (y > this.ViewSize.Height)
{
y = this.ViewSize.Height;
}
}
}
else
{
x = 0; // Return Point.Empty if we couldn't match
y = 0;
}
return new Point(x, y);
}
///
/// Scrolls the control to the given point in the image, offset at the specified display point
///
/// The X co-ordinate of the point to scroll to.
/// The Y co-ordinate of the point to scroll to.
/// The X co-ordinate relative to the x parameter.
/// The Y co-ordinate relative to the y parameter.
public void ScrollTo(int x, int y, int relativeX, int relativeY)
{
this.ScrollTo(new Point(x, y), new Point(relativeX, relativeY));
}
///
/// Scrolls the control to the given point in the image, offset at the specified display point
///
/// The X co-ordinate of the point to scroll to.
/// The Y co-ordinate of the point to scroll to.
/// The X co-ordinate relative to the x parameter.
/// The Y co-ordinate relative to the y parameter.
public void ScrollTo(float x, float y, float relativeX, float relativeY)
{
this.ScrollTo(new Point((int)x, (int)y), new Point((int)relativeX, (int)relativeY));
}
///
/// Scrolls the control to the given point in the image, offset at the specified display point
///
/// The point of the image to attempt to scroll to.
/// The relative display point to offset scrolling by.
public virtual void ScrollTo(Point imageLocation, Point relativeDisplayPoint)
{
int x;
int y;
x = (int)(imageLocation.X * this.ZoomFactor) - relativeDisplayPoint.X;
y = (int)(imageLocation.Y * this.ZoomFactor) - relativeDisplayPoint.Y;
this.AutoScrollPosition = new Point(x, y);
}
///
/// Creates a selection region which encompasses the entire image
///
/// Thrown if no image is currently set
public virtual void SelectAll()
{
this.SelectionRegion = new RectangleF(PointF.Empty, this.ViewSize);
}
///
/// Clears any existing selection region
///
public virtual void SelectNone()
{
this.SelectionRegion = RectangleF.Empty;
}
///
/// Zooms into the image
///
public virtual void ZoomIn()
{
this.ZoomIn(true);
}
///
/// Zooms into the image
///
/// true if the current scrolling position should be preserved relative to the new zoom level, false to reset.
public virtual void ZoomIn(bool preservePosition)
{
this.PerformZoomIn(ImageBoxActionSources.Unknown, preservePosition);
}
///
/// Zooms out of the image
///
public virtual void ZoomOut()
{
this.ZoomOut(true);
}
///
/// Zooms out of the image
///
/// true if the current scrolling position should be preserved relative to the new zoom level, false to reset.
public virtual void ZoomOut(bool preservePosition)
{
this.PerformZoomOut(ImageBoxActionSources.Unknown, preservePosition);
}
///
/// Zooms to the maximum size for displaying the entire image within the bounds of the control.
///
public virtual void ZoomToFit()
{
if (!this.ViewSize.IsEmpty)
{
Rectangle innerRectangle;
double zoom;
double aspectRatio;
this.AutoScrollMinSize = Size.Empty;
innerRectangle = this.GetInsideViewPort(true);
if (this.ViewSize.Width > this.ViewSize.Height)
{
aspectRatio = (double)innerRectangle.Width / this.ViewSize.Width;
zoom = aspectRatio * 100.0;
if (innerRectangle.Height < this.ViewSize.Height * zoom / 100.0)
{
aspectRatio = (double)innerRectangle.Height / this.ViewSize.Height;
zoom = aspectRatio * 100.0;
}
}
else
{
aspectRatio = (double)innerRectangle.Height / this.ViewSize.Height;
zoom = aspectRatio * 100.0;
if (innerRectangle.Width < this.ViewSize.Width * zoom / 100.0)
{
aspectRatio = (double)innerRectangle.Width / this.ViewSize.Width;
zoom = aspectRatio * 100.0;
}
}
this.Zoom = (int)Math.Round(Math.Floor(zoom));
}
}
///
/// Adjusts the view port to fit the given region
///
/// The X co-ordinate of the selection region.
/// The Y co-ordinate of the selection region.
/// The width of the selection region.
/// The height of the selection region.
public void ZoomToRegion(float x, float y, float width, float height)
{
this.ZoomToRegion(new RectangleF(x, y, width, height));
}
///
/// Adjusts the view port to fit the given region
///
/// The X co-ordinate of the selection region.
/// The Y co-ordinate of the selection region.
/// The width of the selection region.
/// The height of the selection region.
public void ZoomToRegion(int x, int y, int width, int height)
{
this.ZoomToRegion(new RectangleF(x, y, width, height));
}
///
/// Adjusts the view port to fit the given region
///
/// The rectangle to fit the view port to.
public virtual void ZoomToRegion(RectangleF rectangle)
{
double ratioX;
double ratioY;
double zoomFactor;
int cx;
int cy;
ratioX = this.ClientSize.Width / rectangle.Width;
ratioY = this.ClientSize.Height / rectangle.Height;
zoomFactor = Math.Min(ratioX, ratioY);
cx = (int)(rectangle.X + rectangle.Width / 2);
cy = (int)(rectangle.Y + rectangle.Height / 2);
this.Zoom = (int)(zoomFactor * 100);
this.CenterAt(new Point(cx, cy));
}
///
/// Adjusts the layout.
///
protected virtual void AdjustLayout()
{
if (this.AllowPainting)
{
if (this.AutoSize)
{
this.AdjustSize();
}
else if (this.SizeMode != ImageBoxSizeMode.Normal)
{
this.ZoomToFit();
}
else if (this.AutoScroll)
{
this.AdjustViewPort();
}
this.Invalidate();
}
}
///
/// Adjusts the scroll.
///
/// The x.
/// The y.
protected virtual void AdjustScroll(int x, int y)
{
Point scrollPosition;
scrollPosition = new Point(this.HorizontalScroll.Value + x, this.VerticalScroll.Value + y);
this.UpdateScrollPosition(scrollPosition);
}
///
/// Adjusts the size.
///
protected virtual void AdjustSize()
{
if (this.AutoSize && this.Dock == DockStyle.None)
{
this.Size = this.PreferredSize;
}
}
///
/// Adjusts the view port.
///
protected virtual void AdjustViewPort()
{
if (this.AutoScroll && !this.ViewSize.IsEmpty)
{
this.AutoScrollMinSize = new Size(this.ScaledImageWidth + this.Padding.Horizontal, this.ScaledImageHeight + this.Padding.Vertical);
}
}
///
/// Creates the grid tile image.
///
/// Size of the cell.
/// The first color.
/// Color of the second.
///
protected virtual Bitmap CreateGridTileImage(int cellSize, Color firstColor, Color secondColor)
{
float scale;
// rescale the cell size
switch (this.GridScale)
{
case ImageBoxGridScale.Medium:
scale = 1.5F;
break;
case ImageBoxGridScale.Large:
scale = 2;
break;
case ImageBoxGridScale.Tiny:
scale = 0.5F;
break;
default:
scale = 1;
break;
}
cellSize = (int)(cellSize * scale);
return CreateCheckerBoxTile(cellSize, firstColor, secondColor);
}
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (this.IsAnimating)
{
ImageAnimator.StopAnimate(this.Image, this.OnFrameChangedHandler);
}
if (_texture != null)
{
_texture.Dispose();
_texture = null;
}
if (_gridTile != null)
{
_gridTile.Dispose();
_gridTile = null;
}
this.KillTimer();
}
base.Dispose(disposing);
}
///
/// Draws the background of the control.
///
/// The instance containing the event data.
protected virtual void DrawBackground(PaintEventArgs e)
{
Rectangle innerRectangle;
innerRectangle = this.GetInsideViewPort();
using (SolidBrush brush = new SolidBrush(this.BackColor))
{
e.Graphics.FillRectangle(brush, innerRectangle);
}
if (_texture != null && this.GridDisplayMode != ImageBoxGridDisplayMode.None)
{
switch (this.GridDisplayMode)
{
case ImageBoxGridDisplayMode.Image:
Rectangle fillRectangle;
fillRectangle = this.GetImageViewPort();
e.Graphics.FillRectangle(_texture, fillRectangle);
break;
case ImageBoxGridDisplayMode.Client:
e.Graphics.FillRectangle(_texture, innerRectangle);
break;
}
}
}
///
/// Draws a drop shadow.
///
/// The graphics.
/// The view port.
protected virtual void DrawDropShadow(Graphics g, Rectangle viewPort)
{
Rectangle rightEdge;
Rectangle bottomEdge;
rightEdge = new Rectangle(viewPort.Right + 1, viewPort.Top + this.DropShadowSize, this.DropShadowSize, viewPort.Height);
bottomEdge = new Rectangle(viewPort.Left + this.DropShadowSize, viewPort.Bottom + 1, viewPort.Width + 1, this.DropShadowSize);
using (Brush brush = new SolidBrush(this.ImageBorderColor))
{
g.FillRectangles(brush, new[]
{
rightEdge,
bottomEdge
});
}
}
///
/// Draws a glow shadow.
///
/// The graphics.
/// The view port.
protected virtual void DrawGlowShadow(Graphics g, Rectangle viewPort)
{
// Glow code adapted from http://www.codeproject.com/Articles/372743/gGlowBox-Create-a-glow-effect-around-a-focused-con
g.SetClip(viewPort, CombineMode.Exclude); // make sure the inside glow doesn't appear
using (GraphicsPath path = new GraphicsPath())
{
int glowSize;
int feather;
path.AddRectangle(viewPort);
glowSize = this.DropShadowSize * 3;
feather = 50;
for (int i = 1; i <= glowSize; i += 2)
{
int alpha;
alpha = feather - feather / glowSize * i;
using (Pen pen = new Pen(Color.FromArgb(alpha, this.ImageBorderColor), i)
{
LineJoin = LineJoin.Round
})
{
g.DrawPath(pen, path);
}
}
}
}
///
/// Draws the image.
///
/// The g.
protected virtual void DrawImage(Graphics g)
{
InterpolationMode currentInterpolationMode;
PixelOffsetMode currentPixelOffsetMode;
currentInterpolationMode = g.InterpolationMode;
currentPixelOffsetMode = g.PixelOffsetMode;
g.InterpolationMode = this.GetInterpolationMode();
// disable pixel offsets. Thanks to Rotem for the info.
// http://stackoverflow.com/questions/14070311/why-is-graphics-drawimage-cropping-part-of-my-image/14070372#14070372
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
try
{
// Animation. Thanks to teamalpha5441 for the contribution
if (this.IsAnimating && !this.DesignMode)
{
ImageAnimator.UpdateFrames(this.Image);
}
g.DrawImage(this.Image, this.GetImageViewPort(), this.GetSourceImageRegion(), GraphicsUnit.Pixel);
}
catch (Exception ex)
{
TextRenderer.DrawText(g, ex.Message, this.Font, this.ClientRectangle, this.ForeColor, this.BackColor, TextFormatFlags.VerticalCenter | TextFormatFlags.HorizontalCenter | TextFormatFlags.WordBreak | TextFormatFlags.NoPadding | TextFormatFlags.NoPrefix);
}
g.PixelOffsetMode = currentPixelOffsetMode;
g.InterpolationMode = currentInterpolationMode;
}
///
/// Draws a border around the image.
///
/// The graphics.
protected virtual void DrawImageBorder(Graphics graphics)
{
if (this.ImageBorderStyle != ImageBoxBorderStyle.None)
{
Rectangle viewPort;
graphics.SetClip(this.GetInsideViewPort()); // make sure the image border doesn't overwrite the control border
viewPort = this.GetImageViewPort();
viewPort = new Rectangle(viewPort.Left - 1, viewPort.Top - 1, viewPort.Width + 1, viewPort.Height + 1);
using (Pen borderPen = new Pen(this.ImageBorderColor))
{
graphics.DrawRectangle(borderPen, viewPort);
}
switch (this.ImageBorderStyle)
{
case ImageBoxBorderStyle.FixedSingleDropShadow:
this.DrawDropShadow(graphics, viewPort);
break;
case ImageBoxBorderStyle.FixedSingleGlowShadow:
this.DrawGlowShadow(graphics, viewPort);
break;
}
graphics.ResetClip();
}
}
///
/// Draws the specified text within the specified bounds using the specified device context.
///
/// The device context in which to draw the text.
/// The text to draw.
/// The that represents the bounds of the text.
protected void DrawLabel(Graphics graphics, string text, Rectangle bounds)
{
this.DrawLabel(graphics, text, this.Font, this.ForeColor, this.TextBackColor, this.TextAlign, bounds);
}
///
/// Draws the specified text within the specified bounds using the specified device context and font.
///
/// The device context in which to draw the text.
/// The text to draw.
/// The to apply to the drawn text.
/// The that represents the bounds of the text.
protected void DrawLabel(Graphics graphics, string text, Font font, Rectangle bounds)
{
this.DrawLabel(graphics, text, font, this.ForeColor, this.TextBackColor, this.TextAlign, bounds);
}
///
/// Draws the specified text within the specified bounds using the specified device context, font, and color.
///
/// The device context in which to draw the text.
/// The text to draw.
/// The to apply to the drawn text.
/// The to apply to the text.
/// The that represents the bounds of the text.
protected void DrawLabel(Graphics graphics, string text, Font font, Color foreColor, Rectangle bounds)
{
this.DrawLabel(graphics, text, font, foreColor, this.TextBackColor, this.TextAlign, bounds);
}
///
/// Draws the specified text within the specified bounds using the specified device context, font, color, and back color.
///
/// The device context in which to draw the text.
/// The text to draw.
/// The to apply to the drawn text.
/// The to apply to the text.
/// The to apply to the area represented by bounds.
/// The that represents the bounds of the text.
protected void DrawLabel(Graphics graphics, string text, Font font, Color foreColor, Color backColor, Rectangle bounds)
{
this.DrawLabel(graphics, text, font, foreColor, backColor, this.TextAlign, bounds);
}
///
/// Draws the specified text within the specified bounds using the specified device context, font, color, back color, and formatting instructions.
///
/// The device context in which to draw the text.
/// The text to draw.
/// The to apply to the drawn text.
/// The to apply to the text.
/// The to apply to the area represented by bounds.
/// The to apply to the text.
/// The that represents the bounds of the text.
protected void DrawLabel(Graphics graphics, string text, Font font, Color foreColor, Color backColor, ContentAlignment textAlign, Rectangle bounds)
{
this.DrawLabel(graphics, text, font, foreColor, backColor, textAlign, bounds, this.ScaleText);
}
///
/// Draws the specified text within the specified bounds using the specified device context, font, color, back color, and formatting instructions.
///
/// The device context in which to draw the text.
/// The text to draw.
/// The to apply to the drawn text.
/// The to apply to the text.
/// The to apply to the area represented by bounds.
/// The to apply to the text.
/// The that represents the bounds of the text.
/// If set to true the font size is scaled according to the current zoom level.
protected virtual void DrawLabel(Graphics graphics, string text, Font font, Color foreColor, Color backColor, ContentAlignment textAlign, Rectangle bounds, bool scaleText)
{
this.DrawLabel(graphics, text, font, foreColor, backColor, textAlign, bounds, scaleText, Padding.Empty);
}
///
/// Draws the specified text within the specified bounds using the specified device context, font, color, back color, and formatting instructions.
///
/// The device context in which to draw the text.
/// The text to draw.
/// The to apply to the drawn text.
/// The to apply to the text.
/// The to apply to the area represented by bounds.
/// The to apply to the text.
/// The that represents the bounds of the text.
/// If set to true the font size is scaled according to the current zoom level.
/// Padding to apply around the text
protected virtual void DrawLabel(Graphics graphics, string text, Font font, Color foreColor, Color backColor, ContentAlignment textAlign, Rectangle bounds, bool scaleText, Padding padding)
{
TextFormatFlags flags;
if (scaleText)
{
font = new Font(font.FontFamily, (float)(font.Size * this.ZoomFactor), font.Style);
}
flags = TextFormatFlags.NoPrefix | TextFormatFlags.WordEllipsis | TextFormatFlags.WordBreak | TextFormatFlags.NoPadding;
switch (textAlign)
{
case ContentAlignment.TopLeft:
case ContentAlignment.MiddleLeft:
case ContentAlignment.BottomLeft:
flags |= TextFormatFlags.Left;
break;
case ContentAlignment.TopRight:
case ContentAlignment.MiddleRight:
case ContentAlignment.BottomRight:
flags |= TextFormatFlags.Right;
break;
default:
flags |= TextFormatFlags.HorizontalCenter;
break;
}
switch (textAlign)
{
case ContentAlignment.TopCenter:
case ContentAlignment.TopLeft:
case ContentAlignment.TopRight:
flags |= TextFormatFlags.Top;
break;
case ContentAlignment.BottomCenter:
case ContentAlignment.BottomLeft:
case ContentAlignment.BottomRight:
flags |= TextFormatFlags.Bottom;
break;
default:
flags |= TextFormatFlags.VerticalCenter;
break;
}
if (padding.Horizontal != 0 || padding.Vertical != 0)
{
Size size;
int x;
int y;
int width;
int height;
size = TextRenderer.MeasureText(graphics, text, font, bounds.Size, flags);
width = size.Width;
height = size.Height;
switch (textAlign)
{
case ContentAlignment.TopLeft:
x = bounds.Left + padding.Left;
y = bounds.Top + padding.Top;
break;
case ContentAlignment.TopCenter:
x = bounds.Left + padding.Left + ((bounds.Width - width) / 2 - padding.Right);
y = bounds.Top + padding.Top;
break;
case ContentAlignment.TopRight:
x = bounds.Right - (padding.Right + width);
y = bounds.Top + padding.Top;
break;
case ContentAlignment.MiddleLeft:
x = bounds.Left + padding.Left;
y = bounds.Top + padding.Top + (bounds.Height - height) / 2;
break;
case ContentAlignment.MiddleCenter:
x = bounds.Left + padding.Left + ((bounds.Width - width) / 2 - padding.Right);
y = bounds.Top + padding.Top + (bounds.Height - height) / 2;
break;
case ContentAlignment.MiddleRight:
x = bounds.Right - (padding.Right + width);
y = bounds.Top + padding.Top + (bounds.Height - height) / 2;
break;
case ContentAlignment.BottomLeft:
x = bounds.Left + padding.Left;
y = bounds.Bottom - (padding.Bottom + height);
break;
case ContentAlignment.BottomCenter:
x = bounds.Left + padding.Left + ((bounds.Width - width) / 2 - padding.Right);
y = bounds.Bottom - (padding.Bottom + height);
break;
case ContentAlignment.BottomRight:
x = bounds.Right - (padding.Right + width);
y = bounds.Bottom - (padding.Bottom + height);
break;
default:
throw new ArgumentOutOfRangeException(nameof(textAlign));
}
if (backColor != Color.Empty && backColor.A > 0)
{
using (Brush brush = new SolidBrush(backColor))
{
graphics.FillRectangle(brush, x - padding.Left, y - padding.Top, width + padding.Horizontal, height + padding.Vertical);
}
}
bounds = new Rectangle(x, y, width, height);
//bounds = new Rectangle(bounds.Left + padding.Left, bounds.Top + padding.Top, bounds.Width - padding.Horizontal, bounds.Height - padding.Vertical);
}
TextRenderer.DrawText(graphics, text, font, bounds, foreColor, backColor, flags);
if (scaleText)
{
font.Dispose();
}
}
///
/// Draws a pixel grid.
///
/// The graphics to draw the grid to.
protected virtual void DrawPixelGrid(Graphics g)
{
float pixelSize;
pixelSize = (float)this.ZoomFactor;
if (pixelSize > this.PixelGridThreshold)
{
Rectangle viewport;
float offsetX;
float offsetY;
viewport = this.GetImageViewPort();
offsetX = Math.Abs(this.AutoScrollPosition.X) % pixelSize;
offsetY = Math.Abs(this.AutoScrollPosition.Y) % pixelSize;
using (Pen pen = new Pen(this.PixelGridColor)
{
DashStyle = DashStyle.Dot
})
{
for (float x = viewport.Left + pixelSize - offsetX; x < viewport.Right; x += pixelSize)
{
g.DrawLine(pen, x, viewport.Top, x, viewport.Bottom);
}
for (float y = viewport.Top + pixelSize - offsetY; y < viewport.Bottom; y += pixelSize)
{
g.DrawLine(pen, viewport.Left, y, viewport.Right, y);
}
g.DrawRectangle(pen, viewport);
}
}
}
///
/// Draws the selection region.
///
///
/// The instance containing the event data.
///
protected virtual void DrawSelection(PaintEventArgs e)
{
RectangleF rect;
e.Graphics.SetClip(this.GetInsideViewPort(true));
rect = this.GetOffsetRectangle(this.SelectionRegion);
using (Brush brush = new SolidBrush(Color.FromArgb(128, this.SelectionColor)))
{
e.Graphics.FillRectangle(brush, rect);
}
using (Pen pen = new Pen(this.SelectionColor))
{
e.Graphics.DrawRectangle(pen, rect.X, rect.Y, rect.Width, rect.Height);
}
e.Graphics.ResetClip();
}
///
/// Draws the text.
///
/// The instance containing the event data.
protected virtual void DrawText(PaintEventArgs e)
{
Rectangle bounds;
bounds = this.TextDisplayMode == ImageBoxGridDisplayMode.Client ? this.GetInsideViewPort() : this.GetImageViewPort();
this.DrawLabel(e.Graphics, this.Text, this.Font, this.ForeColor, this.TextBackColor, this.TextAlign, bounds, this.ScaleText, this.TextPadding);
}
///
/// Completes an ongoing selection or drag operation.
///
protected virtual void EndDrag()
{
this.IsSelecting = false;
this.OnSelected(EventArgs.Empty);
}
///
/// Gets a cursor suitable for the current state of the control
///
/// The mouse cursor position in client co-ordinates.
///
/// A object suitable for the current state of the control
///
protected virtual Cursor GetCursor(Point location)
{
Cursor cursor;
switch (_panStyle)
{
case ImageBoxPanStyle.None:
cursor = Cursors.Default;
break;
case ImageBoxPanStyle.Standard:
cursor = Cursors.SizeAll;
break;
case ImageBoxPanStyle.Free:
switch (this.GetPanDirection(location))
{
case ImageBoxPanDirection.None:
cursor = _panAllCursor;
break;
case ImageBoxPanDirection.Up:
cursor = Cursors.PanNorth;
break;
case ImageBoxPanDirection.Down:
cursor = Cursors.PanSouth;
break;
case ImageBoxPanDirection.Left:
cursor = Cursors.PanWest;
break;
case ImageBoxPanDirection.Right:
cursor = Cursors.PanEast;
break;
default:
cursor = _panAllCursor;
break;
}
break;
default:
cursor = Cursors.Default;
break;
}
return cursor;
}
///
/// Gets an offset based on the current image border style.
///
///
protected virtual int GetImageBorderOffset()
{
int offset;
switch (this.ImageBorderStyle)
{
case ImageBoxBorderStyle.FixedSingle:
offset = 1;
break;
case ImageBoxBorderStyle.FixedSingleDropShadow:
offset = this.DropShadowSize + 1;
break;
default:
offset = 0;
break;
}
return offset;
}
///
/// Gets the interpolation mode used to render the image.
///
///
/// The interpolation mode.
///
/// Returns the value of the property, unless this is set to InterpolationMode.Default, in which case it will use InterpolationMode.HighQualityBicubic for zoomed images otherwise InterpolationMode.NearestNeighbor.
protected virtual InterpolationMode GetInterpolationMode()
{
InterpolationMode mode;
mode = this.InterpolationMode;
if (mode == InterpolationMode.Default)
{
// ReSharper disable once ConvertIfStatementToConditionalTernaryExpression
if (this.Zoom < 100)
{
// TODO: Check to see if we should cherry pick other modes depending on how much the image is actually zoomed
mode = InterpolationMode.HighQualityBicubic;
}
else
{
mode = InterpolationMode.NearestNeighbor;
}
}
return mode;
}
///
/// Determines whether the specified key is a regular input key or a special key that requires preprocessing.
///
///
/// One of the values.
///
///
/// true if the specified key is a regular input key; otherwise, false.
///
protected override bool IsInputKey(Keys keyData)
{
bool result;
if ((keyData & Keys.Right) == Keys.Right | (keyData & Keys.Left) == Keys.Left | (keyData & Keys.Up) == Keys.Up | (keyData & Keys.Down) == Keys.Down)
{
result = true;
}
else
{
result = base.IsInputKey(keyData);
}
return result;
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnAllowClickZoomChanged(EventArgs e)
{
EventHandler handler;
handler = (EventHandler)this.Events[_eventAllowClickZoomChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnAllowDoubleClickChanged(EventArgs e)
{
EventHandler handler;
this.SetStyle(ControlStyles.StandardDoubleClick, this.AllowDoubleClick);
handler = (EventHandler)this.Events[_eventAllowDoubleClickChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
/// The instance containing the event data.
protected virtual void OnAllowFreePanChanged(EventArgs e)
{
EventHandler handler;
handler = (EventHandler)this.Events[_eventAllowFreePanChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
/// The instance containing the event data.
protected virtual void OnAllowUnfocusedMouseWheelChanged(EventArgs e)
{
EventHandler handler;
if (this.AllowUnfocusedMouseWheel)
{
// TODO: Not doing any reference counting so there's
// currently no way of disabling the message filter
// after the first time it has been enabled
ImageBoxMouseWheelMessageFilter.Active = true;
}
handler = (EventHandler)this.Events[_eventAllowUnfocusedMouseWheelChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnAllowZoomChanged(EventArgs e)
{
EventHandler handler;
handler = (EventHandler)this.Events[_eventAllowZoomChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnAutoCenterChanged(EventArgs e)
{
EventHandler handler;
this.Invalidate();
handler = (EventHandler)this.Events[_eventAutoCenterChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnAutoPanChanged(EventArgs e)
{
EventHandler handler;
handler = (EventHandler)this.Events[_eventAutoPanChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
///
/// An that contains the event data.
///
protected override void OnBackColorChanged(EventArgs e)
{
base.OnBackColorChanged(e);
this.Invalidate();
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected override void OnBorderStyleChanged(EventArgs e)
{
base.OnBorderStyleChanged(e);
this.AdjustLayout();
}
///
/// Raises the event.
///
///
/// An that contains the event data.
///
protected override void OnDockChanged(EventArgs e)
{
base.OnDockChanged(e);
if (this.Dock != DockStyle.None)
{
this.AutoSize = false;
}
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnDropShadowSizeChanged(EventArgs e)
{
EventHandler handler;
this.Invalidate();
handler = (EventHandler)this.Events[_eventDropShadowSizeChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
/// An that contains the event data.
protected override void OnFontChanged(EventArgs e)
{
base.OnFontChanged(e);
this.Invalidate();
}
///
/// Raises the event.
///
/// An that contains the event data.
protected override void OnForeColorChanged(EventArgs e)
{
base.OnForeColorChanged(e);
this.Invalidate();
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnGridCellSizeChanged(EventArgs e)
{
EventHandler handler;
this.InitializeGridTile();
handler = (EventHandler)this.Events[_eventGridCellSizeChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnGridColorAlternateChanged(EventArgs e)
{
EventHandler handler;
this.InitializeGridTile();
handler = (EventHandler)this.Events[_eventGridColorAlternateChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnGridColorChanged(EventArgs e)
{
EventHandler handler;
this.InitializeGridTile();
handler = (EventHandler)this.Events[_eventGridColorChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnGridDisplayModeChanged(EventArgs e)
{
EventHandler handler;
this.InitializeGridTile();
this.Invalidate();
handler = (EventHandler)this.Events[_eventGridDisplayModeChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnGridScaleChanged(EventArgs e)
{
EventHandler handler;
this.InitializeGridTile();
handler = (EventHandler)this.Events[_eventGridScaleChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnImageBorderColorChanged(EventArgs e)
{
EventHandler handler;
this.Invalidate();
handler = (EventHandler)this.Events[_eventImageBorderColorChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnImageBorderStyleChanged(EventArgs e)
{
EventHandler handler;
this.Invalidate();
handler = (EventHandler)this.Events[_eventImageBorderStyleChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnImageChanged(EventArgs e)
{
EventHandler handler;
this.IsAnimating = false;
if (this.Image != null)
{
try
{
this.IsAnimating = ImageAnimator.CanAnimate(this.Image);
if (this.IsAnimating)
{
ImageAnimator.Animate(this.Image, this.OnFrameChangedHandler);
}
}
catch (ArgumentException)
{
// probably a disposed image, ignore
}
}
this.AdjustLayout();
handler = (EventHandler)this.Events[_eventImageChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnInterpolationModeChanged(EventArgs e)
{
EventHandler handler;
this.Invalidate();
handler = (EventHandler)this.Events[_eventInterpolationModeChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnInvertMouseChanged(EventArgs e)
{
EventHandler handler;
handler = (EventHandler)this.Events[_eventInvertMouseChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
///
/// A that contains the event data.
///
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
this.ProcessScrollingShortcuts(e);
if (this.ShortcutsEnabled && this.AllowZoom && this.SizeMode == ImageBoxSizeMode.Normal)
{
this.ProcessImageShortcuts(e);
}
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnLimitSelectionToImageChanged(EventArgs e)
{
EventHandler handler;
handler = (EventHandler)this.Events[_eventLimitSelectionToImageChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
///
/// A that contains the event data.
///
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
if (!this.Focused)
{
this.Focus();
}
if (e.Button != MouseButtons.None)
{
if (_panStyle == ImageBoxPanStyle.Free)
{
// already panning, abort
this.ProcessPanEvents(ImageBoxPanStyle.None);
}
else
{
_mouseDownStart = NativeMethods.GetTickCount();
if (AllowFreePan && e.Button is MouseButtons.Middle)
{
this.ProcessPanning(e);
}
}
}
this.SetCursor(e.Location);
}
///
/// Raises the event.
///
///
/// A that contains the event data.
///
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if (e.Button != MouseButtons.None)
{
this.ProcessPanning(e);
this.ProcessSelection(e);
}
this.SetCursor(e.Location);
}
///
/// Raises the event.
///
///
/// A that contains the event data.
///
protected override void OnMouseUp(MouseEventArgs e)
{
bool doNotProcessClick;
base.OnMouseUp(e);
doNotProcessClick = _panStyle != ImageBoxPanStyle.None || this.IsSelecting;
if (_panStyle == ImageBoxPanStyle.Standard || _panStyle == ImageBoxPanStyle.Free && NativeMethods.GetTickCount() > (_mouseDownStart + SystemInformation.DoubleClickTime))
{
this.ProcessPanEvents(ImageBoxPanStyle.None);
}
if (this.IsSelecting)
{
this.EndDrag();
}
this.WasDragCancelled = false;
if (!doNotProcessClick && this.AllowZoom && this.AllowClickZoom && _panStyle == ImageBoxPanStyle.None && this.SizeMode == ImageBoxSizeMode.Normal)
{
if (e.Button == MouseButtons.Left && ModifierKeys == Keys.None)
{
this.ProcessMouseZoom(true, e.Location);
}
else if (e.Button == MouseButtons.Right || e.Button == MouseButtons.Left && ModifierKeys != Keys.None)
{
this.ProcessMouseZoom(false, e.Location);
}
}
}
///
/// Raises the event.
///
///
/// A that contains the event data.
///
protected override void OnMouseWheel(MouseEventArgs e)
{
base.OnMouseWheel(e);
if (MouseWheelMode == ImageBoxMouseWheelMode.Zoom)
{
DoMouseWheelZoom(e);
}
else if (MouseWheelMode == ImageBoxMouseWheelMode.ScrollAndZoom)
{
if (ModifierKeys == Keys.Control)
{
DoMouseWheelZoom(e);
}
else if (VScroll && ModifierKeys == Keys.None)
{
int scrollDelta = SystemInformation.MouseWheelScrollLines * VerticalScroll.SmallChange;
ScrollTo(HorizontalScroll.Value, VerticalScroll.Value + ((e.Delta > 0) ? -scrollDelta : scrollDelta));
}
else if (HScroll && ModifierKeys == Keys.Shift)
{
int scrollDelta = SystemInformation.MouseWheelScrollLines * HorizontalScroll.SmallChange;
ScrollTo(HorizontalScroll.Value + ((e.Delta > 0) ? -scrollDelta : scrollDelta), VerticalScroll.Value);
}
}
}
///
/// Raises the event.
///
/// The instance containing the event data.
protected virtual void OnMouseWheelModeChanged(EventArgs e)
{
EventHandler handler;
handler = (EventHandler)this.Events[_eventMouseWheelModeChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
///
/// An that contains the event data.
///
protected override void OnPaddingChanged(EventArgs e)
{
base.OnPaddingChanged(e);
this.AdjustLayout();
}
///
/// Raises the event.
///
///
/// A that contains the event data.
///
protected override void OnPaint(PaintEventArgs e)
{
if (this.AllowPainting)
{
// draw the background
this.DrawBackground(e);
// draw the image
if (!this.ViewSize.IsEmpty)
{
this.DrawImageBorder(e.Graphics);
}
if (this.VirtualMode)
{
this.OnVirtualDraw(e);
}
else if (this.Image != null)
{
this.DrawImage(e.Graphics);
}
// draw the grid
if (this.ShowPixelGrid && !this.VirtualMode)
{
this.DrawPixelGrid(e.Graphics);
}
// draw the selection
if (this.SelectionRegion != Rectangle.Empty)
{
this.DrawSelection(e);
}
// text
if (!string.IsNullOrEmpty(this.Text) && this.TextDisplayMode != ImageBoxGridDisplayMode.None)
{
this.DrawText(e);
}
if (_panStyle == ImageBoxPanStyle.Free)
{
this.DrawPanAllSymbol(e);
}
base.OnPaint(e);
}
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnPanEnd(EventArgs e)
{
EventHandler handler;
handler = (EventHandler)this.Events[_eventPanEnd];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
/// The instance containing the event data.
protected virtual void OnPanModeChanged(EventArgs e)
{
EventHandler handler;
handler = (EventHandler)this.Events[_eventPanModeChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnPanStart(CancelEventArgs e)
{
EventHandler handler;
handler = (EventHandler)this.Events[_eventPanStart];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
///
/// An that contains the event data.
///
protected override void OnParentChanged(EventArgs e)
{
base.OnParentChanged(e);
this.AdjustLayout();
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnPixelGridColorChanged(EventArgs e)
{
EventHandler handler;
this.Invalidate();
handler = (EventHandler)this.Events[_eventPixelGridColorChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
/// The instance containing the event data.
protected virtual void OnPixelGridThresholdChanged(EventArgs e)
{
EventHandler handler;
handler = (EventHandler)this.Events[_eventPixelGridThresholdChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
///
/// An that contains the event data.
///
protected override void OnResize(EventArgs e)
{
this.AdjustLayout();
base.OnResize(e);
}
///
/// Raises the event.
///
/// The instance containing the event data.
protected virtual void OnScaleTextChanged(EventArgs e)
{
EventHandler handler;
this.Invalidate();
handler = (EventHandler)this.Events[_eventScaleTextChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
///
/// A that contains the event data.
///
protected override void OnScroll(ScrollEventArgs se)
{
this.Invalidate();
base.OnScroll(se);
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnSelected(EventArgs e)
{
EventHandler handler;
switch (this.SelectionMode)
{
case ImageBoxSelectionMode.Zoom:
if (this.SelectionRegion.Width > SelectionDeadZone && this.SelectionRegion.Height > SelectionDeadZone)
{
this.ZoomToRegion(this.SelectionRegion);
this.SelectNone();
}
break;
}
handler = (EventHandler)this.Events[_eventSelected];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnSelecting(ImageBoxCancelEventArgs e)
{
EventHandler handler;
handler = (EventHandler)this.Events[_eventSelecting];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnSelectionColorChanged(EventArgs e)
{
EventHandler handler;
handler = (EventHandler)this.Events[_eventSelectionColorChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnSelectionModeChanged(EventArgs e)
{
EventHandler handler;
handler = (EventHandler)this.Events[_eventSelectionModeChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnSelectionRegionChanged(EventArgs e)
{
EventHandler handler;
this.Invalidate();
handler = (EventHandler)this.Events[_eventSelectionRegionChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnShortcutsEnabledChanged(EventArgs e)
{
EventHandler handler;
handler = (EventHandler)this.Events[_eventShortcutsEnabledChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnShowPixelGridChanged(EventArgs e)
{
EventHandler handler;
this.Invalidate();
handler = (EventHandler)this.Events[_eventShowPixelGridChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
/// The instance containing the event data.
protected virtual void OnSizeModeChanged(EventArgs e)
{
EventHandler handler;
this.AdjustLayout();
handler = (EventHandler)this.Events[_eventSizeModeChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnSizeToFitChanged(EventArgs e)
{
EventHandler handler;
this.AdjustLayout();
handler = (EventHandler)this.Events[_eventSizeToFitChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
/// The instance containing the event data.
protected virtual void OnTextAlignChanged(EventArgs e)
{
EventHandler handler;
this.Invalidate();
handler = (EventHandler)this.Events[_eventTextAlignChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
/// The instance containing the event data.
protected virtual void OnTextBackColorChanged(EventArgs e)
{
EventHandler handler;
this.Invalidate();
handler = (EventHandler)this.Events[_eventTextBackColorChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
/// An that contains the event data.
protected override void OnTextChanged(EventArgs e)
{
base.OnTextChanged(e);
this.Invalidate();
}
///
/// Raises the event.
///
/// The instance containing the event data.
protected virtual void OnTextDisplayModeChanged(EventArgs e)
{
EventHandler handler;
this.Invalidate();
handler = (EventHandler)this.Events[_eventTextDisplayModeChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
/// The instance containing the event data.
protected virtual void OnTextPaddingChanged(EventArgs e)
{
EventHandler handler;
handler = (EventHandler)this.Events[_eventTextPaddingChanged];
this.Invalidate();
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnVirtualDraw(PaintEventArgs e)
{
PaintEventHandler handler;
handler = (PaintEventHandler)this.Events[_eventVirtualDraw];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnVirtualModeChanged(EventArgs e)
{
EventHandler handler;
this.AdjustLayout();
handler = (EventHandler)this.Events[_eventVirtualModeChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnVirtualSizeChanged(EventArgs e)
{
EventHandler handler;
this.AdjustLayout();
handler = (EventHandler)this.Events[_eventVirtualSizeChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnZoomChanged(EventArgs e)
{
EventHandler handler;
this.AdjustLayout();
handler = (EventHandler)this.Events[_eventZoomChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
/// The instance containing the event data.
protected virtual void OnZoomed(ImageBoxZoomEventArgs e)
{
EventHandler handler;
handler = (EventHandler)this.Events[_eventZoomed];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnZoomLevelsChanged(EventArgs e)
{
EventHandler handler;
handler = (EventHandler)this.Events[_eventZoomLevelsChanged];
handler?.Invoke(this, e);
}
///
/// Processes shortcut keys for zooming and selection
///
///
/// The instance containing the event data.
///
protected virtual void ProcessImageShortcuts(KeyEventArgs e)
{
Point currentPixel;
int currentZoom;
Point relativePoint;
relativePoint = this.CenterPoint;
currentPixel = this.PointToImage(relativePoint);
currentZoom = this.Zoom;
switch (e.KeyCode)
{
case Keys.Home:
if (this.AllowZoom)
{
this.PerformActualSize(ImageBoxActionSources.User);
}
break;
case Keys.PageDown:
case Keys.Oemplus:
if (this.AllowZoom)
{
this.PerformZoomIn(ImageBoxActionSources.User, true);
}
break;
case Keys.PageUp:
case Keys.OemMinus:
if (this.AllowZoom)
{
this.PerformZoomOut(ImageBoxActionSources.User, true);
}
break;
}
if (this.Zoom != currentZoom)
{
this.ScrollTo(currentPixel, relativePoint);
}
}
///
/// Processes zooming with the mouse. Attempts to keep the pre-zoom image pixel under the mouse after the zoom has completed.
///
///
/// if set to true zoom in, otherwise zoom out.
///
/// The cursor position.
protected virtual void ProcessMouseZoom(bool isZoomIn, Point cursorPosition)
{
this.PerformZoom(isZoomIn ? ImageBoxZoomActions.ZoomIn : ImageBoxZoomActions.ZoomOut, ImageBoxActionSources.User, true, cursorPosition);
}
///
/// Performs mouse based panning
///
///
/// The instance containing the event data.
///
protected virtual void ProcessPanning(MouseEventArgs e)
{
if (this.CanPan(e.Button))
{
if (_panStyle == ImageBoxPanStyle.None && (this.HScroll || this.VScroll))
{
_startMousePosition = e.Location;
this.ProcessPanEvents(e.Button == MouseButtons.Middle && _allowFreePan ? ImageBoxPanStyle.Free : ImageBoxPanStyle.Standard);
}
}
if (_panStyle == ImageBoxPanStyle.Standard)
{
int x;
int y;
Point position;
if (!this.InvertMouse)
{
x = -_startScrollPosition.X + (_startMousePosition.X - e.Location.X);
y = -_startScrollPosition.Y + (_startMousePosition.Y - e.Location.Y);
}
else
{
x = -(_startScrollPosition.X + (_startMousePosition.X - e.Location.X));
y = -(_startScrollPosition.Y + (_startMousePosition.Y - e.Location.Y));
}
position = new Point(x, y);
this.UpdateScrollPosition(position);
}
}
///
/// Processes shortcut keys for scrolling
///
///
/// The instance containing the event data.
///
protected virtual void ProcessScrollingShortcuts(KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.Left:
this.AdjustScroll(-(e.Modifiers == Keys.None ? this.HorizontalScroll.SmallChange : this.HorizontalScroll.LargeChange), 0);
break;
case Keys.Right:
this.AdjustScroll(e.Modifiers == Keys.None ? this.HorizontalScroll.SmallChange : this.HorizontalScroll.LargeChange, 0);
break;
case Keys.Up:
this.AdjustScroll(0, -(e.Modifiers == Keys.None ? this.VerticalScroll.SmallChange : this.VerticalScroll.LargeChange));
break;
case Keys.Down:
this.AdjustScroll(0, e.Modifiers == Keys.None ? this.VerticalScroll.SmallChange : this.VerticalScroll.LargeChange);
break;
}
}
///
/// Performs mouse based region selection
///
///
/// The instance containing the event data.
///
protected virtual void ProcessSelection(MouseEventArgs e)
{
if (this.SelectionMode != ImageBoxSelectionMode.None && e.Button == MouseButtons.Left && !this.WasDragCancelled)
{
if (!this.IsSelecting)
{
this.StartDrag(e);
}
if (this.IsSelecting)
{
float x;
float y;
float w;
float h;
Point imageOffset;
RectangleF selection;
imageOffset = this.GetImageViewPort().
Location;
if (e.X < _startMousePosition.X)
{
x = e.X;
w = _startMousePosition.X - e.X;
}
else
{
x = _startMousePosition.X;
w = e.X - _startMousePosition.X;
}
if (e.Y < _startMousePosition.Y)
{
y = e.Y;
h = _startMousePosition.Y - e.Y;
}
else
{
y = _startMousePosition.Y;
h = e.Y - _startMousePosition.Y;
}
x = x - imageOffset.X - this.AutoScrollPosition.X;
y = y - imageOffset.Y - this.AutoScrollPosition.Y;
x = x / (float)this.ZoomFactor;
y = y / (float)this.ZoomFactor;
w = w / (float)this.ZoomFactor;
h = h / (float)this.ZoomFactor;
if (w != 0 && h != 0)
{
selection = new RectangleF(x, y, w, h);
if (this.LimitSelectionToImage)
{
selection = this.FitRectangle(selection);
}
this.SelectionRegion = selection;
}
}
}
}
///
/// Resets the property whilsts retaining the original .
///
protected void RestoreSizeMode()
{
if (this.SizeMode != ImageBoxSizeMode.Normal)
{
int previousZoom;
previousZoom = this.Zoom;
this.SizeMode = ImageBoxSizeMode.Normal;
this.Zoom = previousZoom; // Stop the zoom getting reset to 100% before calculating the new zoom
}
}
///
/// Initializes a selection or drag operation.
///
/// The instance containing the event data.
protected virtual void StartDrag(MouseEventArgs e)
{
ImageBoxCancelEventArgs args;
args = new ImageBoxCancelEventArgs(e.Location);
this.OnSelecting(args);
this.WasDragCancelled = args.Cancel;
this.IsSelecting = !args.Cancel;
if (this.IsSelecting)
{
this.SelectNone();
_startMousePosition = e.Location;
}
}
///
/// Updates the scroll position.
///
/// The position.
protected virtual void UpdateScrollPosition(Point position)
{
this.AutoScrollPosition = position;
this.Invalidate();
this.OnScroll(new ScrollEventArgs(ScrollEventType.EndScroll, 0));
}
private bool CanPan(MouseButtons button)
{
return (this.HScroll || this.VScroll) && (_panMode & (ImageBoxPanMode)button) != 0 && !this.ViewSize.IsEmpty && (_selectionMode == ImageBoxSelectionMode.None || button != MouseButtons.Left);
}
private void CreateTimer()
{
_freePanTimer = new Timer
{
Enabled = true,
Interval = _freePanTimerInterval
};
_freePanTimer.Tick += this.FreePanTimerTickHandler;
_freePanTimer.Start();
}
private void DoMouseWheelZoom(MouseEventArgs e)
{
if (this.AllowZoom && this.SizeMode == ImageBoxSizeMode.Normal)
{
// The MouseWheel event can contain multiple "spins" of the wheel so we need to adjust accordingly
int spins = Math.Abs(e.Delta / SystemInformation.MouseWheelScrollDelta);
// TODO: Really should update the source method to handle multiple increments rather than calling it multiple times
for (int i = 0; i < spins; i++)
{
this.ProcessMouseZoom(e.Delta > 0, e.Location);
}
}
}
private void DrawPanAllSymbol(PaintEventArgs e)
{
Graphics g;
int x;
int y;
g = e.Graphics;
x = _startMousePosition.X - (_panAllSymbol.Width >> 1);
y = _startMousePosition.Y - (_panAllSymbol.Height >> 1);
g.DrawImage(_panAllSymbol, x, y);
}
private void FreePanTimerTickHandler(object sender, EventArgs e)
{
Point location;
ImageBoxPanDirection direction;
int distance;
int ox;
int oy;
location = this.PointToClient(MousePosition);
direction = this.GetPanDirection(location);
distance = this.GetDistance(_startMousePosition.X, _startMousePosition.Y, location.X, location.Y);
ox = 0;
oy = 0;
switch (direction)
{
case ImageBoxPanDirection.Up:
oy = -distance;
break;
case ImageBoxPanDirection.Down:
oy = +distance;
break;
case ImageBoxPanDirection.Left:
ox = -distance;
break;
case ImageBoxPanDirection.Right:
ox = +distance;
break;
}
if (ox != 0 || oy != 0)
{
this.AdjustScroll(ox, oy);
}
}
///
/// Gets the distance between two points.
///
/// The first x value.
/// The first y value.
/// The second x value.
/// The second y value.
///
/// The distance.
///
private int GetDistance(int x1, int y1, int x2, int y2)
{
int dx;
int dy;
double distance;
dx = x2 - x1;
dy = y2 - y1;
distance = Math.Sqrt(dx * dx + dy * dy);
return Convert.ToInt32(distance);
}
///
/// Gets the distance between two values.
///
/// The first value.
/// The second value.
///
/// The distance.
///
private int GetDistance(int x1, int x2)
{
int dx;
double distance;
dx = x2 - x1;
distance = Math.Sqrt(dx * dx);
return Convert.ToInt32(distance);
}
///
/// Gets the size of the image.
///
/// If an error occurs, for example due to the image being disposed, an empty size is returned
/// Size.
private Size GetImageSize()
{
Size result;
// HACK: This whole thing stinks. Hey MS, how about an IsDisposed property for images?
if (this.Image != null)
{
try
{
result = this.Image.Size;
}
catch
{
result = Size.Empty;
}
}
else
{
result = Size.Empty;
}
return result;
}
private ImageBoxPanDirection GetPanDirection(Point location)
{
ImageBoxPanDirection result;
int x;
int y;
x = location.X - _startMousePosition.X;
y = location.Y - _startMousePosition.Y;
if (x >= -_panAllDeadSize && x <= _panAllDeadSize && y >= -_panAllDeadSize && y <= _panAllDeadSize)
{
result = ImageBoxPanDirection.None;
}
else
{
int distanceX;
distanceX = location.X - _startMousePosition.X;
if (-y > Math.Abs(distanceX))
{
result = ImageBoxPanDirection.Up;
}
else if (y > Math.Abs(distanceX))
{
result = ImageBoxPanDirection.Down;
}
else
{
result = distanceX < 0 ? ImageBoxPanDirection.Left : ImageBoxPanDirection.Right;
}
}
return result;
}
///
/// Returns an appropriate zoom level based on the specified action, relative to the current zoom level.
///
/// The action to determine the zoom level.
/// Thrown if an unsupported action is specified.
private int GetZoomLevel(ImageBoxZoomActions action)
{
int result;
switch (action)
{
case ImageBoxZoomActions.None:
result = this.Zoom;
break;
case ImageBoxZoomActions.ZoomIn:
result = this.ZoomLevels.NextZoom(this.Zoom);
break;
case ImageBoxZoomActions.ZoomOut:
result = this.ZoomLevels.PreviousZoom(this.Zoom);
break;
case ImageBoxZoomActions.ActualSize:
result = 100;
break;
default:
throw new ArgumentOutOfRangeException(nameof(action));
}
return result;
}
///
/// Initializes the grid tile.
///
private void InitializeGridTile()
{
_texture?.Dispose();
_gridTile?.Dispose();
if (this.GridDisplayMode != ImageBoxGridDisplayMode.None && this.GridCellSize != 0)
{
if (this.GridScale != ImageBoxGridScale.None)
{
_gridTile = this.CreateGridTileImage(this.GridCellSize, this.GridColor, this.GridColorAlternate);
_texture = new TextureBrush(_gridTile);
}
else
{
_texture = new SolidBrush(this.GridColor);
}
}
this.Invalidate();
}
private void KillTimer()
{
if (_freePanTimer != null)
{
_freePanTimer.Stop();
_freePanTimer.Tick -= this.FreePanTimerTickHandler;
_freePanTimer.Dispose();
_freePanTimer = null;
}
}
///
/// Called when the animation frame changes.
///
/// The source of the event.
/// The instance containing the event data.
private void OnFrameChangedHandler(object sender, EventArgs eventArgs)
{
this.Invalidate();
}
///
/// Resets the zoom to 100%.
///
/// The source that initiated the action.
private void PerformActualSize(ImageBoxActionSources source)
{
this.SizeMode = ImageBoxSizeMode.Normal;
this.SetZoom(100, ImageBoxZoomActions.ActualSize | (this.Zoom < 100 ? ImageBoxZoomActions.ZoomIn : ImageBoxZoomActions.ZoomOut), source);
}
///
/// Performs a zoom action.
///
/// The action to perform.
/// The source that initiated the action.
/// true if the current scrolling position should be preserved relative to the new zoom level, false to reset.
private void PerformZoom(ImageBoxZoomActions action, ImageBoxActionSources source, bool preservePosition)
{
this.PerformZoom(action, source, preservePosition, this.CenterPoint);
}
///
/// Performs a zoom action.
///
/// The action to perform.
/// The source that initiated the action.
/// true if the current scrolling position should be preserved relative to the new zoom level, false to reset.
/// A describing the current center of the control.
private void PerformZoom(ImageBoxZoomActions action, ImageBoxActionSources source, bool preservePosition, Point relativePoint)
{
Point currentPixel;
int currentZoom;
int newZoom;
currentPixel = this.PointToImage(relativePoint);
currentZoom = this.Zoom;
newZoom = this.GetZoomLevel(action);
this.RestoreSizeMode();
this.SetZoom(newZoom, action, source);
if (preservePosition && this.Zoom != currentZoom)
{
this.ScrollTo(currentPixel, relativePoint);
}
}
///
/// Zooms into the image
///
/// The source that initiated the action.
/// true if the current scrolling position should be preserved relative to the new zoom level, false to reset.
private void PerformZoomIn(ImageBoxActionSources source, bool preservePosition)
{
this.PerformZoom(ImageBoxZoomActions.ZoomIn, source, preservePosition);
}
///
/// Zooms out of the image
///
/// The source that initiated the action.
/// true if the current scrolling position should be preserved relative to the new zoom level, false to reset.
private void PerformZoomOut(ImageBoxActionSources source, bool preservePosition)
{
this.PerformZoom(ImageBoxZoomActions.ZoomOut, source, preservePosition);
}
///
/// Raises either the PanStart or PanEnd events
///
/// The new pan style.
private void ProcessPanEvents(ImageBoxPanStyle panStyle)
{
if (_panStyle != panStyle)
{
this.KillTimer();
if (panStyle == ImageBoxPanStyle.None)
{
_panStyle = ImageBoxPanStyle.None;
this.Invalidate();
this.OnPanEnd(EventArgs.Empty);
}
else
{
CancelEventArgs args;
args = new CancelEventArgs();
this.OnPanStart(args);
if (!args.Cancel)
{
_panStyle = panStyle;
if (panStyle == ImageBoxPanStyle.Free)
{
ImageBox.LoadPanResources();
this.CreateTimer();
}
_startScrollPosition = this.AutoScrollPosition;
}
this.Invalidate();
}
}
}
///
/// Sets the mouse cursor based on the current control state
///
/// The location of the mouse in client co-ordinates.
private void SetCursor(Point location)
{
Cursor cursor;
cursor = this.GetCursor(location);
if (_currentCursor != cursor)
{
_currentCursor = cursor;
// have to use this.Cursor and not Cursor.Current
// otherwise the cursor gets reset back to Default
// after clicking to initiate Free Pan
// As a result, the Cursor property has been hidden
// to discourage users setting it manually
this.Cursor = cursor;
}
}
///
/// Updates the current zoom.
///
/// The new zoom value.
/// The zoom actions that caused the value to be updated.
/// The source of the zoom operation.
private void SetZoom(int value, ImageBoxZoomActions actions, ImageBoxActionSources source)
{
int previousZoom;
previousZoom = this.Zoom;
if (value < MinZoom)
{
value = MinZoom;
}
else if (value > MaxZoom)
{
value = MaxZoom;
}
if (_zoom != value)
{
_zoom = value;
this.OnZoomChanged(EventArgs.Empty);
this.OnZoomed(new ImageBoxZoomEventArgs(actions, source, previousZoom, this.Zoom));
}
}
#endregion
#region Other
private static Cursor _panAllCursor;
private static Bitmap _panAllSymbol;
#endregion
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox/ImageBoxActionSources.cs
================================================
using System;
namespace Cyotek.Windows.Forms
{
// Cyotek ImageBox
// Copyright (c) 2010-2015 Cyotek Ltd.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
///
/// Specifies the source of an action being performed.
///
[Flags]
public enum ImageBoxActionSources
{
///
/// Unknown source.
///
Unknown = 0,
///
/// A user initialized the action.
///
User = 1
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox/ImageBoxBorderStyle.cs
================================================
namespace Cyotek.Windows.Forms
{
// Cyotek ImageBox
// Copyright (c) 2010-2015 Cyotek Ltd.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
///
/// Specifies the border styles of an image
///
public enum ImageBoxBorderStyle
{
///
/// No border.
///
None,
///
/// A fixed, single-line border.
///
FixedSingle,
///
/// A fixed, single-line border with a solid drop shadow.
///
FixedSingleDropShadow,
///
/// A fixed, single-line border with a soft outer glow.
///
FixedSingleGlowShadow
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox/ImageBoxCancelEventArgs.cs
================================================
using System.ComponentModel;
using System.Drawing;
namespace Cyotek.Windows.Forms
{
// Cyotek ImageBox
// Copyright (c) 2010-2015 Cyotek Ltd.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
///
/// Provides data for a cancelable event.
///
public class ImageBoxCancelEventArgs : CancelEventArgs
{
#region Public Constructors
///
/// Initializes a new instance of the class.
///
/// The location of the action being performed.
public ImageBoxCancelEventArgs(Point location)
: this()
{
this.Location = location;
}
#endregion
#region Protected Constructors
///
/// Initializes a new instance of the class.
///
protected ImageBoxCancelEventArgs()
{ }
#endregion
#region Public Properties
///
/// Gets or sets the location of the action being performed.
///
/// The location of the action being performed.
public Point Location { get; protected set; }
#endregion
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox/ImageBoxGridDisplayMode.cs
================================================
namespace Cyotek.Windows.Forms
{
// Cyotek ImageBox
// Copyright (c) 2010-2015 Cyotek Ltd.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
///
/// Specifies the display styles for the background texture grid
///
public enum ImageBoxGridDisplayMode
{
///
/// No background.
///
None,
///
/// Background is displayed in the control's client area.
///
Client,
///
/// Background is displayed only in the image region.
///
Image
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox/ImageBoxGridScale.cs
================================================
namespace Cyotek.Windows.Forms
{
// Cyotek ImageBox
// Copyright (c) 2010-2015 Cyotek Ltd.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
///
/// Specifies the size of the background texture grid.
///
public enum ImageBoxGridScale
{
///
/// Displays a solid color
///
None,
///
/// Half of the default size.
///
Tiny,
///
/// Default size.
///
Small,
///
/// 50% increase of default size.
///
Medium,
///
/// 100% increase of default size.
///
Large
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox/ImageBoxMouseWheelMessageFilter.cs
================================================
using System;
using System.Drawing;
using System.Windows.Forms;
#if USEWIN32PINVOKELIB
using Cyotek.Win32;
#endif
// Cyotek ImageBox
// Copyright (c) 2010-2015 Cyotek Ltd.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
// This code is derived from http://stackoverflow.com/a/13292894/148962 and http://stackoverflow.com/a/11034674/148962
namespace Cyotek.Windows.Forms
{
///
/// A message filter for WM_MOUSEWHEEL and WM_MOUSEHWHEEL. This class cannot be inherited.
///
///
internal sealed class ImageBoxMouseWheelMessageFilter : IMessageFilter
{
#region Member Declarations
private static ImageBoxMouseWheelMessageFilter _instance;
private static bool _active;
#endregion
#region Constructors
///
/// Constructor that prevents a default instance of this class from being created.
///
private ImageBoxMouseWheelMessageFilter()
{ }
#endregion
#region Static Properties
///
/// Gets or sets a value indicating whether the filter is active
///
///
/// true if the message filter is active, false if not.
///
public static bool Active
{
get { return _active; }
set
{
if (_active != value)
{
_active = value;
if (_active)
{
if (_instance == null)
{
_instance = new ImageBoxMouseWheelMessageFilter();
}
Application.AddMessageFilter(_instance);
}
else
{
if (_instance != null)
{
Application.RemoveMessageFilter(_instance);
}
}
}
}
}
#endregion
#region IMessageFilter Interface
///
/// Filters out a message before it is dispatched.
///
/// [in,out] The message to be dispatched. You cannot modify this message.
///
/// true to filter the message and stop it from being dispatched; false to allow the message to
/// continue to the next filter or control.
///
///
bool IMessageFilter.PreFilterMessage(ref Message m)
{
bool result;
switch (m.Msg)
{
case NativeMethods.WM_MOUSEWHEEL: // 0x020A
case NativeMethods.WM_MOUSEHWHEEL: // 0x020E
IntPtr hControlUnderMouse;
hControlUnderMouse = NativeMethods.WindowFromPoint(new Point((int)m.LParam));
if (hControlUnderMouse == m.HWnd)
{
// already headed for the right control
result = false;
}
else
{
ImageBox control;
control = Control.FromHandle(hControlUnderMouse) as ImageBox;
if (control == null || !control.AllowUnfocusedMouseWheel)
{
// window under the mouse either isn't managed, isn't an imagebox,
// or it is an imagebox but the unfocused whell option is disabled.
// whatever the case, do not try and handle the message
result = false;
}
else
{
// redirect the message to the control under the mouse
NativeMethods.SendMessage(hControlUnderMouse, m.Msg, m.WParam, m.LParam);
// eat the message (otherwise it's possible two controls will scroll
// at the same time, which looks awful... and is probably confusing!)
result = true;
}
}
break;
default:
// not a message we can process, don't try and block it
result = false;
break;
}
return result;
}
#endregion
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox/ImageBoxMouseWheelMode.cs
================================================
namespace Cyotek.Windows.Forms
{
///
/// Specifies the way the mouse wheel is handled for the control.
///
public enum ImageBoxMouseWheelMode
{
///
/// Mouse wheel not handled
///
None,
///
/// Mouse wheel zooms
///
Zoom,
///
/// Mouse wheel scrolls vertically, Shift + mouse wheel scrolls horizontally and Ctrl + mouse wheel zooms
///
ScrollAndZoom = 3
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox/ImageBoxNativeMethods.cs
================================================
// Cyotek ImageBox
// http://cyotek.com/blog/tag/imagebox
// Copyright (c) 2010-2021 Cyotek Ltd.
// This work is licensed under the MIT License.
// See LICENSE.TXT for the full text
// Found this code useful?
// https://www.cyotek.com/contribute
using System;
using System.Drawing;
using System.Runtime.InteropServices;
// ReSharper disable NotAccessedField.Global
// ReSharper disable InconsistentNaming
// ReSharper disable FieldCanBeMadeReadOnly.Global
namespace Cyotek.Windows.Forms
{
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable PartialTypeWithSinglePart
internal partial class NativeMethods // partial for when linking this file into other assemblies
// ReSharper restore PartialTypeWithSinglePart
// ReSharper restore ClassNeverInstantiated.Global
{
#region Enums
[Flags]
public enum SIF
{
SIF_RANGE = 0x0001,
SIF_PAGE = 0x0002,
SIF_POS = 0x0004,
SIF_DISABLENOSCROLL = 0x0008,
SIF_TRACKPOS = 0x0010,
SIF_ALL = SIF_PAGE | SIF_POS | SIF_RANGE | SIF_TRACKPOS
}
#endregion
#region Constants
public const int GWL_STYLE = (-16);
public const int SB_BOTH = 3;
public const int SB_BOTTOM = 7;
public const int SB_CTL = 2;
public const int SB_ENDSCROLL = 8;
public const int SB_HORZ = 0;
public const int SB_LEFT = 6;
public const int SB_LINEDOWN = 1;
public const int SB_LINELEFT = 0;
public const int SB_LINERIGHT = 1;
public const int SB_LINEUP = 0;
public const int SB_PAGEDOWN = 3;
public const int SB_PAGELEFT = 2;
public const int SB_PAGERIGHT = 3;
public const int SB_PAGEUP = 2;
public const int SB_RIGHT = 7;
public const int SB_THUMBPOSITION = 4;
public const int SB_THUMBTRACK = 5;
public const int SB_TOP = 6;
public const int SB_VERT = 1;
public const int WM_HSCROLL = 0x00000114;
public const int WM_VSCROLL = 0x00000115;
public const int WS_BORDER = 0x00800000;
public const int WS_EX_CLIENTEDGE = 0x200;
public const int WS_HSCROLL = 0x00100000;
public const int WS_VSCROLL = 0x00200000;
public const int WM_MOUSEWHEEL = 0x20a;
public const int WM_MOUSEHWHEEL = 0x20e;
#endregion
#region Private Constructors
private NativeMethods()
{ }
#endregion
#region Class Members
[DllImport("user32.dll", SetLastError = true)]
public static extern int GetScrollInfo(IntPtr hwnd, int bar, [MarshalAs(UnmanagedType.LPStruct)] SCROLLINFO scrollInfo);
[DllImport("kernel32.dll")]
public static extern uint GetTickCount();
[DllImport("user32.dll", SetLastError = true)]
public static extern uint GetWindowLong(IntPtr hwnd, int index);
[DllImport("user32.dll")]
public static extern int SetScrollInfo(IntPtr hwnd, int bar, [MarshalAs(UnmanagedType.LPStruct)] SCROLLINFO scrollInfo, bool redraw);
[DllImport("user32.dll")]
public static extern int SetWindowLong(IntPtr hwnd, int index, UInt32 newLong);
[DllImport("user32.dll")]
public static extern IntPtr WindowFromPoint(Point point);
[DllImport("user32.dll", SetLastError = false)]
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
#endregion
#region Nested Types
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public class SCROLLINFO
{
public int cbSize;
public SIF fMask;
public int nMin;
public int nMax;
public int nPage;
public int nPos;
public int nTrackPos;
public SCROLLINFO()
{
cbSize = Marshal.SizeOf(this);
nPage = 0;
nMin = 0;
nMax = 0;
nPos = 0;
nTrackPos = 0;
fMask = 0;
}
}
#endregion
}
// ReSharper restore NotAccessedField.Global
// ReSharper restore FieldCanBeMadeReadOnly.Global
// ReSharper restore InconsistentNaming
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox/ImageBoxPanDirection.cs
================================================
namespace Cyotek.Windows.Forms
{
internal enum ImageBoxPanDirection
{
None,
Up,
Down,
Left,
Right
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox/ImageBoxPanMode.cs
================================================
using System;
using System.Windows.Forms;
namespace Cyotek.Windows.Forms
{
///
/// Specifies constants that define which mouse buttons can be used to pan an control.
///
[Flags]
public enum ImageBoxPanMode
{
///
/// No mouse buttons can be used to pan the control.
///
None = 0,
///
/// The left mouse button can be used to pan the control.
///
Left = MouseButtons.Left,
///
/// The middle mouse button can be used to pan the control.
///
Middle = MouseButtons.Middle,
///
/// Both the left and left mouse buttons can be used to pan the control.
///
Both = Left | Middle
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox/ImageBoxPanStyle.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace Cyotek.Windows.Forms
{
internal enum ImageBoxPanStyle
{
None,
Standard,
Free
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox/ImageBoxSelectionMode.cs
================================================
namespace Cyotek.Windows.Forms
{
// Cyotek ImageBox
// Copyright (c) 2010-2015 Cyotek Ltd.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
///
/// Specifies the selection mode.
///
public enum ImageBoxSelectionMode
{
///
/// No selection.
///
None,
///
/// Rectangle selection.
///
Rectangle,
///
/// Zoom selection.
///
Zoom
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox/ImageBoxSizeMode.cs
================================================
namespace Cyotek.Windows.Forms
{
// Cyotek ImageBox
// Copyright (c) 2010-2015 Cyotek Ltd.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
///
/// Determines the sizing mode of an image hosted in an control.
///
public enum ImageBoxSizeMode
{
///
/// The image is disiplayed according to current zoom and scroll properties.
///
Normal,
///
/// The image is stretched to fill the client area of the control.
///
Stretch,
///
/// The image is stretched to fill as much of the client area of the control as possible, whilst retaining the same aspect ratio for the width and height.
///
Fit
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox/ImageBoxZoomActions.cs
================================================
using System;
namespace Cyotek.Windows.Forms
{
// Cyotek ImageBox
// Copyright (c) 2010-2015 Cyotek Ltd.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
///
/// Describes the zoom action occuring
///
[Flags]
public enum ImageBoxZoomActions
{
///
/// No action.
///
None = 0,
///
/// The control is increasing the zoom.
///
ZoomIn = 1,
///
/// The control is decreasing the zoom.
///
ZoomOut = 2,
///
/// The control zoom was reset.
///
ActualSize = 4
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox/ImageBoxZoomEventArgs.cs
================================================
using System;
namespace Cyotek.Windows.Forms
{
// Cyotek ImageBox
// Copyright (c) 2010-2015 Cyotek Ltd.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
///
/// Contains event data for the event.
///
public class ImageBoxZoomEventArgs : EventArgs
{
#region Public Constructors
///
/// Initializes a new instance of the class.
///
/// The zoom operation being performed.
/// The source of the operation.
/// The old zoom level.
/// The new zoom level.
public ImageBoxZoomEventArgs(ImageBoxZoomActions actions, ImageBoxActionSources source, int oldZoom, int newZoom)
: this()
{
this.Actions = actions;
this.Source = source;
this.OldZoom = oldZoom;
this.NewZoom = newZoom;
}
#endregion
#region Protected Constructors
///
/// Initializes a new instance of the class.
///
protected ImageBoxZoomEventArgs()
{ }
#endregion
#region Public Properties
///
/// Gets or sets the actions that occured.
///
/// The zoom operation.
public ImageBoxZoomActions Actions { get; protected set; }
///
/// Gets or sets the new zoom level.
///
/// The new zoom level.
public int NewZoom { get; protected set; }
///
/// Gets or sets the old zoom level.
///
/// The old zoom level.
public int OldZoom { get; protected set; }
///
/// Gets or sets the source of the operation..
///
/// The source.
public ImageBoxActionSources Source { get; protected set; }
#endregion
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox/Properties/AssemblyInfo.cs
================================================
using System;
using System.Reflection;
using System.Runtime.InteropServices;
// TODO: Next major version reset AssemblyVersion to ensure no strong name versioning nonsense
[assembly: AssemblyTitle("Cyotek ImageBox Control")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Cyotek Ltd")]
[assembly: AssemblyProduct("Cyotek ImageBox Control")]
[assembly: AssemblyCopyright("Copyright © 2010-2022 Cyotek Ltd.")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: Guid("d812a438-008c-47f9-926f-8415490cdda1")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyVersion("1.2.0.0")]
[assembly: AssemblyFileVersion("1.4.0.0")]
[assembly: AssemblyInformationalVersion("1.4.0")]
================================================
FILE: Cyotek.Windows.Forms.ImageBox/ScrollControl.cs
================================================
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;
#if USEWIN32PINVOKELIB
using Cyotek.Win32;
#endif
// Original ScrollControl code by Scott Crawford (http://sukiware.com/)
namespace Cyotek.Windows.Forms
{
///
/// Defines a base class for controls that support scrolling behavior.
///
[ToolboxItem(false)]
public partial class ScrollControl : Control
{
#region Instance Fields
private bool _alwaysShowHScroll;
private bool _alwaysShowVScroll;
private BorderStyle _borderStyle;
private Size _pageSize;
private Size _scrollSize;
private Size _stepSize;
#endregion
#region Public Constructors
///
/// Initializes a new instance of the class.
///
public ScrollControl()
{
// ReSharper disable DoNotCallOverridableMethodsInConstructor
this.BorderStyle = BorderStyle.Fixed3D;
this.ScrollSize = Size.Empty;
this.PageSize = Size.Empty;
this.StepSize = new Size(10, 10);
this.HorizontalScroll = new HScrollProperties(this);
this.VerticalScroll = new VScrollProperties(this);
// ReSharper restore DoNotCallOverridableMethodsInConstructor
}
#endregion
#region Events
///
/// Occurs when the BorderStyle property value changes
///
[Category("Property Changed")]
public event EventHandler BorderStyleChanged;
///
/// Occurs when the mouse wheel moves while the control has focus.
///
[Browsable(true)]
[EditorBrowsable(EditorBrowsableState.Always)]
[Category("Mouse")]
public new event MouseEventHandler MouseWheel;
///
/// Occurs when the PageSize property value changes
///
[Category("Property Changed")]
public event EventHandler PageSizeChanged;
///
/// Occurs when the user or code scrolls through the client area.
///
[Category("Action")]
public event ScrollEventHandler Scroll;
///
/// Occurs when the ScrollSize property value changes
///
[Category("Property Changed")]
public event EventHandler ScrollSizeChanged;
///
/// Occurs when the StepSize property value changes
///
[Category("Property Changed")]
public event EventHandler StepSizeChanged;
#endregion
#region Overridden Properties
///
/// Gets the required creation parameters when the control handle is created.
///
/// The create params.
///
/// A that contains the required creation parameters when the handle to the control is created.
///
protected override CreateParams CreateParams
{
get
{
CreateParams createParams;
createParams = base.CreateParams;
switch (_borderStyle)
{
case BorderStyle.FixedSingle:
createParams.Style |= NativeMethods.WS_BORDER;
break;
case BorderStyle.Fixed3D:
createParams.ExStyle |= NativeMethods.WS_EX_CLIENTEDGE;
break;
}
return createParams;
}
}
#endregion
#region Overridden Methods
///
/// Raises the event.
///
///
/// An that contains the event data.
///
protected override void OnEnabledChanged(EventArgs e)
{
base.OnEnabledChanged(e);
this.UpdateScrollbars();
}
///
/// Raises the event.
///
///
/// A that contains the event data.
///
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
if (!this.Focused)
{
this.Focus();
}
}
///
/// Raises the event.
///
///
/// A that contains the event data.
///
protected override void OnMouseWheel(MouseEventArgs e)
{
MouseEventHandler handler;
if (this.WheelScrollsControl)
{
int x;
int y;
int delta;
x = this.HorizontalScroll.Value;
y = this.VerticalScroll.Value;
// TODO: Find if we are hovering over a horizontal scrollbar and scroll that instead of the default vertical.
if (this.VerticalScroll.Visible && this.VerticalScroll.Enabled)
{
if (ModifierKeys == Keys.Control)
{
delta = this.VerticalScroll.LargeChange;
}
else
{
delta = SystemInformation.MouseWheelScrollLines * this.VerticalScroll.SmallChange;
}
y += (e.Delta > 0) ? -delta : delta;
}
else if (this.HorizontalScroll.Visible && this.HorizontalScroll.Enabled)
{
if (ModifierKeys == Keys.Control)
{
delta = this.HorizontalScroll.LargeChange;
}
else
{
delta = SystemInformation.MouseWheelScrollLines * this.HorizontalScroll.SmallChange;
}
x += (e.Delta > 0) ? -delta : delta;
}
this.ScrollTo(x, y);
}
handler = this.MouseWheel;
if (handler != null)
{
handler(this, e);
}
base.OnMouseWheel(e);
}
///
/// Processes Windows messages.
///
///
/// The Windows to process.
///
[DebuggerStepThrough]
protected override void WndProc(ref Message msg)
{
switch (msg.Msg)
{
case NativeMethods.WM_HSCROLL:
case NativeMethods.WM_VSCROLL:
this.WmScroll(ref msg);
break;
default:
base.WndProc(ref msg);
break;
}
}
#endregion
#region Public Properties
///
/// Gets or sets a value indicating whether the horizontal scrollbar should always be displayed, even when not required.
///
///
/// true if the horizontal scrollbar should always be displayed; otherwise, false.
///
[Category("Layout")]
[DefaultValue(false)]
public bool AlwaysShowHScroll
{
get { return _alwaysShowHScroll; }
set
{
if (_alwaysShowHScroll != value)
{
_alwaysShowHScroll = value;
if (value)
{
NativeMethods.SCROLLINFO scrollInfo;
scrollInfo = new NativeMethods.SCROLLINFO();
scrollInfo.fMask = NativeMethods.SIF.SIF_RANGE | NativeMethods.SIF.SIF_DISABLENOSCROLL;
scrollInfo.nMin = 0;
scrollInfo.nMax = 0;
scrollInfo.nPage = 1;
this.SetScrollInfo(ScrollOrientation.HorizontalScroll, scrollInfo, false);
this.Invalidate();
}
else
{
this.UpdateHorizontalScrollbar();
}
}
}
}
///
/// Gets or sets a value indicating whether the vertical scrollbar should always be displayed, even when not required.
///
///
/// true if the vertical scrollbar should always be displayed; otherwise, false.
///
[Category("Layout")]
[DefaultValue(false)]
public bool AlwaysShowVScroll
{
get { return _alwaysShowVScroll; }
set
{
bool shown = VScroll;
_alwaysShowVScroll = value;
if (_alwaysShowVScroll != shown)
{
if (_alwaysShowVScroll)
{
NativeMethods.SCROLLINFO scrollInfo;
scrollInfo = new NativeMethods.SCROLLINFO();
scrollInfo.fMask = NativeMethods.SIF.SIF_RANGE | NativeMethods.SIF.SIF_DISABLENOSCROLL;
scrollInfo.nMin = 0;
scrollInfo.nMax = 0;
scrollInfo.nPage = 1;
this.SetScrollInfo(ScrollOrientation.VerticalScroll, scrollInfo, false);
this.Invalidate();
}
else
{
this.UpdateVerticalScrollbar();
}
}
}
}
///
/// Gets or sets the border style.
///
/// The border style.
[Category("Appearance")]
[DefaultValue(typeof(BorderStyle), "Fixed3D")]
public virtual BorderStyle BorderStyle
{
get { return _borderStyle; }
set
{
if (this.BorderStyle != value)
{
_borderStyle = value;
this.OnBorderStyleChanged(EventArgs.Empty);
}
}
}
///
/// Gets the horizontal scrollbar properties.
///
/// The horizontal scrollbar properties.
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Browsable(false)]
public HScrollProperties HorizontalScroll { get; protected set; }
///
/// Gets or sets the size of the scroll pages.
///
/// The size of the page.
///
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public virtual Size PageSize
{
get { return _pageSize; }
set
{
if (value.Width < 0)
{
throw new ArgumentOutOfRangeException(nameof(value), "Width must be a positive integer.");
}
if (value.Height < 0)
{
throw new ArgumentOutOfRangeException(nameof(value), "Height must be a positive integer.");
}
if (this.PageSize != value)
{
_pageSize = value;
this.OnPageSizeChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets the size of the scroll area.
///
/// The size of the scroll.
///
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public virtual Size ScrollSize
{
get { return _scrollSize; }
set
{
if (value.Width < 0)
{
throw new ArgumentOutOfRangeException(nameof(value), "Width must be a positive integer.");
}
if (value.Height < 0)
{
throw new ArgumentOutOfRangeException(nameof(value), "Height must be a positive integer.");
}
if (this.ScrollSize != value)
{
_scrollSize = value;
this.OnScrollSizeChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets the size of scrollbar stepping.
///
/// The size of the step.
///
[Category("Layout")]
[DefaultValue(typeof(Size), "10, 10")]
public virtual Size StepSize
{
get { return _stepSize; }
set
{
if (value.Width < 0)
{
throw new ArgumentOutOfRangeException(nameof(value), "Width must be a positive integer.");
}
if (value.Height < 0)
{
throw new ArgumentOutOfRangeException(nameof(value), "Height must be a positive integer.");
}
if (this.StepSize != value)
{
_stepSize = value;
this.OnStepSizeChanged(EventArgs.Empty);
}
}
}
///
/// Gets the vertical scrollbar properties.
///
/// The vertical scrollbar properties.
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Browsable(false)]
public VScrollProperties VerticalScroll { get; protected set; }
#endregion
#region Protected Properties
///
/// Gets or sets a value indicating whether the horizontal scrollbar is displayed
///
///
/// true if the horizontal scrollbar is displayed; otherwise, false.
///
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Browsable(false)]
protected bool HScroll
{
get { return (NativeMethods.GetWindowLong(this.Handle, NativeMethods.GWL_STYLE) & NativeMethods.WS_HSCROLL) == NativeMethods.WS_HSCROLL; }
set
{
uint longValue = NativeMethods.GetWindowLong(this.Handle, NativeMethods.GWL_STYLE);
if (value)
{
longValue |= NativeMethods.WS_HSCROLL;
}
else
{
unchecked
{
longValue &= (uint)~NativeMethods.WS_HSCROLL;
}
}
NativeMethods.SetWindowLong(this.Handle, NativeMethods.GWL_STYLE, longValue);
}
}
///
/// Gets or sets a value indicating whether the vertical scrollbar is displayed
///
///
/// true if the vertical scrollbar is displayed; otherwise, false.
///
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Browsable(false)]
protected bool VScroll
{
get { return (NativeMethods.GetWindowLong(this.Handle, NativeMethods.GWL_STYLE) & NativeMethods.WS_VSCROLL) == NativeMethods.WS_VSCROLL; }
set
{
uint longValue = NativeMethods.GetWindowLong(this.Handle, NativeMethods.GWL_STYLE);
if (value)
{
longValue |= NativeMethods.WS_VSCROLL;
}
else
{
unchecked
{
longValue &= (uint)~NativeMethods.WS_VSCROLL;
}
}
NativeMethods.SetWindowLong(this.Handle, NativeMethods.GWL_STYLE, longValue);
}
}
///
/// Gets or sets a value indicating whether the control is scrolled when the mouse wheel is spun
///
///
/// true if the mouse wheel scrolls the control; otherwise, false.
///
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
protected bool WheelScrollsControl { get; set; }
#endregion
#region Public Members
///
/// Scrolls both scrollbars to the given values
///
/// The x.
/// The y.
public void ScrollTo(int x, int y)
{
this.ScrollTo(ScrollOrientation.HorizontalScroll, x);
this.ScrollTo(ScrollOrientation.VerticalScroll, y);
}
#endregion
#region Protected Members
///
/// Gets the type of scrollbar event.
///
/// The wparam value from a window proc.
///
///
protected ScrollEventType GetEventType(IntPtr wParam)
{
switch (wParam.ToInt32() & 0xFFFF)
{
case NativeMethods.SB_BOTTOM:
return ScrollEventType.Last;
case NativeMethods.SB_ENDSCROLL:
return ScrollEventType.EndScroll;
case NativeMethods.SB_LINEDOWN:
return ScrollEventType.SmallIncrement;
case NativeMethods.SB_LINEUP:
return ScrollEventType.SmallDecrement;
case NativeMethods.SB_PAGEDOWN:
return ScrollEventType.LargeIncrement;
case NativeMethods.SB_PAGEUP:
return ScrollEventType.LargeDecrement;
case NativeMethods.SB_THUMBPOSITION:
return ScrollEventType.ThumbPosition;
case NativeMethods.SB_THUMBTRACK:
return ScrollEventType.ThumbTrack;
case NativeMethods.SB_TOP:
return ScrollEventType.First;
default:
throw new ArgumentException(string.Format("{0} isn't a valid scroll event type.", wParam), "wparam");
}
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnBorderStyleChanged(EventArgs e)
{
EventHandler handler;
base.UpdateStyles();
handler = this.BorderStyleChanged;
if (handler != null)
{
handler(this, e);
}
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnPageSizeChanged(EventArgs e)
{
EventHandler handler;
this.UpdateScrollbars();
handler = this.PageSizeChanged;
if (handler != null)
{
handler(this, e);
}
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnScroll(ScrollEventArgs e)
{
ScrollEventHandler handler;
this.UpdateHorizontalScroll();
this.UpdateVerticalScroll();
handler = this.Scroll;
if (handler != null)
{
handler(this, e);
}
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnScrollSizeChanged(EventArgs e)
{
EventHandler handler;
this.UpdateScrollbars();
handler = this.ScrollSizeChanged;
if (handler != null)
{
handler(this, e);
}
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnStepSizeChanged(EventArgs e)
{
EventHandler handler;
handler = this.StepSizeChanged;
if (handler != null)
{
handler(this, e);
}
}
///
/// Set the given scrollbar's tracking position to the specified value
///
/// The scrollbar.
/// The value.
protected virtual void ScrollTo(ScrollOrientation scrollbar, int value)
{
NativeMethods.SCROLLINFO oldInfo;
oldInfo = this.GetScrollInfo(scrollbar);
if (value > ((oldInfo.nMax - oldInfo.nMin) + 1) - oldInfo.nPage)
{
value = ((oldInfo.nMax - oldInfo.nMin) + 1) - oldInfo.nPage;
}
if (value < oldInfo.nMin)
{
value = oldInfo.nMin;
}
if (oldInfo.nPos != value)
{
NativeMethods.SCROLLINFO scrollInfo;
scrollInfo = new NativeMethods.SCROLLINFO();
scrollInfo.fMask = NativeMethods.SIF.SIF_POS;
scrollInfo.nPos = value;
this.SetScrollInfo(scrollbar, scrollInfo, true);
this.OnScroll(new ScrollEventArgs(ScrollEventType.ThumbPosition, oldInfo.nPos, value, scrollbar));
}
}
///
/// Updates the properties of the horizontal scrollbar.
///
protected virtual void UpdateHorizontalScroll()
{
NativeMethods.SCROLLINFO scrollInfo;
scrollInfo = this.GetScrollInfo(ScrollOrientation.HorizontalScroll);
this.HorizontalScroll.Enabled = this.Enabled;
this.HorizontalScroll.LargeChange = scrollInfo.nPage;
this.HorizontalScroll.Maximum = scrollInfo.nMax;
this.HorizontalScroll.Minimum = scrollInfo.nMin;
this.HorizontalScroll.SmallChange = this.StepSize.Width;
this.HorizontalScroll.Value = scrollInfo.nPos;
this.HorizontalScroll.Visible = true;
}
///
/// Updates the horizontal scrollbar.
///
protected virtual void UpdateHorizontalScrollbar()
{
NativeMethods.SCROLLINFO scrollInfo;
int scrollWidth;
int pageWidth;
scrollWidth = this.ScrollSize.Width - 1;
pageWidth = this.PageSize.Width;
if (scrollWidth < 1)
{
scrollWidth = 0;
pageWidth = 1;
}
scrollInfo = new NativeMethods.SCROLLINFO();
scrollInfo.fMask = NativeMethods.SIF.SIF_PAGE | NativeMethods.SIF.SIF_RANGE;
if (this.AlwaysShowHScroll || !this.Enabled)
{
scrollInfo.fMask |= NativeMethods.SIF.SIF_DISABLENOSCROLL;
}
scrollInfo.nMin = 0;
scrollInfo.nMax = scrollWidth;
scrollInfo.nPage = pageWidth;
this.SetScrollInfo(ScrollOrientation.HorizontalScroll, scrollInfo, true);
}
///
/// Updates the scrollbars.
///
protected void UpdateScrollbars()
{
this.UpdateHorizontalScrollbar();
this.UpdateVerticalScrollbar();
}
///
/// Updates the properties of the vertical scrollbar.
///
protected virtual void UpdateVerticalScroll()
{
NativeMethods.SCROLLINFO scrollInfo;
scrollInfo = this.GetScrollInfo(ScrollOrientation.VerticalScroll);
this.VerticalScroll.Enabled = this.Enabled;
this.VerticalScroll.LargeChange = scrollInfo.nPage;
this.VerticalScroll.Maximum = scrollInfo.nMax;
this.VerticalScroll.Minimum = scrollInfo.nMin;
this.VerticalScroll.SmallChange = this.StepSize.Height;
this.VerticalScroll.Value = scrollInfo.nPos;
this.VerticalScroll.Visible = true;
}
///
/// Updates the vertical scrollbar.
///
protected virtual void UpdateVerticalScrollbar()
{
NativeMethods.SCROLLINFO scrollInfo;
int scrollHeight;
int pageHeight;
scrollHeight = this.ScrollSize.Height - 1;
pageHeight = this.PageSize.Height;
if (scrollHeight < 1)
{
scrollHeight = 0;
pageHeight = 1;
}
scrollInfo = new NativeMethods.SCROLLINFO();
scrollInfo.fMask = NativeMethods.SIF.SIF_PAGE | NativeMethods.SIF.SIF_RANGE;
if (AlwaysShowVScroll)
{
scrollInfo.fMask |= NativeMethods.SIF.SIF_DISABLENOSCROLL;
}
scrollInfo.nMin = 0;
scrollInfo.nMax = scrollHeight;
scrollInfo.nPage = pageHeight;
this.SetScrollInfo(ScrollOrientation.VerticalScroll, scrollInfo, true);
}
///
/// Processes the WM_HSCROLL and WM_VSCROLL Windows messages.
///
///
/// The Windows to process.
///
protected virtual void WmScroll(ref Message msg)
{
ScrollOrientation scrollbar;
int oldValue;
int newValue;
ScrollEventType eventType;
eventType = this.GetEventType(msg.WParam);
scrollbar = msg.Msg == NativeMethods.WM_HSCROLL ? ScrollOrientation.HorizontalScroll : ScrollOrientation.VerticalScroll;
if (eventType != ScrollEventType.EndScroll)
{
int step;
NativeMethods.SCROLLINFO scrollInfo;
step = scrollbar == ScrollOrientation.HorizontalScroll ? this.StepSize.Width : this.StepSize.Height;
scrollInfo = this.GetScrollInfo(scrollbar);
scrollInfo.fMask = NativeMethods.SIF.SIF_POS;
oldValue = scrollInfo.nPos;
switch (eventType)
{
case ScrollEventType.ThumbPosition:
case ScrollEventType.ThumbTrack:
scrollInfo.nPos = scrollInfo.nTrackPos;
break;
case ScrollEventType.SmallDecrement:
scrollInfo.nPos = oldValue - step;
break;
case ScrollEventType.SmallIncrement:
scrollInfo.nPos = oldValue + step;
break;
case ScrollEventType.LargeDecrement:
scrollInfo.nPos = oldValue - scrollInfo.nPage;
break;
case ScrollEventType.LargeIncrement:
scrollInfo.nPos = oldValue + scrollInfo.nPage;
break;
case ScrollEventType.First:
scrollInfo.nPos = scrollInfo.nMin;
break;
case ScrollEventType.Last:
scrollInfo.nPos = scrollInfo.nMax;
break;
default:
Debug.Assert(false, string.Format("Unknown scroll event type {0}", eventType));
break;
}
if (scrollInfo.nPos > ((scrollInfo.nMax - scrollInfo.nMin) + 1) - scrollInfo.nPage)
{
scrollInfo.nPos = ((scrollInfo.nMax - scrollInfo.nMin) + 1) - scrollInfo.nPage;
}
if (scrollInfo.nPos < scrollInfo.nMin)
{
scrollInfo.nPos = scrollInfo.nMin;
}
newValue = scrollInfo.nPos;
this.SetScrollInfo(scrollbar, scrollInfo, true);
}
else
{
oldValue = 0;
newValue = 0;
}
this.OnScroll(new ScrollEventArgs(eventType, oldValue, newValue, scrollbar));
}
#endregion
#region Private Members
///
/// Gets scrollbar properties
///
/// The bar.
///
private NativeMethods.SCROLLINFO GetScrollInfo(ScrollOrientation scrollbar)
{
NativeMethods.SCROLLINFO info;
info = new NativeMethods.SCROLLINFO();
info.fMask = NativeMethods.SIF.SIF_ALL;
NativeMethods.GetScrollInfo(this.Handle, (int)scrollbar, info);
return info;
}
///
/// Sets scrollbar properties.
///
/// The scrollbar.
/// The scrollbar properties.
///
/// if set to true the scrollbar will be repainted.
///
///
// ReSharper disable UnusedMethodReturnValue.Local
private int SetScrollInfo(ScrollOrientation scrollbar, NativeMethods.SCROLLINFO scrollInfo, bool refresh) // ReSharper restore UnusedMethodReturnValue.Local
{
return NativeMethods.SetScrollInfo(this.Handle, (int)scrollbar, scrollInfo, refresh);
}
#endregion
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox/ScrollProperties.cs
================================================
using System.ComponentModel;
// Original ScrollControl code by Scott Crawford (http://sukiware.com/)
namespace Cyotek.Windows.Forms
{
partial class ScrollControl
{
#region Nested Types
///
/// Provides basic properties for the horizontal scroll bar in a .
///
public class HScrollProperties : ScrollProperties
{
#region Public Constructors
///
/// Initializes a new instance of the class.
///
/// The whose scrolling properties this object describes.
public HScrollProperties(ScrollControl container)
: base(container)
{ }
#endregion
}
///
/// Encapsulates properties related to scrolling.
///
public abstract class ScrollProperties
{
#region Instance Fields
private readonly ScrollControl _container;
#endregion
#region Protected Constructors
///
/// Initializes a new instance of the class.
///
/// The whose scrolling properties this object describes.
protected ScrollProperties(ScrollControl container)
{
//System.Windows.Forms.ScrollProperties
_container = container;
}
#endregion
#region Public Properties
///
/// Gets or sets whether the scroll bar can be used on the container.
///
/// true if the scroll bar can be used; otherwise, false.
[DefaultValue(true)]
public bool Enabled { get; set; }
///
/// Gets or sets the distance to move a scroll bar in response to a large scroll command.
///
/// An describing how far, in pixels, to move the scroll bar in response to a large change.
[DefaultValue(10)]
public int LargeChange { get; set; }
///
/// Gets or sets the upper limit of the scrollable range.
///
/// An representing the maximum range of the scroll bar.
[DefaultValue(100)]
public int Maximum { get; set; }
///
/// Gets or sets the lower limit of the scrollable range.
///
/// An representing the lower range of the scroll bar.
[DefaultValue(0)]
public int Minimum { get; set; }
///
/// Gets the control to which this scroll information applies.
///
/// A .
public ScrollControl ParentControl
{
get { return _container; }
}
///
/// Gets or sets the distance to move a scroll bar in response to a small scroll command.
///
/// An representing how far, in pixels, to move the scroll bar.
[DefaultValue(1)]
public int SmallChange { get; set; }
///
/// Gets or sets a numeric value that represents the current position of the scroll bar box.
///
/// An representing the position of the scroll bar box, in pixels.
[Bindable(true)]
[DefaultValue(0)]
public int Value { get; set; }
///
/// Gets or sets whether the scroll bar can be seen by the user.
///
/// true if it can be seen; otherwise, false.
[DefaultValue(false)]
public bool Visible { get; set; }
#endregion
}
///
/// Provides basic properties for the vertical scroll bar in a .
///
public class VScrollProperties : ScrollProperties
{
#region Public Constructors
///
/// Initializes a new instance of the class.
///
/// The whose scrolling properties this object describes.
public VScrollProperties(ScrollControl container)
: base(container)
{ }
#endregion
}
#endregion
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox/VirtualScrollableControl.cs
================================================
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
// Original VirtualScrollableControl code by Scott Crawford (http://sukiware.com/)
namespace Cyotek.Windows.Forms
{
///
/// Defines a base class for controls that support auto-scrolling behavior.
///
[ToolboxItem(false)]
public class VirtualScrollableControl : ScrollControl
{
#region Instance Fields
private bool _autoScroll;
private Size _autoScrollMargin;
private Size _autoScrollMinSize;
private Point _autoScrollPosition;
#endregion
#region Public Constructors
///
/// Initializes a new instance of the class.
///
public VirtualScrollableControl()
{
this.AutoScrollMargin = Size.Empty;
this.AutoScrollMinSize = Size.Empty;
this.AutoScrollPosition = Point.Empty;
this.AutoScroll = true;
base.SetStyle(ControlStyles.ContainerControl, true);
}
#endregion
#region Events
///
/// Occurs when the AutoScroll property value changes
///
[Category("Property Changed")]
public event EventHandler AutoScrollChanged;
///
/// Occurs when the AutoScrollMargin property value changes
///
[Category("Property Changed")]
public event EventHandler AutoScrollMarginChanged;
///
/// Occurs when the AutoScrollMinSize property value changes
///
[Category("Property Changed")]
public event EventHandler AutoScrollMinSizeChanged;
///
/// Occurs when the AutoScrollPosition property value changes
///
[Category("Property Changed")]
public event EventHandler AutoScrollPositionChanged;
#endregion
#region Overridden Methods
///
/// Raises the event.
///
///
/// An that contains the event data.
///
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
this.AdjustScrollbars();
if (this.AutoScroll && !this.AutoScrollPosition.IsEmpty)
{
int xOffset;
int yOffset;
Rectangle scrollArea;
scrollArea = this.ScrollArea;
xOffset = scrollArea.Right - this.DisplayRectangle.Right;
yOffset = scrollArea.Bottom - this.DisplayRectangle.Bottom;
if (this.AutoScrollPosition.Y < 0 && yOffset < 0)
{
yOffset = Math.Max(yOffset, this.AutoScrollPosition.Y);
}
else
{
yOffset = 0;
}
if (this.AutoScrollPosition.X < 0 && xOffset < 0)
{
xOffset = Math.Max(xOffset, this.AutoScrollPosition.X);
}
else
{
xOffset = 0;
}
this.ScrollByOffset(new Size(xOffset, yOffset));
}
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected override void OnScroll(ScrollEventArgs e)
{
if (e.Type != ScrollEventType.EndScroll)
{
switch (e.ScrollOrientation)
{
case ScrollOrientation.HorizontalScroll:
this.ScrollByOffset(new Size(e.NewValue + this.AutoScrollPosition.X, 0));
break;
case ScrollOrientation.VerticalScroll:
this.ScrollByOffset(new Size(0, e.NewValue + this.AutoScrollPosition.Y));
break;
}
}
base.OnScroll(e);
}
///
/// Raises the event.
///
///
/// An that contains the event data.
///
protected override void OnVisibleChanged(EventArgs e)
{
if (base.Visible)
{
base.PerformLayout();
}
base.OnVisibleChanged(e);
}
#endregion
#region Public Properties
///
/// Gets or sets a value indicating whether the container enables the user to scroll to any controls placed outside of its visible boundaries.
///
///
/// true if the container enables auto-scrolling; otherwise, false.
///
[Category("Layout")]
[DefaultValue(true)]
public virtual bool AutoScroll
{
get { return _autoScroll; }
set
{
if (this.AutoScroll != value)
{
_autoScroll = value;
this.OnAutoScrollChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets the size of the auto-scroll margin.
///
///
/// A that represents the height and width of the auto-scroll margin in pixels.
///
///
[Category("Layout")]
[DefaultValue(typeof(Size), "0, 0")]
public virtual Size AutoScrollMargin
{
get { return _autoScrollMargin; }
set
{
if (value.Width < 0)
{
throw new ArgumentOutOfRangeException(nameof(value), "Width must be a positive integer.");
}
else if (value.Height < 0)
{
throw new ArgumentOutOfRangeException(nameof(value), "Height must be a positive integer.");
}
if (this.AutoScrollMargin != value)
{
_autoScrollMargin = value;
this.OnAutoScrollMarginChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets the minimum size of the auto-scroll.
///
///
/// A that determines the minimum size of the virtual area through which the user can scroll.
///
[Category("Layout")]
[DefaultValue(typeof(Size), "0, 0")]
public virtual Size AutoScrollMinSize
{
get { return _autoScrollMinSize; }
set
{
if (this.AutoScrollMinSize != value)
{
_autoScrollMinSize = value;
this.OnAutoScrollMinSizeChanged(EventArgs.Empty);
}
}
}
///
/// Gets or sets the location of the auto-scroll position.
///
///
/// A that represents the auto-scroll position in pixels.
///
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public virtual Point AutoScrollPosition
{
get { return _autoScrollPosition; }
set
{
Point translated;
translated = this.AdjustPositionToSize(new Point(-value.X, -value.Y));
if (this.AutoScrollPosition != translated)
{
this.ScrollByOffset(new Size(_autoScrollPosition.X - translated.X, _autoScrollPosition.Y - translated.Y));
_autoScrollPosition = translated;
this.OnAutoScrollPositionChanged(EventArgs.Empty);
}
}
}
#endregion
#region Protected Properties
///
/// Total area of all visible controls which are scrolled with this container
///
protected Rectangle ScrollArea
{
get
{
Rectangle area;
area = Rectangle.Empty;
foreach (Control child in Controls)
{
if (child.Visible)
{
area = Rectangle.Union(child.Bounds, area);
}
}
return Rectangle.Union(area, new Rectangle(_autoScrollPosition, _autoScrollMinSize));
}
}
///
/// Gets the view port rectangle.
///
/// The view port rectangle.
protected Rectangle ViewPortRectangle
{
get { return new Rectangle(-_autoScrollPosition.X, -_autoScrollPosition.Y, this.DisplayRectangle.Width, this.DisplayRectangle.Height); }
}
#endregion
#region Public Members
///
/// Scrolls the specified child control into view on an auto-scroll enabled control.
///
/// The child control to scroll into view.
public void ScrollControlIntoView(Control activeControl)
{
if (activeControl.Visible && AutoScroll && (HorizontalScroll.Visible || VerticalScroll.Visible))
{
Point position;
position = this.AdjustPositionToSize(new Point(this.AutoScrollPosition.X + activeControl.Left, this.AutoScrollPosition.Y + activeControl.Top));
if (position.X != this.AutoScrollPosition.X || position.Y != this.AutoScrollPosition.Y)
{
this.ScrollByOffset(new Size(this.AutoScrollPosition.X - position.X, this.AutoScrollPosition.Y - position.Y));
}
}
}
#endregion
#region Protected Members
///
/// Adjusts the given Point according to the scroll size
///
/// The position.
///
protected Point AdjustPositionToSize(Point position)
{
int x;
int y;
x = position.X;
y = position.Y;
if (x < -(this.AutoScrollMinSize.Width - this.ClientRectangle.Width))
{
x = -(this.AutoScrollMinSize.Width - this.ClientRectangle.Width);
}
if (y < -(this.AutoScrollMinSize.Height - this.ClientRectangle.Height))
{
y = -(this.AutoScrollMinSize.Height - base.ClientRectangle.Height);
}
if (x > 0)
{
x = 0;
}
if (y > 0)
{
y = 0;
}
return new Point(x, y);
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnAutoScrollChanged(EventArgs e)
{
EventHandler handler;
handler = this.AutoScrollChanged;
if (handler != null)
{
handler(this, e);
}
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnAutoScrollMarginChanged(EventArgs e)
{
EventHandler handler;
handler = this.AutoScrollMarginChanged;
if (handler != null)
{
handler(this, e);
}
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnAutoScrollMinSizeChanged(EventArgs e)
{
EventHandler handler;
this.AutoScrollPosition = this.AdjustPositionToSize(this.AutoScrollPosition);
this.AdjustScrollbars();
handler = this.AutoScrollMinSizeChanged;
if (handler != null)
{
handler(this, e);
}
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected virtual void OnAutoScrollPositionChanged(EventArgs e)
{
EventHandler handler;
handler = this.AutoScrollPositionChanged;
if (handler != null)
{
handler(this, e);
}
}
#endregion
#region Private Members
///
/// Adjusts the scrollbars.
///
private void AdjustScrollbars()
{
Rectangle clientRectangle;
clientRectangle = this.ClientRectangle;
if (clientRectangle.Width > 1 && clientRectangle.Height > 1)
{
Size scrollSize;
Size pageSize;
bool horizontalScrollVisible;
bool verticalScrollVisible;
scrollSize = Size.Empty;
pageSize = Size.Empty;
horizontalScrollVisible = this.AutoScroll && this.AutoScrollMinSize.Width > clientRectangle.Width;
verticalScrollVisible = this.AutoScroll && this.AutoScrollMinSize.Height > clientRectangle.Height;
if (verticalScrollVisible)
{
scrollSize.Height = this.AutoScrollMinSize.Height;
pageSize.Height = clientRectangle.Height - 1;
}
if (horizontalScrollVisible)
{
scrollSize.Width = this.AutoScrollMinSize.Width;
pageSize.Width = clientRectangle.Width - 1;
}
this.ScrollSize = scrollSize;
this.PageSize = pageSize;
}
}
///
/// Scrolls child controls by the given offset
///
/// The offset.
private void ScrollByOffset(Size offset)
{
if (!offset.IsEmpty)
{
this.SuspendLayout();
foreach (Control child in Controls)
{
child.Location -= offset;
}
_autoScrollPosition = new Point(_autoScrollPosition.X - offset.Width, _autoScrollPosition.Y - offset.Height);
this.ScrollTo(-_autoScrollPosition.X, -_autoScrollPosition.Y);
this.ResumeLayout();
this.Invalidate();
}
}
#endregion
};
} ;
================================================
FILE: Cyotek.Windows.Forms.ImageBox/ZoomLevelCollection.cs
================================================
using System;
using System.Collections;
using System.Collections.Generic;
namespace Cyotek.Windows.Forms
{
// Cyotek ImageBox
// Copyright (c) 2010-2015 Cyotek Ltd.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
///
/// Represents available levels of zoom in an control
///
public class ZoomLevelCollection : IList
{
#region Public Constructors
///
/// Initializes a new instance of the class.
///
public ZoomLevelCollection()
{
this.List = new SortedList();
}
///
/// Initializes a new instance of the class.
///
/// The default values to populate the collection with.
/// Thrown if the collection parameter is null
public ZoomLevelCollection(IEnumerable collection)
: this()
{
if (collection == null)
{
throw new ArgumentNullException(nameof(collection));
}
this.AddRange(collection);
}
#endregion
#region Public Class Properties
///
/// Returns the default zoom levels
///
public static ZoomLevelCollection Default
{
get
{
return new ZoomLevelCollection(new[]
{
7, 10, 15, 20, 25, 30, 50, 70, 100, 150, 200, 300, 400, 500, 600, 700, 800, 1200, 1600
});
}
}
#endregion
#region Public Properties
///
/// Gets the number of elements contained in the .
///
///
/// The number of elements contained in the .
///
public int Count
{
get { return this.List.Count; }
}
///
/// Gets a value indicating whether the is read-only.
///
/// true if this instance is read only; otherwise, false.
/// true if the is read-only; otherwise, false.
///
public bool IsReadOnly
{
get { return false; }
}
///
/// Gets or sets the zoom level at the specified index.
///
/// The index.
public int this[int index]
{
get { return this.List.Values[index]; }
set
{
this.List.RemoveAt(index);
this.Add(value);
}
}
#endregion
#region Protected Properties
///
/// Gets or sets the backing list.
///
protected SortedList List { get; set; }
#endregion
#region Public Members
///
/// Adds an item to the .
///
/// The object to add to the .
public void Add(int item)
{
this.List.Add(item, item);
}
///
/// Adds a range of items to the .
///
/// The items to add to the collection.
/// Thrown if the collection parameter is null.
public void AddRange(IEnumerable collection)
{
if (collection == null)
{
throw new ArgumentNullException(nameof(collection));
}
foreach (int value in collection)
{
this.Add(value);
}
}
///
/// Removes all items from the .
///
public void Clear()
{
this.List.Clear();
}
///
/// Determines whether the contains a specific value.
///
/// The object to locate in the .
/// true if is found in the ; otherwise, false.
public bool Contains(int item)
{
return this.List.ContainsKey(item);
}
///
/// Copies a range of elements this collection into a destination .
///
/// The that receives the data.
/// A 64-bit integer that represents the index in the at which storing begins.
public void CopyTo(int[] array, int arrayIndex)
{
for (int i = 0; i < this.Count; i++)
{
array[arrayIndex + i] = this.List.Values[i];
}
}
///
/// Finds the index of a zoom level matching or nearest to the specified value.
///
/// The zoom level.
public int FindNearest(int zoomLevel)
{
int nearestValue = this.List.Values[0];
int nearestDifference = Math.Abs(nearestValue - zoomLevel);
for (int i = 1; i < this.Count; i++)
{
int value = this.List.Values[i];
int difference = Math.Abs(value - zoomLevel);
if (difference < nearestDifference)
{
nearestValue = value;
nearestDifference = difference;
}
}
return nearestValue;
}
///
/// Returns an enumerator that iterates through the collection.
///
/// A that can be used to iterate through the collection.
public IEnumerator GetEnumerator()
{
return this.List.Values.GetEnumerator();
}
///
/// Determines the index of a specific item in the .
///
/// The object to locate in the .
/// The index of if found in the list; otherwise, -1.
public int IndexOf(int item)
{
return this.List.IndexOfKey(item);
}
///
/// Not implemented.
///
/// The index.
/// The item.
/// Not implemented
public void Insert(int index, int item)
{
throw new NotImplementedException();
}
///
/// Returns the next increased zoom level for the given current zoom.
///
/// The current zoom level.
/// The next matching increased zoom level for the given current zoom if applicable, otherwise the nearest zoom.
public int NextZoom(int zoomLevel)
{
int index;
index = this.IndexOf(this.FindNearest(zoomLevel));
if (index < this.Count - 1)
{
index++;
}
return this[index];
}
///
/// Returns the next decreased zoom level for the given current zoom.
///
/// The current zoom level.
/// The next matching decreased zoom level for the given current zoom if applicable, otherwise the nearest zoom.
public int PreviousZoom(int zoomLevel)
{
int index;
index = this.IndexOf(this.FindNearest(zoomLevel));
if (index > 0)
{
index--;
}
return this[index];
}
///
/// Removes the first occurrence of a specific object from the .
///
/// The object to remove from the .
/// true if was successfully removed from the ; otherwise, false. This method also returns false if is not found in the original .
public bool Remove(int item)
{
return this.List.Remove(item);
}
///
/// Removes the element at the specified index of the .
///
/// The zero-based index of the element to remove.
public void RemoveAt(int index)
{
this.List.RemoveAt(index);
}
///
/// Copies the elements of the to a new array.
///
/// An array containing copies of the elements of the .
public int[] ToArray()
{
int[] results;
results = new int[this.Count];
this.CopyTo(results, 0);
return results;
}
#endregion
#region IList Members
///
/// Returns an enumerator that iterates through a collection.
///
/// An object that can be used to iterate through the collection.
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
#endregion
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox/ZoomLevelCollectionConverter.cs
================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
namespace Cyotek.Windows.Forms
{
public class ZoomLevelCollectionConverter
: TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return destinationType == typeof(InstanceDescriptor) || base.CanConvertTo(context, destinationType);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
string data;
ZoomLevelCollection result;
data = value as string;
if (!string.IsNullOrEmpty(data))
{
char separator;
string[] items;
TypeConverter converter;
if (culture == null)
culture = CultureInfo.CurrentCulture;
result = new ZoomLevelCollection();
separator = culture.TextInfo.ListSeparator[0];
items = data.Split(separator);
converter = TypeDescriptor.GetConverter(typeof(int));
foreach (string item in items)
result.Add((int)converter.ConvertFromString(context, culture, item));
}
else
result = null;
return result;
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
object result;
if (destinationType == null)
throw new ArgumentNullException("destinationType");
if (value is ZoomLevelCollection)
{
if (destinationType == typeof(string))
{
ZoomLevelCollection collection;
StringBuilder data;
string separator;
TypeConverter converter;
collection = (ZoomLevelCollection)value;
if (culture == null)
culture = CultureInfo.CurrentCulture;
separator = culture.TextInfo.ListSeparator + " ";
converter = TypeDescriptor.GetConverter(typeof(int));
data = new StringBuilder();
foreach (int item in collection)
{
if (data.Length != 0)
data.Append(separator);
data.Append(converter.ConvertToString(context, culture, item));
}
result = data.ToString();
}
else if (destinationType == typeof(InstanceDescriptor))
{
ZoomLevelCollection collection;
ConstructorInfo constructor;
collection = (ZoomLevelCollection)value;
constructor = typeof(ZoomLevelCollection).GetConstructor(new Type[] { typeof(IList) });
result = new InstanceDescriptor(constructor, new object[] { collection.ToArray() });
}
else
result = null;
}
else
result = null;
if (result == null)
result = base.ConvertTo(context, culture, value, destinationType);
return result;
}
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/AboutDialog.cs
================================================
using System;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using CommonMark;
using Cyotek.Windows.Forms.Demo.Properties;
using TheArtOfDev.HtmlRenderer.WinForms;
namespace Cyotek.Windows.Forms.Demo
{
// Cyotek ImageBox
// Copyright (c) 2010-2015 Cyotek Ltd.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
internal partial class AboutDialog : BaseForm
{
#region Constructors
public AboutDialog()
{
this.InitializeComponent();
}
#endregion
#region Static Methods
internal static void ShowAboutDialog()
{
using (Form dialog = new AboutDialog())
{
dialog.ShowDialog();
}
}
#endregion
#region Properties
protected TabControl TabControl
{
get { return docsTabControl; }
}
#endregion
#region Methods
protected override void OnFontChanged(EventArgs e)
{
base.OnFontChanged(e);
this.PositionTabControl();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (!this.DesignMode)
{
FileVersionInfo info;
Assembly assembly;
string title;
assembly = typeof(ImageBox).Assembly;
info = FileVersionInfo.GetVersionInfo(assembly.Location);
title = info.ProductName;
this.Text = string.Format("About {0}", title);
nameLabel.Text = title;
versionLabel.Text = string.Format("Version {0}", info.FileVersion);
copyrightLabel.Text = info.LegalCopyright;
this.AddReadme("CHANGELOG.md");
this.AddReadme("README.md");
this.AddReadme("ACKNOWLEDGEMENTS.md");
this.AddReadme("LICENSE.txt");
this.LoadDocumentForTab(docsTabControl.SelectedTab);
}
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
this.PositionTabControl();
}
private void AddReadme(string fileName)
{
docsTabControl.TabPages.Add(new TabPage
{
UseVisualStyleBackColor = true,
Padding = new Padding(9),
ToolTipText = this.GetFullReadmePath(fileName),
Text = fileName,
Tag = fileName
});
}
private void closeButton_Click(object sender, EventArgs e)
{
this.Close();
}
private void docsTabControl_Selecting(object sender, TabControlCancelEventArgs e)
{
this.LoadDocumentForTab(e.TabPage);
}
private void footerGroupBox_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawLine(SystemPens.ControlDark, 0, 0, footerGroupBox.Width, 0);
e.Graphics.DrawLine(SystemPens.ControlLightLight, 0, 1, footerGroupBox.Width, 1);
}
private string GetFullReadmePath(string fileName)
{
return Path.GetFullPath(Path.Combine(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"..\..\..\"), fileName));
}
private void LoadDocumentForTab(TabPage page)
{
if (page != null && page.Controls.Count == 0 && page.Tag != null)
{
Control documentView;
string fullPath;
string text;
Cursor.Current = Cursors.WaitCursor;
Debug.Print("Loading readme: {0}", page.Tag);
fullPath = this.GetFullReadmePath(page.Tag.ToString());
text = File.Exists(fullPath) ? File.ReadAllText(fullPath) : string.Format("Cannot find file '{0}'", fullPath);
if (text.IndexOf('\n') != -1 && text.IndexOf('\r') == -1)
{
text = text.Replace("\n", "\r\n");
}
switch (Path.GetExtension(fullPath))
{
case ".md":
documentView = new HtmlPanel
{
Dock = DockStyle.Fill,
BaseStylesheet = Resources.CSS,
Text = string.Concat("", CommonMarkConverter.Convert(text), "") // HACK: HTML panel screws up rendering if a tag isn't present
};
break;
default:
documentView = new TextBox
{
ReadOnly = true,
Multiline = true,
WordWrap = true,
ScrollBars = ScrollBars.Vertical,
Dock = DockStyle.Fill,
Text = text
};
break;
}
page.Controls.Add(documentView);
Cursor.Current = Cursors.Default;
}
}
private void PositionTabControl()
{
docsTabControl?.SetBounds(docsTabControl.Left, docsTabControl.Top, this.ClientSize.Width - docsTabControl.Left * 2, this.ClientSize.Height - (docsTabControl.Top + footerGroupBox.Height + docsTabControl.Left));
}
private void webLinkLabel_Click(object sender, EventArgs e)
{
try
{
Process.Start(((Control)sender).Text);
}
catch (Exception ex)
{
MessageBox.Show(string.Format("Unable to start the specified URI.\n\n{0}", ex.Message), this.Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
#endregion
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/AboutDialog.designer.cs
================================================
namespace Cyotek.Windows.Forms.Demo
{
partial class AboutDialog
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.closeButton = new System.Windows.Forms.Button();
this.nameLabel = new System.Windows.Forms.Label();
this.versionLabel = new System.Windows.Forms.Label();
this.copyrightLabel = new System.Windows.Forms.Label();
this.iconPictureBox = new System.Windows.Forms.PictureBox();
this.footerGroupBox = new System.Windows.Forms.Panel();
this.webLinkLabel = new System.Windows.Forms.LinkLabel();
this.docsTabControl = new System.Windows.Forms.TabControl();
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
((System.ComponentModel.ISupportInitialize)(this.iconPictureBox)).BeginInit();
this.footerGroupBox.SuspendLayout();
this.SuspendLayout();
//
// closeButton
//
this.closeButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.closeButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.closeButton.Location = new System.Drawing.Point(453, 10);
this.closeButton.Name = "closeButton";
this.closeButton.Size = new System.Drawing.Size(64, 20);
this.closeButton.TabIndex = 1;
this.closeButton.Text = "Close";
this.closeButton.UseVisualStyleBackColor = true;
this.closeButton.Click += new System.EventHandler(this.closeButton_Click);
//
// nameLabel
//
this.nameLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.nameLabel.AutoSize = true;
this.nameLabel.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.nameLabel.Location = new System.Drawing.Point(43, 10);
this.nameLabel.Name = "nameLabel";
this.nameLabel.Size = new System.Drawing.Size(38, 13);
this.nameLabel.TabIndex = 0;
this.nameLabel.Text = "Name";
//
// versionLabel
//
this.versionLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.versionLabel.AutoSize = true;
this.versionLabel.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.versionLabel.Location = new System.Drawing.Point(43, 22);
this.versionLabel.Name = "versionLabel";
this.versionLabel.Size = new System.Drawing.Size(45, 13);
this.versionLabel.TabIndex = 1;
this.versionLabel.Text = "Version";
//
// copyrightLabel
//
this.copyrightLabel.AutoSize = true;
this.copyrightLabel.Location = new System.Drawing.Point(45, 41);
this.copyrightLabel.Name = "copyrightLabel";
this.copyrightLabel.Size = new System.Drawing.Size(50, 13);
this.copyrightLabel.TabIndex = 2;
this.copyrightLabel.Text = "copyright";
//
// iconPictureBox
//
this.iconPictureBox.Image = global::Cyotek.Windows.Forms.Demo.Properties.Resources.Icon;
this.iconPictureBox.Location = new System.Drawing.Point(10, 10);
this.iconPictureBox.Name = "iconPictureBox";
this.iconPictureBox.Size = new System.Drawing.Size(32, 32);
this.iconPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
this.iconPictureBox.TabIndex = 4;
this.iconPictureBox.TabStop = false;
//
// footerGroupBox
//
this.footerGroupBox.BackColor = System.Drawing.SystemColors.Control;
this.footerGroupBox.Controls.Add(this.webLinkLabel);
this.footerGroupBox.Controls.Add(this.closeButton);
this.footerGroupBox.Dock = System.Windows.Forms.DockStyle.Bottom;
this.footerGroupBox.Location = new System.Drawing.Point(0, 388);
this.footerGroupBox.Name = "footerGroupBox";
this.footerGroupBox.Size = new System.Drawing.Size(527, 41);
this.footerGroupBox.TabIndex = 4;
this.footerGroupBox.Paint += new System.Windows.Forms.PaintEventHandler(this.footerGroupBox_Paint);
//
// webLinkLabel
//
this.webLinkLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.webLinkLabel.AutoSize = true;
this.webLinkLabel.ForeColor = System.Drawing.SystemColors.HotTrack;
this.webLinkLabel.Location = new System.Drawing.Point(10, 14);
this.webLinkLabel.Name = "webLinkLabel";
this.webLinkLabel.Size = new System.Drawing.Size(89, 13);
this.webLinkLabel.TabIndex = 0;
this.webLinkLabel.TabStop = true;
this.webLinkLabel.Tag = "www.cyotek.com";
this.webLinkLabel.Text = "www.cyotek.com";
this.toolTip.SetToolTip(this.webLinkLabel, "Visit the Cyotek website for development topics and code");
this.webLinkLabel.Click += new System.EventHandler(this.webLinkLabel_Click);
//
// docsTabControl
//
this.docsTabControl.Location = new System.Drawing.Point(10, 67);
this.docsTabControl.Name = "docsTabControl";
this.docsTabControl.SelectedIndex = 0;
this.docsTabControl.Size = new System.Drawing.Size(505, 315);
this.docsTabControl.TabIndex = 3;
this.docsTabControl.Selecting += new System.Windows.Forms.TabControlCancelEventHandler(this.docsTabControl_Selecting);
//
// AboutDialog
//
this.AcceptButton = this.closeButton;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.BackColor = System.Drawing.SystemColors.Window;
this.CancelButton = this.closeButton;
this.ClientSize = new System.Drawing.Size(527, 429);
this.Controls.Add(this.docsTabControl);
this.Controls.Add(this.footerGroupBox);
this.Controls.Add(this.iconPictureBox);
this.Controls.Add(this.copyrightLabel);
this.Controls.Add(this.versionLabel);
this.Controls.Add(this.nameLabel);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.Name = "AboutDialog";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "About";
((System.ComponentModel.ISupportInitialize)(this.iconPictureBox)).EndInit();
this.footerGroupBox.ResumeLayout(false);
this.footerGroupBox.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button closeButton;
private System.Windows.Forms.Label nameLabel;
private System.Windows.Forms.Label versionLabel;
private System.Windows.Forms.Label copyrightLabel;
private System.Windows.Forms.PictureBox iconPictureBox;
private System.Windows.Forms.Panel footerGroupBox;
private System.Windows.Forms.LinkLabel webLinkLabel;
private System.Windows.Forms.TabControl docsTabControl;
private System.Windows.Forms.ToolTip toolTip;
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/AboutDialog.resx
================================================
text/microsoft-resx
2.0
System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
17, 17
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/AnimatedGifDemoForm.Designer.cs
================================================
namespace Cyotek.Windows.Forms.Demo
{
partial class AnimatedGifDemoForm
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.splitContainer = new System.Windows.Forms.SplitContainer();
this.propertyGrid = new Cyotek.Windows.Forms.Demo.PropertyGrid();
this.imageBox = new Cyotek.Windows.Forms.ImageBox();
this.statusStrip = new System.Windows.Forms.StatusStrip();
this.menuStrip = new System.Windows.Forms.MenuStrip();
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.closeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.splitContainer.Panel1.SuspendLayout();
this.splitContainer.Panel2.SuspendLayout();
this.splitContainer.SuspendLayout();
this.menuStrip.SuspendLayout();
this.SuspendLayout();
//
// splitContainer
//
this.splitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
this.splitContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel1;
this.splitContainer.Location = new System.Drawing.Point(0, 24);
this.splitContainer.Name = "splitContainer";
//
// splitContainer.Panel1
//
this.splitContainer.Panel1.Controls.Add(this.propertyGrid);
//
// splitContainer.Panel2
//
this.splitContainer.Panel2.Controls.Add(this.imageBox);
this.splitContainer.Size = new System.Drawing.Size(848, 490);
this.splitContainer.SplitterDistance = 300;
this.splitContainer.SplitterWidth = 3;
this.splitContainer.TabIndex = 0;
//
// propertyGrid
//
this.propertyGrid.Dock = System.Windows.Forms.DockStyle.Fill;
this.propertyGrid.Location = new System.Drawing.Point(0, 0);
this.propertyGrid.Name = "propertyGrid";
this.propertyGrid.SelectedObject = this.imageBox;
this.propertyGrid.Size = new System.Drawing.Size(300, 490);
this.propertyGrid.TabIndex = 0;
//
// imageBox
//
this.imageBox.BackColor = System.Drawing.SystemColors.GradientActiveCaption;
this.imageBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.imageBox.GridDisplayMode = Cyotek.Windows.Forms.ImageBoxGridDisplayMode.Image;
this.imageBox.Image = global::Cyotek.Windows.Forms.Demo.Properties.Resources.AnimationDemo;
this.imageBox.ImageBorderStyle = Cyotek.Windows.Forms.ImageBoxBorderStyle.FixedSingleGlowShadow;
this.imageBox.Location = new System.Drawing.Point(0, 0);
this.imageBox.Name = "imageBox";
this.imageBox.ShowPixelGrid = true;
this.imageBox.Size = new System.Drawing.Size(545, 490);
this.imageBox.TabIndex = 0;
//
// statusStrip
//
this.statusStrip.Location = new System.Drawing.Point(0, 514);
this.statusStrip.Name = "statusStrip";
this.statusStrip.Padding = new System.Windows.Forms.Padding(1, 0, 12, 0);
this.statusStrip.Size = new System.Drawing.Size(848, 22);
this.statusStrip.TabIndex = 6;
//
// menuStrip
//
this.menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.fileToolStripMenuItem,
this.helpToolStripMenuItem});
this.menuStrip.Location = new System.Drawing.Point(0, 0);
this.menuStrip.Name = "menuStrip";
this.menuStrip.Padding = new System.Windows.Forms.Padding(5, 2, 0, 2);
this.menuStrip.Size = new System.Drawing.Size(848, 24);
this.menuStrip.TabIndex = 5;
//
// fileToolStripMenuItem
//
this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.closeToolStripMenuItem});
this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
this.fileToolStripMenuItem.Text = "&File";
//
// closeToolStripMenuItem
//
this.closeToolStripMenuItem.Name = "closeToolStripMenuItem";
this.closeToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.W)));
this.closeToolStripMenuItem.Size = new System.Drawing.Size(148, 22);
this.closeToolStripMenuItem.Text = "&Close";
this.closeToolStripMenuItem.Click += new System.EventHandler(this.closeToolStripMenuItem_Click);
//
// helpToolStripMenuItem
//
this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.aboutToolStripMenuItem});
this.helpToolStripMenuItem.Name = "helpToolStripMenuItem";
this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 20);
this.helpToolStripMenuItem.Text = "&Help";
//
// aboutToolStripMenuItem
//
this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
this.aboutToolStripMenuItem.Size = new System.Drawing.Size(116, 22);
this.aboutToolStripMenuItem.Text = "&About...";
this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click);
//
// AnimatedGifDemoForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(848, 536);
this.Controls.Add(this.splitContainer);
this.Controls.Add(this.statusStrip);
this.Controls.Add(this.menuStrip);
this.Name = "AnimatedGifDemoForm";
this.Text = "Animations";
this.splitContainer.Panel1.ResumeLayout(false);
this.splitContainer.Panel2.ResumeLayout(false);
this.splitContainer.ResumeLayout(false);
this.menuStrip.ResumeLayout(false);
this.menuStrip.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.SplitContainer splitContainer;
private PropertyGrid propertyGrid;
private ImageBox imageBox;
private System.Windows.Forms.StatusStrip statusStrip;
private System.Windows.Forms.MenuStrip menuStrip;
private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem closeToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem;
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/AnimatedGifDemoForm.cs
================================================
using System;
namespace Cyotek.Windows.Forms.Demo
{
// Cyotek ImageBox
// Copyright (c) 2010-2015 Cyotek Ltd.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
internal partial class AnimatedGifDemoForm : BaseForm
{
#region Public Constructors
public AnimatedGifDemoForm()
{
this.InitializeComponent();
}
#endregion
#region Event Handlers
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
{
AboutDialog.ShowAboutDialog();
}
private void closeToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Close();
}
#endregion
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/AnimatedGifDemoForm.resx
================================================
text/microsoft-resx
2.0
System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
248, 17
364, 17
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/BaseForm.Designer.cs
================================================
namespace Cyotek.Windows.Forms.Demo
{
partial class BaseForm
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.SuspendLayout();
//
// BaseForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(726, 323);
this.MinimizeBox = false;
this.Name = "BaseForm";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "BaseForm";
this.ResumeLayout(false);
}
#endregion
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/BaseForm.cs
================================================
using System;
using System.Drawing;
using System.Windows.Forms;
namespace Cyotek.Windows.Forms.Demo
{
// Cyotek ImageBox
// Copyright (c) 2010-2015 Cyotek Ltd.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
internal partial class BaseForm : Form
{
#region Public Constructors
public BaseForm()
{
this.InitializeComponent();
}
#endregion
#region Overridden Methods
protected override void OnLoad(EventArgs e)
{
if (!this.DesignMode)
{
this.Font = SystemFonts.MessageBoxFont;
}
base.OnLoad(e);
}
protected override void OnShown(EventArgs e)
{
base.OnShown(e);
Cursor.Current = Cursors.Default;
}
#endregion
#region Protected Members
protected string FormatPoint(Point point)
{
return string.Format("X:{0}, Y:{1}", point.X, point.Y);
}
protected string FormatRectangle(RectangleF rect)
{
return string.Format("X:{0}, Y:{1}, W:{2}, H:{3}", (int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height);
}
#endregion
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/BaseForm.resx
================================================
text/microsoft-resx
2.0
System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/Cyotek.Windows.Forms.ImageBox.Demo.csproj
================================================
Debug
AnyCPU
{86D47D73-B3E7-4ED3-86EA-7BFC0C978A7B}
WinExe
Properties
Cyotek.Windows.Forms.Demo
imgbxdmo
v3.5
512
..\
true
AnyCPU
true
full
false
bin\Debug\
DEBUG;TRACE
prompt
4
false
AnyCPU
pdbonly
true
bin\Release\
TRACE
prompt
4
false
cyopublic.snk
..\res\icon.ico
app.manifest
False
..\packages\CommonMark.NET.0.9.0\lib\net35-client\CommonMark.dll
False
..\packages\HtmlRenderer.Core.1.5.0.5\lib\net35-client\HtmlRenderer.dll
..\packages\HtmlRenderer.WinForms.1.5.0.6\lib\net35-client\HtmlRenderer.WinForms.dll
Form
BaseForm.cs
Form
AnimatedGifDemoForm.cs
Form
DisposedImageDemoForm.cs
Component
Component
Component
Form
MiniMapDemoForm.cs
Form
OpenUrlDialog.cs
Form
ResizableSelectionDemoForm.cs
Form
PanStylesDemoForm.cs
Form
TextDemoForm.cs
Form
DragTestForm.cs
Component
Form
GeneralDemoForm.cs
Form
MainMenuForm.cs
Form
PixelGridForm.cs
True
True
Resources.resx
Component
Form
AboutDialog.cs
Form
ScaledAdornmentsDemoForm.cs
Form
SizeModeDemoForm.cs
Form
SwitchImageDuringZoomDemoForm.cs
Form
VirtualModeDemonstrationForm.cs
icon.ico
BaseForm.cs
AnimatedGifDemoForm.cs
DisposedImageDemoForm.cs
MiniMapDemoForm.cs
OpenUrlDialog.cs
ResizableSelectionDemoForm.cs
Designer
PanStylesDemoForm.cs
TextDemoForm.cs
DragTestForm.cs
GeneralDemoForm.cs
MainMenuForm.cs
PixelGridForm.cs
ResXFileCodeGenerator
Designer
Resources.Designer.cs
AboutDialog.cs
ScaledAdornmentsDemoForm.cs
SizeModeDemoForm.cs
Designer
SwitchImageDuringZoomDemoForm.cs
VirtualModeDemonstrationForm.cs
{4159c8d3-c18d-4bed-8be6-9bad1b0ca4f6}
Cyotek.Windows.Forms.ImageBox
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/DisposedImageDemoForm.Designer.cs
================================================
namespace Cyotek.Windows.Forms.Demo
{
partial class DisposedImageDemoForm
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.menuStrip = new System.Windows.Forms.MenuStrip();
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.closeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.statusStrip = new System.Windows.Forms.StatusStrip();
this.imageBox = new Cyotek.Windows.Forms.ImageBox();
this.menuStrip.SuspendLayout();
this.SuspendLayout();
//
// menuStrip
//
this.menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.fileToolStripMenuItem,
this.helpToolStripMenuItem});
this.menuStrip.Location = new System.Drawing.Point(0, 0);
this.menuStrip.Name = "menuStrip";
this.menuStrip.Size = new System.Drawing.Size(722, 24);
this.menuStrip.TabIndex = 3;
//
// fileToolStripMenuItem
//
this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.closeToolStripMenuItem});
this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
this.fileToolStripMenuItem.Text = "&File";
//
// closeToolStripMenuItem
//
this.closeToolStripMenuItem.Name = "closeToolStripMenuItem";
this.closeToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.W)));
this.closeToolStripMenuItem.Size = new System.Drawing.Size(148, 22);
this.closeToolStripMenuItem.Text = "&Close";
this.closeToolStripMenuItem.Click += new System.EventHandler(this.closeToolStripMenuItem_Click);
//
// helpToolStripMenuItem
//
this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.aboutToolStripMenuItem});
this.helpToolStripMenuItem.Name = "helpToolStripMenuItem";
this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 20);
this.helpToolStripMenuItem.Text = "&Help";
//
// aboutToolStripMenuItem
//
this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
this.aboutToolStripMenuItem.Size = new System.Drawing.Size(116, 22);
this.aboutToolStripMenuItem.Text = "&About...";
this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click);
//
// statusStrip
//
this.statusStrip.Location = new System.Drawing.Point(0, 393);
this.statusStrip.Name = "statusStrip";
this.statusStrip.Size = new System.Drawing.Size(722, 22);
this.statusStrip.TabIndex = 4;
//
// imageBox
//
this.imageBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.imageBox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(192)))));
this.imageBox.Location = new System.Drawing.Point(0, 24);
this.imageBox.Name = "imageBox";
this.imageBox.ScaleText = true;
this.imageBox.ShowPixelGrid = true;
this.imageBox.Size = new System.Drawing.Size(722, 369);
this.imageBox.TabIndex = 5;
this.imageBox.Text = "This is a demonstration of the ImageBox text functionality";
this.imageBox.TextBackColor = System.Drawing.Color.Teal;
this.imageBox.TextDisplayMode = Cyotek.Windows.Forms.ImageBoxGridDisplayMode.Image;
//
// DisposedImageDemoForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(722, 415);
this.Controls.Add(this.imageBox);
this.Controls.Add(this.menuStrip);
this.Controls.Add(this.statusStrip);
this.Name = "DisposedImageDemoForm";
this.Text = "Disposed Image Demonstration";
this.menuStrip.ResumeLayout(false);
this.menuStrip.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.MenuStrip menuStrip;
private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem closeToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem;
private System.Windows.Forms.StatusStrip statusStrip;
private ImageBox imageBox;
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/DisposedImageDemoForm.cs
================================================
using System;
using System.Drawing;
namespace Cyotek.Windows.Forms.Demo
{
// Cyotek ImageBox
// Copyright (c) 2010-2015 Cyotek Ltd.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
internal partial class DisposedImageDemoForm : BaseForm
{
#region Instance Fields
private Image _image;
#endregion
#region Public Constructors
public DisposedImageDemoForm()
{
InitializeComponent();
}
#endregion
#region Overridden Methods
protected override void OnLoad(EventArgs e)
{
_image = new Bitmap(100, 100);
_image.Dispose();
imageBox.Image = _image;
base.OnLoad(e);
}
#endregion
#region Event Handlers
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
{
AboutDialog.ShowAboutDialog();
}
private void closeToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Close();
}
#endregion
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/DisposedImageDemoForm.resx
================================================
text/microsoft-resx
2.0
System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
703, 17
811, 17
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/DragHandle.cs
================================================
using System.Drawing;
namespace Cyotek.Windows.Forms.Demo
{
// Cyotek ImageBox
// Copyright (c) 2010-2015 Cyotek Ltd.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
internal class DragHandle
{
#region Public Constructors
public DragHandle(DragHandleAnchor anchor)
: this()
{
this.Anchor = anchor;
}
#endregion
#region Protected Constructors
protected DragHandle()
{
this.Enabled = true;
this.Visible = true;
}
#endregion
#region Public Properties
public DragHandleAnchor Anchor { get; protected set; }
public Rectangle Bounds { get; set; }
public bool Enabled { get; set; }
public bool Visible { get; set; }
#endregion
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/DragHandleAnchor.cs
================================================
namespace Cyotek.Windows.Forms.Demo
{
// Cyotek ImageBox
// Copyright (c) 2010-2015 Cyotek Ltd.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
internal enum DragHandleAnchor
{
None,
TopLeft,
TopCenter,
TopRight,
MiddleLeft,
MiddleRight,
BottomLeft,
BottomCenter,
BottomRight
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/DragHandleCollection.cs
================================================
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
namespace Cyotek.Windows.Forms.Demo
{
// Cyotek ImageBox
// Copyright (c) 2010-2015 Cyotek Ltd.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
internal class DragHandleCollection : IEnumerable
{
#region Instance Fields
private readonly IDictionary _items;
#endregion
#region Public Constructors
public DragHandleCollection()
{
_items = new Dictionary();
_items.Add(DragHandleAnchor.TopLeft, new DragHandle(DragHandleAnchor.TopLeft));
_items.Add(DragHandleAnchor.TopCenter, new DragHandle(DragHandleAnchor.TopCenter));
_items.Add(DragHandleAnchor.TopRight, new DragHandle(DragHandleAnchor.TopRight));
_items.Add(DragHandleAnchor.MiddleLeft, new DragHandle(DragHandleAnchor.MiddleLeft));
_items.Add(DragHandleAnchor.MiddleRight, new DragHandle(DragHandleAnchor.MiddleRight));
_items.Add(DragHandleAnchor.BottomLeft, new DragHandle(DragHandleAnchor.BottomLeft));
_items.Add(DragHandleAnchor.BottomCenter, new DragHandle(DragHandleAnchor.BottomCenter));
_items.Add(DragHandleAnchor.BottomRight, new DragHandle(DragHandleAnchor.BottomRight));
}
#endregion
#region Public Properties
public int Count
{
get { return _items.Count; }
}
public DragHandle this[DragHandleAnchor index]
{
get { return _items[index]; }
}
#endregion
#region Public Members
///
/// Returns an enumerator that iterates through the collection.
///
///
/// A that can be used to iterate through the collection.
///
public IEnumerator GetEnumerator()
{
return _items.Values.GetEnumerator();
}
public DragHandleAnchor HitTest(Point point)
{
DragHandleAnchor result;
result = DragHandleAnchor.None;
foreach (DragHandle handle in this)
{
if (handle.Visible && handle.Bounds.Contains(point))
{
result = handle.Anchor;
break;
}
}
return result;
}
#endregion
#region IEnumerable Members
///
/// Returns an enumerator that iterates through a collection.
///
///
/// An object that can be used to iterate through the collection.
///
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
#endregion
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/DragTestForm.Designer.cs
================================================
namespace Cyotek.Windows.Forms.Demo
{
partial class DragTestForm
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DragTestForm));
this.imageBox = new Cyotek.Windows.Forms.ImageBox();
this.demoLabel = new System.Windows.Forms.Label();
this.splitContainer = new System.Windows.Forms.SplitContainer();
this.menuStrip = new System.Windows.Forms.MenuStrip();
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.closeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.statusStrip = new System.Windows.Forms.StatusStrip();
this.splitContainer.Panel1.SuspendLayout();
this.splitContainer.Panel2.SuspendLayout();
this.splitContainer.SuspendLayout();
this.menuStrip.SuspendLayout();
this.SuspendLayout();
//
// imageBox
//
this.imageBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.imageBox.Location = new System.Drawing.Point(0, 0);
this.imageBox.Name = "imageBox";
this.imageBox.SelectionMode = Cyotek.Windows.Forms.ImageBoxSelectionMode.Rectangle;
this.imageBox.Size = new System.Drawing.Size(342, 278);
this.imageBox.TabIndex = 0;
this.imageBox.VirtualMode = true;
this.imageBox.VirtualSize = new System.Drawing.Size(256, 256);
this.imageBox.Selecting += new System.EventHandler(this.imageBox_Selecting);
this.imageBox.SelectionRegionChanged += new System.EventHandler(this.imageBox_SelectionRegionChanged);
this.imageBox.VirtualDraw += new System.Windows.Forms.PaintEventHandler(this.imageBox_VirtualDraw);
this.imageBox.MouseDown += new System.Windows.Forms.MouseEventHandler(this.imageBox_MouseDown);
this.imageBox.MouseMove += new System.Windows.Forms.MouseEventHandler(this.imageBox_MouseMove);
this.imageBox.MouseUp += new System.Windows.Forms.MouseEventHandler(this.imageBox_MouseUp);
//
// demoLabel
//
this.demoLabel.AutoEllipsis = true;
this.demoLabel.BackColor = System.Drawing.SystemColors.Info;
this.demoLabel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.demoLabel.Dock = System.Windows.Forms.DockStyle.Fill;
this.demoLabel.ForeColor = System.Drawing.SystemColors.InfoText;
this.demoLabel.Location = new System.Drawing.Point(0, 0);
this.demoLabel.Name = "demoLabel";
this.demoLabel.Padding = new System.Windows.Forms.Padding(8, 8, 8, 8);
this.demoLabel.Size = new System.Drawing.Size(360, 278);
this.demoLabel.TabIndex = 1;
this.demoLabel.Text = resources.GetString("demoLabel.Text");
//
// splitContainer
//
this.splitContainer.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.splitContainer.Location = new System.Drawing.Point(10, 23);
this.splitContainer.Name = "splitContainer";
//
// splitContainer.Panel1
//
this.splitContainer.Panel1.Controls.Add(this.imageBox);
//
// splitContainer.Panel2
//
this.splitContainer.Panel2.Controls.Add(this.demoLabel);
this.splitContainer.Size = new System.Drawing.Size(705, 278);
this.splitContainer.SplitterDistance = 342;
this.splitContainer.SplitterWidth = 3;
this.splitContainer.TabIndex = 2;
//
// menuStrip
//
this.menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.fileToolStripMenuItem,
this.helpToolStripMenuItem});
this.menuStrip.Location = new System.Drawing.Point(0, 0);
this.menuStrip.Name = "menuStrip";
this.menuStrip.Padding = new System.Windows.Forms.Padding(5, 2, 0, 2);
this.menuStrip.Size = new System.Drawing.Size(726, 24);
this.menuStrip.TabIndex = 3;
//
// fileToolStripMenuItem
//
this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.closeToolStripMenuItem});
this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
this.fileToolStripMenuItem.Text = "&File";
//
// closeToolStripMenuItem
//
this.closeToolStripMenuItem.Name = "closeToolStripMenuItem";
this.closeToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.W)));
this.closeToolStripMenuItem.Size = new System.Drawing.Size(148, 22);
this.closeToolStripMenuItem.Text = "&Close";
this.closeToolStripMenuItem.Click += new System.EventHandler(this.closeToolStripMenuItem_Click);
//
// helpToolStripMenuItem
//
this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.aboutToolStripMenuItem});
this.helpToolStripMenuItem.Name = "helpToolStripMenuItem";
this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 20);
this.helpToolStripMenuItem.Text = "&Help";
//
// aboutToolStripMenuItem
//
this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
this.aboutToolStripMenuItem.Size = new System.Drawing.Size(116, 22);
this.aboutToolStripMenuItem.Text = "&About...";
this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click);
//
// statusStrip
//
this.statusStrip.Location = new System.Drawing.Point(0, 301);
this.statusStrip.Name = "statusStrip";
this.statusStrip.Padding = new System.Windows.Forms.Padding(1, 0, 12, 0);
this.statusStrip.Size = new System.Drawing.Size(726, 22);
this.statusStrip.TabIndex = 4;
//
// DragTestForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(726, 323);
this.Controls.Add(this.statusStrip);
this.Controls.Add(this.splitContainer);
this.Controls.Add(this.menuStrip);
this.MainMenuStrip = this.menuStrip;
this.Name = "DragTestForm";
this.Text = "Drag Test";
this.splitContainer.Panel1.ResumeLayout(false);
this.splitContainer.Panel2.ResumeLayout(false);
this.splitContainer.ResumeLayout(false);
this.menuStrip.ResumeLayout(false);
this.menuStrip.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private ImageBox imageBox;
private System.Windows.Forms.Label demoLabel;
private System.Windows.Forms.SplitContainer splitContainer;
private System.Windows.Forms.MenuStrip menuStrip;
private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem closeToolStripMenuItem;
private System.Windows.Forms.StatusStrip statusStrip;
private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem;
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/DragTestForm.cs
================================================
using System;
using System.Drawing;
using System.Windows.Forms;
namespace Cyotek.Windows.Forms.Demo
{
// Cyotek ImageBox
// Copyright (c) 2010-2015 Cyotek Ltd.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
internal partial class DragTestForm : BaseForm
{
#region Instance Fields
private RectangleF _dragItem;
private Point _dragOffset;
private bool _isDragging;
#endregion
#region Public Constructors
public DragTestForm()
{
InitializeComponent();
_dragItem = new RectangleF(32, 32, 64, 32);
}
#endregion
#region Event Handlers
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
{
AboutDialog.ShowAboutDialog();
}
private void closeToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Close();
}
private void imageBox_MouseDown(object sender, MouseEventArgs e)
{
Point imagePoint;
imagePoint = imageBox.PointToImage(e.Location);
if (_dragItem.Contains(imagePoint) && e.Button == MouseButtons.Left)
{
_isDragging = true;
_dragOffset = new Point(imagePoint.X - (int)_dragItem.Location.X, imagePoint.Y - (int)_dragItem.Location.Y);
}
}
private void imageBox_MouseMove(object sender, MouseEventArgs e)
{
Point imagePoint;
imagePoint = imageBox.PointToImage(e.Location, true);
// set the cursor
imageBox.Cursor = _dragItem.Contains(imagePoint) ? Cursors.SizeAll : Cursors.Default;
// drag!
if (_isDragging)
{
int x;
int y;
x = Math.Max(0, imagePoint.X - _dragOffset.X);
y = Math.Max(0, imagePoint.Y - _dragOffset.Y);
if (x + _dragItem.Width >= imageBox.VirtualSize.Width)
{
x = imageBox.VirtualSize.Width - (int)_dragItem.Width;
}
if (y + _dragItem.Height >= imageBox.VirtualSize.Height)
{
y = imageBox.VirtualSize.Height - (int)_dragItem.Height;
}
_dragItem.Location = new PointF(x, y);
imageBox.Invalidate();
}
}
private void imageBox_MouseUp(object sender, MouseEventArgs e)
{
_isDragging = false;
}
private void imageBox_Selecting(object sender, ImageBoxCancelEventArgs e)
{
if (_dragItem.Contains(imageBox.PointToImage(e.Location)))
{
e.Cancel = true;
}
}
private void imageBox_SelectionRegionChanged(object sender, EventArgs e)
{
if (!imageBox.SelectionRegion.IsEmpty)
{
_dragItem = imageBox.SelectionRegion;
imageBox.SelectionRegion = RectangleF.Empty;
}
}
private void imageBox_VirtualDraw(object sender, PaintEventArgs e)
{
RectangleF bounds;
// draw the virtual area
bounds = imageBox.GetOffsetRectangle(new RectangleF(PointF.Empty, imageBox.VirtualSize));
using (Brush brush = new SolidBrush(Color.FromArgb(128, Color.Goldenrod)))
{
e.Graphics.FillRectangle(brush, bounds);
}
e.Graphics.DrawRectangle(Pens.DarkGoldenrod, bounds.X, bounds.Y, bounds.Width, bounds.Height);
// draw the "drag" item
bounds = imageBox.GetOffsetRectangle(_dragItem);
using (Brush brush = new SolidBrush(Color.FromArgb(128, Color.CornflowerBlue)))
{
e.Graphics.FillRectangle(brush, bounds);
}
e.Graphics.DrawRectangle(Pens.Blue, bounds.X, bounds.Y, bounds.Width, bounds.Height);
}
#endregion
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/DragTestForm.resx
================================================
text/microsoft-resx
2.0
System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
In this demo, a virtual mode ImageBox is being used to define a drag region, and then move it around.
When the Selecting event is raised, a check is made to see if the current cursor (adjusted for zoom of course!) is within the drag area. If it is, the event is cancelled. If it is not, a new selection region is allowed to be created.
The MouseDown, MouseMove and MouseUp events are used to allow the drag region to be moved around, within the confines of the virtual area.
See the "Resizable Selection" demo for an improved version of this code, which also supports cancelation and resizing support.
17, 17
132, 17
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/EventsListBox.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
namespace Cyotek.Windows.Forms.Demo
{
// Cyotek ImageBox
// Copyright (c) 2010-2015 Cyotek Ltd.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
internal class EventsListBox : ListBox
{
#region Public Members
public void AddEvent(Control sender, string eventName)
{
this.AddEvent(sender, eventName, null);
}
public void AddEvent(Control sender, string eventName, IDictionary values)
{
StringBuilder eventData;
eventData = new StringBuilder();
eventData.Append(DateTime.Now.ToLongTimeString());
eventData.Append("\t");
eventData.Append(sender.Name);
eventData.Append(".");
eventData.Append(eventName);
eventData.Append("(");
if (values != null)
{
int index;
index = 0;
foreach (KeyValuePair value in values)
{
eventData.AppendFormat("{0} = {1}", value.Key, value.Value);
if (index < values.Count - 1)
{
eventData.Append(", ");
}
index++;
}
}
eventData.Append(")");
this.Items.Add(eventData.ToString());
this.TopIndex = this.Items.Count - (this.ClientSize.Height / this.ItemHeight);
}
#endregion
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/FilteredPropertyGrid.cs
================================================
using System;
using System.Collections.Generic;
using System.ComponentModel;
// Derived from https://www.codeproject.com/articles/13342/filtering-properties-in-a-propertygrid
namespace Cyotek.Windows.Forms.Demo
{
///
/// This class overrides the standard PropertyGrid provided by Microsoft.
/// It also allows to hide (or filter) the properties of the SelectedObject displayed by the PropertyGrid.
///
internal class FilteredPropertyGrid : PropertyGrid
{
#region Private Fields
private AttributeCollection _browsableAttributes;
private string[] _browsableProperties;
private AttributeCollection _hiddenAttributes;
private string[] _hiddenProperties;
private List _propertyDescriptors;
private ObjectWrapper _wrapper;
#endregion Private Fields
#region Public Constructors
/// Public constructor.
public FilteredPropertyGrid()
{
_propertyDescriptors = new List();
}
#endregion Public Constructors
#region Public Properties
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new AttributeCollection BrowsableAttributes
{
get { return _browsableAttributes; }
set
{
if (_browsableAttributes != value)
{
_hiddenAttributes = null;
_browsableAttributes = value;
this.RefreshProperties();
}
}
}
/// Get or set the properties to show.
/// if one or several properties don't exist.
[DefaultValue(typeof(string[]), null)]
public string[] BrowsableProperties
{
get { return _browsableProperties; }
set
{
if (value != _browsableProperties)
{
_browsableProperties = value;
//m_HiddenProperties = null;
this.RefreshProperties();
}
}
}
/// Get or set the categories to hide.
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public AttributeCollection HiddenAttributes
{
get { return _hiddenAttributes; }
set
{
if (value != _hiddenAttributes)
{
_hiddenAttributes = value;
_browsableAttributes = null;
this.RefreshProperties();
}
}
}
/// Get or set the properties to hide.
[DefaultValue(typeof(string[]), null)]
public string[] HiddenProperties
{
get { return _hiddenProperties; }
set
{
if (value != _hiddenProperties)
{
//m_BrowsableProperties = null;
_hiddenProperties = value;
this.RefreshProperties();
}
}
}
/// Overwrite the PropertyGrid.SelectedObject property.
/// The object passed to the base PropertyGrid is the wrapper.
public new object SelectedObject
{
get { return _wrapper != null ? ((ObjectWrapper)base.SelectedObject).SelectedObject : null; }
set
{
// Set the new object to the wrapper and create one if necessary.
if (_wrapper == null)
{
_wrapper = new ObjectWrapper(value);
this.RefreshProperties();
}
else if (_wrapper.SelectedObject != value)
{
bool needrefresh = value.GetType() != _wrapper.SelectedObject.GetType();
_wrapper.SelectedObject = value;
if (needrefresh) this.RefreshProperties();
}
// Set the list of properties to the wrapper.
_wrapper.PropertyDescriptors = _propertyDescriptors;
// Link the wrapper to the parent PropertyGrid.
base.SelectedObject = _wrapper;
}
}
#endregion Public Properties
#region Private Methods
/// Allows to hide a set of properties to the parent PropertyGrid.
/// A set of attributes that filter the original collection of properties.
/// For better performance, include the BrowsableAttribute with true value.
private void HideAttribute(Attribute attribute)
{
PropertyDescriptorCollection filteredoriginalpropertydescriptors;
filteredoriginalpropertydescriptors = TypeDescriptor.GetProperties(_wrapper.SelectedObject, new Attribute[] { attribute });
if (filteredoriginalpropertydescriptors == null || filteredoriginalpropertydescriptors.Count == 0)
{
throw new ArgumentException("Attribute not found", attribute.ToString());
}
foreach (PropertyDescriptor propertydescriptor in filteredoriginalpropertydescriptors)
{
this.HideProperty(propertydescriptor);
}
}
/// Allows to hide a property to the parent PropertyGrid.
/// The name of the property to be hidden.
private void HideProperty(PropertyDescriptor property)
{
if (_propertyDescriptors.Contains(property))
{
_propertyDescriptors.Remove(property);
}
}
/// Build the list of the properties to be displayed in the PropertyGrid, following the filters defined the Browsable and Hidden properties.
private void RefreshProperties()
{
if (_wrapper != null)
{
PropertyDescriptorCollection allproperties;
// Clear the list of properties to be displayed.
_propertyDescriptors.Clear();
// Check whether the list is filtered
if (_browsableAttributes != null && _browsableAttributes.Count > 0)
{
// Add to the list the attributes that need to be displayed.
foreach (Attribute attribute in _browsableAttributes)
{
this.ShowAttribute(attribute);
}
}
else
{
// Fill the collection with all the properties.
// PropertyDescriptorCollection originalpropertydescriptors = TypeDescriptor.GetProperties(m_Wrapper.SelectedObject);
// foreach (PropertyDescriptor propertydescriptor in originalpropertydescriptors) m_PropertyDescriptors.Add(propertydescriptor);
// Remove from the list the attributes that mustn't be displayed.
if (_hiddenAttributes != null)
{
foreach (Attribute attribute in _hiddenAttributes)
{
this.HideAttribute(attribute);
}
}
}
// Get all the properties of the SelectedObject
allproperties = TypeDescriptor.GetProperties(_wrapper.SelectedObject);
// Hide if necessary, some properties
if (_hiddenProperties != null && _hiddenProperties.Length > 0)
{
// Remove from the list the properties that mustn't be displayed.
foreach (string propertyname in _hiddenProperties)
{
// Remove from the list the property
this.HideProperty(allproperties[propertyname]);
}
}
// Display if necessary, some properties
if (_browsableProperties != null && _browsableProperties.Length > 0)
{
foreach (string propertyname in _browsableProperties)
{
this.ShowProperty(allproperties[propertyname]);
}
}
}
}
/// Add all the properties that match an attribute to the list of properties to be displayed in the PropertyGrid.
/// The attribute to be added.
private void ShowAttribute(Attribute attribute)
{
PropertyDescriptorCollection filteredoriginalpropertydescriptors;
filteredoriginalpropertydescriptors = TypeDescriptor.GetProperties(_wrapper.SelectedObject, new Attribute[] { attribute });
if (filteredoriginalpropertydescriptors == null || filteredoriginalpropertydescriptors.Count == 0)
{
throw new ArgumentException("Attribute not found", attribute.ToString());
}
foreach (PropertyDescriptor propertydescriptor in filteredoriginalpropertydescriptors)
{
this.ShowProperty(propertydescriptor);
}
}
/// Add a property to the list of properties to be displayed in the PropertyGrid.
/// The property to be added.
private void ShowProperty(PropertyDescriptor property)
{
if (!_propertyDescriptors.Contains(property))
{
_propertyDescriptors.Add(property);
}
}
#endregion Private Methods
#region Private Classes
/// This class is a wrapper. It contains the object the propertyGrid has to display.
private sealed class ObjectWrapper : ICustomTypeDescriptor
{
#region Private Fields
private List _propertyDescriptors;
private object _selectedObject;
#endregion Private Fields
#region Internal Constructors
/// Simple constructor.
/// A reference to the selected object that will linked to the parent PropertyGrid.
internal ObjectWrapper(object obj)
{
_propertyDescriptors = new List();
_selectedObject = obj;
}
#endregion Internal Constructors
#region Public Properties
/// Get or set a reference to the collection of properties to show in the parent PropertyGrid.
public List PropertyDescriptors
{
get { return _propertyDescriptors; }
set { _propertyDescriptors = value; }
}
/// Get or set a reference to the selected objet that will linked to the parent PropertyGrid.
public object SelectedObject
{
get { return _selectedObject; }
set
{
if (_selectedObject != value)
{
_selectedObject = value;
}
}
}
#endregion Public Properties
#region Public Methods
/// GetAttributes.
/// AttributeCollection
public AttributeCollection GetAttributes()
{
return TypeDescriptor.GetAttributes(_selectedObject, true);
}
/// Get Class Name.
/// String
public string GetClassName()
{
return TypeDescriptor.GetClassName(_selectedObject, true);
}
/// GetComponentName.
/// String
public string GetComponentName()
{
return TypeDescriptor.GetComponentName(_selectedObject, true);
}
/// GetConverter.
/// TypeConverter
public TypeConverter GetConverter()
{
return TypeDescriptor.GetConverter(_selectedObject, true);
}
/// GetDefaultEvent.
/// EventDescriptor
public EventDescriptor GetDefaultEvent()
{
return TypeDescriptor.GetDefaultEvent(_selectedObject, true);
}
/// GetDefaultProperty.
/// PropertyDescriptor
public PropertyDescriptor GetDefaultProperty()
{
return TypeDescriptor.GetDefaultProperty(_selectedObject, true);
}
/// GetEditor.
/// editorBaseType
/// object
public object GetEditor(Type editorBaseType)
{
return TypeDescriptor.GetEditor(this, editorBaseType, true);
}
public EventDescriptorCollection GetEvents(Attribute[] attributes)
{
return TypeDescriptor.GetEvents(_selectedObject, attributes, true);
}
public EventDescriptorCollection GetEvents()
{
return TypeDescriptor.GetEvents(_selectedObject, true);
}
public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
return this.GetProperties();
}
public PropertyDescriptorCollection GetProperties()
{
return new PropertyDescriptorCollection(_propertyDescriptors.ToArray(), true);
}
public object GetPropertyOwner(PropertyDescriptor pd)
{
return _selectedObject;
}
#endregion Public Methods
}
#endregion Private Classes
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/GeneralDemoForm.Designer.cs
================================================
namespace Cyotek.Windows.Forms.Demo
{
partial class GeneralDemoForm
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (_previewImage != null)
_previewImage.Dispose();
if (components != null)
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(GeneralDemoForm));
this.viewSplitContainer = new System.Windows.Forms.SplitContainer();
this.selectionSplitContainer = new System.Windows.Forms.SplitContainer();
this.imageBox = new Cyotek.Windows.Forms.ImageBox();
this.previewImageBox = new Cyotek.Windows.Forms.ImageBox();
this.propertyGrid = new Cyotek.Windows.Forms.Demo.PropertyGrid();
this.statusStrip = new System.Windows.Forms.StatusStrip();
this.cursorToolStripStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel();
this.autoScrollPositionToolStripStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
this.imageSizeToolStripStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
this.zoomToolStripStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
this.selectionToolStripStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
this.toolStrip = new System.Windows.Forms.ToolStrip();
this.openFromFileToolStripButton = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator8 = new System.Windows.Forms.ToolStripSeparator();
this.showImageRegionToolStripButton = new System.Windows.Forms.ToolStripButton();
this.showSourceImageRegionToolStripButton = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
this.actualSizeToolStripButton = new System.Windows.Forms.ToolStripButton();
this.zoomInToolStripButton = new System.Windows.Forms.ToolStripButton();
this.zoomOutToolStripButton = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
this.selectAllToolStripButton = new System.Windows.Forms.ToolStripButton();
this.selectNoneToolStripButton = new System.Windows.Forms.ToolStripButton();
this.zoomLevelsToolStripComboBox = new System.Windows.Forms.ToolStripComboBox();
this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator();
this.menuStrip = new System.Windows.Forms.MenuStrip();
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.openToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.openFromFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.fromURLToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator();
this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.editToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.copyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator6 = new System.Windows.Forms.ToolStripSeparator();
this.selectAllToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.selectNoneToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.viewToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.fitCursorLocationToBoundsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.viewSplitContainer.Panel1.SuspendLayout();
this.viewSplitContainer.Panel2.SuspendLayout();
this.viewSplitContainer.SuspendLayout();
this.selectionSplitContainer.Panel1.SuspendLayout();
this.selectionSplitContainer.Panel2.SuspendLayout();
this.selectionSplitContainer.SuspendLayout();
this.statusStrip.SuspendLayout();
this.toolStrip.SuspendLayout();
this.menuStrip.SuspendLayout();
this.SuspendLayout();
//
// viewSplitContainer
//
this.viewSplitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
this.viewSplitContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel2;
this.viewSplitContainer.Location = new System.Drawing.Point(0, 49);
this.viewSplitContainer.Name = "viewSplitContainer";
//
// viewSplitContainer.Panel1
//
this.viewSplitContainer.Panel1.Controls.Add(this.selectionSplitContainer);
//
// viewSplitContainer.Panel2
//
this.viewSplitContainer.Panel2.Controls.Add(this.propertyGrid);
this.viewSplitContainer.Size = new System.Drawing.Size(909, 455);
this.viewSplitContainer.SplitterDistance = 597;
this.viewSplitContainer.TabIndex = 0;
//
// selectionSplitContainer
//
this.selectionSplitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
this.selectionSplitContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel2;
this.selectionSplitContainer.Location = new System.Drawing.Point(0, 0);
this.selectionSplitContainer.Name = "selectionSplitContainer";
this.selectionSplitContainer.Orientation = System.Windows.Forms.Orientation.Horizontal;
//
// selectionSplitContainer.Panel1
//
this.selectionSplitContainer.Panel1.Controls.Add(this.imageBox);
//
// selectionSplitContainer.Panel2
//
this.selectionSplitContainer.Panel2.Controls.Add(this.previewImageBox);
this.selectionSplitContainer.Size = new System.Drawing.Size(597, 455);
this.selectionSplitContainer.SplitterDistance = 293;
this.selectionSplitContainer.TabIndex = 1;
//
// imageBox
//
this.imageBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.imageBox.Location = new System.Drawing.Point(0, 0);
this.imageBox.Name = "imageBox";
this.imageBox.Size = new System.Drawing.Size(597, 293);
this.imageBox.TabIndex = 0;
this.imageBox.Selected += new System.EventHandler(this.imageBox_Selected);
this.imageBox.SelectionRegionChanged += new System.EventHandler(this.imageBox_SelectionRegionChanged);
this.imageBox.ZoomChanged += new System.EventHandler(this.imageBox_ZoomChanged);
this.imageBox.ZoomLevelsChanged += new System.EventHandler(this.imageBox_ZoomLevelsChanged);
this.imageBox.Scroll += new System.Windows.Forms.ScrollEventHandler(this.imageBox_Scroll);
this.imageBox.Paint += new System.Windows.Forms.PaintEventHandler(this.imageBox_Paint);
this.imageBox.MouseLeave += new System.EventHandler(this.imageBox_MouseLeave);
this.imageBox.MouseMove += new System.Windows.Forms.MouseEventHandler(this.imageBox_MouseMove);
this.imageBox.Resize += new System.EventHandler(this.imageBox_Resize);
//
// previewImageBox
//
this.previewImageBox.AllowZoom = false;
this.previewImageBox.PanMode = ImageBoxPanMode.Middle;
this.previewImageBox.BackColor = System.Drawing.SystemColors.Control;
this.previewImageBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.previewImageBox.GridDisplayMode = Cyotek.Windows.Forms.ImageBoxGridDisplayMode.Image;
this.previewImageBox.ImageBorderStyle = Cyotek.Windows.Forms.ImageBoxBorderStyle.FixedSingle;
this.previewImageBox.Location = new System.Drawing.Point(0, 0);
this.previewImageBox.Name = "previewImageBox";
this.previewImageBox.Size = new System.Drawing.Size(597, 158);
this.previewImageBox.TabIndex = 0;
//
// propertyGrid
//
this.propertyGrid.CommandsVisibleIfAvailable = false;
this.propertyGrid.Dock = System.Windows.Forms.DockStyle.Fill;
this.propertyGrid.HelpVisible = false;
this.propertyGrid.Location = new System.Drawing.Point(0, 0);
this.propertyGrid.Name = "propertyGrid";
this.propertyGrid.SelectedObject = this.imageBox;
this.propertyGrid.Size = new System.Drawing.Size(308, 455);
this.propertyGrid.TabIndex = 0;
//
// statusStrip
//
this.statusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.cursorToolStripStatusLabel,
this.toolStripStatusLabel1,
this.autoScrollPositionToolStripStatusLabel,
this.imageSizeToolStripStatusLabel,
this.zoomToolStripStatusLabel,
this.selectionToolStripStatusLabel});
this.statusStrip.Location = new System.Drawing.Point(0, 504);
this.statusStrip.Name = "statusStrip";
this.statusStrip.ShowItemToolTips = true;
this.statusStrip.Size = new System.Drawing.Size(909, 22);
this.statusStrip.TabIndex = 1;
//
// cursorToolStripStatusLabel
//
this.cursorToolStripStatusLabel.Image = global::Cyotek.Windows.Forms.Demo.Properties.Resources.Cursor;
this.cursorToolStripStatusLabel.Name = "cursorToolStripStatusLabel";
this.cursorToolStripStatusLabel.Size = new System.Drawing.Size(16, 17);
this.cursorToolStripStatusLabel.ToolTipText = "Current Cursor Position";
//
// toolStripStatusLabel1
//
this.toolStripStatusLabel1.Name = "toolStripStatusLabel1";
this.toolStripStatusLabel1.Size = new System.Drawing.Size(814, 17);
this.toolStripStatusLabel1.Spring = true;
//
// autoScrollPositionToolStripStatusLabel
//
this.autoScrollPositionToolStripStatusLabel.Image = global::Cyotek.Windows.Forms.Demo.Properties.Resources.Position;
this.autoScrollPositionToolStripStatusLabel.Name = "autoScrollPositionToolStripStatusLabel";
this.autoScrollPositionToolStripStatusLabel.Size = new System.Drawing.Size(16, 17);
this.autoScrollPositionToolStripStatusLabel.ToolTipText = "Auto Scroll Position";
//
// imageSizeToolStripStatusLabel
//
this.imageSizeToolStripStatusLabel.Image = global::Cyotek.Windows.Forms.Demo.Properties.Resources.Size;
this.imageSizeToolStripStatusLabel.Name = "imageSizeToolStripStatusLabel";
this.imageSizeToolStripStatusLabel.Size = new System.Drawing.Size(16, 17);
this.imageSizeToolStripStatusLabel.ToolTipText = "Image Size";
//
// zoomToolStripStatusLabel
//
this.zoomToolStripStatusLabel.Image = global::Cyotek.Windows.Forms.Demo.Properties.Resources.Zoom;
this.zoomToolStripStatusLabel.Name = "zoomToolStripStatusLabel";
this.zoomToolStripStatusLabel.Size = new System.Drawing.Size(16, 17);
this.zoomToolStripStatusLabel.ToolTipText = "Zoom";
//
// selectionToolStripStatusLabel
//
this.selectionToolStripStatusLabel.Image = global::Cyotek.Windows.Forms.Demo.Properties.Resources.SelectAll;
this.selectionToolStripStatusLabel.Name = "selectionToolStripStatusLabel";
this.selectionToolStripStatusLabel.Size = new System.Drawing.Size(16, 17);
//
// toolStrip
//
this.toolStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.openFromFileToolStripButton,
this.toolStripSeparator8,
this.showImageRegionToolStripButton,
this.showSourceImageRegionToolStripButton,
this.toolStripSeparator1,
this.actualSizeToolStripButton,
this.zoomInToolStripButton,
this.zoomOutToolStripButton,
this.toolStripSeparator2,
this.selectAllToolStripButton,
this.selectNoneToolStripButton,
this.zoomLevelsToolStripComboBox,
this.toolStripSeparator4});
this.toolStrip.Location = new System.Drawing.Point(0, 24);
this.toolStrip.Name = "toolStrip";
this.toolStrip.Size = new System.Drawing.Size(909, 25);
this.toolStrip.TabIndex = 2;
//
// openFromFileToolStripButton
//
this.openFromFileToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.openFromFileToolStripButton.Image = global::Cyotek.Windows.Forms.Demo.Properties.Resources.Open;
this.openFromFileToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta;
this.openFromFileToolStripButton.Name = "openFromFileToolStripButton";
this.openFromFileToolStripButton.Size = new System.Drawing.Size(23, 22);
this.openFromFileToolStripButton.Text = "&Open";
this.openFromFileToolStripButton.Click += new System.EventHandler(this.openFromFileToolStripMenuItem_Click);
//
// toolStripSeparator8
//
this.toolStripSeparator8.Name = "toolStripSeparator8";
this.toolStripSeparator8.Size = new System.Drawing.Size(6, 25);
//
// showImageRegionToolStripButton
//
this.showImageRegionToolStripButton.CheckOnClick = true;
this.showImageRegionToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.showImageRegionToolStripButton.Image = global::Cyotek.Windows.Forms.Demo.Properties.Resources.Zone;
this.showImageRegionToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta;
this.showImageRegionToolStripButton.Name = "showImageRegionToolStripButton";
this.showImageRegionToolStripButton.Size = new System.Drawing.Size(23, 22);
this.showImageRegionToolStripButton.Text = "Show Image Region";
this.showImageRegionToolStripButton.Click += new System.EventHandler(this.showImageRegionToolStripButton_Click);
//
// showSourceImageRegionToolStripButton
//
this.showSourceImageRegionToolStripButton.CheckOnClick = true;
this.showSourceImageRegionToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.showSourceImageRegionToolStripButton.Image = global::Cyotek.Windows.Forms.Demo.Properties.Resources.Zone;
this.showSourceImageRegionToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta;
this.showSourceImageRegionToolStripButton.Name = "showSourceImageRegionToolStripButton";
this.showSourceImageRegionToolStripButton.Size = new System.Drawing.Size(23, 22);
this.showSourceImageRegionToolStripButton.Text = "Show Source Image Region";
this.showSourceImageRegionToolStripButton.Click += new System.EventHandler(this.showImageRegionToolStripButton_Click);
//
// toolStripSeparator1
//
this.toolStripSeparator1.Name = "toolStripSeparator1";
this.toolStripSeparator1.Size = new System.Drawing.Size(6, 25);
//
// actualSizeToolStripButton
//
this.actualSizeToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.actualSizeToolStripButton.Image = global::Cyotek.Windows.Forms.Demo.Properties.Resources.ActualSize;
this.actualSizeToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta;
this.actualSizeToolStripButton.Name = "actualSizeToolStripButton";
this.actualSizeToolStripButton.Size = new System.Drawing.Size(23, 22);
this.actualSizeToolStripButton.Text = "Actual Size";
this.actualSizeToolStripButton.Click += new System.EventHandler(this.actualSizeToolStripButton_Click);
//
// zoomInToolStripButton
//
this.zoomInToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.zoomInToolStripButton.Image = global::Cyotek.Windows.Forms.Demo.Properties.Resources.ZoomIn;
this.zoomInToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta;
this.zoomInToolStripButton.Name = "zoomInToolStripButton";
this.zoomInToolStripButton.Size = new System.Drawing.Size(23, 22);
this.zoomInToolStripButton.Text = "Zoom In";
this.zoomInToolStripButton.Click += new System.EventHandler(this.zoomInToolStripButton_Click);
//
// zoomOutToolStripButton
//
this.zoomOutToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.zoomOutToolStripButton.Image = global::Cyotek.Windows.Forms.Demo.Properties.Resources.ZoomOut;
this.zoomOutToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta;
this.zoomOutToolStripButton.Name = "zoomOutToolStripButton";
this.zoomOutToolStripButton.Size = new System.Drawing.Size(23, 22);
this.zoomOutToolStripButton.Text = "Zoom Out";
this.zoomOutToolStripButton.Click += new System.EventHandler(this.zoomOutToolStripButton_Click);
//
// toolStripSeparator2
//
this.toolStripSeparator2.Name = "toolStripSeparator2";
this.toolStripSeparator2.Size = new System.Drawing.Size(6, 25);
//
// selectAllToolStripButton
//
this.selectAllToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.selectAllToolStripButton.Image = global::Cyotek.Windows.Forms.Demo.Properties.Resources.SelectAll;
this.selectAllToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta;
this.selectAllToolStripButton.Name = "selectAllToolStripButton";
this.selectAllToolStripButton.Size = new System.Drawing.Size(23, 22);
this.selectAllToolStripButton.Text = "Select All";
this.selectAllToolStripButton.Click += new System.EventHandler(this.selectAllToolStripMenuItem_Click);
//
// selectNoneToolStripButton
//
this.selectNoneToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.selectNoneToolStripButton.Image = global::Cyotek.Windows.Forms.Demo.Properties.Resources.SelectNone;
this.selectNoneToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta;
this.selectNoneToolStripButton.Name = "selectNoneToolStripButton";
this.selectNoneToolStripButton.Size = new System.Drawing.Size(23, 22);
this.selectNoneToolStripButton.Text = "Select None";
this.selectNoneToolStripButton.Click += new System.EventHandler(this.selectNoneToolStripMenuItem_Click);
//
// zoomLevelsToolStripComboBox
//
this.zoomLevelsToolStripComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.zoomLevelsToolStripComboBox.Name = "zoomLevelsToolStripComboBox";
this.zoomLevelsToolStripComboBox.Size = new System.Drawing.Size(121, 25);
this.zoomLevelsToolStripComboBox.SelectedIndexChanged += new System.EventHandler(this.zoomLevelsToolStripComboBox_SelectedIndexChanged);
//
// toolStripSeparator4
//
this.toolStripSeparator4.Name = "toolStripSeparator4";
this.toolStripSeparator4.Size = new System.Drawing.Size(6, 25);
//
// menuStrip
//
this.menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.fileToolStripMenuItem,
this.editToolStripMenuItem,
this.viewToolStripMenuItem,
this.helpToolStripMenuItem});
this.menuStrip.Location = new System.Drawing.Point(0, 0);
this.menuStrip.Name = "menuStrip";
this.menuStrip.Size = new System.Drawing.Size(909, 24);
this.menuStrip.TabIndex = 3;
//
// fileToolStripMenuItem
//
this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.openToolStripMenuItem,
this.toolStripSeparator3,
this.exitToolStripMenuItem});
this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
this.fileToolStripMenuItem.Text = "&File";
//
// openToolStripMenuItem
//
this.openToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.openFromFileToolStripMenuItem,
this.fromURLToolStripMenuItem});
this.openToolStripMenuItem.Name = "openToolStripMenuItem";
this.openToolStripMenuItem.Size = new System.Drawing.Size(148, 22);
this.openToolStripMenuItem.Text = "&Open";
//
// openFromFileToolStripMenuItem
//
this.openFromFileToolStripMenuItem.Image = global::Cyotek.Windows.Forms.Demo.Properties.Resources.Open;
this.openFromFileToolStripMenuItem.ImageTransparentColor = System.Drawing.Color.Magenta;
this.openFromFileToolStripMenuItem.Name = "openFromFileToolStripMenuItem";
this.openFromFileToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.O)));
this.openFromFileToolStripMenuItem.Size = new System.Drawing.Size(175, 22);
this.openFromFileToolStripMenuItem.Text = "From &File...";
this.openFromFileToolStripMenuItem.Click += new System.EventHandler(this.openFromFileToolStripMenuItem_Click);
//
// fromURLToolStripMenuItem
//
this.fromURLToolStripMenuItem.Name = "fromURLToolStripMenuItem";
this.fromURLToolStripMenuItem.Size = new System.Drawing.Size(175, 22);
this.fromURLToolStripMenuItem.Text = "From &URL...";
this.fromURLToolStripMenuItem.Click += new System.EventHandler(this.fromURLToolStripMenuItem_Click);
//
// toolStripSeparator3
//
this.toolStripSeparator3.Name = "toolStripSeparator3";
this.toolStripSeparator3.Size = new System.Drawing.Size(145, 6);
//
// exitToolStripMenuItem
//
this.exitToolStripMenuItem.Name = "exitToolStripMenuItem";
this.exitToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.W)));
this.exitToolStripMenuItem.Size = new System.Drawing.Size(148, 22);
this.exitToolStripMenuItem.Text = "&Close";
this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click);
//
// editToolStripMenuItem
//
this.editToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.copyToolStripMenuItem,
this.toolStripSeparator6,
this.selectAllToolStripMenuItem,
this.selectNoneToolStripMenuItem});
this.editToolStripMenuItem.Name = "editToolStripMenuItem";
this.editToolStripMenuItem.Size = new System.Drawing.Size(39, 20);
this.editToolStripMenuItem.Text = "&Edit";
//
// copyToolStripMenuItem
//
this.copyToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("copyToolStripMenuItem.Image")));
this.copyToolStripMenuItem.ImageTransparentColor = System.Drawing.Color.Magenta;
this.copyToolStripMenuItem.Name = "copyToolStripMenuItem";
this.copyToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.C)));
this.copyToolStripMenuItem.Size = new System.Drawing.Size(179, 22);
this.copyToolStripMenuItem.Text = "&Copy";
this.copyToolStripMenuItem.Click += new System.EventHandler(this.copyToolStripMenuItem_Click);
//
// toolStripSeparator6
//
this.toolStripSeparator6.Name = "toolStripSeparator6";
this.toolStripSeparator6.Size = new System.Drawing.Size(176, 6);
//
// selectAllToolStripMenuItem
//
this.selectAllToolStripMenuItem.Image = global::Cyotek.Windows.Forms.Demo.Properties.Resources.SelectAll;
this.selectAllToolStripMenuItem.Name = "selectAllToolStripMenuItem";
this.selectAllToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.A)));
this.selectAllToolStripMenuItem.Size = new System.Drawing.Size(179, 22);
this.selectAllToolStripMenuItem.Text = "Select &All";
this.selectAllToolStripMenuItem.Click += new System.EventHandler(this.selectAllToolStripMenuItem_Click);
//
// selectNoneToolStripMenuItem
//
this.selectNoneToolStripMenuItem.Image = global::Cyotek.Windows.Forms.Demo.Properties.Resources.SelectNone;
this.selectNoneToolStripMenuItem.Name = "selectNoneToolStripMenuItem";
this.selectNoneToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.D)));
this.selectNoneToolStripMenuItem.Size = new System.Drawing.Size(179, 22);
this.selectNoneToolStripMenuItem.Text = "Select &None";
this.selectNoneToolStripMenuItem.Click += new System.EventHandler(this.selectNoneToolStripMenuItem_Click);
//
// viewToolStripMenuItem
//
this.viewToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.fitCursorLocationToBoundsToolStripMenuItem});
this.viewToolStripMenuItem.Name = "viewToolStripMenuItem";
this.viewToolStripMenuItem.Size = new System.Drawing.Size(44, 20);
this.viewToolStripMenuItem.Text = "&View";
//
// fitCursorLocationToBoundsToolStripMenuItem
//
this.fitCursorLocationToBoundsToolStripMenuItem.Checked = true;
this.fitCursorLocationToBoundsToolStripMenuItem.CheckOnClick = true;
this.fitCursorLocationToBoundsToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked;
this.fitCursorLocationToBoundsToolStripMenuItem.Name = "fitCursorLocationToBoundsToolStripMenuItem";
this.fitCursorLocationToBoundsToolStripMenuItem.Size = new System.Drawing.Size(233, 22);
this.fitCursorLocationToBoundsToolStripMenuItem.Text = "Fit Cursor Location To &Bounds";
//
// helpToolStripMenuItem
//
this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.aboutToolStripMenuItem});
this.helpToolStripMenuItem.Name = "helpToolStripMenuItem";
this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 20);
this.helpToolStripMenuItem.Text = "&Help";
//
// aboutToolStripMenuItem
//
this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
this.aboutToolStripMenuItem.Size = new System.Drawing.Size(116, 22);
this.aboutToolStripMenuItem.Text = "&About...";
this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click);
//
// GeneralDemoForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(909, 526);
this.Controls.Add(this.viewSplitContainer);
this.Controls.Add(this.statusStrip);
this.Controls.Add(this.toolStrip);
this.Controls.Add(this.menuStrip);
this.MainMenuStrip = this.menuStrip;
this.Name = "GeneralDemoForm";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "General Demonstration";
this.viewSplitContainer.Panel1.ResumeLayout(false);
this.viewSplitContainer.Panel2.ResumeLayout(false);
this.viewSplitContainer.ResumeLayout(false);
this.selectionSplitContainer.Panel1.ResumeLayout(false);
this.selectionSplitContainer.Panel2.ResumeLayout(false);
this.selectionSplitContainer.ResumeLayout(false);
this.statusStrip.ResumeLayout(false);
this.statusStrip.PerformLayout();
this.toolStrip.ResumeLayout(false);
this.toolStrip.PerformLayout();
this.menuStrip.ResumeLayout(false);
this.menuStrip.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.SplitContainer viewSplitContainer;
private Cyotek.Windows.Forms.ImageBox imageBox;
private PropertyGrid propertyGrid;
private System.Windows.Forms.StatusStrip statusStrip;
private System.Windows.Forms.ToolStripStatusLabel autoScrollPositionToolStripStatusLabel;
private System.Windows.Forms.ToolStrip toolStrip;
private System.Windows.Forms.ToolStripButton showImageRegionToolStripButton;
private System.Windows.Forms.ToolStripButton showSourceImageRegionToolStripButton;
private System.Windows.Forms.ToolStripStatusLabel imageSizeToolStripStatusLabel;
private System.Windows.Forms.ToolStripStatusLabel zoomToolStripStatusLabel;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
private System.Windows.Forms.ToolStripButton actualSizeToolStripButton;
private System.Windows.Forms.ToolStripButton zoomInToolStripButton;
private System.Windows.Forms.ToolStripButton zoomOutToolStripButton;
private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel1;
private System.Windows.Forms.ToolStripStatusLabel cursorToolStripStatusLabel;
private System.Windows.Forms.SplitContainer selectionSplitContainer;
private Cyotek.Windows.Forms.ImageBox previewImageBox;
private System.Windows.Forms.ToolStripStatusLabel selectionToolStripStatusLabel;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
private System.Windows.Forms.ToolStripButton selectAllToolStripButton;
private System.Windows.Forms.ToolStripButton selectNoneToolStripButton;
private System.Windows.Forms.ToolStripButton openFromFileToolStripButton;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator8;
private System.Windows.Forms.MenuStrip menuStrip;
private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator3;
private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem editToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem copyToolStripMenuItem;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator6;
private System.Windows.Forms.ToolStripMenuItem selectAllToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem;
private System.Windows.Forms.ToolStripComboBox zoomLevelsToolStripComboBox;
private System.Windows.Forms.ToolStripMenuItem selectNoneToolStripMenuItem;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator4;
private System.Windows.Forms.ToolStripMenuItem viewToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem fitCursorLocationToBoundsToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem openToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem openFromFileToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem fromURLToolStripMenuItem;
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/GeneralDemoForm.cs
================================================
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Net;
using System.Windows.Forms;
using Cyotek.Windows.Forms.Demo.Properties;
namespace Cyotek.Windows.Forms.Demo
{
// Cyotek ImageBox
// Copyright (c) 2010-2017 Cyotek Ltd.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
internal partial class GeneralDemoForm : BaseForm
{
#region Fields
private Image _previewImage;
#endregion
#region Constructors
public GeneralDemoForm()
{
this.InitializeComponent();
}
#endregion
#region Methods
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
this.FillZoomLevels();
this.OpenImage(Resources.Sample);
imageBox.SelectionMode = ImageBoxSelectionMode.Zoom;
imageBox.AllowClickZoom = true;
}
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
{
AboutDialog.ShowAboutDialog();
}
private void actualSizeToolStripButton_Click(object sender, EventArgs e)
{
imageBox.ActualSize();
}
private void copyToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
Clipboard.Clear();
Clipboard.SetImage(imageBox.GetSelectedImage() ?? imageBox.Image);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void DrawBox(Graphics graphics, Color color, RectangleF rectangle, double scale)
{
float penWidth;
penWidth = 2 * (float)scale;
using (SolidBrush brush = new SolidBrush(Color.FromArgb(64, color)))
{
graphics.FillRectangle(brush, rectangle);
}
using (Pen pen = new Pen(color, penWidth)
{
DashStyle = DashStyle.Dot,
DashCap = DashCap.Round
})
{
graphics.DrawRectangle(pen, rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
}
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Close();
}
private void FillZoomLevels()
{
zoomLevelsToolStripComboBox.Items.Clear();
foreach (int zoom in imageBox.ZoomLevels)
{
zoomLevelsToolStripComboBox.Items.Add(string.Format("{0}%", zoom));
}
}
private void fromURLToolStripMenuItem_Click(object sender, EventArgs e)
{
using (OpenUrlDialog dialog = new OpenUrlDialog())
{
if (dialog.ShowDialog(this) == DialogResult.OK)
{
this.OpenImageFromUrl(dialog.Url);
}
}
}
private void imageBox_MouseLeave(object sender, EventArgs e)
{
cursorToolStripStatusLabel.Text = string.Empty;
}
private void imageBox_MouseMove(object sender, MouseEventArgs e)
{
this.UpdateCursorPosition(e.Location);
}
private void imageBox_Paint(object sender, PaintEventArgs e)
{
// highlight the image
if (showImageRegionToolStripButton.Checked)
{
this.DrawBox(e.Graphics, Color.CornflowerBlue, imageBox.GetImageViewPort(), 1);
}
// show the region that will be drawn from the source image
if (showSourceImageRegionToolStripButton.Checked)
{
this.DrawBox(e.Graphics, Color.Firebrick, new RectangleF(imageBox.GetImageViewPort().Location, imageBox.GetSourceImageRegion().Size), 1);
}
}
private void imageBox_Resize(object sender, EventArgs e)
{
this.UpdateStatusBar();
}
private void imageBox_Scroll(object sender, ScrollEventArgs e)
{
this.UpdateStatusBar();
}
private void imageBox_Selected(object sender, EventArgs e)
{
this.UpdatePreviewImage();
}
private void imageBox_SelectionRegionChanged(object sender, EventArgs e)
{
selectionToolStripStatusLabel.Text = this.FormatRectangle(imageBox.SelectionRegion);
}
private void imageBox_ZoomChanged(object sender, EventArgs e)
{
this.UpdateStatusBar();
}
private void imageBox_ZoomLevelsChanged(object sender, EventArgs e)
{
this.FillZoomLevels();
}
private void openFromFileToolStripMenuItem_Click(object sender, EventArgs e)
{
using (FileDialog dialog = new OpenFileDialog())
{
dialog.Filter = "All Supported Images (*.bmp;*.dib;*.rle;*.gif;*.jpg;*.png;*.tif;*.tiff)|*.bmp;*.dib;*.rle;*.gif;*.jpg;*.png;*.tif;*.tiff|Bitmaps (*.bmp;*.dib;*.rle)|*.bmp;*.dib;*.rle|Graphics Interchange Format (*.gif)|*.gif|Joint Photographic Experts (*.jpg)|*.jpg|Portable Network Graphics (*.png)|*.png|Tagged Image File Format (*.tif;*.tiff)|*.tif;*.tiff|All Files (*.*)|*.*";
dialog.DefaultExt = "png";
if (dialog.ShowDialog(this) == DialogResult.OK)
{
try
{
this.OpenImage(Image.FromFile(dialog.FileName));
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
private void OpenImage(Image image)
{
imageBox.Image = image;
imageBox.ZoomToFit();
this.UpdateStatusBar();
this.UpdatePreviewImage();
}
private void OpenImageFromUrl(string url)
{
try
{
using (WebClient client = new WebClient())
{
byte[] data;
data = client.DownloadData(url);
using (Stream stream = new MemoryStream(data))
{
this.OpenImage(Image.FromStream(stream));
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void selectAllToolStripMenuItem_Click(object sender, EventArgs e)
{
imageBox.SelectAll();
}
private void selectNoneToolStripMenuItem_Click(object sender, EventArgs e)
{
imageBox.SelectNone();
}
private void showImageRegionToolStripButton_Click(object sender, EventArgs e)
{
imageBox.Invalidate();
}
private void UpdateCursorPosition(Point location)
{
if (!fitCursorLocationToBoundsToolStripMenuItem.Checked || imageBox.IsPointInImage(location))
{
Point point;
point = imageBox.PointToImage(location);
cursorToolStripStatusLabel.Text = this.FormatPoint(point);
}
else
{
cursorToolStripStatusLabel.Text = string.Empty;
}
}
private void UpdatePreviewImage()
{
if (_previewImage != null)
{
_previewImage.Dispose();
}
_previewImage = imageBox.GetSelectedImage();
previewImageBox.Image = _previewImage;
}
private void UpdateStatusBar()
{
zoomLevelsToolStripComboBox.Text = string.Format("{0}%", imageBox.Zoom);
autoScrollPositionToolStripStatusLabel.Text = this.FormatPoint(imageBox.AutoScrollPosition);
imageSizeToolStripStatusLabel.Text = this.FormatRectangle(imageBox.GetImageViewPort());
zoomToolStripStatusLabel.Text = string.Format("{0}%", imageBox.Zoom);
}
private void zoomInToolStripButton_Click(object sender, EventArgs e)
{
imageBox.ZoomIn();
}
private void zoomLevelsToolStripComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
int zoom;
zoom = Convert.ToInt32(zoomLevelsToolStripComboBox.Text.Substring(0, zoomLevelsToolStripComboBox.Text.Length - 1));
imageBox.Zoom = zoom;
}
private void zoomOutToolStripButton_Click(object sender, EventArgs e)
{
imageBox.ZoomOut();
}
#endregion
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/GeneralDemoForm.resx
================================================
text/microsoft-resx
2.0
System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
17, 17
126, 17
231, 17
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHkSURBVDhPvZHfS1NhHIf3p5QypLr2D4goMwoMCi/qIugH
Xe1Cr7qKDIMkZixwNhfWLGWbnuki0kXKzLU023KubBNPJrbRdOzocm6e2dPOO21mMS+CHvjcvOf9PF++
79H9M+7RT2iRRsIi9sEAXe43yAvf2LpSHq28G9uAnytNT4jMLewtcQ2Ht2pF8ps/aOt+gccX5lxD694S
+1BQFD1RkN5DSFa4Z3uONKbgHE3h8KZ4OJTC1J8UiSzmfhd2uf1CoJHbyKOsZokl0kKwm+aeJaov+wjO
rpQkVqdXfOz0bWAcVLghfaXxkUz3y2VxvpMGSwL3uMKh+gHezSSLEnNhX23vtYzKUirDfGyFj/Iy1mdx
UWqR8iKhwtQLxjgH659y4EwvVXWPiwJt3/Ws+muywRrlqvkDdx3zQrCN8l1ldnEd3/QqFmkS/akHJYGS
zjLzOUEwEsMf+sLI2zmaOou/93pPGoM5zvk7UU7fnBKxSBPoT7SXBNW1F/9Io2lKCNTCeomUyrS8xnBA
wfUqyf1eP5U1ptJD/o1LzeNCsHPydtqdr6k4aiwvOHvNSya3ibU/QIdrEkvfhJislc32MfYfuV1eUGPw
FF7bIVJVZ0N/soPK421UHGstlFvYd/hWecF/Qqf7CR0A5wwgSQA2AAAAAElFTkSuQmCC
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/GroupBox.cs
================================================
using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace Cyotek.Windows.Forms
{
// Cyotek GroupBox Component
// www.cyotek.com
///
/// Represents a Windows control that displays a frame at the top of a group of controls with an optional caption and icon.
///
[ToolboxItem(true)]
[DefaultEvent("Click")]
[DefaultProperty("Text")]
[Designer("System.Windows.Forms.Design.GroupBoxDesigner, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
[Designer("System.Windows.Forms.Design.DocumentDesigner, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(IRootDesigner))]
internal class GroupBox : System.Windows.Forms.GroupBox
{
#region Instance Fields
private Border3DSide _borders = Border3DSide.Top;
private Pen _bottomPen;
private Color _headerForeColor;
private Size _iconMargin;
private Image _image;
private Color _lineColorBottom;
private Color _lineColorTop;
private bool _showBorders;
private Pen _topPen;
#endregion
#region Public Constructors
///
/// Initializes a new instance of the class.
///
public GroupBox()
{
_showBorders = true;
_iconMargin = new Size(0, 6);
_lineColorBottom = SystemColors.ButtonHighlight;
_lineColorTop = SystemColors.ButtonShadow;
_headerForeColor = SystemColors.HotTrack;
this.SetStyle(ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw | ControlStyles.UserPaint | ControlStyles.SupportsTransparentBackColor, true);
this.CreateResources();
}
#endregion
#region Overridden Properties
///
/// Gets a rectangle that represents the dimensions of the .
///
///
///
/// A with the dimensions of the .
///
public override Rectangle DisplayRectangle
{
get
{
Size clientSize;
int fontHeight;
int imageSize;
clientSize = base.ClientSize;
fontHeight = this.Font.Height;
if (_image != null)
{
imageSize = _iconMargin.Width + _image.Width + 3;
}
else
{
imageSize = 0;
}
return new Rectangle(3 + imageSize, fontHeight + 3, Math.Max(clientSize.Width - (imageSize + 6), 0), Math.Max((clientSize.Height - fontHeight) - 6, 0));
}
}
///
/// Returns or sets the text displayed in this control.
///
///
///
/// The text associated with this control.
///
[Browsable(true)]
[DefaultValue("")]
public override string Text
{
get { return base.Text; }
set
{
base.Text = value;
this.Invalidate();
}
}
#endregion
#region Overridden Methods
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing)
{
this.CleanUpResources();
}
base.Dispose(disposing);
}
///
/// Occurs when the control is to be painted.
///
/// A that contains the event data.
protected override void OnPaint(PaintEventArgs e)
{
SizeF size;
int y;
TextFormatFlags flags;
Rectangle textBounds;
flags = TextFormatFlags.WordEllipsis | TextFormatFlags.NoPrefix | TextFormatFlags.Left | TextFormatFlags.SingleLine;
size = TextRenderer.MeasureText(e.Graphics, this.Text, this.Font, this.ClientSize, flags);
y = (int)(size.Height + 3) / 2;
textBounds = new Rectangle(1, 1, (int)size.Width, (int)size.Height);
if (this.ShowBorders)
{
if ((_borders & Border3DSide.All) == Border3DSide.All)
{
e.Graphics.DrawRectangle(_bottomPen, 1, y + 1, this.Width - 2, this.Height - (y + 2));
e.Graphics.DrawRectangle(_topPen, 0, y, this.Width - 2, this.Height - (y + 2));
}
else
{
if ((_borders & Border3DSide.Top) == Border3DSide.Top)
{
e.Graphics.DrawLine(_topPen, size.Width + 3, y, this.Width - 5, y);
e.Graphics.DrawLine(_bottomPen, size.Width + 3, y + 1, this.Width - 5, y + 1);
}
if ((_borders & Border3DSide.Left) == Border3DSide.Left)
{
e.Graphics.DrawLine(_topPen, 0, y, 0, this.Height - 1);
e.Graphics.DrawLine(_bottomPen, 1, y, 1, this.Height - 1);
}
if ((_borders & Border3DSide.Right) == Border3DSide.Right)
{
e.Graphics.DrawLine(_bottomPen, this.Width - 1, y, this.Width - 1, this.Height - 1);
e.Graphics.DrawLine(_topPen, this.Width - 2, y, this.Width - 2, this.Height - 1);
}
if ((_borders & Border3DSide.Bottom) == Border3DSide.Bottom)
{
e.Graphics.DrawLine(_topPen, 0, this.Height - 2, this.Width, this.Height - 2);
e.Graphics.DrawLine(_bottomPen, 0, this.Height - 1, this.Width, this.Height - 1);
}
}
}
// header text
TextRenderer.DrawText(e.Graphics, this.Text, this.Font, textBounds, this.HeaderForeColor, flags);
// draw the image
if ((_image != null))
{
e.Graphics.DrawImage(_image, this.Padding.Left + _iconMargin.Width, this.Padding.Top + (int)size.Height + _iconMargin.Height, _image.Width, _image.Height);
}
//draw a designtime outline
if (this.DesignMode && (_borders & Border3DSide.All) != Border3DSide.All)
{
using (Pen pen = new Pen(SystemColors.ButtonShadow))
{
pen.DashStyle = DashStyle.Dot;
e.Graphics.DrawRectangle(pen, 0, 0, Width - 1, Height - 1);
}
}
}
///
/// Raises the event.
///
/// An that contains the event data.
protected override void OnSystemColorsChanged(EventArgs e)
{
base.OnSystemColorsChanged(e);
this.CreateResources();
this.Invalidate();
}
#endregion
#region Public Properties
[Category("Appearance")]
[DefaultValue(typeof(Border3DSide), "Top")]
public Border3DSide Borders
{
get { return _borders; }
set
{
_borders = value;
this.Invalidate();
}
}
[Category("Appearance")]
[DefaultValue(typeof(Color), "HotTrack")]
public Color HeaderForeColor
{
get { return _headerForeColor; }
set
{
_headerForeColor = value;
this.CreateResources();
this.Invalidate();
}
}
///
/// Gets or sets the icon margin.
///
/// The icon margin.
[Category("Appearance")]
[DefaultValue(typeof(Size), "0, 6")]
public Size IconMargin
{
get { return _iconMargin; }
set
{
_iconMargin = value;
this.Invalidate();
}
}
///
/// Gets or sets the image to display.
///
/// The image to display.
[Browsable(true)]
[Category("Appearance")]
[DefaultValue(typeof(Image), "")]
public Image Image
{
get { return _image; }
set
{
_image = value;
this.Invalidate();
}
}
///
/// Gets or sets the line color bottom.
///
/// The line color bottom.
[Browsable(true)]
[Category("Appearance")]
[DefaultValue(typeof(Color), "ButtonHighlight")]
public Color LineColorBottom
{
get { return _lineColorBottom; }
set
{
_lineColorBottom = value;
this.CreateResources();
this.Invalidate();
}
}
///
/// Gets or sets the line color top.
///
/// The line color top.
[Browsable(true)]
[Category("Appearance")]
[DefaultValue(typeof(Color), "ButtonShadow")]
public Color LineColorTop
{
get { return _lineColorTop; }
set
{
_lineColorTop = value;
this.CreateResources();
this.Invalidate();
}
}
[DefaultValue(true)]
[Category("Appearance")]
public bool ShowBorders
{
get { return _showBorders; }
set
{
_showBorders = value;
this.Invalidate();
}
}
#endregion
#region Private Members
///
/// Cleans up GDI resources.
///
private void CleanUpResources()
{
if (_topPen != null)
{
_topPen.Dispose();
}
if (_bottomPen != null)
{
_bottomPen.Dispose();
}
}
///
/// Creates GDI resources.
///
private void CreateResources()
{
this.CleanUpResources();
_topPen = new Pen(_lineColorTop);
_bottomPen = new Pen(_lineColorBottom);
}
#endregion
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/ImageBoxEx.cs
================================================
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
namespace Cyotek.Windows.Forms.Demo
{
// Cyotek ImageBox
// Copyright (c) 2010-2015 Cyotek Ltd.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
internal class ImageBoxEx : ImageBox
{
#region Constants
private readonly DragHandleCollection _dragHandles;
private static readonly object _eventDragHandleSizeChanged = new object();
private static readonly object _eventMaximumSelectionSizeChanged = new object();
private static readonly object _eventMinimumSelectionSizeChanged = new object();
private static readonly object _eventSelectionMoved = new object();
private static readonly object _eventSelectionMoving = new object();
private static readonly object _eventSelectionResized = new object();
private static readonly object _eventSelectionResizing = new object();
#endregion
#region Fields
private int _dragHandleSize;
private Point _dragOrigin;
private Point _dragOriginOffset;
private bool _isMoving;
private bool _isResizing;
private Size _maximumSelectionSize;
private Size _minimumSelectionSize;
private RectangleF _previousSelectionRegion;
private DragHandleAnchor _resizeAnchor;
#endregion
#region Constructors
public ImageBoxEx()
{
_dragHandles = new DragHandleCollection();
_dragHandleSize = 8;
_maximumSelectionSize = Size.Empty;
this.PositionDragHandles();
}
#endregion
#region Events
///
/// Occurs when the DragHandleSize property value changes
///
[Category("Property Changed")]
public event EventHandler DragHandleSizeChanged
{
add { this.Events.AddHandler(_eventDragHandleSizeChanged, value); }
remove { this.Events.RemoveHandler(_eventDragHandleSizeChanged, value); }
}
///
/// Occurs when the MaximumSelectionSize property value changes
///
[Category("Property Changed")]
public event EventHandler MaximumSelectionSizeChanged
{
add { this.Events.AddHandler(_eventMaximumSelectionSizeChanged, value); }
remove { this.Events.RemoveHandler(_eventMaximumSelectionSizeChanged, value); }
}
///
/// Occurs when the MinimumSelectionSize property value changes
///
[Category("Property Changed")]
public event EventHandler MinimumSelectionSizeChanged
{
add { this.Events.AddHandler(_eventMinimumSelectionSizeChanged, value); }
remove { this.Events.RemoveHandler(_eventMinimumSelectionSizeChanged, value); }
}
[Category("Action")]
public event EventHandler SelectionMoved
{
add { this.Events.AddHandler(_eventSelectionMoved, value); }
remove { this.Events.RemoveHandler(_eventSelectionMoved, value); }
}
[Category("Action")]
public event CancelEventHandler SelectionMoving
{
add { this.Events.AddHandler(_eventSelectionMoving, value); }
remove { this.Events.RemoveHandler(_eventSelectionMoving, value); }
}
[Category("Action")]
public event EventHandler SelectionResized
{
add { this.Events.AddHandler(_eventSelectionResized, value); }
remove { this.Events.RemoveHandler(_eventSelectionResized, value); }
}
[Category("Action")]
public event CancelEventHandler SelectionResizing
{
add { this.Events.AddHandler(_eventSelectionResizing, value); }
remove { this.Events.RemoveHandler(_eventSelectionResizing, value); }
}
#endregion
#region Properties
[Browsable(false)]
public DragHandleCollection DragHandles
{
get { return _dragHandles; }
}
[Category("Appearance")]
[DefaultValue(8)]
public virtual int DragHandleSize
{
get { return _dragHandleSize; }
set
{
if (_dragHandleSize != value)
{
_dragHandleSize = value;
this.OnDragHandleSizeChanged(EventArgs.Empty);
}
}
}
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsMoving
{
get { return _isMoving; }
protected set { _isMoving = value; }
}
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsResizing
{
get { return _isResizing; }
protected set { _isResizing = value; }
}
[Category("Behavior")]
[DefaultValue(typeof(Size), "0, 0")]
public virtual Size MaximumSelectionSize
{
get { return _maximumSelectionSize; }
set
{
if (this.MaximumSelectionSize != value)
{
_maximumSelectionSize = value;
this.OnMaximumSelectionSizeChanged(EventArgs.Empty);
}
}
}
[Category("Behavior")]
[DefaultValue(typeof(Size), "0, 0")]
public virtual Size MinimumSelectionSize
{
get { return _minimumSelectionSize; }
set
{
if (this.MinimumSelectionSize != value)
{
_minimumSelectionSize = value;
this.OnMinimumSelectionSizeChanged(EventArgs.Empty);
}
}
}
[Browsable(false)]
public RectangleF PreviousSelectionRegion
{
get { return _previousSelectionRegion; }
protected set { _previousSelectionRegion = value; }
}
protected Point DragOrigin
{
get { return _dragOrigin; }
set { _dragOrigin = value; }
}
protected Point DragOriginOffset
{
get { return _dragOriginOffset; }
set { _dragOriginOffset = value; }
}
protected DragHandleAnchor ResizeAnchor
{
get { return _resizeAnchor; }
set { _resizeAnchor = value; }
}
#endregion
#region Methods
public void CancelResize()
{
this.SelectionRegion = _previousSelectionRegion;
this.CompleteResize();
}
public void StartMove()
{
CancelEventArgs e;
if (_isMoving || _isResizing)
{
throw new InvalidOperationException("A move or resize action is currently being performed.");
}
e = new CancelEventArgs();
this.OnSelectionMoving(e);
if (!e.Cancel)
{
_previousSelectionRegion = this.SelectionRegion;
_isMoving = true;
}
}
protected virtual void DrawDragHandle(Graphics graphics, DragHandle handle)
{
int left;
int top;
int width;
int height;
Pen outerPen;
Brush innerBrush;
left = handle.Bounds.Left;
top = handle.Bounds.Top;
width = handle.Bounds.Width;
height = handle.Bounds.Height;
if (handle.Enabled)
{
outerPen = SystemPens.WindowFrame;
innerBrush = SystemBrushes.Window;
}
else
{
outerPen = SystemPens.ControlDark;
innerBrush = SystemBrushes.Control;
}
graphics.FillRectangle(innerBrush, left + 1, top + 1, width - 2, height - 2);
graphics.DrawLine(outerPen, left + 1, top, left + width - 2, top);
graphics.DrawLine(outerPen, left, top + 1, left, top + height - 2);
graphics.DrawLine(outerPen, left + 1, top + height - 1, left + width - 2, top + height - 1);
graphics.DrawLine(outerPen, left + width - 1, top + 1, left + width - 1, top + height - 2);
}
///
/// Raises the event.
///
/// The instance containing the event data.
protected virtual void OnDragHandleSizeChanged(EventArgs e)
{
EventHandler handler;
this.PositionDragHandles();
this.Invalidate();
handler = (EventHandler)this.Events[_eventDragHandleSizeChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
/// The instance containing the event data.
protected virtual void OnMaximumSelectionSizeChanged(EventArgs e)
{
EventHandler handler;
handler = (EventHandler)this.Events[_eventMaximumSelectionSizeChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
/// The instance containing the event data.
protected virtual void OnMinimumSelectionSizeChanged(EventArgs e)
{
EventHandler handler;
handler = (EventHandler)this.Events[_eventMinimumSelectionSizeChanged];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
///
/// A that contains the event data.
///
protected override void OnMouseDown(MouseEventArgs e)
{
Point imagePoint;
RectangleF selectionRegion;
imagePoint = this.PointToImage(e.Location);
selectionRegion = this.SelectionRegion;
if (e.Button == MouseButtons.Left && (selectionRegion.Contains(imagePoint) || this.HitTest(e.Location) != DragHandleAnchor.None))
{
_dragOrigin = e.Location;
_dragOriginOffset = new Point(imagePoint.X - (int)selectionRegion.X, imagePoint.Y - (int)selectionRegion.Y);
}
else
{
_dragOriginOffset = Point.Empty;
_dragOrigin = Point.Empty;
}
base.OnMouseDown(e);
}
///
/// Raises the event.
///
///
/// A that contains the event data.
///
protected override void OnMouseMove(MouseEventArgs e)
{
// start either a move or a resize operation
if (!this.IsSelecting && !_isMoving && !_isResizing && e.Button == MouseButtons.Left && !_dragOrigin.IsEmpty && this.IsOutsideDragZone(e.Location))
{
DragHandleAnchor anchor;
anchor = this.HitTest(_dragOrigin);
if (anchor == DragHandleAnchor.None)
{
// move
this.StartMove();
}
else if (_dragHandles[anchor].
Enabled && _dragHandles[anchor].
Visible)
{
// resize
this.StartResize(anchor);
}
}
// set the cursor
this.SetCursor(e.Location);
// perform operations
this.ProcessSelectionMove(e.Location);
this.ProcessSelectionResize(e.Location);
base.OnMouseMove(e);
}
///
/// Raises the event.
///
///
/// A that contains the event data.
///
protected override void OnMouseUp(MouseEventArgs e)
{
if (_isMoving)
{
this.CompleteMove();
}
else if (_isResizing)
{
this.CompleteResize();
}
base.OnMouseUp(e);
}
///
/// Raises the event.
///
///
/// A that contains the event data.
///
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (this.AllowPainting && !this.SelectionRegion.IsEmpty)
{
foreach (DragHandle handle in _dragHandles)
{
if (handle.Visible)
{
this.DrawDragHandle(e.Graphics, handle);
}
}
}
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected override void OnPanStart(CancelEventArgs e)
{
if (_isMoving || _isResizing || !_dragOrigin.IsEmpty)
{
e.Cancel = true;
}
base.OnPanStart(e);
}
///
/// Raises the event.
///
///
/// An that contains the event data.
///
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
this.PositionDragHandles();
}
///
/// Raises the event.
///
///
/// A that contains the event data.
///
protected override void OnScroll(ScrollEventArgs se)
{
base.OnScroll(se);
this.PositionDragHandles();
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected override void OnSelecting(ImageBoxCancelEventArgs e)
{
e.Cancel = _isMoving || _isResizing || this.SelectionRegion.Contains(this.PointToImage(e.Location)) || this.HitTest(e.Location) != DragHandleAnchor.None;
base.OnSelecting(e);
}
///
/// Raises the event.
///
/// The instance containing the event data.
protected virtual void OnSelectionMoved(EventArgs e)
{
EventHandler handler;
handler = (EventHandler)this.Events[_eventSelectionMoved];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
/// The instance containing the event data.
protected virtual void OnSelectionMoving(CancelEventArgs e)
{
CancelEventHandler handler;
handler = (CancelEventHandler)this.Events[_eventSelectionMoving];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected override void OnSelectionRegionChanged(EventArgs e)
{
base.OnSelectionRegionChanged(e);
this.PositionDragHandles();
}
///
/// Raises the event.
///
/// The instance containing the event data.
protected virtual void OnSelectionResized(EventArgs e)
{
EventHandler handler;
handler = (EventHandler)this.Events[_eventSelectionResized];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
/// The instance containing the event data.
protected virtual void OnSelectionResizing(CancelEventArgs e)
{
CancelEventHandler handler;
handler = (CancelEventHandler)this.Events[_eventSelectionResizing];
handler?.Invoke(this, e);
}
///
/// Raises the event.
///
///
/// The instance containing the event data.
///
protected override void OnZoomChanged(EventArgs e)
{
base.OnZoomChanged(e);
this.PositionDragHandles();
}
///
/// Processes a dialog key.
///
///
/// true if the key was processed by the control; otherwise, false.
///
/// One of the values that represents the key to process.
protected override bool ProcessDialogKey(Keys keyData)
{
bool result;
if (keyData == Keys.Escape && (_isResizing || _isMoving))
{
if (_isResizing)
{
this.CancelResize();
}
else
{
this.CancelMove();
}
result = true;
}
else
{
result = base.ProcessDialogKey(keyData);
}
return result;
}
protected virtual void SetCursor(Point point)
{
// http://forums.cyotek.com/imagebox/cursor-issue-in-imageboxex/msg92/#msg92
if (!this.IsPanning)
{
Cursor cursor;
if (this.IsSelecting)
{
cursor = Cursors.Default;
}
else
{
DragHandleAnchor handleAnchor;
handleAnchor = _isResizing ? _resizeAnchor : this.HitTest(point);
if (handleAnchor != DragHandleAnchor.None && _dragHandles[handleAnchor].
Enabled)
{
switch (handleAnchor)
{
case DragHandleAnchor.TopLeft:
case DragHandleAnchor.BottomRight:
cursor = Cursors.SizeNWSE;
break;
case DragHandleAnchor.TopCenter:
case DragHandleAnchor.BottomCenter:
cursor = Cursors.SizeNS;
break;
case DragHandleAnchor.TopRight:
case DragHandleAnchor.BottomLeft:
cursor = Cursors.SizeNESW;
break;
case DragHandleAnchor.MiddleLeft:
case DragHandleAnchor.MiddleRight:
cursor = Cursors.SizeWE;
break;
default:
throw new ArgumentOutOfRangeException();
}
}
else if (_isMoving || this.SelectionRegion.Contains(this.PointToImage(point)))
{
cursor = Cursors.SizeAll;
}
else
{
cursor = Cursors.Default;
}
}
this.Cursor = cursor;
}
}
private void CancelMove()
{
this.SelectionRegion = _previousSelectionRegion;
this.CompleteMove();
}
private void CompleteMove()
{
this.ResetDrag();
this.OnSelectionMoved(EventArgs.Empty);
}
private void CompleteResize()
{
this.ResetDrag();
this.OnSelectionResized(EventArgs.Empty);
}
private DragHandleAnchor HitTest(Point cursorPosition)
{
return _dragHandles.HitTest(cursorPosition);
}
private bool IsOutsideDragZone(Point location)
{
Rectangle dragZone;
int dragWidth;
int dragHeight;
dragWidth = SystemInformation.DragSize.Width;
dragHeight = SystemInformation.DragSize.Height;
dragZone = new Rectangle(_dragOrigin.X - (dragWidth / 2), _dragOrigin.Y - (dragHeight / 2), dragWidth, dragHeight);
return !dragZone.Contains(location);
}
private void PositionDragHandles()
{
if (_dragHandles != null && _dragHandleSize > 0)
{
RectangleF selectionRegion;
selectionRegion = this.SelectionRegion;
if (selectionRegion.IsEmpty)
{
foreach (DragHandle handle in _dragHandles)
{
handle.Bounds = Rectangle.Empty;
}
}
else
{
int left;
int top;
int right;
int bottom;
int halfWidth;
int halfHeight;
int halfDragHandleSize;
Rectangle viewport;
int offsetX;
int offsetY;
viewport = this.GetImageViewPort();
offsetX = viewport.Left + this.Padding.Left + this.AutoScrollPosition.X;
offsetY = viewport.Top + this.Padding.Top + this.AutoScrollPosition.Y;
halfDragHandleSize = _dragHandleSize / 2;
left = Convert.ToInt32((selectionRegion.Left * this.ZoomFactor) + offsetX);
top = Convert.ToInt32((selectionRegion.Top * this.ZoomFactor) + offsetY);
right = left + Convert.ToInt32(selectionRegion.Width * this.ZoomFactor);
bottom = top + Convert.ToInt32(selectionRegion.Height * this.ZoomFactor);
halfWidth = Convert.ToInt32(selectionRegion.Width * this.ZoomFactor) / 2;
halfHeight = Convert.ToInt32(selectionRegion.Height * this.ZoomFactor) / 2;
_dragHandles[DragHandleAnchor.TopLeft].
Bounds = new Rectangle(left - _dragHandleSize, top - _dragHandleSize, _dragHandleSize, _dragHandleSize);
_dragHandles[DragHandleAnchor.TopCenter].
Bounds = new Rectangle(left + halfWidth - halfDragHandleSize, top - _dragHandleSize, _dragHandleSize, _dragHandleSize);
_dragHandles[DragHandleAnchor.TopRight].
Bounds = new Rectangle(right, top - _dragHandleSize, _dragHandleSize, _dragHandleSize);
_dragHandles[DragHandleAnchor.MiddleLeft].
Bounds = new Rectangle(left - _dragHandleSize, top + halfHeight - halfDragHandleSize, _dragHandleSize, _dragHandleSize);
_dragHandles[DragHandleAnchor.MiddleRight].
Bounds = new Rectangle(right, top + halfHeight - halfDragHandleSize, _dragHandleSize, _dragHandleSize);
_dragHandles[DragHandleAnchor.BottomLeft].
Bounds = new Rectangle(left - _dragHandleSize, bottom, _dragHandleSize, _dragHandleSize);
_dragHandles[DragHandleAnchor.BottomCenter].
Bounds = new Rectangle(left + halfWidth - halfDragHandleSize, bottom, _dragHandleSize, _dragHandleSize);
_dragHandles[DragHandleAnchor.BottomRight].
Bounds = new Rectangle(right, bottom, _dragHandleSize, _dragHandleSize);
}
}
}
private void ProcessSelectionMove(Point cursorPosition)
{
if (_isMoving)
{
int x;
int y;
Point imagePoint;
Size viewSize;
RectangleF selectionRegion;
imagePoint = this.PointToImage(cursorPosition, false);
viewSize = this.ViewSize;
selectionRegion = this.SelectionRegion;
x = Math.Max(0, imagePoint.X - _dragOriginOffset.X);
if (x + selectionRegion.Width >= viewSize.Width)
{
x = viewSize.Width - (int)selectionRegion.Width;
}
y = Math.Max(0, imagePoint.Y - _dragOriginOffset.Y);
if (y + selectionRegion.Height >= viewSize.Height)
{
y = viewSize.Height - (int)selectionRegion.Height;
}
this.SelectionRegion = new RectangleF(x, y, selectionRegion.Width, selectionRegion.Height);
}
}
private void ProcessSelectionResize(Point cursorPosition)
{
if (_isResizing)
{
Point imagePosition;
float left;
float top;
float right;
float bottom;
bool resizingTopEdge;
bool resizingBottomEdge;
bool resizingLeftEdge;
bool resizingRightEdge;
RectangleF selectionRegion;
Size viewSize;
imagePosition = this.PointToImage(cursorPosition);
viewSize = this.ViewSize;
// get the current selection
selectionRegion = this.SelectionRegion;
left = selectionRegion.Left;
top = selectionRegion.Top;
right = selectionRegion.Right;
bottom = selectionRegion.Bottom;
// decide which edges we're resizing
resizingTopEdge = _resizeAnchor >= DragHandleAnchor.TopLeft && _resizeAnchor <= DragHandleAnchor.TopRight;
resizingBottomEdge = _resizeAnchor >= DragHandleAnchor.BottomLeft && _resizeAnchor <= DragHandleAnchor.BottomRight;
resizingLeftEdge = _resizeAnchor == DragHandleAnchor.TopLeft || _resizeAnchor == DragHandleAnchor.MiddleLeft || _resizeAnchor == DragHandleAnchor.BottomLeft;
resizingRightEdge = _resizeAnchor == DragHandleAnchor.TopRight || _resizeAnchor == DragHandleAnchor.MiddleRight || _resizeAnchor == DragHandleAnchor.BottomRight;
// and resize!
if (resizingTopEdge)
{
top = imagePosition.Y > 0 ? imagePosition.Y : 0;
if (bottom - top < this.MinimumSelectionSize.Height)
{
top = bottom - this.MinimumSelectionSize.Height;
}
else if (this.MaximumSelectionSize.Height > 0 && bottom - top > this.MaximumSelectionSize.Height)
{
top = bottom - this.MaximumSelectionSize.Height;
}
}
else if (resizingBottomEdge)
{
bottom = imagePosition.Y < viewSize.Height ? imagePosition.Y : viewSize.Height;
if (bottom - top < this.MinimumSelectionSize.Height)
{
bottom = top + this.MinimumSelectionSize.Height;
}
else if (this.MaximumSelectionSize.Height > 0 && bottom - top > this.MaximumSelectionSize.Height)
{
bottom = top + this.MaximumSelectionSize.Height;
}
}
if (resizingLeftEdge)
{
left = imagePosition.X > 0 ? imagePosition.X : 0;
if (right - left < this.MinimumSelectionSize.Width)
{
left = right - this.MinimumSelectionSize.Width;
}
else if (this.MaximumSelectionSize.Width > 0 && right - left > this.MaximumSelectionSize.Width)
{
left = right - this.MaximumSelectionSize.Width;
}
}
else if (resizingRightEdge)
{
right = imagePosition.X < viewSize.Width ? imagePosition.X : viewSize.Width;
if (right - left < this.MinimumSelectionSize.Width)
{
right = left + this.MinimumSelectionSize.Width;
}
else if (this.MaximumSelectionSize.Width > 0 && right - left > this.MaximumSelectionSize.Width)
{
right = left + this.MaximumSelectionSize.Width;
}
}
this.SelectionRegion = new RectangleF(left, top, right - left, bottom - top);
}
}
private void ResetDrag()
{
_isResizing = false;
_isMoving = false;
_dragOrigin = Point.Empty;
_dragOriginOffset = Point.Empty;
}
private void StartResize(DragHandleAnchor anchor)
{
CancelEventArgs e;
if (_isMoving || _isResizing)
{
throw new InvalidOperationException("A move or resize action is currently being performed.");
}
e = new CancelEventArgs();
this.OnSelectionResizing(e);
if (!e.Cancel)
{
_resizeAnchor = anchor;
_previousSelectionRegion = this.SelectionRegion;
_isResizing = true;
}
}
#endregion
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/MainMenuForm.cs
================================================
// Cyotek ImageBox
// http://cyotek.com/blog/tag/imagebox
// Copyright (c) 2010-2021 Cyotek Ltd.
// This work is licensed under the MIT License.
// See LICENSE.TXT for the full text
// Found this code useful?
// https://www.cyotek.com/contribute
using System;
using System.Windows.Forms;
namespace Cyotek.Windows.Forms.Demo
{
internal partial class MainMenuForm : AboutDialog
{
#region Constructors
public MainMenuForm()
{
this.InitializeComponent();
}
#endregion
#region Methods
protected override void OnLoad(EventArgs e)
{
TabPage demoPage;
base.OnLoad(e);
demoPage = new TabPage
{
UseVisualStyleBackColor = true,
Padding = new Padding(9),
Text = "Demonstrations"
};
demoGroupBox.Dock = DockStyle.Fill;
demoPage.Controls.Add(demoGroupBox);
this.TabControl.TabPages.Insert(0, demoPage);
this.TabControl.SelectedTab = demoPage;
this.Text = "Cyotek ImageBox Control for Windows Forms";
}
///
/// Raises the event.
///
/// A that contains the event data.
protected override void OnShown(EventArgs e)
{
base.OnShown(e);
imageBoxDemoButton.Focus();
}
private void animatedGifDemoButton_Click(object sender, EventArgs e)
{
this.ShowDemo();
}
private void dragTestDemoButton_Click(object sender, EventArgs e)
{
this.ShowDemo();
}
private void imageBoxDemoButton_Click(object sender, EventArgs e)
{
this.ShowDemo();
}
private void minimapDemoButton_Click(object sender, EventArgs e)
{
this.ShowDemo();
}
private void panDemoButton_Click(object sender, EventArgs e)
{
this.ShowDemo();
}
private void pixelGridDemoButton_Click(object sender, EventArgs e)
{
this.ShowDemo();
}
private void resizableSelectionDemoButton_Click(object sender, EventArgs e)
{
this.ShowDemo();
}
private void scaledAdornmentsDemoButton_Click(object sender, EventArgs e)
{
this.ShowDemo();
}
private void ShowDemo()
where T : Form, new()
{
Cursor.Current = Cursors.WaitCursor;
using (Form form = new T())
{
form.ShowDialog(this);
}
}
private void sizeModeDemoButton_Click(object sender, EventArgs e)
{
this.ShowDemo();
}
private void switchImageDuringZoomDemoButton_Click(object sender, EventArgs e)
{
this.ShowDemo();
}
private void textDemoButton_Click(object sender, EventArgs e)
{
this.ShowDemo();
}
private void virtualModeDemoButton_Click(object sender, EventArgs e)
{
this.ShowDemo();
}
#endregion
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/MainMenuForm.designer.cs
================================================
namespace Cyotek.Windows.Forms.Demo
{
partial class MainMenuForm
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainMenuForm));
this.imageBoxDemoButton = new System.Windows.Forms.Button();
this.pixelGridDemoButton = new System.Windows.Forms.Button();
this.virtualModeDemoButton = new System.Windows.Forms.Button();
this.demoGroupBox = new Cyotek.Windows.Forms.GroupBox();
this.panDemoButton = new System.Windows.Forms.Button();
this.minimapDemoButton = new System.Windows.Forms.Button();
this.resizableSelectionDemoButton = new System.Windows.Forms.Button();
this.textDemoButton = new System.Windows.Forms.Button();
this.animatedGifDemoButton = new System.Windows.Forms.Button();
this.switchImageDuringZoomDemoButton = new System.Windows.Forms.Button();
this.sizeModeDemoButton = new System.Windows.Forms.Button();
this.scaledAdornmentsDemoButton = new System.Windows.Forms.Button();
this.dragTestDemoButton = new System.Windows.Forms.Button();
this.demoGroupBox.SuspendLayout();
this.SuspendLayout();
//
// imageBoxDemoButton
//
this.imageBoxDemoButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.imageBoxDemoButton.Location = new System.Drawing.Point(5, 19);
this.imageBoxDemoButton.Name = "imageBoxDemoButton";
this.imageBoxDemoButton.Size = new System.Drawing.Size(406, 23);
this.imageBoxDemoButton.TabIndex = 0;
this.imageBoxDemoButton.Text = "&General Demonstration";
this.imageBoxDemoButton.UseVisualStyleBackColor = true;
this.imageBoxDemoButton.Click += new System.EventHandler(this.imageBoxDemoButton_Click);
//
// pixelGridDemoButton
//
this.pixelGridDemoButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.pixelGridDemoButton.Location = new System.Drawing.Point(5, 48);
this.pixelGridDemoButton.Name = "pixelGridDemoButton";
this.pixelGridDemoButton.Size = new System.Drawing.Size(406, 23);
this.pixelGridDemoButton.TabIndex = 1;
this.pixelGridDemoButton.Text = "Pi&xel Grid Demonstration";
this.pixelGridDemoButton.UseVisualStyleBackColor = true;
this.pixelGridDemoButton.Click += new System.EventHandler(this.pixelGridDemoButton_Click);
//
// virtualModeDemoButton
//
this.virtualModeDemoButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.virtualModeDemoButton.Location = new System.Drawing.Point(5, 77);
this.virtualModeDemoButton.Name = "virtualModeDemoButton";
this.virtualModeDemoButton.Size = new System.Drawing.Size(406, 23);
this.virtualModeDemoButton.TabIndex = 2;
this.virtualModeDemoButton.Text = "&Virtual Mode Demonstration";
this.virtualModeDemoButton.UseVisualStyleBackColor = true;
this.virtualModeDemoButton.Click += new System.EventHandler(this.virtualModeDemoButton_Click);
//
// demoGroupBox
//
this.demoGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.demoGroupBox.Controls.Add(this.panDemoButton);
this.demoGroupBox.Controls.Add(this.minimapDemoButton);
this.demoGroupBox.Controls.Add(this.resizableSelectionDemoButton);
this.demoGroupBox.Controls.Add(this.textDemoButton);
this.demoGroupBox.Controls.Add(this.animatedGifDemoButton);
this.demoGroupBox.Controls.Add(this.switchImageDuringZoomDemoButton);
this.demoGroupBox.Controls.Add(this.sizeModeDemoButton);
this.demoGroupBox.Controls.Add(this.scaledAdornmentsDemoButton);
this.demoGroupBox.Controls.Add(this.dragTestDemoButton);
this.demoGroupBox.Controls.Add(this.imageBoxDemoButton);
this.demoGroupBox.Controls.Add(this.virtualModeDemoButton);
this.demoGroupBox.Controls.Add(this.pixelGridDemoButton);
this.demoGroupBox.Location = new System.Drawing.Point(27, 56);
this.demoGroupBox.Name = "demoGroupBox";
this.demoGroupBox.Size = new System.Drawing.Size(417, 418);
this.demoGroupBox.TabIndex = 0;
this.demoGroupBox.TabStop = false;
this.demoGroupBox.Text = "Available Demonstrations";
//
// panDemoButton
//
this.panDemoButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.panDemoButton.Location = new System.Drawing.Point(5, 338);
this.panDemoButton.Name = "panDemoButton";
this.panDemoButton.Size = new System.Drawing.Size(406, 23);
this.panDemoButton.TabIndex = 12;
this.panDemoButton.Text = "&Pan Demonstration";
this.panDemoButton.UseVisualStyleBackColor = true;
this.panDemoButton.Click += new System.EventHandler(this.panDemoButton_Click);
//
// minimapDemoButton
//
this.minimapDemoButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.minimapDemoButton.Location = new System.Drawing.Point(5, 309);
this.minimapDemoButton.Name = "minimapDemoButton";
this.minimapDemoButton.Size = new System.Drawing.Size(406, 23);
this.minimapDemoButton.TabIndex = 11;
this.minimapDemoButton.Text = "M&inimap Demonstration";
this.minimapDemoButton.UseVisualStyleBackColor = true;
this.minimapDemoButton.Click += new System.EventHandler(this.minimapDemoButton_Click);
//
// resizableSelectionDemoButton
//
this.resizableSelectionDemoButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.resizableSelectionDemoButton.Location = new System.Drawing.Point(5, 280);
this.resizableSelectionDemoButton.Name = "resizableSelectionDemoButton";
this.resizableSelectionDemoButton.Size = new System.Drawing.Size(406, 23);
this.resizableSelectionDemoButton.TabIndex = 10;
this.resizableSelectionDemoButton.Text = "&Resizable Selection Demonstration";
this.resizableSelectionDemoButton.UseVisualStyleBackColor = true;
this.resizableSelectionDemoButton.Click += new System.EventHandler(this.resizableSelectionDemoButton_Click);
//
// textDemoButton
//
this.textDemoButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.textDemoButton.Location = new System.Drawing.Point(5, 251);
this.textDemoButton.Name = "textDemoButton";
this.textDemoButton.Size = new System.Drawing.Size(406, 23);
this.textDemoButton.TabIndex = 9;
this.textDemoButton.Text = "&Text Demonstration";
this.textDemoButton.UseVisualStyleBackColor = true;
this.textDemoButton.Click += new System.EventHandler(this.textDemoButton_Click);
//
// animatedGifDemoButton
//
this.animatedGifDemoButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.animatedGifDemoButton.Location = new System.Drawing.Point(5, 222);
this.animatedGifDemoButton.Name = "animatedGifDemoButton";
this.animatedGifDemoButton.Size = new System.Drawing.Size(406, 23);
this.animatedGifDemoButton.TabIndex = 8;
this.animatedGifDemoButton.Text = "&Animated GIF Demonstration";
this.animatedGifDemoButton.UseVisualStyleBackColor = true;
this.animatedGifDemoButton.Click += new System.EventHandler(this.animatedGifDemoButton_Click);
//
// switchImageDuringZoomDemoButton
//
this.switchImageDuringZoomDemoButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.switchImageDuringZoomDemoButton.Location = new System.Drawing.Point(5, 193);
this.switchImageDuringZoomDemoButton.Name = "switchImageDuringZoomDemoButton";
this.switchImageDuringZoomDemoButton.Size = new System.Drawing.Size(406, 23);
this.switchImageDuringZoomDemoButton.TabIndex = 7;
this.switchImageDuringZoomDemoButton.Text = "Switch Image During &Zoom Demonstration";
this.switchImageDuringZoomDemoButton.UseVisualStyleBackColor = true;
this.switchImageDuringZoomDemoButton.Click += new System.EventHandler(this.switchImageDuringZoomDemoButton_Click);
//
// sizeModeDemoButton
//
this.sizeModeDemoButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.sizeModeDemoButton.Location = new System.Drawing.Point(5, 164);
this.sizeModeDemoButton.Name = "sizeModeDemoButton";
this.sizeModeDemoButton.Size = new System.Drawing.Size(406, 23);
this.sizeModeDemoButton.TabIndex = 6;
this.sizeModeDemoButton.Text = "Size &Mode Demonstration";
this.sizeModeDemoButton.UseVisualStyleBackColor = true;
this.sizeModeDemoButton.Click += new System.EventHandler(this.sizeModeDemoButton_Click);
//
// scaledAdornmentsDemoButton
//
this.scaledAdornmentsDemoButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.scaledAdornmentsDemoButton.Location = new System.Drawing.Point(5, 135);
this.scaledAdornmentsDemoButton.Name = "scaledAdornmentsDemoButton";
this.scaledAdornmentsDemoButton.Size = new System.Drawing.Size(406, 23);
this.scaledAdornmentsDemoButton.TabIndex = 4;
this.scaledAdornmentsDemoButton.Text = "&Scaled Adornments Demonstration";
this.scaledAdornmentsDemoButton.UseVisualStyleBackColor = true;
this.scaledAdornmentsDemoButton.Click += new System.EventHandler(this.scaledAdornmentsDemoButton_Click);
//
// dragTestDemoButton
//
this.dragTestDemoButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.dragTestDemoButton.Location = new System.Drawing.Point(5, 106);
this.dragTestDemoButton.Name = "dragTestDemoButton";
this.dragTestDemoButton.Size = new System.Drawing.Size(406, 23);
this.dragTestDemoButton.TabIndex = 3;
this.dragTestDemoButton.Text = "&Drag Test Demonstration";
this.dragTestDemoButton.UseVisualStyleBackColor = true;
this.dragTestDemoButton.Click += new System.EventHandler(this.dragTestDemoButton_Click);
//
// MainMenuForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(527, 535);
this.Controls.Add(this.demoGroupBox);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Name = "MainMenuForm";
this.ShowIcon = true;
this.ShowInTaskbar = true;
this.Text = "Cyotek ImageBox Control for Windows Forms";
this.Controls.SetChildIndex(this.demoGroupBox, 0);
this.demoGroupBox.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button imageBoxDemoButton;
private System.Windows.Forms.Button pixelGridDemoButton;
private System.Windows.Forms.Button virtualModeDemoButton;
private GroupBox demoGroupBox;
private System.Windows.Forms.Button dragTestDemoButton;
private System.Windows.Forms.Button scaledAdornmentsDemoButton;
private System.Windows.Forms.Button sizeModeDemoButton;
private System.Windows.Forms.Button switchImageDuringZoomDemoButton;
private System.Windows.Forms.Button animatedGifDemoButton;
private System.Windows.Forms.Button textDemoButton;
private System.Windows.Forms.Button resizableSelectionDemoButton;
private System.Windows.Forms.Button minimapDemoButton;
private System.Windows.Forms.Button panDemoButton;
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/MainMenuForm.resx
================================================
text/microsoft-resx
2.0
System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
AAABAAIAICAAAAEAIACoEAAAJgAAABAQAAABACAAaAQAAM4QAAAoAAAAIAAAAEAAAAABACAAAAAAAIAQ
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsKCQ/7CgkP+vn4//r5+P/66ejv+tnY3/rZ2N/6yc
jP+snIz/q5uL/6ubi/+qmor/qpqK/6mZif+pmYn/qJiI/6iYiP+nl4f/p5eH/6aWhv+llYX/pZWF/6SU
hP+klIT/o5OD/6OTg/+ikoL/opKC/6GRgf+hkYH/AAAAAAAAAACxoZH/7eXg/+3k3//s493/6+Lc/+vh
2//q4Nr/6d/Z/+ne2P/o3df/59zW/+fb1P/m2tP/5tnS/+XY0f/k19D/5NbP/+PVzv/i1Mz/4tPL/+HS
yv+hkYH//////+HSyv/h0sr/4dLK/+HSyv/h0sr/4dLK/6GRgf8AAAAAAAAAALGhkf/u5uH/C3kX/wh0
Ev8Gbg3/A2kI/wFjAv8AYAD/AGAA/wBgAP8AYAD/AGAA/wBgAP8AYAD/AGEB/wBgAP8AYAD/AGAA/wBg
AP8AYAD/4tPL/6KSgv//////8uvo//Do5P/t5eD/6+Ld/+ne2f/h0sr/opKC/wAAAAAAAAAAsqKS/+/n
4v8Ofxz/C3kX/wh0Ev8Gbg3/A2kI/wFjAv8AYAD/AGAA/wBgAP8AYAD/AGAA/wBgAP8AYAD/AGEB/wBg
AP8AYAD/AGAA/wBgAP/i1Mz/opKC///////07uz/8uvo/0w3KP/t5eD/6+Ld/+HSyv+ikoL/AAAAAAAA
AACyopL/7+fj/xCFIf8Ofxz/C3kX/wh0Ev8Gbg3/A2kI/wFjAv8AYAD/AGAA/wBgAP8AYAD/AGAA/wBg
AP8AYAD/AGEB/wBgAP8AYAD/AGAA/+PVzv+jk4P///////by8P9YPSv/Ujoq/0w3KP/t5eD/4dLK/6OT
g/8AAAAAAAAAALOjk//w6OT/E4on/xCFIf8Ofxz/C3kX/wh0Ev8Gbg3/A2kI/wFjAv8AYAD/AGAA/wBg
AP8AYAD/AGAA/wBgAP8AYAD/AGEB/wBgAP8AYAD/5NbP/6OTg///////+PXz//by8P/07uz/8uvo//Do
5P/h0sr/o5OD/wAAAAAAAAAAs6OT//Dp5f8WkCz/E4on/xCFIf8Ofxz/C3kX/wh0Ev8Gbg3/A2kI/wFj
Av8AYAD/AGAA/wBgAP8AYAD/AGAA/wBgAP8AYAD/AGEB/wNmBv/k19D/pJSE///////6+Pf/+PXz//by
8P/07uz/8uvo/+HSyv+klIT/AAAAAAAAAAC0pJT/8ern/xiWMf8WkSz/E4sn/xGGIv8OgB3/C3sY/wl1
E/8Gbw3/A2kI/wFkA/8AYAD/AGAA/wBgAP8AYAD/AGAA/wBhAf8Gbw7/B3AO/+XY0f+klIT/////////
/////////////////////////////6SUhP8AAAAAAAAAALSklP/y6+j/Gps2/xiWMf8WkSz/E4sn/xGG
Iv8OgB3/DHsY/wl1FP8Hbw7/BGoJ/wJlBP8AYAD/AGAA/wBgAP8AYAD/Bm8O/w5/Hf8LeRf/5tnS/6WV
hf+llYX/pZWF/6WVhf+llYX/pZWF/6WVhf+llYX/pZWF/wAAAAAAAAAAtaWV//Ls6f8doDv/Gps2/xiW
Mf8WkS3/E4sn/xGGIv8OgB3/DHsY/wl1E/8HcA//BGsK/wFkBP8AYAD/AGAA/wJlBf8SiSb/Eokl/w+C
H//m2tP/pZWF/+vh3P/r4dz/6+Hc/+vh3P/r4dz/6+Hc/+vh3P+llYX/AAAAAAAAAAC1pZX/8+3q/yGn
Qv8eoj3/G504/xmXM/8WkS3/FIwo/xGGI/8OgB3/DHsY/wl1FP8HcA//BGsK/wJlBP8AYgL/EoYj/xqY
NP8WkS3/Eoom/+fb1P+mlob/7OLd/+zi3f/s4t3/7OLd/+zi3f/s4t3/7OLd/6aWhv8AAAAAAAAAALam
lv/07uv/IqpE/yCnQv8eoj3/G504/xmXM/8Xki7/FI0p/xGHJP8Pgh//DHwa/wp2FP8HcA//BGgH/whn
Bv8cnDf/HqE8/xuaNf8TiCX/59zW/6eXh//t5N//7eTf/+3k3//t5N//7eTf/+3k3//t5N//p5eH/wAA
AAAAAAAAtqaW//Tv7P8alTH/I6xG/yCnQv8eoj3/G5w4/xmXM/8Xki7/FI0p/xKHJP8Pgh//DXwa/wh0
Ev8fbQz/ZIEd/xqKJ/8hp0H/G5g0/yZ3Ev/o3df/p5eH/+7l4f/u5eH/7uXh/+7l4f/u5eH/7uXh/+7l
4f+nl4f/AAAAAAAAAAC3p5f/9fDt/ziGLv8gpkD/I65I/yGoQ/8eoz3/G504/xmXM/8Xki7/FI0p/xKH
JP8PgR7/DWwL/5OQL//pq0X/TH8c/xqSLv8lfxv/DWwL/+ne2P+omIj/7+fi/+/n4v/v5+L/7+fi/+/n
4v/v5+L/7+fi/6iYiP8AAAAAAAAAALiomP/28e//ybd9/zeIL/8cnTj/I61H/yGpQ/8epD7/HJ45/xmZ
NP8Xky7/FIwp/wt3Ff9wiCr/7a9S//exUP/TpEH/iZEs/w1sC//2qTj/6d/Z/6iYiP/w6OT/8Ojk//Do
5P/w6OT/8Ojk//Do5P/w6OT/qJiI/wAAAAAAAAAAuKiY//by8P/3x5f/x7Z8/0eMN/8ZkC3/IqpE/yGp
Q/8fpD7/HJ45/xmYM/8UhiP/P3sf/+awWv/4tFv/+LNW//ixUP/3r0r/965E//isPv/q4Nr/qZmJ//Hq
5v/x6ub/8erm//Hq5v/x6ub/8erm//Hq5v+pmYn/AAAAAAAAAAC5qZn/9/Px//jImP/4yJj/37+K/26T
R/8UgSD/HaA7/yGpQ/8epD7/F5Et/zJ8H//Lqln/+Lhm//i2Yf/4tFv/+LNW//ixUP/4r0r/+K5E/+vh
2/+pmYn/8evn//Hr5//x6+f/8evn//Hr5//x6+f/8evn/6mZif8AAAAAAAAAALmpmf/39PL/+MiY//jI
mP/4yJj/+MiY/8S0ef9Vizn/GoYl/xeOKv9AgCf/zK5l//i8dP/4u27/+Llp//i3Y//4tFz/+LNX//ix
Uf/4r0v/6+Lc/6qaiv/y7On/8uzp//Ls6f/y7On/8uzp//Ls6f/y7On/qpqK/wAAAAAAAAAAuqqa//j1
8//4yJj/+MiY//jImP/4yJj/98iX/+jBjf+Dm0//g5tP/9u3dv/2v3//+L56//i8dP/4u27/+Llp//e2
Y//psmj/1a5y/9OscP/s493/qpqK//Pu6//z7uv/8+7r//Pu6//z7uv/8+7r//Pu6/+qmor/AAAAAAAA
AAC6qpr/+fb0//jImP/4yJj/+MiY//jImP/4yJj/+MiX//jHlv/4xZH/+MOL//jBhf/4wH//+L55//i8
dP/0unH/t66W/2ehzf9Gm+b/QZrp/+3k3/+rm4v/9O/s//Tv7P/07+z/9O/s//Tv7P/07+z/9O/s/6ub
i/8AAAAAAAAAALurm//59/X/+MiY//jImP/4yJj/+MiY//jImP/4yJj/+MiY//jHl//4xpL/+MSM//jC
hv/4wID/9r57/7Gxov84pO//KqT3/y2c+P8wmPj/7eXg/6ubi//18e7/9fHu//Xx7v/18e7/9fHu//Xx
7v/18e7/q5uL/wAAAAAAAAAAu6ub//r49//4yJj/+MiY//jImP/4yJj/+MiY//jImP/4yJj/+MiY//jH
l//4xpL/+MSN//jCh//ivY7/Warc/yK49/8lr/j/KaX4/y2c+P/u5uH/rJyM/6ycjP+snIz/rJyM/6yc
jP+snIz/rJyM/6ycjP+snIz/AAAAAAAAAAC8rJz/+/n4//jImP/4yJj/+MiY//jImP/4yJj/+MiY//jI
mP/4yJj/+MiY//jHl//4xpL/+MSM/8S5pP8us/H/HMT4/yC6+P8lsPj/Kab4/+/n4v+snIz//////+HS
yv/h0sr/4dLK/+HSyv/h0sr/4dLK/6ycjP8AAAAAAAAAALysnP/7+vn/+MiY//jImP/4yJj/+MiY//jI
mP/4yJj/+MiY//jImP/4yJj/+MiY//jHl//4xpL/urit/yW99P8X0Pj/G8b4/yC9+P8ks/j/7+fj/62d
jf//////8uvo//Do5P/t5eD/6+Ld/+ne2f/h0sr/rZ2N/wAAAAAAAAAAva2d//z7+v/4yJj/+MiY//jI
mP/4yJj/+MiY//jImP/4yJj/+MiY//jImP/4yJj/+MiY//jIl//XwaX/QbTq/xLY+P8X0Pj/G8f4/x++
+P/w6OT/rZ2N///////07uz/8uvo//Do5P/t5eD/6+Ld/+HSyv+tnY3/AAAAAAAAAAC9rZ3//fz7//jI
mP/4yJj/+MiY//jImP/4yJj/+MiY//jImP/4yJj/+MiY//jImP/4yJj/+MiY//HGmv+HtMz/Hcv2/xPY
9/8X0Pj/G8f4//Dp5f+uno7///////by8P9YPSv/Ujoq/0w3KP/t5eD/4dLK/66ejv8AAAAAAAAAAL6u
nv/9/fz/+MiY//jImP/4yJj/+MiY//jImP/4yJj/+MiY//jImP/4yJj/+MiY//jImP/4yJj/+MiY/+XE
oP9xs9X/Lbzx/xzJ9v8dxff/8ern/6+fj///////+PXz//by8P9YPSv/8uvo//Do5P/h0sr/r5+P/wAA
AAAAAAAAvq6e//7+/f/4yJj/+MiY//jImP/4yJj/+MiY//jImP/4yJj/+MiY//jImP/4yJj/+MiY//jI
mP/4yJj/+MiY//PGmf/Dvq7/lrLC/5Cvwv/y6+j/r5+P///////6+Pf/+PXz//by8P/07uz/8uvo/+HS
yv+vn4//AAAAAAAAAAC/r5////////7+/f/9/fz//fz7//z7+v/7+vn/+/n4//r49//59/X/+fb0//j1
8//39PL/9/Px//by8P/28e//9fDt//Tv7P/07uv/8+3q//Ls6f+woJD/////////////////////////
/////////////7CgkP8AAAAAAAAAAMCwoP+/r5//vq6e/76unv+9rZ3/va2d/7ysnP+8rJz/u6ub/7ur
m/+6qpr/uqqa/7mpmf+5qZn/uKiY/7iomP+3p5f/tqaW/7amlv+1pZX/taWV/7SklP+0pJT/s6OT/7Oj
k/+yopL/sqKS/7Ghkf+xoZH/sKCQ/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////+AAAABgAAAAYAAAAGAAAABgAAAAYAA
AAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAA
AAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAH/////KAAAABAAAAAgAAAAAQAgAAAA
AABABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsaGR/7CgkP+uno7/rZ2N/6ycjP+rm4v/qpqK/6mZ
if+omIj/ppaG/6WVhf+klIT/o5OD/6KSgv8AAAAAAAAAALKikv/u5uH/7eTf/+vh3P/q39n/6N3X/+fb
1P/l2NH/5NbP/6OTg//28e//8ern/+3j3/+jk4P/AAAAAAAAAACzo5P/8Ojk/xOQK/8QhyT/DHwb/whz
E/8FaQz/AmAG/+XY0f+klIT/+vj3/2lHMf/x6uf/pJSE/wAAAAAAAAAAtKSU//Hq5/8YnDX/FJMu/xCI
Jf8Mfh3/CXQV/wVoDf/n29T/pZWF///////6+Pf/9vHv/6WVhf8AAAAAAAAAALWllf/z7en/G5o1/xid
Nv8Uki3/EIgl/w1/Hf8FZgz/6N3X/6aWhv+mlob/ppaG/6aWhv+mlob/AAAAAAAAAAC2ppb/9O/s/zeI
L/8bmzb/GJ01/xSTLv8NgB7/AloD/+rf2f+omIj/7+fj/+/n4//v5+P/qJiI/wAAAAAAAAAAuKiY//bx
7//buID/N4gv/zeIL/8XmjT/E2gR/xljDP/r4dz/qZmJ//Hq5//x6uf/8ern/6mZif8AAAAAAAAAALmp
mf/38/H/98KP//fCj/+2qWv/NIUs/ylrFv+wm0//7eTf/6qaiv/z7er/8+3q//Pt6v+qmor/AAAAAAAA
AAC6qpr/+fb0//fCj//3wo//9cGO/7apa//htXj/87l3/+7m4f+rm4v/9fDt//Xw7f/18O3/q5uL/wAA
AAAAAAAAu6ub//r49//3wo//98KP//fCj//3wY7/98CM//e+hP/w6OT/rJyM/6ycjP+snIz/rJyM/6yc
jP8AAAAAAAAAALysnP/8+vn/98KP//fCj//3wo//98KP//fBjv/3wY3/8ern/62djf/28e//8ern/+3j
3/+tnY3/AAAAAAAAAAC9rZ3//fz8//fCj//3wo//98KP//fCj//3wo//98KP//Pt6f+uno7/+vj3/2lH
Mf/x6uf/rp6O/wAAAAAAAAAAvq6e///////9/Pz//Pr5//r49//59vT/9/Px//bx7//07+z/sKCQ////
///6+Pf/9vHv/7CgkP8AAAAAAAAAAMCwoP++rp7/va2d/7ysnP+7q5v/uqqa/7mpmf+4qJj/tqaW/7Wl
lf+0pJT/s6OT/7Kikv+xoZH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIAB
AACAAQAAgAEAAIABAACAAQAAgAEAAIABAAD//wAA
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/MiniMapDemoForm.cs
================================================
// Cyotek ImageBox
// Copyright (c) 2010-2017 Cyotek Ltd.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
using System;
using System.Drawing;
using System.Windows.Forms;
using Cyotek.Windows.Forms.Demo.Properties;
// demonstration was derived based on the following forum post
// https://forums.cyotek.com/imagebox/problem-when-trying-to-create-a-minimap-using-imagebox/
namespace Cyotek.Windows.Forms.Demo
{
internal partial class MiniMapDemoForm : BaseForm
{
#region Fields
private Rectangle _minimap;
private Bitmap _thumbnailBitmap;
#endregion
#region Constructors
public MiniMapDemoForm()
{
this.InitializeComponent();
}
#endregion
#region Methods
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
zoomImageBox.Image = Resources.Sample;
this.UpdateMiniMap();
}
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
{
AboutDialog.ShowAboutDialog();
}
private void closeToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Close();
}
private void miniMapImageBox_Paint(object sender, PaintEventArgs e)
{
if (_thumbnailBitmap != null)
{
using (Pen pen = new Pen(Color.Aquamarine, 3))
{
e.Graphics.DrawImage(_thumbnailBitmap, miniMapImageBox.GetImageViewPort().
Location);
e.Graphics.DrawRectangle(pen, _minimap.X, _minimap.Y, _minimap.Width, _minimap.Height);
}
}
}
private void RefreshMiniMap()
{
Image image;
image = zoomImageBox.Image;
if (image != null)
{
Bitmap minimap;
Size minimapSize;
// https://github.com/cyotek/Cyotek.Windows.Forms.ImageBox/issues/27
// I found that ImageBox can cause performance issues if you instruct it
// to paint a large image that is zoomed out repeatly. As the image for
// our minimap doesn't actually change or allow zooming, lets create
// a tiny version up front. To make it easy, the "mini map" ImageBox
// has its VirtualMode property set to True, and the SizeMode set to
// Fit. I then set the VirtualSize to be the size if the original
// image and it will then calculate the size I need for the thumbnail
// which saves me some manual work. However, it does mean that I need
// to manually paint the thumbnail
miniMapImageBox.VirtualSize = image.Size;
minimapSize = miniMapImageBox.GetImageViewPort().
Size;
minimap = new Bitmap(minimapSize.Width, minimapSize.Height);
// generate the thumbnail
using (Graphics g = Graphics.FromImage(minimap))
{
g.DrawImage(image, new Rectangle(Point.Empty, minimap.Size), new Rectangle(Point.Empty, image.Size), GraphicsUnit.Pixel);
}
// always clean up
if (_thumbnailBitmap != null)
{
_thumbnailBitmap.Dispose();
_thumbnailBitmap = null;
}
_thumbnailBitmap = minimap;
// force a paint of the minimap
this.UpdateMiniMap();
}
}
private void splitContainer_SplitterMoved(object sender, SplitterEventArgs e)
{
this.RefreshMiniMap();
}
private void UpdateMiniMap()
{
Rectangle proposedView;
Size viewSize;
Point location;
double x;
double y;
double w;
double h;
// define the initial size. We'll take the current
// size from the source imagebox's image viewport
viewSize = zoomImageBox.GetImageViewPort().
Size;
w = viewSize.Width;
h = viewSize.Height;
// next we need to scale the size to match the zoomfactor of the source imagebox
w /= zoomImageBox.ZoomFactor;
h /= zoomImageBox.ZoomFactor;
// next we scale the size again - this time by the zoomfactor the destination imagebox
w *= miniMapImageBox.ZoomFactor;
h *= miniMapImageBox.ZoomFactor;
// with the size define, we can now turn out attention to the origin
// first, we get the current auto scroll offsets, and reverse them
// to give us our origin
x = -zoomImageBox.AutoScrollPosition.X;
y = -zoomImageBox.AutoScrollPosition.Y;
// next, we need to scale that to account for the source imagebox zoom
x /= zoomImageBox.ZoomFactor;
y /= zoomImageBox.ZoomFactor;
// as with the size, we need to scale again to account for the destination imagebox
x *= miniMapImageBox.ZoomFactor;
y *= miniMapImageBox.ZoomFactor;
// and for our final action, we need to offset the origin to account
// for where the destination imagebox is painting the output image
location = miniMapImageBox.GetImageViewPort().
Location;
x += location.X;
y += location.Y;
// all done, create the final rectangle for painting
proposedView = new Rectangle(Convert.ToInt32(x), Convert.ToInt32(y), Convert.ToInt32(w), Convert.ToInt32(h));
// see if the final rectangle is different to the one already being used
// to avoid painting if we don't need to
if (proposedView != _minimap)
{
_minimap = proposedView;
// force the destination to repaint to show the new rectangle
// this has performance issues
// https://github.com/cyotek/Cyotek.Windows.Forms.ImageBox/issues/27
miniMapImageBox.Invalidate();
imageViewPortToolStripStatusLabel.Text = "Image Viewport: " + zoomImageBox.GetImageViewPort().
ToString();
calculatedRectangleToolStripStatusLabel.Text = "Rectangle: " + _minimap.ToString();
}
}
private void zoomImageBox_ImageChanged(object sender, EventArgs e)
{
this.RefreshMiniMap();
}
private void zoomImageBox_Resize(object sender, EventArgs e)
{
this.RefreshMiniMap();
}
private void zoomImageBox_Scroll(object sender, ScrollEventArgs e)
{
this.UpdateMiniMap();
}
private void zoomImageBox_Zoomed(object sender, ImageBoxZoomEventArgs e)
{
this.UpdateMiniMap();
}
#endregion
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/MiniMapDemoForm.designer.cs
================================================
namespace Cyotek.Windows.Forms.Demo
{
partial class MiniMapDemoForm
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.zoomImageBox = new Cyotek.Windows.Forms.ImageBox();
this.miniMapImageBox = new Cyotek.Windows.Forms.ImageBox();
this.statusStrip1 = new System.Windows.Forms.StatusStrip();
this.imageViewPortToolStripStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
this.calculatedRectangleToolStripStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
this.menuStrip = new System.Windows.Forms.MenuStrip();
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.closeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.splitContainer = new System.Windows.Forms.SplitContainer();
this.statusStrip1.SuspendLayout();
this.menuStrip.SuspendLayout();
this.splitContainer.Panel1.SuspendLayout();
this.splitContainer.Panel2.SuspendLayout();
this.splitContainer.SuspendLayout();
this.SuspendLayout();
//
// zoomImageBox
//
this.zoomImageBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.zoomImageBox.Location = new System.Drawing.Point(0, 0);
this.zoomImageBox.Name = "zoomImageBox";
this.zoomImageBox.Size = new System.Drawing.Size(680, 483);
this.zoomImageBox.TabIndex = 0;
this.zoomImageBox.TabStop = false;
this.zoomImageBox.ImageChanged += new System.EventHandler(this.zoomImageBox_ImageChanged);
this.zoomImageBox.Zoomed += new System.EventHandler(this.zoomImageBox_Zoomed);
this.zoomImageBox.Scroll += new System.Windows.Forms.ScrollEventHandler(this.zoomImageBox_Scroll);
this.zoomImageBox.Resize += new System.EventHandler(this.zoomImageBox_Resize);
//
// miniMapImageBox
//
this.miniMapImageBox.AllowZoom = false;
this.miniMapImageBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.miniMapImageBox.PanMode = ImageBoxPanMode.None;
this.miniMapImageBox.Location = new System.Drawing.Point(3, 3);
this.miniMapImageBox.Name = "miniMapImageBox";
this.miniMapImageBox.Size = new System.Drawing.Size(291, 155);
this.miniMapImageBox.SizeMode = Cyotek.Windows.Forms.ImageBoxSizeMode.Fit;
this.miniMapImageBox.TabIndex = 0;
this.miniMapImageBox.TabStop = false;
this.miniMapImageBox.VirtualMode = true;
this.miniMapImageBox.Paint += new System.Windows.Forms.PaintEventHandler(this.miniMapImageBox_Paint);
//
// statusStrip1
//
this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.imageViewPortToolStripStatusLabel,
this.calculatedRectangleToolStripStatusLabel});
this.statusStrip1.Location = new System.Drawing.Point(0, 507);
this.statusStrip1.Name = "statusStrip1";
this.statusStrip1.Size = new System.Drawing.Size(980, 22);
this.statusStrip1.TabIndex = 2;
this.statusStrip1.Text = "statusStrip1";
//
// imageViewPortToolStripStatusLabel
//
this.imageViewPortToolStripStatusLabel.Name = "imageViewPortToolStripStatusLabel";
this.imageViewPortToolStripStatusLabel.Size = new System.Drawing.Size(0, 17);
//
// calculatedRectangleToolStripStatusLabel
//
this.calculatedRectangleToolStripStatusLabel.Name = "calculatedRectangleToolStripStatusLabel";
this.calculatedRectangleToolStripStatusLabel.Size = new System.Drawing.Size(0, 17);
//
// menuStrip
//
this.menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.fileToolStripMenuItem,
this.helpToolStripMenuItem});
this.menuStrip.Location = new System.Drawing.Point(0, 0);
this.menuStrip.Name = "menuStrip";
this.menuStrip.Padding = new System.Windows.Forms.Padding(5, 2, 0, 2);
this.menuStrip.Size = new System.Drawing.Size(980, 24);
this.menuStrip.TabIndex = 0;
//
// fileToolStripMenuItem
//
this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.closeToolStripMenuItem});
this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
this.fileToolStripMenuItem.Text = "&File";
//
// closeToolStripMenuItem
//
this.closeToolStripMenuItem.Name = "closeToolStripMenuItem";
this.closeToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.W)));
this.closeToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.closeToolStripMenuItem.Text = "&Close";
this.closeToolStripMenuItem.Click += new System.EventHandler(this.closeToolStripMenuItem_Click);
//
// helpToolStripMenuItem
//
this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.aboutToolStripMenuItem});
this.helpToolStripMenuItem.Name = "helpToolStripMenuItem";
this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 20);
this.helpToolStripMenuItem.Text = "&Help";
//
// aboutToolStripMenuItem
//
this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
this.aboutToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.aboutToolStripMenuItem.Text = "&About...";
this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click);
//
// splitContainer
//
this.splitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
this.splitContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel1;
this.splitContainer.Location = new System.Drawing.Point(0, 24);
this.splitContainer.Name = "splitContainer";
//
// splitContainer.Panel1
//
this.splitContainer.Panel1.Controls.Add(this.zoomImageBox);
//
// splitContainer.Panel2
//
this.splitContainer.Panel2.Controls.Add(this.miniMapImageBox);
this.splitContainer.Size = new System.Drawing.Size(980, 483);
this.splitContainer.SplitterDistance = 680;
this.splitContainer.SplitterWidth = 3;
this.splitContainer.TabIndex = 1;
this.splitContainer.SplitterMoved += new System.Windows.Forms.SplitterEventHandler(this.splitContainer_SplitterMoved);
//
// MiniMapDemoForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(980, 529);
this.Controls.Add(this.splitContainer);
this.Controls.Add(this.menuStrip);
this.Controls.Add(this.statusStrip1);
this.Name = "MiniMapDemoForm";
this.Text = "Minimap Overlay Demonstration";
this.statusStrip1.ResumeLayout(false);
this.statusStrip1.PerformLayout();
this.menuStrip.ResumeLayout(false);
this.menuStrip.PerformLayout();
this.splitContainer.Panel1.ResumeLayout(false);
this.splitContainer.Panel2.ResumeLayout(false);
this.splitContainer.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private Cyotek.Windows.Forms.ImageBox zoomImageBox;
private Cyotek.Windows.Forms.ImageBox miniMapImageBox;
private System.Windows.Forms.StatusStrip statusStrip1;
private System.Windows.Forms.ToolStripStatusLabel imageViewPortToolStripStatusLabel;
private System.Windows.Forms.ToolStripStatusLabel calculatedRectangleToolStripStatusLabel;
private System.Windows.Forms.MenuStrip menuStrip;
private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem closeToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem;
private System.Windows.Forms.SplitContainer splitContainer;
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/MiniMapDemoForm.resx
================================================
text/microsoft-resx
2.0
System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
17, 17
477, 17
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/OpenUrlDialog.Designer.cs
================================================
namespace Cyotek.Windows.Forms.Demo
{
partial class OpenUrlDialog
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.urlTextBox = new System.Windows.Forms.TextBox();
this.okButton = new System.Windows.Forms.Button();
this.cancelButton = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(10, 8);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(275, 13);
this.label1.TabIndex = 0;
this.label1.Text = "Type the Internet address of an image document to open";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(10, 34);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(36, 13);
this.label2.TabIndex = 1;
this.label2.Text = "&Open:";
//
// urlTextBox
//
this.urlTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.urlTextBox.Location = new System.Drawing.Point(49, 31);
this.urlTextBox.Margin = new System.Windows.Forms.Padding(3, 10, 3, 3);
this.urlTextBox.Name = "urlTextBox";
this.urlTextBox.Size = new System.Drawing.Size(265, 20);
this.urlTextBox.TabIndex = 2;
this.urlTextBox.Text = "https://www.cyotek.com/files/articleimages/aeg1e.png";
//
// okButton
//
this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.okButton.Location = new System.Drawing.Point(180, 72);
this.okButton.Name = "okButton";
this.okButton.Size = new System.Drawing.Size(64, 20);
this.okButton.TabIndex = 3;
this.okButton.Text = "OK";
this.okButton.UseVisualStyleBackColor = true;
this.okButton.Click += new System.EventHandler(this.okButton_Click);
//
// cancelButton
//
this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.cancelButton.Location = new System.Drawing.Point(249, 72);
this.cancelButton.Name = "cancelButton";
this.cancelButton.Size = new System.Drawing.Size(64, 20);
this.cancelButton.TabIndex = 4;
this.cancelButton.Text = "Cancel";
this.cancelButton.UseVisualStyleBackColor = true;
this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click);
//
// OpenUrlDialog
//
this.AcceptButton = this.okButton;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.cancelButton;
this.ClientSize = new System.Drawing.Size(324, 102);
this.Controls.Add(this.cancelButton);
this.Controls.Add(this.okButton);
this.Controls.Add(this.urlTextBox);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.Name = "OpenUrlDialog";
this.Text = "Open";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.TextBox urlTextBox;
private System.Windows.Forms.Button okButton;
private System.Windows.Forms.Button cancelButton;
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/OpenUrlDialog.cs
================================================
using System;
using System.ComponentModel;
using System.Windows.Forms;
// Cyotek ImageBox
// Copyright (c) 2010-2017 Cyotek Ltd.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
namespace Cyotek.Windows.Forms.Demo
{
internal sealed partial class OpenUrlDialog : BaseForm
{
#region Constructors
public OpenUrlDialog()
{
this.InitializeComponent();
}
#endregion
#region Properties
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public string Url { get; set; }
#endregion
#region Methods
private void cancelButton_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
this.Close();
}
private void okButton_Click(object sender, EventArgs e)
{
string url;
url = urlTextBox.Text;
if (this.ValidateUrl(url))
{
this.DialogResult = DialogResult.OK;
this.Url = url;
this.Close();
}
else
{
this.DialogResult = DialogResult.None;
}
}
private bool ValidateUrl(string url)
{
Uri uri;
bool result;
result = !string.IsNullOrEmpty(url) && Uri.TryCreate(url, UriKind.Absolute, out uri) && (uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps);
return result;
}
#endregion
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/OpenUrlDialog.resx
================================================
text/microsoft-resx
2.0
System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/PanStylesDemoForm.Designer.cs
================================================
namespace Cyotek.Windows.Forms.Demo
{
partial class PanStylesDemoForm
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PanStylesDemoForm));
this.splitContainer = new System.Windows.Forms.SplitContainer();
this.imageBox = new Cyotek.Windows.Forms.ImageBox();
this.propertyGrid = new Cyotek.Windows.Forms.Demo.FilteredPropertyGrid();
this.demoLabel = new System.Windows.Forms.Label();
this.eventsListBox = new Cyotek.Windows.Forms.Demo.EventsListBox();
this.menuStrip = new System.Windows.Forms.MenuStrip();
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.closeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.statusStrip = new System.Windows.Forms.StatusStrip();
this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel();
this.positionToolStripStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
this.splitContainer.Panel1.SuspendLayout();
this.splitContainer.Panel2.SuspendLayout();
this.splitContainer.SuspendLayout();
this.menuStrip.SuspendLayout();
this.statusStrip.SuspendLayout();
this.SuspendLayout();
//
// splitContainer
//
this.splitContainer.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.splitContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel2;
this.splitContainer.Location = new System.Drawing.Point(10, 23);
this.splitContainer.Name = "splitContainer";
//
// splitContainer.Panel1
//
this.splitContainer.Panel1.Controls.Add(this.imageBox);
//
// splitContainer.Panel2
//
this.splitContainer.Panel2.Controls.Add(this.propertyGrid);
this.splitContainer.Panel2.Controls.Add(this.demoLabel);
this.splitContainer.Panel2.Controls.Add(this.eventsListBox);
this.splitContainer.Size = new System.Drawing.Size(764, 556);
this.splitContainer.SplitterDistance = 497;
this.splitContainer.TabIndex = 1;
//
// imageBox
//
this.imageBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.imageBox.Image = global::Cyotek.Windows.Forms.Demo.Properties.Resources.Sample;
this.imageBox.Location = new System.Drawing.Point(0, 0);
this.imageBox.Name = "imageBox";
this.imageBox.Size = new System.Drawing.Size(497, 556);
this.imageBox.TabIndex = 0;
this.imageBox.PanEnd += new System.EventHandler(this.imageBox_PanEnd);
this.imageBox.PanStart += new System.EventHandler(this.imageBox_PanStart);
//
// propertyGrid
//
this.propertyGrid.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.propertyGrid.CommandsVisibleIfAvailable = false;
this.propertyGrid.HelpVisible = false;
this.propertyGrid.Location = new System.Drawing.Point(3, 352);
this.propertyGrid.Name = "propertyGrid";
this.propertyGrid.Size = new System.Drawing.Size(260, 90);
this.propertyGrid.TabIndex = 1;
this.propertyGrid.ToolbarVisible = false;
//
// demoLabel
//
this.demoLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.demoLabel.AutoEllipsis = true;
this.demoLabel.BackColor = System.Drawing.SystemColors.Info;
this.demoLabel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.demoLabel.ForeColor = System.Drawing.SystemColors.InfoText;
this.demoLabel.Location = new System.Drawing.Point(0, 1);
this.demoLabel.Name = "demoLabel";
this.demoLabel.Padding = new System.Windows.Forms.Padding(9);
this.demoLabel.Size = new System.Drawing.Size(263, 348);
this.demoLabel.TabIndex = 0;
this.demoLabel.Text = resources.GetString("demoLabel.Text");
//
// eventsListBox
//
this.eventsListBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.eventsListBox.FormattingEnabled = true;
this.eventsListBox.Location = new System.Drawing.Point(3, 448);
this.eventsListBox.Name = "eventsListBox";
this.eventsListBox.Size = new System.Drawing.Size(260, 108);
this.eventsListBox.TabIndex = 2;
//
// menuStrip
//
this.menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.fileToolStripMenuItem,
this.helpToolStripMenuItem});
this.menuStrip.Location = new System.Drawing.Point(0, 0);
this.menuStrip.Name = "menuStrip";
this.menuStrip.Size = new System.Drawing.Size(784, 24);
this.menuStrip.TabIndex = 0;
//
// fileToolStripMenuItem
//
this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.closeToolStripMenuItem});
this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
this.fileToolStripMenuItem.Text = "&File";
//
// closeToolStripMenuItem
//
this.closeToolStripMenuItem.Name = "closeToolStripMenuItem";
this.closeToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.W)));
this.closeToolStripMenuItem.Size = new System.Drawing.Size(148, 22);
this.closeToolStripMenuItem.Text = "&Close";
this.closeToolStripMenuItem.Click += new System.EventHandler(this.closeToolStripMenuItem_Click);
//
// helpToolStripMenuItem
//
this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.aboutToolStripMenuItem});
this.helpToolStripMenuItem.Name = "helpToolStripMenuItem";
this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 20);
this.helpToolStripMenuItem.Text = "&Help";
//
// aboutToolStripMenuItem
//
this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
this.aboutToolStripMenuItem.Size = new System.Drawing.Size(116, 22);
this.aboutToolStripMenuItem.Text = "&About...";
this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click);
//
// statusStrip
//
this.statusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripStatusLabel1,
this.positionToolStripStatusLabel});
this.statusStrip.Location = new System.Drawing.Point(0, 579);
this.statusStrip.Name = "statusStrip";
this.statusStrip.Size = new System.Drawing.Size(784, 22);
this.statusStrip.TabIndex = 2;
//
// toolStripStatusLabel1
//
this.toolStripStatusLabel1.Name = "toolStripStatusLabel1";
this.toolStripStatusLabel1.Size = new System.Drawing.Size(769, 17);
this.toolStripStatusLabel1.Spring = true;
//
// positionToolStripStatusLabel
//
this.positionToolStripStatusLabel.Name = "positionToolStripStatusLabel";
this.positionToolStripStatusLabel.Size = new System.Drawing.Size(0, 17);
//
// PanStylesDemoForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(784, 601);
this.Controls.Add(this.splitContainer);
this.Controls.Add(this.menuStrip);
this.Controls.Add(this.statusStrip);
this.Name = "PanStylesDemoForm";
this.Text = "Panning";
this.splitContainer.Panel1.ResumeLayout(false);
this.splitContainer.Panel2.ResumeLayout(false);
this.splitContainer.ResumeLayout(false);
this.menuStrip.ResumeLayout(false);
this.menuStrip.PerformLayout();
this.statusStrip.ResumeLayout(false);
this.statusStrip.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private ImageBox imageBox;
private System.Windows.Forms.Label demoLabel;
private System.Windows.Forms.SplitContainer splitContainer;
private System.Windows.Forms.MenuStrip menuStrip;
private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem closeToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem;
private System.Windows.Forms.StatusStrip statusStrip;
private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel1;
private System.Windows.Forms.ToolStripStatusLabel positionToolStripStatusLabel;
private EventsListBox eventsListBox;
private FilteredPropertyGrid propertyGrid;
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/PanStylesDemoForm.cs
================================================
// Cyotek ImageBox
// http://cyotek.com/blog/tag/imagebox
// Copyright (c) 2021 Cyotek Ltd.
// This work is licensed under the MIT License.
// See LICENSE.TXT for the full text
// Found this code useful?
// https://www.cyotek.com/contribute
using System;
using System.Windows.Forms;
namespace Cyotek.Windows.Forms.Demo
{
internal partial class PanStylesDemoForm : BaseForm
{
#region Public Constructors
public PanStylesDemoForm()
{
this.InitializeComponent();
}
#endregion Public Constructors
#region Protected Methods
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
propertyGrid.BrowsableProperties = new[]
{
nameof(ImageBox.AllowFreePan),
nameof(ImageBox.InvertMouse),
nameof(ImageBox.PanMode)
};
propertyGrid.SelectedObject = imageBox;
}
#endregion Protected Methods
#region Private Methods
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
{
AboutDialog.ShowAboutDialog();
}
private void closeToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Close();
}
private void imageBox_PanEnd(object sender, EventArgs e)
{
eventsListBox.AddEvent((Control)sender, nameof(ImageBox.PanEnd));
}
private void imageBox_PanStart(object sender, EventArgs e)
{
eventsListBox.AddEvent((Control)sender, nameof(ImageBox.PanStart));
}
#endregion Private Methods
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/PanStylesDemoForm.resx
================================================
text/microsoft-resx
2.0
System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Panning allows you to scroll the ImageBox via the mouse. The ImageBox supports two pan modes, standard and free.
In standard mode, you click with the left or middle mouse buttons and drag - this will cause the control to scroll. The PanMode property can be used to set which mouse buttons can be used to initiate the pan. You can also use the InvertMouse property to reverse the scroll orientation. Note that if the SelectionMode property is set to a value other than None, you cannot pan with the left mouse button.
If the AllowFreePan property is set, clicking with the middle mouse button enables an automatic pan. In this mode, the further away the mouse is from the click origin, the faster the control will scroll. The automatic pan will continue untile the control is clicked again. Alternatively, if you hold down the middle button, the automatic pan will end once the button is released.
17, 17
140, 17
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/PixelGridForm.Designer.cs
================================================
namespace Cyotek.Windows.Forms.Demo
{
partial class PixelGridForm
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.splitContainer = new System.Windows.Forms.SplitContainer();
this.propertyGrid = new Cyotek.Windows.Forms.Demo.PropertyGrid();
this.imageBox = new Cyotek.Windows.Forms.ImageBox();
this.statusStrip = new System.Windows.Forms.StatusStrip();
this.menuStrip = new System.Windows.Forms.MenuStrip();
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.closeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.splitContainer.Panel1.SuspendLayout();
this.splitContainer.Panel2.SuspendLayout();
this.splitContainer.SuspendLayout();
this.menuStrip.SuspendLayout();
this.SuspendLayout();
//
// splitContainer
//
this.splitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
this.splitContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel1;
this.splitContainer.Location = new System.Drawing.Point(0, 24);
this.splitContainer.Name = "splitContainer";
//
// splitContainer.Panel1
//
this.splitContainer.Panel1.Controls.Add(this.propertyGrid);
//
// splitContainer.Panel2
//
this.splitContainer.Panel2.Controls.Add(this.imageBox);
this.splitContainer.Size = new System.Drawing.Size(848, 490);
this.splitContainer.SplitterDistance = 300;
this.splitContainer.SplitterWidth = 3;
this.splitContainer.TabIndex = 0;
//
// propertyGrid
//
this.propertyGrid.Dock = System.Windows.Forms.DockStyle.Fill;
this.propertyGrid.Location = new System.Drawing.Point(0, 0);
this.propertyGrid.Name = "propertyGrid";
this.propertyGrid.SelectedObject = this.imageBox;
this.propertyGrid.Size = new System.Drawing.Size(300, 490);
this.propertyGrid.TabIndex = 0;
//
// imageBox
//
this.imageBox.BackColor = System.Drawing.SystemColors.GradientActiveCaption;
this.imageBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.imageBox.GridDisplayMode = Cyotek.Windows.Forms.ImageBoxGridDisplayMode.Image;
this.imageBox.Image = global::Cyotek.Windows.Forms.Demo.Properties.Resources.Monitor;
this.imageBox.ImageBorderStyle = Cyotek.Windows.Forms.ImageBoxBorderStyle.FixedSingleGlowShadow;
this.imageBox.Location = new System.Drawing.Point(0, 0);
this.imageBox.Name = "imageBox";
this.imageBox.ShowPixelGrid = true;
this.imageBox.Size = new System.Drawing.Size(545, 490);
this.imageBox.TabIndex = 0;
this.imageBox.Zoom = 1600;
//
// statusStrip
//
this.statusStrip.Location = new System.Drawing.Point(0, 514);
this.statusStrip.Name = "statusStrip";
this.statusStrip.Padding = new System.Windows.Forms.Padding(1, 0, 12, 0);
this.statusStrip.Size = new System.Drawing.Size(848, 22);
this.statusStrip.TabIndex = 6;
//
// menuStrip
//
this.menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.fileToolStripMenuItem,
this.helpToolStripMenuItem});
this.menuStrip.Location = new System.Drawing.Point(0, 0);
this.menuStrip.Name = "menuStrip";
this.menuStrip.Padding = new System.Windows.Forms.Padding(5, 2, 0, 2);
this.menuStrip.Size = new System.Drawing.Size(848, 24);
this.menuStrip.TabIndex = 5;
//
// fileToolStripMenuItem
//
this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.closeToolStripMenuItem});
this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
this.fileToolStripMenuItem.Text = "&File";
//
// closeToolStripMenuItem
//
this.closeToolStripMenuItem.Name = "closeToolStripMenuItem";
this.closeToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.W)));
this.closeToolStripMenuItem.Size = new System.Drawing.Size(148, 22);
this.closeToolStripMenuItem.Text = "&Close";
this.closeToolStripMenuItem.Click += new System.EventHandler(this.closeToolStripMenuItem_Click);
//
// helpToolStripMenuItem
//
this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.aboutToolStripMenuItem});
this.helpToolStripMenuItem.Name = "helpToolStripMenuItem";
this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 20);
this.helpToolStripMenuItem.Text = "&Help";
//
// aboutToolStripMenuItem
//
this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
this.aboutToolStripMenuItem.Size = new System.Drawing.Size(116, 22);
this.aboutToolStripMenuItem.Text = "&About...";
this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click);
//
// PixelGridForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(848, 536);
this.Controls.Add(this.splitContainer);
this.Controls.Add(this.statusStrip);
this.Controls.Add(this.menuStrip);
this.Name = "PixelGridForm";
this.Text = "Pixel Grid";
this.splitContainer.Panel1.ResumeLayout(false);
this.splitContainer.Panel2.ResumeLayout(false);
this.splitContainer.ResumeLayout(false);
this.menuStrip.ResumeLayout(false);
this.menuStrip.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.SplitContainer splitContainer;
private PropertyGrid propertyGrid;
private ImageBox imageBox;
private System.Windows.Forms.StatusStrip statusStrip;
private System.Windows.Forms.MenuStrip menuStrip;
private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem closeToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem;
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/PixelGridForm.cs
================================================
using System;
namespace Cyotek.Windows.Forms.Demo
{
// Cyotek ImageBox
// Copyright (c) 2010-2015 Cyotek Ltd.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
internal partial class PixelGridForm : BaseForm
{
#region Public Constructors
public PixelGridForm()
{
this.InitializeComponent();
}
#endregion
#region Overridden Methods
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
propertyGrid.SelectItem("ShowPixelGrid");
}
#endregion
#region Event Handlers
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
{
AboutDialog.ShowAboutDialog();
}
private void closeToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Close();
}
#endregion
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/PixelGridForm.resx
================================================
text/microsoft-resx
2.0
System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
248, 17
364, 17
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/Program.cs
================================================
using System;
using System.Windows.Forms;
namespace Cyotek.Windows.Forms.Demo
{
// Cyotek ImageBox
// Copyright (c) 2010-2015 Cyotek Ltd.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
internal static class Program
{
#region Class Members
///
/// The main entry point for the application.
///
[STAThread]
private static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainMenuForm());
}
#endregion
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/Properties/AssemblyInfo.cs
================================================
using System;
using System.Reflection;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("Cyotek ImageBox Demonstration")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Cyotek Ltd")]
[assembly: AssemblyProduct("Cyotek ImageBox Control")]
[assembly: AssemblyCopyright("Copyright © 2010-2017 Cyotek Ltd.")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: Guid("e01e91cb-0059-4d88-880a-ed43e130f7f4")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.2.0.0")]
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/Properties/Resources.Designer.cs
================================================
//------------------------------------------------------------------------------
//
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
//------------------------------------------------------------------------------
namespace Cyotek.Windows.Forms.Demo.Properties {
using System;
///
/// A strongly-typed resource class, for looking up localized strings, etc.
///
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
///
/// Returns the cached ResourceManager instance used by this class.
///
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Cyotek.Windows.Forms.Demo.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
///
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
///
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
internal static System.Drawing.Bitmap ActualSize {
get {
object obj = ResourceManager.GetObject("ActualSize", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
internal static System.Drawing.Bitmap AnimationDemo {
get {
object obj = ResourceManager.GetObject("AnimationDemo", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
///
/// Looks up a localized string similar to /* GitHub stylesheet for MarkdownPad (http://markdownpad.com) */
////* Author: Nicolas Hery - http://nicolashery.com */
////* Version: 29d1c5bc36da364ad5aa86946d420b7bbc54a253 */
////* Source: https://github.com/nicolahery/markdownpad-github */
///
////* RESET
///=============================================================================*/
///
///html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, s [rest of string was truncated]";.
///
internal static string CSS {
get {
return ResourceManager.GetString("CSS", resourceCulture);
}
}
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
internal static System.Drawing.Bitmap Cursor {
get {
object obj = ResourceManager.GetObject("Cursor", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
internal static System.Drawing.Bitmap Grid {
get {
object obj = ResourceManager.GetObject("Grid", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
internal static System.Drawing.Bitmap Icon {
get {
object obj = ResourceManager.GetObject("Icon", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
internal static System.Drawing.Bitmap IconA {
get {
object obj = ResourceManager.GetObject("IconA", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
internal static System.Drawing.Bitmap Map {
get {
object obj = ResourceManager.GetObject("Map", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
internal static System.Drawing.Bitmap MapMarker {
get {
object obj = ResourceManager.GetObject("MapMarker", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
internal static System.Drawing.Bitmap Monitor {
get {
object obj = ResourceManager.GetObject("Monitor", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
internal static System.Drawing.Bitmap Open {
get {
object obj = ResourceManager.GetObject("Open", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
internal static System.Drawing.Bitmap Position {
get {
object obj = ResourceManager.GetObject("Position", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
internal static System.Drawing.Bitmap Sample {
get {
object obj = ResourceManager.GetObject("Sample", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
internal static System.Drawing.Bitmap samplecrop {
get {
object obj = ResourceManager.GetObject("samplecrop", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
internal static System.Drawing.Bitmap SelectAll {
get {
object obj = ResourceManager.GetObject("SelectAll", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
internal static System.Drawing.Bitmap SelectNone {
get {
object obj = ResourceManager.GetObject("SelectNone", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
internal static System.Drawing.Bitmap Size {
get {
object obj = ResourceManager.GetObject("Size", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
internal static System.Drawing.Bitmap SmallMap {
get {
object obj = ResourceManager.GetObject("SmallMap", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
internal static System.Drawing.Bitmap VirtualMode {
get {
object obj = ResourceManager.GetObject("VirtualMode", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
internal static System.Drawing.Bitmap Zone {
get {
object obj = ResourceManager.GetObject("Zone", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
internal static System.Drawing.Bitmap Zoom {
get {
object obj = ResourceManager.GetObject("Zoom", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
internal static System.Drawing.Bitmap ZoomIn {
get {
object obj = ResourceManager.GetObject("ZoomIn", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
internal static System.Drawing.Bitmap ZoomOut {
get {
object obj = ResourceManager.GetObject("ZoomOut", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/Properties/Resources.resx
================================================
text/microsoft-resx
2.0
System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
..\Resources\image-resize-actual.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
..\Resources\The_Legendary_Treasure_Map_by_Bogbrush.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
..\Resources\selection.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
..\Resources\icon-32a.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
..\Resources\sample.jpg;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
..\Resources\icon-32.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
..\Resources\zone.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
..\Resources\image-crop.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
..\Resources\map.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
..\Resources\selection-select.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
..\Resources\Object Position.ico;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
..\Resources\Object Size.ico;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
..\Resources\markdownpad-github.css;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8
..\Resources\monitor-sidebar.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
..\Resources\MapMarker.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
..\Resources\Newtons_cradle_animation_book_2.gif;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
..\Resources\magnifier-zoom-in.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
..\Resources\grid-dot.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
..\Resources\cursor.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
..\Resources\samplecrop.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
..\Resources\magnifier-zoom.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
..\Resources\magnifier-zoom-out.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
..\Resources\Open.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/PropertyGrid.cs
================================================
using System.Collections.Generic;
using System.Windows.Forms;
namespace Cyotek.Windows.Forms.Demo
{
// Cyotek ImageBox
// Copyright (c) 2010-2015 Cyotek Ltd.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
internal class PropertyGrid : System.Windows.Forms.PropertyGrid
{
#region Public Members
public GridItem FindItem(string itemLabel)
{
// http://www.vb-helper.com/howto_net_select_propertygrid_item.html
GridItem rootItem;
GridItem matchingItem;
Queue searchItems;
matchingItem = null;
// Find the GridItem root.
rootItem = this.SelectedGridItem;
while (rootItem.Parent != null)
{
rootItem = rootItem.Parent;
}
// Search the tree.
searchItems = new Queue();
searchItems.Enqueue(rootItem);
while (searchItems.Count != 0 && matchingItem == null)
{
GridItem checkItem;
checkItem = searchItems.Dequeue();
if (checkItem.Label == itemLabel)
{
matchingItem = checkItem;
}
foreach (GridItem item in checkItem.GridItems)
{
searchItems.Enqueue(item);
}
}
return matchingItem;
}
public void SelectItem(string itemLabel)
{
GridItem selection;
selection = this.FindItem(itemLabel);
if (selection != null)
{
try
{
this.SelectedGridItem = selection;
}
catch
{
// ignore
}
}
}
#endregion
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/ResizableSelectionDemoForm.Designer.cs
================================================
namespace Cyotek.Windows.Forms.Demo
{
partial class ResizableSelectionDemoForm
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ResizableSelectionDemoForm));
this.demoLabel = new System.Windows.Forms.Label();
this.splitContainer = new System.Windows.Forms.SplitContainer();
this.imageBox = new Cyotek.Windows.Forms.Demo.ImageBoxEx();
this.eventsSplitContainer = new System.Windows.Forms.SplitContainer();
this.tabControl1 = new System.Windows.Forms.TabControl();
this.eventsTabPage = new System.Windows.Forms.TabPage();
this.eventsListBox = new Cyotek.Windows.Forms.Demo.EventsListBox();
this.dragHandlesTabPage = new System.Windows.Forms.TabPage();
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
this.enabledCheckedListBox = new System.Windows.Forms.CheckedListBox();
this.label1 = new System.Windows.Forms.Label();
this.visibleCheckedListBox = new System.Windows.Forms.CheckedListBox();
this.label2 = new System.Windows.Forms.Label();
this.propertiesTabPage = new System.Windows.Forms.TabPage();
this.propertyGrid = new System.Windows.Forms.PropertyGrid();
this.menuStrip = new System.Windows.Forms.MenuStrip();
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.closeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.editToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.selectAllToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.selectNoneToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.statusStrip = new System.Windows.Forms.StatusStrip();
this.cursorToolStripStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
this.statusToolStripStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
this.autoScrollPositionToolStripStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
this.imageSizeToolStripStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
this.zoomToolStripStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
this.selectionToolStripStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
this.splitContainer.Panel1.SuspendLayout();
this.splitContainer.Panel2.SuspendLayout();
this.splitContainer.SuspendLayout();
this.eventsSplitContainer.Panel1.SuspendLayout();
this.eventsSplitContainer.Panel2.SuspendLayout();
this.eventsSplitContainer.SuspendLayout();
this.tabControl1.SuspendLayout();
this.eventsTabPage.SuspendLayout();
this.dragHandlesTabPage.SuspendLayout();
this.splitContainer1.Panel1.SuspendLayout();
this.splitContainer1.Panel2.SuspendLayout();
this.splitContainer1.SuspendLayout();
this.propertiesTabPage.SuspendLayout();
this.menuStrip.SuspendLayout();
this.statusStrip.SuspendLayout();
this.SuspendLayout();
//
// demoLabel
//
this.demoLabel.AutoEllipsis = true;
this.demoLabel.BackColor = System.Drawing.SystemColors.Info;
this.demoLabel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.demoLabel.Dock = System.Windows.Forms.DockStyle.Fill;
this.demoLabel.ForeColor = System.Drawing.SystemColors.InfoText;
this.demoLabel.Location = new System.Drawing.Point(0, 0);
this.demoLabel.Name = "demoLabel";
this.demoLabel.Padding = new System.Windows.Forms.Padding(8, 8, 8, 8);
this.demoLabel.Size = new System.Drawing.Size(360, 180);
this.demoLabel.TabIndex = 1;
this.demoLabel.Text = resources.GetString("demoLabel.Text");
//
// splitContainer
//
this.splitContainer.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.splitContainer.Location = new System.Drawing.Point(10, 23);
this.splitContainer.Name = "splitContainer";
//
// splitContainer.Panel1
//
this.splitContainer.Panel1.Controls.Add(this.imageBox);
//
// splitContainer.Panel2
//
this.splitContainer.Panel2.Controls.Add(this.eventsSplitContainer);
this.splitContainer.Size = new System.Drawing.Size(705, 362);
this.splitContainer.SplitterDistance = 342;
this.splitContainer.SplitterWidth = 3;
this.splitContainer.TabIndex = 5;
//
// imageBox
//
this.imageBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.imageBox.Location = new System.Drawing.Point(0, 0);
this.imageBox.Name = "imageBox";
this.imageBox.SelectionMode = Cyotek.Windows.Forms.ImageBoxSelectionMode.Rectangle;
this.imageBox.Size = new System.Drawing.Size(342, 362);
this.imageBox.TabIndex = 0;
this.imageBox.VirtualMode = true;
this.imageBox.VirtualSize = new System.Drawing.Size(256, 256);
this.imageBox.SelectionMoved += new System.EventHandler(this.imageBox_SelectionMoved);
this.imageBox.SelectionMoving += new System.ComponentModel.CancelEventHandler(this.imageBox_SelectionMoving);
this.imageBox.SelectionResized += new System.EventHandler(this.imageBox_SelectionResized);
this.imageBox.SelectionResizing += new System.ComponentModel.CancelEventHandler(this.imageBox_SelectionResizing);
this.imageBox.Selected += new System.EventHandler(this.imageBox_Selected);
this.imageBox.Selecting += new System.EventHandler(this.imageBox_Selecting);
this.imageBox.SelectionRegionChanged += new System.EventHandler(this.imageBox_SelectionRegionChanged);
this.imageBox.VirtualDraw += new System.Windows.Forms.PaintEventHandler(this.imageBox_VirtualDraw);
this.imageBox.Zoomed += new System.EventHandler(this.imageBox_Zoomed);
this.imageBox.Scroll += new System.Windows.Forms.ScrollEventHandler(this.imageBox_Scroll);
this.imageBox.MouseLeave += new System.EventHandler(this.imageBox_MouseLeave);
this.imageBox.MouseMove += new System.Windows.Forms.MouseEventHandler(this.imageBox_MouseMove);
this.imageBox.Resize += new System.EventHandler(this.imageBox_Resize);
//
// eventsSplitContainer
//
this.eventsSplitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
this.eventsSplitContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel1;
this.eventsSplitContainer.IsSplitterFixed = true;
this.eventsSplitContainer.Location = new System.Drawing.Point(0, 0);
this.eventsSplitContainer.Name = "eventsSplitContainer";
this.eventsSplitContainer.Orientation = System.Windows.Forms.Orientation.Horizontal;
//
// eventsSplitContainer.Panel1
//
this.eventsSplitContainer.Panel1.Controls.Add(this.demoLabel);
//
// eventsSplitContainer.Panel2
//
this.eventsSplitContainer.Panel2.Controls.Add(this.tabControl1);
this.eventsSplitContainer.Size = new System.Drawing.Size(360, 362);
this.eventsSplitContainer.SplitterDistance = 180;
this.eventsSplitContainer.SplitterWidth = 3;
this.eventsSplitContainer.TabIndex = 2;
//
// tabControl1
//
this.tabControl1.Controls.Add(this.eventsTabPage);
this.tabControl1.Controls.Add(this.dragHandlesTabPage);
this.tabControl1.Controls.Add(this.propertiesTabPage);
this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tabControl1.Location = new System.Drawing.Point(0, 0);
this.tabControl1.Name = "tabControl1";
this.tabControl1.SelectedIndex = 0;
this.tabControl1.Size = new System.Drawing.Size(360, 179);
this.tabControl1.TabIndex = 0;
//
// eventsTabPage
//
this.eventsTabPage.Controls.Add(this.eventsListBox);
this.eventsTabPage.Location = new System.Drawing.Point(4, 22);
this.eventsTabPage.Name = "eventsTabPage";
this.eventsTabPage.Padding = new System.Windows.Forms.Padding(5, 5, 5, 5);
this.eventsTabPage.Size = new System.Drawing.Size(352, 153);
this.eventsTabPage.TabIndex = 0;
this.eventsTabPage.Text = "Events";
this.eventsTabPage.UseVisualStyleBackColor = true;
//
// eventsListBox
//
this.eventsListBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.eventsListBox.FormattingEnabled = true;
this.eventsListBox.Location = new System.Drawing.Point(5, 5);
this.eventsListBox.Name = "eventsListBox";
this.eventsListBox.Size = new System.Drawing.Size(342, 143);
this.eventsListBox.TabIndex = 0;
//
// dragHandlesTabPage
//
this.dragHandlesTabPage.Controls.Add(this.splitContainer1);
this.dragHandlesTabPage.Location = new System.Drawing.Point(4, 24);
this.dragHandlesTabPage.Name = "dragHandlesTabPage";
this.dragHandlesTabPage.Padding = new System.Windows.Forms.Padding(5, 5, 5, 5);
this.dragHandlesTabPage.Size = new System.Drawing.Size(351, 175);
this.dragHandlesTabPage.TabIndex = 1;
this.dragHandlesTabPage.Text = "Drag Handles";
this.dragHandlesTabPage.UseVisualStyleBackColor = true;
//
// splitContainer1
//
this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
this.splitContainer1.Location = new System.Drawing.Point(5, 5);
this.splitContainer1.Name = "splitContainer1";
//
// splitContainer1.Panel1
//
this.splitContainer1.Panel1.Controls.Add(this.enabledCheckedListBox);
this.splitContainer1.Panel1.Controls.Add(this.label1);
//
// splitContainer1.Panel2
//
this.splitContainer1.Panel2.Controls.Add(this.visibleCheckedListBox);
this.splitContainer1.Panel2.Controls.Add(this.label2);
this.splitContainer1.Size = new System.Drawing.Size(341, 165);
this.splitContainer1.SplitterDistance = 167;
this.splitContainer1.SplitterWidth = 3;
this.splitContainer1.TabIndex = 0;
//
// enabledCheckedListBox
//
this.enabledCheckedListBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.enabledCheckedListBox.FormattingEnabled = true;
this.enabledCheckedListBox.IntegralHeight = false;
this.enabledCheckedListBox.Location = new System.Drawing.Point(3, 16);
this.enabledCheckedListBox.Name = "enabledCheckedListBox";
this.enabledCheckedListBox.Size = new System.Drawing.Size(162, 147);
this.enabledCheckedListBox.TabIndex = 1;
this.enabledCheckedListBox.ItemCheck += new System.Windows.Forms.ItemCheckEventHandler(this.enabledCheckedListBox_ItemCheck);
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(-3, 0);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(91, 13);
this.label1.TabIndex = 0;
this.label1.Text = "Enabled Handles:";
//
// visibleCheckedListBox
//
this.visibleCheckedListBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.visibleCheckedListBox.FormattingEnabled = true;
this.visibleCheckedListBox.IntegralHeight = false;
this.visibleCheckedListBox.Location = new System.Drawing.Point(3, 16);
this.visibleCheckedListBox.Name = "visibleCheckedListBox";
this.visibleCheckedListBox.Size = new System.Drawing.Size(166, 147);
this.visibleCheckedListBox.TabIndex = 1;
this.visibleCheckedListBox.ItemCheck += new System.Windows.Forms.ItemCheckEventHandler(this.visibleCheckedListBox_ItemCheck);
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(0, 0);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(82, 13);
this.label2.TabIndex = 0;
this.label2.Text = "Visible Handles:";
//
// propertiesTabPage
//
this.propertiesTabPage.Controls.Add(this.propertyGrid);
this.propertiesTabPage.Location = new System.Drawing.Point(4, 24);
this.propertiesTabPage.Name = "propertiesTabPage";
this.propertiesTabPage.Padding = new System.Windows.Forms.Padding(5, 5, 5, 5);
this.propertiesTabPage.Size = new System.Drawing.Size(351, 175);
this.propertiesTabPage.TabIndex = 2;
this.propertiesTabPage.Text = "Properties";
this.propertiesTabPage.UseVisualStyleBackColor = true;
//
// propertyGrid
//
this.propertyGrid.CommandsVisibleIfAvailable = false;
this.propertyGrid.Dock = System.Windows.Forms.DockStyle.Fill;
this.propertyGrid.HelpVisible = false;
this.propertyGrid.Location = new System.Drawing.Point(5, 5);
this.propertyGrid.Name = "propertyGrid";
this.propertyGrid.SelectedObject = this.imageBox;
this.propertyGrid.Size = new System.Drawing.Size(341, 165);
this.propertyGrid.TabIndex = 0;
this.propertyGrid.ToolbarVisible = false;
//
// menuStrip
//
this.menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.fileToolStripMenuItem,
this.editToolStripMenuItem,
this.helpToolStripMenuItem});
this.menuStrip.Location = new System.Drawing.Point(0, 0);
this.menuStrip.Name = "menuStrip";
this.menuStrip.Padding = new System.Windows.Forms.Padding(5, 2, 0, 2);
this.menuStrip.Size = new System.Drawing.Size(726, 24);
this.menuStrip.TabIndex = 6;
//
// fileToolStripMenuItem
//
this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.closeToolStripMenuItem});
this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
this.fileToolStripMenuItem.Text = "&File";
//
// closeToolStripMenuItem
//
this.closeToolStripMenuItem.Name = "closeToolStripMenuItem";
this.closeToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.W)));
this.closeToolStripMenuItem.Size = new System.Drawing.Size(148, 22);
this.closeToolStripMenuItem.Text = "&Close";
this.closeToolStripMenuItem.Click += new System.EventHandler(this.closeToolStripMenuItem_Click);
//
// editToolStripMenuItem
//
this.editToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.selectAllToolStripMenuItem,
this.selectNoneToolStripMenuItem});
this.editToolStripMenuItem.Name = "editToolStripMenuItem";
this.editToolStripMenuItem.Size = new System.Drawing.Size(39, 20);
this.editToolStripMenuItem.Text = "&Edit";
//
// selectAllToolStripMenuItem
//
this.selectAllToolStripMenuItem.Name = "selectAllToolStripMenuItem";
this.selectAllToolStripMenuItem.Size = new System.Drawing.Size(137, 22);
this.selectAllToolStripMenuItem.Text = "Select &All";
this.selectAllToolStripMenuItem.Click += new System.EventHandler(this.selectAllToolStripMenuItem_Click);
//
// selectNoneToolStripMenuItem
//
this.selectNoneToolStripMenuItem.Name = "selectNoneToolStripMenuItem";
this.selectNoneToolStripMenuItem.Size = new System.Drawing.Size(137, 22);
this.selectNoneToolStripMenuItem.Text = "Select &None";
this.selectNoneToolStripMenuItem.Click += new System.EventHandler(this.selectNoneToolStripMenuItem_Click);
//
// helpToolStripMenuItem
//
this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.aboutToolStripMenuItem});
this.helpToolStripMenuItem.Name = "helpToolStripMenuItem";
this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 20);
this.helpToolStripMenuItem.Text = "&Help";
//
// aboutToolStripMenuItem
//
this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
this.aboutToolStripMenuItem.Size = new System.Drawing.Size(116, 22);
this.aboutToolStripMenuItem.Text = "&About...";
this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click);
//
// statusStrip
//
this.statusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.cursorToolStripStatusLabel,
this.statusToolStripStatusLabel,
this.autoScrollPositionToolStripStatusLabel,
this.imageSizeToolStripStatusLabel,
this.zoomToolStripStatusLabel,
this.selectionToolStripStatusLabel});
this.statusStrip.Location = new System.Drawing.Point(0, 385);
this.statusStrip.Name = "statusStrip";
this.statusStrip.Padding = new System.Windows.Forms.Padding(1, 0, 12, 0);
this.statusStrip.Size = new System.Drawing.Size(726, 22);
this.statusStrip.TabIndex = 7;
//
// cursorToolStripStatusLabel
//
this.cursorToolStripStatusLabel.Image = global::Cyotek.Windows.Forms.Demo.Properties.Resources.Cursor;
this.cursorToolStripStatusLabel.Name = "cursorToolStripStatusLabel";
this.cursorToolStripStatusLabel.Size = new System.Drawing.Size(16, 17);
this.cursorToolStripStatusLabel.ToolTipText = "Current Cursor Position";
//
// statusToolStripStatusLabel
//
this.statusToolStripStatusLabel.Name = "statusToolStripStatusLabel";
this.statusToolStripStatusLabel.Size = new System.Drawing.Size(665, 17);
this.statusToolStripStatusLabel.Spring = true;
this.statusToolStripStatusLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// autoScrollPositionToolStripStatusLabel
//
this.autoScrollPositionToolStripStatusLabel.Image = global::Cyotek.Windows.Forms.Demo.Properties.Resources.Position;
this.autoScrollPositionToolStripStatusLabel.Name = "autoScrollPositionToolStripStatusLabel";
this.autoScrollPositionToolStripStatusLabel.Size = new System.Drawing.Size(16, 17);
this.autoScrollPositionToolStripStatusLabel.ToolTipText = "Auto Scroll Position";
this.autoScrollPositionToolStripStatusLabel.Visible = false;
//
// imageSizeToolStripStatusLabel
//
this.imageSizeToolStripStatusLabel.Image = global::Cyotek.Windows.Forms.Demo.Properties.Resources.Size;
this.imageSizeToolStripStatusLabel.Name = "imageSizeToolStripStatusLabel";
this.imageSizeToolStripStatusLabel.Size = new System.Drawing.Size(16, 17);
this.imageSizeToolStripStatusLabel.ToolTipText = "Image Size";
this.imageSizeToolStripStatusLabel.Visible = false;
//
// zoomToolStripStatusLabel
//
this.zoomToolStripStatusLabel.Image = global::Cyotek.Windows.Forms.Demo.Properties.Resources.Zoom;
this.zoomToolStripStatusLabel.Name = "zoomToolStripStatusLabel";
this.zoomToolStripStatusLabel.Size = new System.Drawing.Size(16, 17);
this.zoomToolStripStatusLabel.ToolTipText = "Zoom";
//
// selectionToolStripStatusLabel
//
this.selectionToolStripStatusLabel.Image = global::Cyotek.Windows.Forms.Demo.Properties.Resources.SelectAll;
this.selectionToolStripStatusLabel.Name = "selectionToolStripStatusLabel";
this.selectionToolStripStatusLabel.Size = new System.Drawing.Size(16, 17);
//
// ResizableSelectionDemoForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(726, 407);
this.Controls.Add(this.splitContainer);
this.Controls.Add(this.menuStrip);
this.Controls.Add(this.statusStrip);
this.Name = "ResizableSelectionDemoForm";
this.Text = "Resizable Selection Demonstration";
this.splitContainer.Panel1.ResumeLayout(false);
this.splitContainer.Panel2.ResumeLayout(false);
this.splitContainer.ResumeLayout(false);
this.eventsSplitContainer.Panel1.ResumeLayout(false);
this.eventsSplitContainer.Panel2.ResumeLayout(false);
this.eventsSplitContainer.ResumeLayout(false);
this.tabControl1.ResumeLayout(false);
this.eventsTabPage.ResumeLayout(false);
this.dragHandlesTabPage.ResumeLayout(false);
this.splitContainer1.Panel1.ResumeLayout(false);
this.splitContainer1.Panel1.PerformLayout();
this.splitContainer1.Panel2.ResumeLayout(false);
this.splitContainer1.Panel2.PerformLayout();
this.splitContainer1.ResumeLayout(false);
this.propertiesTabPage.ResumeLayout(false);
this.menuStrip.ResumeLayout(false);
this.menuStrip.PerformLayout();
this.statusStrip.ResumeLayout(false);
this.statusStrip.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private ImageBoxEx imageBox;
private System.Windows.Forms.Label demoLabel;
private System.Windows.Forms.SplitContainer splitContainer;
private System.Windows.Forms.MenuStrip menuStrip;
private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem closeToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem;
private System.Windows.Forms.StatusStrip statusStrip;
private System.Windows.Forms.ToolStripStatusLabel selectionToolStripStatusLabel;
private System.Windows.Forms.ToolStripStatusLabel cursorToolStripStatusLabel;
private System.Windows.Forms.ToolStripStatusLabel statusToolStripStatusLabel;
private System.Windows.Forms.SplitContainer eventsSplitContainer;
private EventsListBox eventsListBox;
private System.Windows.Forms.ToolStripMenuItem editToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem selectAllToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem selectNoneToolStripMenuItem;
private System.Windows.Forms.ToolStripStatusLabel zoomToolStripStatusLabel;
private System.Windows.Forms.ToolStripStatusLabel autoScrollPositionToolStripStatusLabel;
private System.Windows.Forms.ToolStripStatusLabel imageSizeToolStripStatusLabel;
private System.Windows.Forms.TabControl tabControl1;
private System.Windows.Forms.TabPage eventsTabPage;
private System.Windows.Forms.TabPage dragHandlesTabPage;
private System.Windows.Forms.TabPage propertiesTabPage;
private System.Windows.Forms.PropertyGrid propertyGrid;
private System.Windows.Forms.SplitContainer splitContainer1;
private System.Windows.Forms.CheckedListBox enabledCheckedListBox;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.CheckedListBox visibleCheckedListBox;
private System.Windows.Forms.Label label2;
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/ResizableSelectionDemoForm.cs
================================================
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
namespace Cyotek.Windows.Forms.Demo
{
// Cyotek ImageBox
// Copyright (c) 2010-2015 Cyotek Ltd.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
internal partial class ResizableSelectionDemoForm : BaseForm
{
#region Public Constructors
public ResizableSelectionDemoForm()
{
InitializeComponent();
}
#endregion
#region Overridden Methods
///
/// Raises the event.
///
/// An that contains the event data.
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
this.UpdateStatusBar();
// set a default selection
imageBox.SelectionRegion = new RectangleF(0, 0, 64, 64);
// apply a minimum selection size for resize operations
imageBox.MinimumSelectionSize = new Size(8, 8);
// setup the option lists
foreach (DragHandle handle in imageBox.DragHandles)
{
enabledCheckedListBox.Items.Add(handle.Anchor, handle.Enabled);
visibleCheckedListBox.Items.Add(handle.Anchor, handle.Visible);
}
}
#endregion
#region Private Members
private void SetStatus(string message)
{
statusToolStripStatusLabel.Text = message;
}
private void UpdateCursorPosition(Point location)
{
if (imageBox.IsPointInImage(location))
{
Point point;
point = imageBox.PointToImage(location);
cursorToolStripStatusLabel.Text = this.FormatPoint(point);
}
else
{
cursorToolStripStatusLabel.Text = string.Empty;
}
}
private void UpdateStatusBar()
{
autoScrollPositionToolStripStatusLabel.Text = this.FormatPoint(imageBox.AutoScrollPosition);
imageSizeToolStripStatusLabel.Text = this.FormatRectangle(imageBox.GetImageViewPort());
zoomToolStripStatusLabel.Text = string.Format("{0}%", imageBox.Zoom);
}
#endregion
#region Event Handlers
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
{
AboutDialog.ShowAboutDialog();
}
private void closeToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Close();
}
private void enabledCheckedListBox_ItemCheck(object sender, ItemCheckEventArgs e)
{
DragHandleAnchor anchor;
anchor = (DragHandleAnchor)enabledCheckedListBox.Items[e.Index];
imageBox.DragHandles[anchor].Enabled = e.NewValue == CheckState.Checked;
imageBox.Invalidate(); // No change events on the DragHandleCollection class so need to manually refresh
}
private void imageBox_MouseLeave(object sender, EventArgs e)
{
cursorToolStripStatusLabel.Text = string.Empty;
}
private void imageBox_MouseMove(object sender, MouseEventArgs e)
{
this.UpdateCursorPosition(e.Location);
}
private void imageBox_Resize(object sender, EventArgs e)
{
this.UpdateStatusBar();
}
private void imageBox_Scroll(object sender, ScrollEventArgs e)
{
this.UpdateStatusBar();
}
private void imageBox_Selected(object sender, EventArgs e)
{
this.UpdateStatusBar();
eventsListBox.AddEvent((Control)sender, "Selected");
}
private void imageBox_Selecting(object sender, ImageBoxCancelEventArgs e)
{
eventsListBox.AddEvent((Control)sender, "Selecting", new Dictionary
{
{
"Location", e.Location
},
{
"Cancel", e.Cancel
}
});
}
private void imageBox_SelectionMoved(object sender, EventArgs e)
{
this.SetStatus(string.Empty);
eventsListBox.AddEvent((Control)sender, "SelectionMoved");
}
private void imageBox_SelectionMoving(object sender, CancelEventArgs e)
{
this.SetStatus("Press escape to cancel move.");
eventsListBox.AddEvent((Control)sender, "SelectionMoving", new Dictionary
{
{
"Cancel", e.Cancel
}
});
}
private void imageBox_SelectionRegionChanged(object sender, EventArgs e)
{
selectionToolStripStatusLabel.Text = this.FormatRectangle(imageBox.SelectionRegion);
}
private void imageBox_SelectionResized(object sender, EventArgs e)
{
this.SetStatus(string.Empty);
eventsListBox.AddEvent((Control)sender, "SelectionResized");
}
private void imageBox_SelectionResizing(object sender, CancelEventArgs e)
{
this.SetStatus("Press escape to cancel resize.");
eventsListBox.AddEvent((Control)sender, "SelectionResizing", new Dictionary
{
{
"Cancel", e.Cancel
}
});
}
private void imageBox_VirtualDraw(object sender, PaintEventArgs e)
{
RectangleF bounds;
// draw the virtual area
bounds = imageBox.GetOffsetRectangle(new RectangleF(PointF.Empty, imageBox.VirtualSize));
using (Brush brush = new SolidBrush(Color.FromArgb(128, Color.Goldenrod)))
{
e.Graphics.FillRectangle(brush, bounds);
}
e.Graphics.DrawRectangle(Pens.DarkGoldenrod, bounds.X, bounds.Y, bounds.Width, bounds.Height);
}
private void imageBox_Zoomed(object sender, ImageBoxZoomEventArgs e)
{
this.UpdateStatusBar();
}
private void selectAllToolStripMenuItem_Click(object sender, EventArgs e)
{
imageBox.SelectAll();
}
private void selectNoneToolStripMenuItem_Click(object sender, EventArgs e)
{
imageBox.SelectNone();
}
private void visibleCheckedListBox_ItemCheck(object sender, ItemCheckEventArgs e)
{
DragHandleAnchor anchor;
anchor = (DragHandleAnchor)visibleCheckedListBox.Items[e.Index];
imageBox.DragHandles[anchor].Visible = e.NewValue == CheckState.Checked;
imageBox.Invalidate(); // No change events on the DragHandleCollection class so need to manually refresh
}
#endregion
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/ResizableSelectionDemoForm.resx
================================================
text/microsoft-resx
2.0
System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
This demonstration shows how to expand the SelectionRegion to include the ability to drag the region around, and to resize it via the use of drag handles.
You can use the MinimumSelectionSize and MaximumSelectionSize to allow greater control over the selection process - for example when cropping an image.
VirtualMode is used to create a canvas area without requiring a backing image.
246, 17
359, 17
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/Resources/markdownpad-github.css
================================================
/* GitHub stylesheet for MarkdownPad (http://markdownpad.com) */
/* Author: Nicolas Hery - http://nicolashery.com */
/* Version: 29d1c5bc36da364ad5aa86946d420b7bbc54a253 */
/* Source: https://github.com/nicolahery/markdownpad-github */
/* RESET
=============================================================================*/
html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
}
/* BODY
=============================================================================*/
body {
font-family: Helvetica, arial, freesans, clean, sans-serif;
font-size: 14px;
line-height: 1.6;
color: #333;
background-color: #fff;
padding: 6px;
max-width: 960px;
margin: 0 auto;
}
body>*:first-child {
margin-top: 0 !important;
}
body>*:last-child {
margin-bottom: 0 !important;
}
/* BLOCKS
=============================================================================*/
p, blockquote, ul, ol, dl, table, pre {
margin: 15px 0;
}
/* HEADERS
=============================================================================*/
h1, h2, h3, h4, h5, h6 {
margin: 20px 0 10px;
padding: 0;
font-weight: bold;
-webkit-font-smoothing: antialiased;
}
h1 tt, h1 code, h2 tt, h2 code, h3 tt, h3 code, h4 tt, h4 code, h5 tt, h5 code, h6 tt, h6 code {
font-size: inherit;
}
h1 {
font-size: 28px;
color: #000;
}
h2 {
font-size: 24px;
border-bottom: 1px solid #ccc;
color: #000;
}
h3 {
font-size: 18px;
}
h4 {
font-size: 16px;
}
h5 {
font-size: 14px;
}
h6 {
color: #777;
font-size: 14px;
}
body>h2:first-child, body>h1:first-child, body>h1:first-child+h2, body>h3:first-child, body>h4:first-child, body>h5:first-child, body>h6:first-child {
margin-top: 0;
padding-top: 0;
}
a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6 {
margin-top: 0;
padding-top: 0;
}
h1+p, h2+p, h3+p, h4+p, h5+p, h6+p {
margin-top: 10px;
}
/* LINKS
=============================================================================*/
a {
color: #4183C4;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
/* LISTS
=============================================================================*/
ul, ol {
padding-left: 30px;
}
ul li > :first-child,
ol li > :first-child,
ul li ul:first-of-type,
ol li ol:first-of-type,
ul li ol:first-of-type,
ol li ul:first-of-type {
margin-top: 0px;
}
ul ul, ul ol, ol ol, ol ul {
margin-bottom: 0;
}
dl {
padding: 0;
}
dl dt {
font-size: 14px;
font-weight: bold;
font-style: italic;
padding: 0;
margin: 15px 0 5px;
}
dl dt:first-child {
padding: 0;
}
dl dt>:first-child {
margin-top: 0px;
}
dl dt>:last-child {
margin-bottom: 0px;
}
dl dd {
margin: 0 0 15px;
padding: 0 15px;
}
dl dd>:first-child {
margin-top: 0px;
}
dl dd>:last-child {
margin-bottom: 0px;
}
/* CODE
=============================================================================*/
pre, code, tt {
font-size: 12px;
font-family: Consolas, "Liberation Mono", Courier, monospace;
}
code, tt {
margin: 0 0px;
padding: 0px 0px;
white-space: nowrap;
border: 1px solid #eaeaea;
background-color: #f8f8f8;
border-radius: 3px;
}
pre>code {
margin: 0;
padding: 0;
white-space: pre;
border: none;
background: transparent;
}
pre {
background-color: #f8f8f8;
border: 1px solid #ccc;
font-size: 13px;
line-height: 19px;
overflow: auto;
padding: 6px 10px;
border-radius: 3px;
}
pre code, pre tt {
background-color: transparent;
border: none;
}
/* QUOTES
=============================================================================*/
blockquote {
border-left: 4px solid #DDD;
padding: 0 15px;
color: #777;
}
blockquote>:first-child {
margin-top: 0px;
}
blockquote>:last-child {
margin-bottom: 0px;
}
/* HORIZONTAL RULES
=============================================================================*/
hr {
clear: both;
margin: 15px 0;
height: 0px;
overflow: hidden;
border: none;
background: transparent;
border-bottom: 4px solid #ddd;
padding: 0;
}
/* TABLES
=============================================================================*/
table th {
font-weight: bold;
}
table th, table td {
border: 1px solid #ccc;
padding: 6px 13px;
}
table tr {
border-top: 1px solid #ccc;
background-color: #fff;
}
table tr:nth-child(2n) {
background-color: #f8f8f8;
}
/* IMAGES
=============================================================================*/
img {
max-width: 100%
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/ScaledAdornmentsDemoForm.Designer.cs
================================================
namespace Cyotek.Windows.Forms.Demo
{
partial class ScaledAdornmentsDemoForm
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ScaledAdornmentsDemoForm));
this.splitContainer = new System.Windows.Forms.SplitContainer();
this.imageBox = new Cyotek.Windows.Forms.ImageBox();
this.demoLabel = new System.Windows.Forms.Label();
this.panel1 = new System.Windows.Forms.Panel();
this.scaleAdornmentsCheckBox = new System.Windows.Forms.CheckBox();
this.menuStrip = new System.Windows.Forms.MenuStrip();
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.closeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.statusStrip = new System.Windows.Forms.StatusStrip();
this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel();
this.positionToolStripStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
this.splitContainer.Panel1.SuspendLayout();
this.splitContainer.Panel2.SuspendLayout();
this.splitContainer.SuspendLayout();
this.panel1.SuspendLayout();
this.menuStrip.SuspendLayout();
this.statusStrip.SuspendLayout();
this.SuspendLayout();
//
// splitContainer
//
this.splitContainer.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.splitContainer.Location = new System.Drawing.Point(10, 23);
this.splitContainer.Name = "splitContainer";
//
// splitContainer.Panel1
//
this.splitContainer.Panel1.Controls.Add(this.imageBox);
//
// splitContainer.Panel2
//
this.splitContainer.Panel2.Controls.Add(this.demoLabel);
this.splitContainer.Panel2.Controls.Add(this.panel1);
this.splitContainer.Size = new System.Drawing.Size(789, 375);
this.splitContainer.SplitterDistance = 574;
this.splitContainer.TabIndex = 5;
//
// imageBox
//
this.imageBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.imageBox.Image = global::Cyotek.Windows.Forms.Demo.Properties.Resources.Map;
this.imageBox.Location = new System.Drawing.Point(0, 0);
this.imageBox.Name = "imageBox";
this.imageBox.Size = new System.Drawing.Size(574, 375);
this.imageBox.TabIndex = 0;
this.imageBox.Paint += new System.Windows.Forms.PaintEventHandler(this.imageBox_Paint);
this.imageBox.MouseClick += new System.Windows.Forms.MouseEventHandler(this.imageBox_MouseClick);
this.imageBox.MouseLeave += new System.EventHandler(this.imageBox_MouseLeave);
this.imageBox.MouseMove += new System.Windows.Forms.MouseEventHandler(this.imageBox_MouseMove);
//
// demoLabel
//
this.demoLabel.AutoEllipsis = true;
this.demoLabel.BackColor = System.Drawing.SystemColors.Info;
this.demoLabel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.demoLabel.Dock = System.Windows.Forms.DockStyle.Fill;
this.demoLabel.ForeColor = System.Drawing.SystemColors.InfoText;
this.demoLabel.Location = new System.Drawing.Point(0, 0);
this.demoLabel.Name = "demoLabel";
this.demoLabel.Padding = new System.Windows.Forms.Padding(9, 9, 9, 9);
this.demoLabel.Size = new System.Drawing.Size(211, 352);
this.demoLabel.TabIndex = 1;
this.demoLabel.Text = resources.GetString("demoLabel.Text");
//
// panel1
//
this.panel1.Controls.Add(this.scaleAdornmentsCheckBox);
this.panel1.Dock = System.Windows.Forms.DockStyle.Bottom;
this.panel1.Location = new System.Drawing.Point(0, 352);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(211, 23);
this.panel1.TabIndex = 2;
//
// scaleAdornmentsCheckBox
//
this.scaleAdornmentsCheckBox.AutoSize = true;
this.scaleAdornmentsCheckBox.Checked = true;
this.scaleAdornmentsCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
this.scaleAdornmentsCheckBox.Location = new System.Drawing.Point(0, 3);
this.scaleAdornmentsCheckBox.Name = "scaleAdornmentsCheckBox";
this.scaleAdornmentsCheckBox.Size = new System.Drawing.Size(112, 17);
this.scaleAdornmentsCheckBox.TabIndex = 0;
this.scaleAdornmentsCheckBox.Text = "&Scale Adornments";
this.scaleAdornmentsCheckBox.UseVisualStyleBackColor = true;
this.scaleAdornmentsCheckBox.CheckedChanged += new System.EventHandler(this.scaleAdornmentsCheckBox_CheckedChanged);
//
// menuStrip
//
this.menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.fileToolStripMenuItem,
this.helpToolStripMenuItem});
this.menuStrip.Location = new System.Drawing.Point(0, 0);
this.menuStrip.Name = "menuStrip";
this.menuStrip.Size = new System.Drawing.Size(809, 24);
this.menuStrip.TabIndex = 6;
//
// fileToolStripMenuItem
//
this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.closeToolStripMenuItem});
this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
this.fileToolStripMenuItem.Text = "&File";
//
// closeToolStripMenuItem
//
this.closeToolStripMenuItem.Name = "closeToolStripMenuItem";
this.closeToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.W)));
this.closeToolStripMenuItem.Size = new System.Drawing.Size(148, 22);
this.closeToolStripMenuItem.Text = "&Close";
this.closeToolStripMenuItem.Click += new System.EventHandler(this.closeToolStripMenuItem_Click);
//
// helpToolStripMenuItem
//
this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.aboutToolStripMenuItem});
this.helpToolStripMenuItem.Name = "helpToolStripMenuItem";
this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 20);
this.helpToolStripMenuItem.Text = "&Help";
//
// aboutToolStripMenuItem
//
this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
this.aboutToolStripMenuItem.Size = new System.Drawing.Size(116, 22);
this.aboutToolStripMenuItem.Text = "&About...";
this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click);
//
// statusStrip
//
this.statusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripStatusLabel1,
this.positionToolStripStatusLabel});
this.statusStrip.Location = new System.Drawing.Point(0, 398);
this.statusStrip.Name = "statusStrip";
this.statusStrip.Size = new System.Drawing.Size(809, 22);
this.statusStrip.TabIndex = 7;
//
// toolStripStatusLabel1
//
this.toolStripStatusLabel1.Name = "toolStripStatusLabel1";
this.toolStripStatusLabel1.Size = new System.Drawing.Size(794, 17);
this.toolStripStatusLabel1.Spring = true;
//
// positionToolStripStatusLabel
//
this.positionToolStripStatusLabel.Name = "positionToolStripStatusLabel";
this.positionToolStripStatusLabel.Size = new System.Drawing.Size(0, 17);
//
// ScaledAdornmentsDemoForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(809, 420);
this.Controls.Add(this.splitContainer);
this.Controls.Add(this.menuStrip);
this.Controls.Add(this.statusStrip);
this.Name = "ScaledAdornmentsDemoForm";
this.Text = "Scaled Adornments";
this.splitContainer.Panel1.ResumeLayout(false);
this.splitContainer.Panel2.ResumeLayout(false);
this.splitContainer.ResumeLayout(false);
this.panel1.ResumeLayout(false);
this.panel1.PerformLayout();
this.menuStrip.ResumeLayout(false);
this.menuStrip.PerformLayout();
this.statusStrip.ResumeLayout(false);
this.statusStrip.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private ImageBox imageBox;
private System.Windows.Forms.Label demoLabel;
private System.Windows.Forms.SplitContainer splitContainer;
private System.Windows.Forms.MenuStrip menuStrip;
private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem closeToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem;
private System.Windows.Forms.StatusStrip statusStrip;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.CheckBox scaleAdornmentsCheckBox;
private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel1;
private System.Windows.Forms.ToolStripStatusLabel positionToolStripStatusLabel;
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/ScaledAdornmentsDemoForm.cs
================================================
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using Cyotek.Windows.Forms.Demo.Properties;
namespace Cyotek.Windows.Forms.Demo
{
// Cyotek ImageBox
// Copyright (c) 2010-2015 Cyotek Ltd.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
internal partial class ScaledAdornmentsDemoForm : BaseForm
{
#region Fields
private List _landmarks;
private Bitmap _markerImage;
#endregion
#region Constructors
public ScaledAdornmentsDemoForm()
{
this.InitializeComponent();
}
#endregion
#region Methods
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
imageBox.ZoomToFit();
_markerImage = Resources.MapMarker;
_landmarks = new List();
this.AddLandmark(new Point(467, 447));
this.AddLandmark(new Point(662, 262));
this.AddLandmark(new Point(779, 239));
}
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
{
AboutDialog.ShowAboutDialog();
}
private void AddLandmark(Point point)
{
Debug.Print("Added landmark: {0}", point);
_landmarks.Add(new Point(point.X, point.Y));
}
private void closeToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Close();
}
private void imageBox_MouseClick(object sender, MouseEventArgs e)
{
if (imageBox.IsPointInImage(e.Location))
{
// add a new landmark
this.AddLandmark(imageBox.PointToImage(e.Location));
// force the image to repaint
imageBox.Invalidate();
}
}
private void imageBox_MouseLeave(object sender, EventArgs e)
{
positionToolStripStatusLabel.Text = string.Empty;
}
private void imageBox_MouseMove(object sender, MouseEventArgs e)
{
this.UpdateCursorPosition(e.Location);
}
private void imageBox_Paint(object sender, PaintEventArgs e)
{
Graphics g;
GraphicsState originalState;
Size scaledSize;
Size originalSize;
Size drawSize;
bool scaleAdornmentSize;
scaleAdornmentSize = scaleAdornmentsCheckBox.Checked;
g = e.Graphics;
originalState = g.Save();
// Work out the size of the marker graphic according to the current zoom level
originalSize = _markerImage.Size;
scaledSize = imageBox.GetScaledSize(originalSize);
drawSize = scaleAdornmentSize ? scaledSize : originalSize;
foreach (Point landmark in _landmarks)
{
Point location;
// Work out the location of the marker graphic according to the current zoom level and scroll offset
location = imageBox.GetOffsetPoint(landmark);
// adjust the location so that the image is displayed above the location and centered to it
location.Y -= drawSize.Height;
location.X -= drawSize.Width >> 1;
// Draw the marker
g.InterpolationMode = InterpolationMode.NearestNeighbor;
g.DrawImage(_markerImage, new Rectangle(location, drawSize), new Rectangle(Point.Empty, originalSize), GraphicsUnit.Pixel);
}
g.Restore(originalState);
}
private void scaleAdornmentsCheckBox_CheckedChanged(object sender, EventArgs e)
{
imageBox.Invalidate();
}
private void UpdateCursorPosition(Point location)
{
Point point;
point = imageBox.PointToImage(location);
positionToolStripStatusLabel.Text = this.FormatPoint(point);
}
#endregion
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/ScaledAdornmentsDemoForm.resx
================================================
text/microsoft-resx
2.0
System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
This demonstration shows how to add scaled adornments to an image.
In this case, we are displaying a map with a number of pre-defined points of interest. Clicking the image will add a new point.
Each time the ImageBox is invalidated and the map drawn, a graphic is also drawn at each point of interest, scaled according to the current zoom level and scroll positions.
By making use of the GetOffsetPoint, GetOffsetRectangle, GetScaledPoint, GetScaledRectangle and GetScaledSize, you can easily add additional adornments to an ImageBox that are always sized and positioned appropriately.
248, 17
363, 17
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/SizeModeDemoForm.Designer.cs
================================================
namespace Cyotek.Windows.Forms.Demo
{
partial class SizeModeDemoForm
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SizeModeDemoForm));
this.menuStrip = new System.Windows.Forms.MenuStrip();
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.closeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.statusStrip = new System.Windows.Forms.StatusStrip();
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
this.imageBox1 = new Cyotek.Windows.Forms.ImageBox();
this.cyotekPreviewHeaderLabel = new System.Windows.Forms.Label();
this.splitContainer2 = new System.Windows.Forms.SplitContainer();
this.imageBox2 = new Cyotek.Windows.Forms.ImageBox();
this.label1 = new System.Windows.Forms.Label();
this.imageBox3 = new Cyotek.Windows.Forms.ImageBox();
this.label2 = new System.Windows.Forms.Label();
this.menuStrip.SuspendLayout();
this.splitContainer1.Panel1.SuspendLayout();
this.splitContainer1.Panel2.SuspendLayout();
this.splitContainer1.SuspendLayout();
this.splitContainer2.Panel1.SuspendLayout();
this.splitContainer2.Panel2.SuspendLayout();
this.splitContainer2.SuspendLayout();
this.SuspendLayout();
//
// menuStrip
//
this.menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.fileToolStripMenuItem,
this.helpToolStripMenuItem});
this.menuStrip.Location = new System.Drawing.Point(0, 0);
this.menuStrip.Name = "menuStrip";
this.menuStrip.Size = new System.Drawing.Size(771, 24);
this.menuStrip.TabIndex = 8;
//
// fileToolStripMenuItem
//
this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.closeToolStripMenuItem});
this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
this.fileToolStripMenuItem.Text = "&File";
//
// closeToolStripMenuItem
//
this.closeToolStripMenuItem.Name = "closeToolStripMenuItem";
this.closeToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.W)));
this.closeToolStripMenuItem.Size = new System.Drawing.Size(148, 22);
this.closeToolStripMenuItem.Text = "&Close";
this.closeToolStripMenuItem.Click += new System.EventHandler(this.closeToolStripMenuItem_Click);
//
// helpToolStripMenuItem
//
this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.aboutToolStripMenuItem});
this.helpToolStripMenuItem.Name = "helpToolStripMenuItem";
this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 20);
this.helpToolStripMenuItem.Text = "&Help";
//
// aboutToolStripMenuItem
//
this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
this.aboutToolStripMenuItem.Size = new System.Drawing.Size(116, 22);
this.aboutToolStripMenuItem.Text = "&About...";
this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click);
//
// statusStrip
//
this.statusStrip.Location = new System.Drawing.Point(0, 406);
this.statusStrip.Name = "statusStrip";
this.statusStrip.Size = new System.Drawing.Size(771, 22);
this.statusStrip.TabIndex = 9;
//
// splitContainer1
//
this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
this.splitContainer1.Location = new System.Drawing.Point(0, 24);
this.splitContainer1.Name = "splitContainer1";
//
// splitContainer1.Panel1
//
this.splitContainer1.Panel1.Controls.Add(this.imageBox1);
this.splitContainer1.Panel1.Controls.Add(this.cyotekPreviewHeaderLabel);
//
// splitContainer1.Panel2
//
this.splitContainer1.Panel2.Controls.Add(this.splitContainer2);
this.splitContainer1.Size = new System.Drawing.Size(771, 382);
this.splitContainer1.SplitterDistance = 257;
this.splitContainer1.SplitterWidth = 3;
this.splitContainer1.TabIndex = 10;
//
// imageBox1
//
this.imageBox1.Dock = System.Windows.Forms.DockStyle.Fill;
this.imageBox1.Image = ((System.Drawing.Image)(resources.GetObject("imageBox1.Image")));
this.imageBox1.Location = new System.Drawing.Point(0, 0);
this.imageBox1.Name = "imageBox1";
this.imageBox1.Size = new System.Drawing.Size(257, 361);
this.imageBox1.TabIndex = 0;
//
// cyotekPreviewHeaderLabel
//
this.cyotekPreviewHeaderLabel.AutoEllipsis = true;
this.cyotekPreviewHeaderLabel.BackColor = System.Drawing.SystemColors.ActiveCaption;
this.cyotekPreviewHeaderLabel.Dock = System.Windows.Forms.DockStyle.Bottom;
this.cyotekPreviewHeaderLabel.ForeColor = System.Drawing.SystemColors.HighlightText;
this.cyotekPreviewHeaderLabel.Location = new System.Drawing.Point(0, 361);
this.cyotekPreviewHeaderLabel.Name = "cyotekPreviewHeaderLabel";
this.cyotekPreviewHeaderLabel.Size = new System.Drawing.Size(257, 21);
this.cyotekPreviewHeaderLabel.TabIndex = 8;
this.cyotekPreviewHeaderLabel.Text = "Normal";
this.cyotekPreviewHeaderLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// splitContainer2
//
this.splitContainer2.Dock = System.Windows.Forms.DockStyle.Fill;
this.splitContainer2.Location = new System.Drawing.Point(0, 0);
this.splitContainer2.Name = "splitContainer2";
//
// splitContainer2.Panel1
//
this.splitContainer2.Panel1.Controls.Add(this.imageBox2);
this.splitContainer2.Panel1.Controls.Add(this.label1);
//
// splitContainer2.Panel2
//
this.splitContainer2.Panel2.Controls.Add(this.imageBox3);
this.splitContainer2.Panel2.Controls.Add(this.label2);
this.splitContainer2.Size = new System.Drawing.Size(511, 382);
this.splitContainer2.SplitterDistance = 255;
this.splitContainer2.SplitterWidth = 3;
this.splitContainer2.TabIndex = 11;
//
// imageBox2
//
this.imageBox2.Dock = System.Windows.Forms.DockStyle.Fill;
this.imageBox2.Image = ((System.Drawing.Image)(resources.GetObject("imageBox2.Image")));
this.imageBox2.Location = new System.Drawing.Point(0, 0);
this.imageBox2.Name = "imageBox2";
this.imageBox2.Size = new System.Drawing.Size(255, 361);
this.imageBox2.SizeMode = Cyotek.Windows.Forms.ImageBoxSizeMode.Stretch;
this.imageBox2.TabIndex = 1;
this.imageBox2.Zoom = 167;
//
// label1
//
this.label1.AutoEllipsis = true;
this.label1.BackColor = System.Drawing.SystemColors.ActiveCaption;
this.label1.Dock = System.Windows.Forms.DockStyle.Bottom;
this.label1.ForeColor = System.Drawing.SystemColors.HighlightText;
this.label1.Location = new System.Drawing.Point(0, 361);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(255, 21);
this.label1.TabIndex = 8;
this.label1.Text = "Stretch";
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// imageBox3
//
this.imageBox3.Dock = System.Windows.Forms.DockStyle.Fill;
this.imageBox3.Image = ((System.Drawing.Image)(resources.GetObject("imageBox3.Image")));
this.imageBox3.Location = new System.Drawing.Point(0, 0);
this.imageBox3.Name = "imageBox3";
this.imageBox3.Size = new System.Drawing.Size(253, 361);
this.imageBox3.SizeMode = Cyotek.Windows.Forms.ImageBoxSizeMode.Fit;
this.imageBox3.TabIndex = 1;
this.imageBox3.Zoom = 166;
//
// label2
//
this.label2.AutoEllipsis = true;
this.label2.BackColor = System.Drawing.SystemColors.ActiveCaption;
this.label2.Dock = System.Windows.Forms.DockStyle.Bottom;
this.label2.ForeColor = System.Drawing.SystemColors.HighlightText;
this.label2.Location = new System.Drawing.Point(0, 361);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(253, 21);
this.label2.TabIndex = 8;
this.label2.Text = "Fit";
this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// SizeModeDemoForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(771, 428);
this.Controls.Add(this.splitContainer1);
this.Controls.Add(this.menuStrip);
this.Controls.Add(this.statusStrip);
this.Name = "SizeModeDemoForm";
this.Text = "SizeMode Demonstation";
this.menuStrip.ResumeLayout(false);
this.menuStrip.PerformLayout();
this.splitContainer1.Panel1.ResumeLayout(false);
this.splitContainer1.Panel2.ResumeLayout(false);
this.splitContainer1.ResumeLayout(false);
this.splitContainer2.Panel1.ResumeLayout(false);
this.splitContainer2.Panel2.ResumeLayout(false);
this.splitContainer2.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.MenuStrip menuStrip;
private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem closeToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem;
private System.Windows.Forms.StatusStrip statusStrip;
private System.Windows.Forms.SplitContainer splitContainer1;
private System.Windows.Forms.SplitContainer splitContainer2;
private ImageBox imageBox1;
private ImageBox imageBox2;
private ImageBox imageBox3;
private System.Windows.Forms.Label cyotekPreviewHeaderLabel;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/SizeModeDemoForm.cs
================================================
using System;
namespace Cyotek.Windows.Forms.Demo
{
// Cyotek ImageBox
// Copyright (c) 2010-2015 Cyotek Ltd.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
internal partial class SizeModeDemoForm : BaseForm
{
#region Public Constructors
public SizeModeDemoForm()
{
InitializeComponent();
}
#endregion
#region Event Handlers
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
{
AboutDialog.ShowAboutDialog();
}
private void closeToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Close();
}
#endregion
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/SizeModeDemoForm.resx
================================================
text/microsoft-resx
2.0
System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
479, 17
594, 17
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
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/SwitchImageDuringZoomDemoForm.Designer.cs
================================================
namespace Cyotek.Windows.Forms.Demo
{
partial class SwitchImageDuringZoomDemoForm
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.menuStrip = new System.Windows.Forms.MenuStrip();
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.closeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.statusStrip = new System.Windows.Forms.StatusStrip();
this.statusToolStripStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
this.cursorToolStripStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
this.zoomToolStripStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
this.mapNameToolStripStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
this.imageBox = new Cyotek.Windows.Forms.ImageBox();
this.messageLabel = new System.Windows.Forms.Label();
this.resetMessageTimer = new System.Windows.Forms.Timer(this.components);
this.refreshMapTimer = new System.Windows.Forms.Timer(this.components);
this.menuStrip.SuspendLayout();
this.statusStrip.SuspendLayout();
this.SuspendLayout();
//
// menuStrip
//
this.menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.fileToolStripMenuItem,
this.helpToolStripMenuItem});
this.menuStrip.Location = new System.Drawing.Point(0, 0);
this.menuStrip.Name = "menuStrip";
this.menuStrip.Size = new System.Drawing.Size(747, 24);
this.menuStrip.TabIndex = 10;
//
// fileToolStripMenuItem
//
this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.closeToolStripMenuItem});
this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
this.fileToolStripMenuItem.Text = "&File";
//
// closeToolStripMenuItem
//
this.closeToolStripMenuItem.Name = "closeToolStripMenuItem";
this.closeToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.W)));
this.closeToolStripMenuItem.Size = new System.Drawing.Size(148, 22);
this.closeToolStripMenuItem.Text = "&Close";
this.closeToolStripMenuItem.Click += new System.EventHandler(this.closeToolStripMenuItem_Click);
//
// helpToolStripMenuItem
//
this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.aboutToolStripMenuItem});
this.helpToolStripMenuItem.Name = "helpToolStripMenuItem";
this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 20);
this.helpToolStripMenuItem.Text = "&Help";
//
// aboutToolStripMenuItem
//
this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
this.aboutToolStripMenuItem.Size = new System.Drawing.Size(116, 22);
this.aboutToolStripMenuItem.Text = "&About...";
this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click);
//
// statusStrip
//
this.statusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.statusToolStripStatusLabel,
this.cursorToolStripStatusLabel,
this.zoomToolStripStatusLabel,
this.mapNameToolStripStatusLabel});
this.statusStrip.Location = new System.Drawing.Point(0, 496);
this.statusStrip.Name = "statusStrip";
this.statusStrip.Size = new System.Drawing.Size(747, 22);
this.statusStrip.TabIndex = 11;
//
// statusToolStripStatusLabel
//
this.statusToolStripStatusLabel.Name = "statusToolStripStatusLabel";
this.statusToolStripStatusLabel.Size = new System.Drawing.Size(649, 17);
this.statusToolStripStatusLabel.Spring = true;
this.statusToolStripStatusLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// cursorToolStripStatusLabel
//
this.cursorToolStripStatusLabel.Image = global::Cyotek.Windows.Forms.Demo.Properties.Resources.Cursor;
this.cursorToolStripStatusLabel.Name = "cursorToolStripStatusLabel";
this.cursorToolStripStatusLabel.Size = new System.Drawing.Size(16, 17);
this.cursorToolStripStatusLabel.ToolTipText = "Current Cursor Position";
//
// zoomToolStripStatusLabel
//
this.zoomToolStripStatusLabel.Image = global::Cyotek.Windows.Forms.Demo.Properties.Resources.Zoom;
this.zoomToolStripStatusLabel.Name = "zoomToolStripStatusLabel";
this.zoomToolStripStatusLabel.Size = new System.Drawing.Size(51, 17);
this.zoomToolStripStatusLabel.Text = "100%";
this.zoomToolStripStatusLabel.ToolTipText = "Zoom";
//
// mapNameToolStripStatusLabel
//
this.mapNameToolStripStatusLabel.Image = global::Cyotek.Windows.Forms.Demo.Properties.Resources.SmallMap;
this.mapNameToolStripStatusLabel.Name = "mapNameToolStripStatusLabel";
this.mapNameToolStripStatusLabel.Size = new System.Drawing.Size(16, 17);
this.mapNameToolStripStatusLabel.ToolTipText = "Zoom";
//
// imageBox
//
this.imageBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.imageBox.Location = new System.Drawing.Point(0, 24);
this.imageBox.Name = "imageBox";
this.imageBox.Size = new System.Drawing.Size(747, 451);
this.imageBox.TabIndex = 12;
this.imageBox.ZoomChanged += new System.EventHandler(this.imageBox_ZoomChanged);
this.imageBox.Zoomed += new System.EventHandler(this.imageBox_Zoomed);
this.imageBox.MouseLeave += new System.EventHandler(this.imageBox_MouseLeave);
this.imageBox.MouseMove += new System.Windows.Forms.MouseEventHandler(this.imageBox_MouseMove);
//
// messageLabel
//
this.messageLabel.AutoEllipsis = true;
this.messageLabel.BackColor = System.Drawing.SystemColors.ActiveCaption;
this.messageLabel.Dock = System.Windows.Forms.DockStyle.Bottom;
this.messageLabel.ForeColor = System.Drawing.SystemColors.HighlightText;
this.messageLabel.Location = new System.Drawing.Point(0, 475);
this.messageLabel.Name = "messageLabel";
this.messageLabel.Size = new System.Drawing.Size(747, 21);
this.messageLabel.TabIndex = 13;
this.messageLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// resetMessageTimer
//
this.resetMessageTimer.Interval = 5000;
this.resetMessageTimer.Tick += new System.EventHandler(this.resetMessageTimer_Tick);
//
// refreshMapTimer
//
this.refreshMapTimer.Interval = 5;
this.refreshMapTimer.Tick += new System.EventHandler(this.refreshMapTimer_Tick);
//
// SwitchImageDuringZoomDemoForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(747, 518);
this.Controls.Add(this.imageBox);
this.Controls.Add(this.menuStrip);
this.Controls.Add(this.messageLabel);
this.Controls.Add(this.statusStrip);
this.Name = "SwitchImageDuringZoomDemoForm";
this.Text = "Switch Image During Zoom Demonstration";
this.menuStrip.ResumeLayout(false);
this.menuStrip.PerformLayout();
this.statusStrip.ResumeLayout(false);
this.statusStrip.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.MenuStrip menuStrip;
private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem closeToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem;
private System.Windows.Forms.StatusStrip statusStrip;
private ImageBox imageBox;
private System.Windows.Forms.ToolStripStatusLabel zoomToolStripStatusLabel;
private System.Windows.Forms.ToolStripStatusLabel mapNameToolStripStatusLabel;
private System.Windows.Forms.ToolStripStatusLabel cursorToolStripStatusLabel;
private System.Windows.Forms.ToolStripStatusLabel statusToolStripStatusLabel;
private System.Windows.Forms.Label messageLabel;
private System.Windows.Forms.Timer resetMessageTimer;
private System.Windows.Forms.Timer refreshMapTimer;
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/SwitchImageDuringZoomDemoForm.cs
================================================
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
namespace Cyotek.Windows.Forms.Demo
{
// Cyotek ImageBox
// Copyright (c) 2010-2015 Cyotek Ltd.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
internal partial class SwitchImageDuringZoomDemoForm : BaseForm
{
#region Instance Fields
private int _virtualZoom;
#endregion
#region Public Constructors
public SwitchImageDuringZoomDemoForm()
{
InitializeComponent();
}
#endregion
#region Overridden Methods
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (components != null)
{
components.Dispose();
}
if (this.ImageCache != null)
{
foreach (Image image in this.ImageCache.Values)
{
image.Dispose();
}
this.ImageCache = null;
}
}
base.Dispose(disposing);
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
LayerData = new List();
// add some map layers for the different zoom levels
this.AddLayer("map10", int.MinValue, 0);
this.AddLayer("map20", 0, 2);
this.AddLayer("map30", 2, 4);
this.AddLayer("map40", 4, 6);
this.AddLayer("map50", 6, 8);
this.AddLayer("map60", 8, 9);
this.AddLayer("map70", 9, 10);
this.AddLayer("map80", 10, 11);
this.AddLayer("map90", 11, 12);
this.AddLayer("map100", 12, int.MaxValue);
// load the lowest detail map
imageBox.Image = this.GetMapImage("map10");
// now zoom in a bit
this.VirtualZoom = 5;
this.UpdateMap();
imageBox.Zoom = 125;
imageBox.CenterAt(3350, 800);
}
#endregion
#region Private Properties
private IDictionary ImageCache { get; set; }
private bool IsUpdatingMap { get; set; }
private int Layer { get; set; }
private List LayerData { get; set; }
private bool ResetZoomOnUpdate { get; set; }
private int VirtualZoom
{
get { return _virtualZoom; }
set
{
_virtualZoom = value;
this.UpdateZoomLabel();
}
}
#endregion
#region Private Members
private void AddLayer(string name, int lowerZoom, int upperZoom)
{
// The larger map sizes (>map50) are 80MB, so I'm not including them in the GitHub repository.
// Therefore, just silently skip any missing maps without raising an error
if (File.Exists(this.GetMapFileName(name)))
{
MapLayerData data;
data = new MapLayerData();
data.Name = name;
data.UpperZoom = upperZoom;
data.LowerZoom = lowerZoom;
this.LayerData.Add(data);
}
}
private int FindNearestLayer(int zoom)
{
int result;
result = -1;
for (int i = 0; i < this.LayerData.Count; i++)
{
MapLayerData data;
data = this.LayerData[i];
if (zoom >= data.LowerZoom && zoom < data.UpperZoom)
{
result = i;
break;
}
}
return result;
}
private string GetMapFileName(string name)
{
return Path.GetFullPath(Path.Combine(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"..\..\..\maps"), Path.ChangeExtension(name, ".jpg")));
}
private Image GetMapImage(string name)
{
Image result;
if (this.ImageCache == null)
{
this.ImageCache = new Dictionary();
}
if (!this.ImageCache.TryGetValue(name, out result))
{
this.SetStatus("Loading image...");
result = Image.FromFile(this.GetMapFileName(name));
this.ImageCache.Add(name, result);
this.SetStatus(string.Empty);
}
this.SetMessage(string.Format("Switching to image {0}.jpg", name));
return result;
}
private void SetMessage(string message)
{
messageLabel.Text = message;
resetMessageTimer.Stop();
resetMessageTimer.Start();
}
private void SetStatus(string message)
{
Cursor.Current = string.IsNullOrEmpty(message) ? Cursors.Default : Cursors.WaitCursor;
statusToolStripStatusLabel.Text = message;
statusToolStripStatusLabel.Owner.Refresh();
}
private void UpdateCursorPosition(Point location)
{
if (imageBox.IsPointInImage(location))
{
Point point;
point = imageBox.PointToImage(location);
cursorToolStripStatusLabel.Text = this.FormatPoint(point);
}
else
{
cursorToolStripStatusLabel.Text = string.Empty;
}
}
private void UpdateMap()
{
if (!this.IsUpdatingMap)
{
int mapLayer;
this.IsUpdatingMap = true;
mapLayer = this.FindNearestLayer(this.VirtualZoom);
if (mapLayer != -1 && mapLayer != this.Layer)
{
MapLayerData data;
Image newImage;
RectangleF currentViewport;
RectangleF newViewport;
Size currentSize;
float vAspectRatio;
float hAspectRatio;
this.Layer = mapLayer;
data = this.LayerData[mapLayer];
mapNameToolStripStatusLabel.Text = data.Name;
newImage = this.GetMapImage(data.Name);
currentViewport = imageBox.GetSourceImageRegion();
currentSize = imageBox.Image.Size;
hAspectRatio = newImage.Width / (float)currentSize.Width;
vAspectRatio = newImage.Height / (float)currentSize.Height;
imageBox.BeginUpdate();
imageBox.Image = newImage;
newViewport = new RectangleF(currentViewport.X * hAspectRatio, currentViewport.Y * vAspectRatio, currentViewport.Width * hAspectRatio, currentViewport.Height * vAspectRatio);
imageBox.ZoomToRegion(newViewport);
if (this.ResetZoomOnUpdate)
{
this.ResetZoomOnUpdate = false;
imageBox.Zoom = 100;
imageBox.CenterToImage();
}
imageBox.EndUpdate();
}
this.IsUpdatingMap = false;
}
}
private void UpdateZoomLabel()
{
zoomToolStripStatusLabel.Text = string.Format("{0}% [{1}]", imageBox.Zoom, this.VirtualZoom);
}
#endregion
#region Event Handlers
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
{
AboutDialog.ShowAboutDialog();
}
private void closeToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Close();
}
private void imageBox_MouseLeave(object sender, EventArgs e)
{
cursorToolStripStatusLabel.Text = string.Empty;
}
private void imageBox_MouseMove(object sender, MouseEventArgs e)
{
this.UpdateCursorPosition(e.Location);
}
private void imageBox_ZoomChanged(object sender, EventArgs e)
{
this.UpdateZoomLabel();
}
private void imageBox_Zoomed(object sender, ImageBoxZoomEventArgs e)
{
if ((e.Source & ImageBoxActionSources.User) == ImageBoxActionSources.User)
{
if ((e.Actions & ImageBoxZoomActions.ActualSize) == ImageBoxZoomActions.ActualSize)
{
this.VirtualZoom = 0;
this.ResetZoomOnUpdate = true;
}
else if ((e.Actions & ImageBoxZoomActions.ZoomIn) == ImageBoxZoomActions.ZoomIn)
{
this.VirtualZoom++;
}
else if ((e.Actions & ImageBoxZoomActions.ZoomOut) == ImageBoxZoomActions.ZoomOut)
{
this.VirtualZoom--;
}
// TODO: Currently the ZoomChanged and Zoomed events are raised after the zoom level has changed, but before any
// actions such as modifying scrollbars occur. This means methods such as GetSourceImageRegion will return the
// wrong X and Y values. Until this is fixed, using a timer to trigger the change.
// However, if you had lots of map changes to make then using a timer would be a good idea regardless; for example
// if the user rapdily zooms through the available levels, they'll have a smoother experience if you only load
// the data once they've stopped zooming
refreshMapTimer.Stop();
refreshMapTimer.Start();
}
}
private void refreshMapTimer_Tick(object sender, EventArgs e)
{
refreshMapTimer.Stop();
this.UpdateMap();
}
private void resetMessageTimer_Tick(object sender, EventArgs e)
{
resetMessageTimer.Stop();
messageLabel.Text = string.Empty;
}
#endregion
#region Nested Types
private struct MapLayerData
{
#region Public Properties
public int LowerZoom { get; set; }
public string Name { get; set; }
public int UpperZoom { get; set; }
#endregion
}
#endregion
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/SwitchImageDuringZoomDemoForm.resx
================================================
text/microsoft-resx
2.0
System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
17, 17
125, 17
234, 17
321, 17
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/TextDemoForm.Designer.cs
================================================
namespace Cyotek.Windows.Forms.Demo
{
partial class TextDemoForm
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.menuStrip = new System.Windows.Forms.MenuStrip();
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.closeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.statusStrip = new System.Windows.Forms.StatusStrip();
this.splitContainer = new System.Windows.Forms.SplitContainer();
this.propertyGrid = new Cyotek.Windows.Forms.Demo.PropertyGrid();
this.imageBox = new Cyotek.Windows.Forms.ImageBox();
this.menuStrip.SuspendLayout();
this.splitContainer.Panel1.SuspendLayout();
this.splitContainer.Panel2.SuspendLayout();
this.splitContainer.SuspendLayout();
this.SuspendLayout();
//
// menuStrip
//
this.menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.fileToolStripMenuItem,
this.helpToolStripMenuItem});
this.menuStrip.Location = new System.Drawing.Point(0, 0);
this.menuStrip.Name = "menuStrip";
this.menuStrip.Size = new System.Drawing.Size(771, 24);
this.menuStrip.TabIndex = 0;
//
// fileToolStripMenuItem
//
this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.closeToolStripMenuItem});
this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
this.fileToolStripMenuItem.Text = "&File";
//
// closeToolStripMenuItem
//
this.closeToolStripMenuItem.Name = "closeToolStripMenuItem";
this.closeToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.W)));
this.closeToolStripMenuItem.Size = new System.Drawing.Size(148, 22);
this.closeToolStripMenuItem.Text = "&Close";
this.closeToolStripMenuItem.Click += new System.EventHandler(this.closeToolStripMenuItem_Click);
//
// helpToolStripMenuItem
//
this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.aboutToolStripMenuItem});
this.helpToolStripMenuItem.Name = "helpToolStripMenuItem";
this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 20);
this.helpToolStripMenuItem.Text = "&Help";
//
// aboutToolStripMenuItem
//
this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
this.aboutToolStripMenuItem.Size = new System.Drawing.Size(116, 22);
this.aboutToolStripMenuItem.Text = "&About...";
this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click);
//
// statusStrip
//
this.statusStrip.Location = new System.Drawing.Point(0, 406);
this.statusStrip.Name = "statusStrip";
this.statusStrip.Size = new System.Drawing.Size(771, 22);
this.statusStrip.TabIndex = 2;
//
// splitContainer
//
this.splitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
this.splitContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel1;
this.splitContainer.Location = new System.Drawing.Point(0, 24);
this.splitContainer.Name = "splitContainer";
//
// splitContainer.Panel1
//
this.splitContainer.Panel1.Controls.Add(this.propertyGrid);
//
// splitContainer.Panel2
//
this.splitContainer.Panel2.Controls.Add(this.imageBox);
this.splitContainer.Size = new System.Drawing.Size(771, 382);
this.splitContainer.SplitterDistance = 300;
this.splitContainer.SplitterWidth = 3;
this.splitContainer.TabIndex = 1;
//
// propertyGrid
//
this.propertyGrid.Dock = System.Windows.Forms.DockStyle.Fill;
this.propertyGrid.Location = new System.Drawing.Point(0, 0);
this.propertyGrid.Name = "propertyGrid";
this.propertyGrid.SelectedObject = this.imageBox;
this.propertyGrid.Size = new System.Drawing.Size(300, 382);
this.propertyGrid.TabIndex = 0;
//
// imageBox
//
this.imageBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.imageBox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(192)))));
this.imageBox.Image = global::Cyotek.Windows.Forms.Demo.Properties.Resources.samplecrop;
this.imageBox.Location = new System.Drawing.Point(0, 0);
this.imageBox.Name = "imageBox";
this.imageBox.ScaleText = true;
this.imageBox.ShowPixelGrid = true;
this.imageBox.Size = new System.Drawing.Size(468, 382);
this.imageBox.TabIndex = 0;
this.imageBox.Text = "This is a demonstration of the ImageBox text functionality";
this.imageBox.TextBackColor = System.Drawing.Color.Teal;
this.imageBox.TextDisplayMode = Cyotek.Windows.Forms.ImageBoxGridDisplayMode.Image;
this.imageBox.TextPadding = new System.Windows.Forms.Padding(3);
//
// TextDemoForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(771, 428);
this.Controls.Add(this.splitContainer);
this.Controls.Add(this.menuStrip);
this.Controls.Add(this.statusStrip);
this.Name = "TextDemoForm";
this.Text = "Text Demonstation";
this.menuStrip.ResumeLayout(false);
this.menuStrip.PerformLayout();
this.splitContainer.Panel1.ResumeLayout(false);
this.splitContainer.Panel2.ResumeLayout(false);
this.splitContainer.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.MenuStrip menuStrip;
private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem closeToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem;
private System.Windows.Forms.StatusStrip statusStrip;
private System.Windows.Forms.SplitContainer splitContainer;
private PropertyGrid propertyGrid;
private ImageBox imageBox;
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/TextDemoForm.cs
================================================
using System;
namespace Cyotek.Windows.Forms.Demo
{
// Cyotek ImageBox
// Copyright (c) 2010-2015 Cyotek Ltd.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
internal partial class TextDemoForm : BaseForm
{
#region Public Constructors
public TextDemoForm()
{
InitializeComponent();
}
#endregion
#region Overridden Methods
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
propertyGrid.SelectItem("TextPadding"); // HACK: This forces the property grid to scroll the property into view
propertyGrid.SelectItem("Text");
}
#endregion
#region Event Handlers
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
{
AboutDialog.ShowAboutDialog();
}
private void closeToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Close();
}
#endregion
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/TextDemoForm.resx
================================================
text/microsoft-resx
2.0
System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
479, 17
594, 17
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/VirtualModeDemonstrationForm.Designer.cs
================================================
namespace Cyotek.Windows.Forms.Demo
{
partial class VirtualModeDemonstrationForm
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.imageBox = new Cyotek.Windows.Forms.ImageBox();
this.splitContainer = new System.Windows.Forms.SplitContainer();
this.propertyGrid = new Cyotek.Windows.Forms.Demo.PropertyGrid();
this.statusStrip = new System.Windows.Forms.StatusStrip();
this.menuStrip = new System.Windows.Forms.MenuStrip();
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.closeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.splitContainer.Panel1.SuspendLayout();
this.splitContainer.Panel2.SuspendLayout();
this.splitContainer.SuspendLayout();
this.menuStrip.SuspendLayout();
this.SuspendLayout();
//
// imageBox
//
this.imageBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.imageBox.Location = new System.Drawing.Point(0, 0);
this.imageBox.Name = "imageBox";
this.imageBox.SelectionMode = Cyotek.Windows.Forms.ImageBoxSelectionMode.Rectangle;
this.imageBox.Size = new System.Drawing.Size(423, 277);
this.imageBox.TabIndex = 0;
this.imageBox.VirtualMode = true;
this.imageBox.VirtualSize = new System.Drawing.Size(300, 200);
this.imageBox.VirtualDraw += new System.Windows.Forms.PaintEventHandler(this.imageBox_VirtualDraw);
//
// splitContainer
//
this.splitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
this.splitContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel1;
this.splitContainer.Location = new System.Drawing.Point(0, 24);
this.splitContainer.Name = "splitContainer";
//
// splitContainer.Panel1
//
this.splitContainer.Panel1.Controls.Add(this.propertyGrid);
//
// splitContainer.Panel2
//
this.splitContainer.Panel2.Controls.Add(this.imageBox);
this.splitContainer.Size = new System.Drawing.Size(726, 277);
this.splitContainer.SplitterDistance = 300;
this.splitContainer.SplitterWidth = 3;
this.splitContainer.TabIndex = 0;
//
// propertyGrid
//
this.propertyGrid.Dock = System.Windows.Forms.DockStyle.Fill;
this.propertyGrid.Location = new System.Drawing.Point(0, 0);
this.propertyGrid.Name = "propertyGrid";
this.propertyGrid.SelectedObject = this.imageBox;
this.propertyGrid.Size = new System.Drawing.Size(300, 277);
this.propertyGrid.TabIndex = 0;
//
// statusStrip
//
this.statusStrip.Location = new System.Drawing.Point(0, 301);
this.statusStrip.Name = "statusStrip";
this.statusStrip.Padding = new System.Windows.Forms.Padding(1, 0, 12, 0);
this.statusStrip.Size = new System.Drawing.Size(726, 22);
this.statusStrip.TabIndex = 8;
//
// menuStrip
//
this.menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.fileToolStripMenuItem,
this.helpToolStripMenuItem});
this.menuStrip.Location = new System.Drawing.Point(0, 0);
this.menuStrip.Name = "menuStrip";
this.menuStrip.Padding = new System.Windows.Forms.Padding(5, 2, 0, 2);
this.menuStrip.Size = new System.Drawing.Size(726, 24);
this.menuStrip.TabIndex = 7;
//
// fileToolStripMenuItem
//
this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.closeToolStripMenuItem});
this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
this.fileToolStripMenuItem.Text = "&File";
//
// closeToolStripMenuItem
//
this.closeToolStripMenuItem.Name = "closeToolStripMenuItem";
this.closeToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.W)));
this.closeToolStripMenuItem.Size = new System.Drawing.Size(148, 22);
this.closeToolStripMenuItem.Text = "&Close";
this.closeToolStripMenuItem.Click += new System.EventHandler(this.closeToolStripMenuItem_Click);
//
// helpToolStripMenuItem
//
this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.aboutToolStripMenuItem});
this.helpToolStripMenuItem.Name = "helpToolStripMenuItem";
this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 20);
this.helpToolStripMenuItem.Text = "&Help";
//
// aboutToolStripMenuItem
//
this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
this.aboutToolStripMenuItem.Size = new System.Drawing.Size(116, 22);
this.aboutToolStripMenuItem.Text = "&About...";
this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click);
//
// VirtualModeDemonstrationForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(726, 323);
this.Controls.Add(this.splitContainer);
this.Controls.Add(this.statusStrip);
this.Controls.Add(this.menuStrip);
this.Name = "VirtualModeDemonstrationForm";
this.Text = "Virtual Mode Demonstration";
this.splitContainer.Panel1.ResumeLayout(false);
this.splitContainer.Panel2.ResumeLayout(false);
this.splitContainer.ResumeLayout(false);
this.menuStrip.ResumeLayout(false);
this.menuStrip.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private ImageBox imageBox;
private System.Windows.Forms.SplitContainer splitContainer;
private PropertyGrid propertyGrid;
private System.Windows.Forms.StatusStrip statusStrip;
private System.Windows.Forms.MenuStrip menuStrip;
private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem closeToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem;
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/VirtualModeDemonstrationForm.cs
================================================
using System;
using System.Drawing;
using System.Windows.Forms;
namespace Cyotek.Windows.Forms.Demo
{
// Cyotek ImageBox
// Copyright (c) 2010-2015 Cyotek Ltd.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
internal partial class VirtualModeDemonstrationForm : BaseForm
{
#region Public Constructors
public VirtualModeDemonstrationForm()
{
this.InitializeComponent();
}
#endregion
#region Overridden Methods
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
propertyGrid.SelectItem("VirtualSize");
}
#endregion
#region Event Handlers
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
{
AboutDialog.ShowAboutDialog();
}
private void closeToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Close();
}
private void imageBox_VirtualDraw(object sender, PaintEventArgs e)
{
RectangleF bounds;
bounds = imageBox.GetOffsetRectangle(new RectangleF(PointF.Empty, imageBox.VirtualSize));
using (Brush brush = new SolidBrush(Color.FromArgb(128, Color.Goldenrod)))
{
e.Graphics.FillRectangle(brush, bounds);
}
e.Graphics.DrawRectangle(Pens.DarkGoldenrod, bounds.X, bounds.Y, bounds.Width, bounds.Height);
using (Font font = new Font(this.Font.FontFamily, (float)(8 * imageBox.ZoomFactor)))
{
TextRenderer.DrawText(e.Graphics, "Use the VirtualMode and VirtualSize properties along with the VirtualDraw event to provide full control without needing a backing image.", font, new Rectangle((int)bounds.Left, (int)bounds.Top, (int)bounds.Width, (int)bounds.Height), Color.Black, TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter | TextFormatFlags.WordBreak | TextFormatFlags.WordEllipsis);
}
}
#endregion
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/VirtualModeDemonstrationForm.resx
================================================
text/microsoft-resx
2.0
System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
479, 17
595, 17
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/app.manifest
================================================
true/PM
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Demo/packages.config
================================================
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Design/Cyotek.Windows.Forms.ImageBox.Design.csproj
================================================
Debug
AnyCPU
{9F169B78-70FD-456A-BB48-2AA470938D38}
Library
Properties
Cyotek.Windows.Forms.ImageBox.Design
Cyotek.Windows.Forms.ImageBox.Design
v2.0
512
true
full
false
bin\Debug\
DEBUG;TRACE
prompt
4
pdbonly
true
bin\Release\
TRACE
prompt
4
{4159C8D3-C18D-4BED-8BE6-9BAD1B0CA4F6}
Cyotek.Windows.Forms.ImageBox
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Design/ImageBoxDesigner.cs
================================================
using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Windows.Forms;
using System.Windows.Forms.Design;
// ReSharper disable CheckNamespace
namespace Cyotek.Windows.Forms.Design // ReSharper restore CheckNamespace
{
// Cyotek ImageBox
// Copyright (c) 2010-2015 Cyotek Ltd.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
// TODO: This library currently isn't used until I can work out how to properly get client applications to use it without an explicit reference.
// Using a Designer attribute with a string type and DLL name is supposed to work, but the IDE isn't displaying tasks for the demo project this way
// I don't want it to be a part of the core ImageBox library due to the reference to System.Design as this means you can no longer flag
// the assembly as only requiring the Client version of the .NET Framework but only the Full, which may not be suitable for everyone
///
/// Provides design mode behavior for an control.
///
public class ImageBoxDesigner : ControlDesigner
{
#region Instance Fields
private DesignerVerb _dockVerb;
private DesignerVerb _undockVerb;
private DesignerVerbCollection _verbs;
#endregion
#region Overridden Properties
///
/// Gets the design-time verbs supported by the component that is associated with the designer.
///
/// A collection that contains the verbs that are available to the designer.
/// A of objects, or null if no designer verbs are available. This default implementation always returns null.
public override DesignerVerbCollection Verbs
{
get
{
if (_verbs == null)
{
_verbs = new DesignerVerbCollection();
_dockVerb = new DesignerVerb("Dock to parent control", this.DockVerbHandler)
{
Description = "Dock this control with its parent.",
Enabled = this.ImageBoxControl.Dock == DockStyle.None
};
_verbs.Add(_dockVerb);
_undockVerb = new DesignerVerb("Undock from parent control", this.UndockVerbHandler)
{
Description = "Undock this control from its parent.",
Enabled = this.ImageBoxControl.Dock != DockStyle.None
};
_verbs.Add(_undockVerb);
}
return _verbs;
}
}
#endregion
#region Overridden Methods
///
/// Initializes the designer with the specified component.
///
/// The to associate with the designer.
public override void Initialize(IComponent component)
{
IComponentChangeService changeService;
base.Initialize(component);
// attach an event to notify us of when a component has been modified
changeService = (IComponentChangeService)this.GetService(typeof(IComponentChangeService));
if (changeService != null)
{
changeService.ComponentChanged += this.OnComponentChanged;
}
}
///
/// Releases the unmanaged resources used by the , and optionally releases the managed resources.
///
/// true to release both managed and unmanaged resources; false to release only unmanaged resources.
protected override void Dispose(bool disposing)
{
if (disposing)
{
IComponentChangeService changeService;
changeService = (IComponentChangeService)this.GetService(typeof(IComponentChangeService));
if (changeService != null)
{
changeService.ComponentChanged -= this.OnComponentChanged;
}
}
base.Dispose(disposing);
}
#endregion
#region Protected Properties
///
/// Gets the TabList control currently being designed
///
/// The TabList control being designed.
protected ImageBox ImageBoxControl
{
get { return this.Component as ImageBox; }
}
#endregion
#region Private Members
///
/// Called when the Dock verb is activated
///
/// The sender.
/// The instance containing the event data.
private void DockVerbHandler(object sender, EventArgs e)
{
this.SetDock(DockStyle.Fill);
}
///
/// Applies a new dock setting to the hosted control
///
private void SetDock(DockStyle dock)
{
ImageBox control;
IDesignerHost host;
control = this.ImageBoxControl;
host = (IDesignerHost)this.GetService(typeof(IDesignerHost));
if (control != null && host != null)
{
using (DesignerTransaction transaction = host.CreateTransaction(string.Format("Add TabListPage to '{0}'", control.Name)))
{
try
{
MemberDescriptor dockProperty;
dockProperty = TypeDescriptor.GetProperties(control)["Dock"];
// tell the designer we're about to start making changes
this.RaiseComponentChanging(dockProperty);
// dock it!
control.Dock = dock;
// inform the designer we're finished making changes
this.RaiseComponentChanged(dockProperty, null, null);
// commit the transaction
transaction.Commit();
}
catch
{
transaction.Cancel();
throw;
}
}
}
}
///
/// Occurs when the Undock verb is activated
///
/// The sender.
/// The instance containing the event data.
private void UndockVerbHandler(object sender, EventArgs e)
{
this.SetDock(DockStyle.None);
}
#endregion
#region Event Handlers
///
/// Called when the component attached to this designer has changed
///
/// The sender.
/// The instance containing the event data.
private void OnComponentChanged(object sender, ComponentChangedEventArgs e)
{
if (_dockVerb != null)
{
_dockVerb.Enabled = this.ImageBoxControl.Dock == DockStyle.None;
}
if (_undockVerb != null)
{
_undockVerb.Enabled = this.ImageBoxControl.Dock != DockStyle.None;
}
}
#endregion
}
}
================================================
FILE: Cyotek.Windows.Forms.ImageBox.Design/Properties/AssemblyInfo.cs
================================================
using System;
using System.Reflection;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("Cyotek ImageBox Control Designer")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Cyotek Ltd")]
[assembly: AssemblyProduct("Cyotek ImageBox Control")]
[assembly: AssemblyCopyright("Copyright © 2013-2015 Cyotek Ltd.")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: Guid("3cadaf8e-61b8-407c-a82d-0d29f70ce38f")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
================================================
FILE: Cyotek.Windows.Forms.ImageBox.sln
================================================
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cyotek.Windows.Forms.ImageBox.Demo", "Cyotek.Windows.Forms.ImageBox.Demo\Cyotek.Windows.Forms.ImageBox.Demo.csproj", "{86D47D73-B3E7-4ED3-86EA-7BFC0C978A7B}"
ProjectSection(ProjectDependencies) = postProject
{9F169B78-70FD-456A-BB48-2AA470938D38} = {9F169B78-70FD-456A-BB48-2AA470938D38}
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cyotek.Windows.Forms.ImageBox", "Cyotek.Windows.Forms.ImageBox\Cyotek.Windows.Forms.ImageBox.csproj", "{4159C8D3-C18D-4BED-8BE6-9BAD1B0CA4F6}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Resources", "Resources", "{7E34AEC6-0EF4-4B37-B0DE-E28096960FA0}"
ProjectSection(SolutionItems) = preProject
ACKNOWLEDGEMENTS.md = ACKNOWLEDGEMENTS.md
CHANGELOG.md = CHANGELOG.md
LICENSE.txt = LICENSE.txt
README.md = README.md
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cyotek.Windows.Forms.ImageBox.Design", "Cyotek.Windows.Forms.ImageBox.Design\Cyotek.Windows.Forms.ImageBox.Design.csproj", "{9F169B78-70FD-456A-BB48-2AA470938D38}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{86D47D73-B3E7-4ED3-86EA-7BFC0C978A7B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{86D47D73-B3E7-4ED3-86EA-7BFC0C978A7B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{86D47D73-B3E7-4ED3-86EA-7BFC0C978A7B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{86D47D73-B3E7-4ED3-86EA-7BFC0C978A7B}.Release|Any CPU.Build.0 = Release|Any CPU
{4159C8D3-C18D-4BED-8BE6-9BAD1B0CA4F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4159C8D3-C18D-4BED-8BE6-9BAD1B0CA4F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4159C8D3-C18D-4BED-8BE6-9BAD1B0CA4F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4159C8D3-C18D-4BED-8BE6-9BAD1B0CA4F6}.Release|Any CPU.Build.0 = Release|Any CPU
{9F169B78-70FD-456A-BB48-2AA470938D38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9F169B78-70FD-456A-BB48-2AA470938D38}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9F169B78-70FD-456A-BB48-2AA470938D38}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9F169B78-70FD-456A-BB48-2AA470938D38}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
================================================
FILE: LICENSE.txt
================================================
The MIT License (MIT)
Copyright © 2010-2022 Cyotek Ltd.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
================================================
FILE: README.md
================================================
# Cyotek ImageBox Control
## About
The `ImageBox` is a lightweight owner drawn control for displaying images. It
supports zooming, scrolling, panning, region selection and much more! In
addition to the traditional mode of binding to an `Image`, you can also use a
*virtual mode*, and provide your own custom drawing whilst retaining all the
`ImageBox` functionality.
The `ImageBox` control also provides convenient helper methods for translating
points, rectangles and sizes according to the current zoom level and scroll
position of the control - this makes it easy to scale custom drawing to fit the
control.
As well as the different behaviours offered, the `ImageBox` also supports a
large number of display properties. The background of the control can display a
solid colour, or a coloured grid in various sizes. You can also configure how
the grid is to be drawn, for example just around the image bounds, or the full
control bounds. Other options include the pixel grid, which is displayed when
zooming in on an image to highlight each pixel, custom border styles for
surrounding the image, and many other properties. You can also display text, and
specifying formatting and alignment options.
## Example Screenshots



## License
The `ImageBox` control is licensed under the MIT License. See `license.txt` for
the full text.
## Further Reading
For more information on this control, see the
[articles tagged withimagebox](https://www.cyotek.com/blog/tag/imagebox) at
cyotek.com.
================================================
FILE: acknowledgements.md
================================================
# Acknowledgements
## Graphics
### Toolbar Icons
Toolbar icons from [Fugue Icons](http://p.yusukekamiyamane.com/).
### The Dread Pirate Hale's Legendary Treasure Map
Treasure map graphic created by [~Bogbrush](http://bogbrush.deviantart.com/).
Original map can be found [here](http://bogbrush.deviantart.com/art/The-Legendary-Treasure-Map-64737930).
### Marker Icon
Marker icon used in Scaled Adornments demonstrated created by [Icons Land](http://www.icons-land.com).
Original graphic can be found [here](https://www.iconfinder.com/icondetails/73053/128/base_map_marker_outside_pink_icon).
### World Maps
Physical Map of the World image by [Tom Patterson](http://www.shadedrelief.com/).
Original map (I used the "Large Wall Map", both labelled and unlabelled) can be found [here](http://www.shadedrelief.com/world/).
### Animated GIF's
[Newtons cradle animation book 2.gif](http://en.wikipedia.org/wiki/File:Newtons_cradle_animation_book_2.gif).
## Code
### ScrollControl
Original `ScrollControl` code by [Scott Crawford](http://sukiware.com/).
### Pixel Clipping
Original information on pixel clipping [Rotem](http://stackoverflow.com/questions/14070311/why-is-graphics-drawimage-cropping-part-of-my-image/14070372#14070372)
### Animated GIF Support
Contribution by [Eggy](https://github.com/teamalpha5441)
### Removal of .NET 3.5 requirement
Contribution by [dahmage](https://github.com/dahmage)
### Focusless Mouse Wheel Scroll
Derived from this [answer](http://stackoverflow.com/a/11034674/148962) and [this answer](http://stackoverflow.com/a/13292894/148962) on StackOverflow as suggested by [mtagliaf](http://forums.cyotek.com/imagebox/mouse-scroll-without-focusing-on-imagebox/msg194/#msg194)
### Mouse wheel scroll and zoom
Contribution by [Fruchtzwerg94](https://github.com/Fruchtzwerg94)
================================================
FILE: build.cmd
================================================
@ECHO OFF
SETLOCAL
CALL ..\..\..\build\set35vars.bat
%msbuildexe% Cyotek.Windows.Forms.ImageBox.sln /p:Configuration=Release /verbosity:minimal /nologo /t:Clean,Build
CALL dualsigncmd Cyotek.Windows.Forms.ImageBox\bin\Release\Cyotek.Windows.Forms.ImageBox.dll
PUSHD
IF NOT EXIST nuget MKDIR nuget
CD nuget
DEL *.* /Q
%nugetexe% pack ..\Cyotek.Windows.Forms.ImageBox\Cyotek.Windows.Forms.ImageBox.csproj -Prop Configuration=Release
%zipexe% a -bd -tZip Cyotek.Windows.Forms.ImageBox.x.x.x.x.zip ..\Cyotek.Windows.Forms.ImageBox\bin\Release\Cyotek.Windows.Forms.ImageBox.*
CALL sign-package *.nupkg
REM temp for push
DEL ..\Cyotek.Windows.Forms.ImageBox\bin\Release\*.nupkg
COPY *.nupkg ..\Cyotek.Windows.Forms.ImageBox\bin\Release\
POPD
ENDLOCAL
================================================
FILE: nuget.config
================================================