From 8cf0c5f1153742b8c697c4512064237e61d1941c Mon Sep 17 00:00:00 2001 From: Shuai Zhang Date: Wed, 18 Dec 2019 01:10:22 +0800 Subject: [PATCH] Add back Xceed.Wpf.Toolkit project. --- copy.bara.sky | 39 + third_party/ExtendedWPFToolkit/.gitignore | 295 ++ third_party/ExtendedWPFToolkit/LICENSE.md | 31 + third_party/ExtendedWPFToolkit/README.md | 199 + .../Xceed.Wpf.Toolkit/AssemblyVersionInfo.cs | 28 + .../AssemblyVersionInfoCommon.cs | 22 + .../Implementation/AutoSelectBehaviorEnum.cs | 28 + .../Implementation/AutoSelectTextBox.Icon.bmp | 3 + .../Implementation/AutoSelectTextBox.cs | 299 ++ .../Implementation/QueryMoveFocusEventArgs.cs | 73 + .../Implementation/BusyIndicator.Icon.bmp | 3 + .../Implementation/BusyIndicator.cs | 360 ++ .../Converters/ProgressBarWidthConverter.cs | 41 + .../VisualStates.BusyIndicator.cs | 51 + .../Themes/Aero2.NormalColor.xaml | 215 + .../BusyIndicator/Themes/Generic.xaml | 227 + .../Implementation/ButtonSpinner.Icon.bmp | 3 + .../Implementation/ButtonSpinner.cs | 368 ++ .../Implementation/SpinDirection.cs | 35 + .../Implementation/SpinEventArgs.cs | 76 + .../ButtonSpinner/Implementation/Spinner.cs | 119 + .../Implementation/ValidSpinDirections.cs | 42 + .../Themes/Aero2.NormalColor.xaml | 158 + .../ButtonSpinner/Themes/Generic.xaml | 145 + .../Implementation/Calculator.Icon.bmp | 3 + .../Calculator/Implementation/Calculator.cs | 582 +++ .../Implementation/CalculatorCommands.cs | 33 + .../Calculator/Themes/Aero2.NormalColor.xaml | 408 ++ .../Calculator/Themes/Generic.xaml | 832 ++++ .../Implementation/CalculatorUpDown.Icon.bmp | 3 + .../Implementation/CalculatorUpDown.cs | 282 ++ .../Themes/Aero2.NormalColor.xaml | 222 + .../CalculatorUpDown/Themes/Generic.xaml | 229 + .../Implementation/CheckComboBox.Icon.bmp | 3 + .../Implementation/CheckComboBox.cs | 402 ++ .../Themes/Aero2.NormalColor.xaml | 237 + .../CheckComboBox/Themes/Generic.xaml | 229 + .../Implementation/CheckListBox.Icon.bmp | 3 + .../Implementation/CheckListBox.cs | 42 + .../Themes/Aero2.NormalColor.xaml | 69 + .../CheckListBox/Themes/Generic.xaml | 55 + .../Implementation/ChildWindow.Icon.bmp | 3 + .../ChildWindow/Implementation/ChildWindow.cs | 875 ++++ .../Implementation/WindowStartupLocation.cs | 24 + .../ChildWindow/Implementation/WindowState.cs | 24 + .../ChildWindow/Themes/Aero2.NormalColor.xaml | 110 + .../ChildWindow/Themes/Generic.xaml | 105 + .../Chromes/Implementation/ButtonChrome.cs | 272 ++ .../Chromes/Themes/Aero2.NormalColor.xaml | 177 + .../Chromes/Themes/Generic.xaml | 228 + .../CollectionControl/Images/Delete16.png | 3 + .../CollectionControl/Images/Duplicate.png | 3 + .../Implementation/CollectionControl.Icon.bmp | 3 + .../Implementation/CollectionControl.cs | 712 +++ .../CollectionControlButton.Icon.bmp | 3 + .../Implementation/CollectionControlButton.cs | 178 + .../CollectionControlDialog.xaml | 54 + .../CollectionControlDialog.xaml.cs | 353 ++ .../NewItemTypesComboBoxConverter.cs | 74 + .../Implementation/ItemAddingEventArgs.cs | 52 + .../Implementation/ItemDeletingEventArgs.cs | 56 + .../Implementation/ItemEventArgs.cs | 55 + .../PrimitiveTypeCollectionControl.Icon.bmp | 3 + .../PrimitiveTypeCollectionControl.cs | 314 ++ .../Themes/Aero2.NormalColor.xaml | 334 ++ .../CollectionControl/Themes/Generic.xaml | 327 ++ .../Implementation/ColorCanvas.Icon.bmp | 3 + .../ColorCanvas/Implementation/ColorCanvas.cs | 635 +++ .../Implementation/ColorSpectrumSlider.cs | 114 + .../ColorCanvas/Themes/Aero2.NormalColor.xaml | 481 ++ .../ColorCanvas/Themes/Generic.xaml | 622 +++ .../ColorPicker/Implementation/ColorItem.cs | 53 + .../Implementation/ColorPicker.Icon.bmp | 3 + .../ColorPicker/Implementation/ColorPicker.cs | 891 ++++ .../Implementation/ColorPickerTabItem.cs | 43 + .../ColorPicker/Implementation/ColorSorter.cs | 77 + .../ColorPicker/Themes/Aero2.NormalColor.xaml | 523 +++ .../ColorPicker/Themes/Generic.xaml | 551 +++ .../Core/CancelRoutedEventArgs.cs | 59 + .../Core/Converters/AditionConverter.cs | 46 + ...rderThicknessToStrokeThicknessConverter.cs | 43 + .../CalculatorMemoryToVisibilityConverter.cs | 35 + .../Core/Converters/CenterTitleConverter.cs | 59 + .../Core/Converters/ColorBlendConverter.cs | 82 + .../ColorModeToTabItemSelectedConverter.cs | 37 + .../ColorToSolidColorBrushConverter.cs | 67 + .../CornerRadiusToDoubleConverter.cs | 48 + .../Core/Converters/HalfConverter.cs | 43 + .../Converters/IntToThicknessConverter.cs | 48 + .../Core/Converters/InverseBoolConverter.cs | 38 + .../Core/Converters/NullToBoolConverter.cs | 35 + .../Converters/ObjectTypeToNameConverter.cs | 54 + .../Core/Converters/RoundedValueConverter.cs | 65 + .../SolidColorBrushToColorConverter.cs | 49 + .../ThicknessSideRemovalConverter.cs | 50 + .../Converters/ThicknessToDoubleConverter.cs | 48 + .../Converters/VisibilityToBoolConverter.cs | 89 + .../WindowContentBorderMarginConverter.cs | 67 + .../WindowControlBackgroundConverter.cs | 61 + .../WizardPageButtonVisibilityConverter.cs | 64 + .../Core/EditableKeyValuePair.cs | 96 + .../Xceed.Wpf.Toolkit/Core/ErrorMessages.cs | 88 + .../Xceed.Wpf.Toolkit/Core/ErrorMessages.resx | 228 + .../Core/IndexChangedEventArgs.cs | 38 + .../Core/IndexChangedEventHandler.cs | 20 + .../Core/Input/IValidateInput.cs | 29 + .../Input/InputValidationErrorEventArgs.cs | 73 + .../Core/Input/KeyModifier.cs | 35 + .../Core/Input/KeyModifierCollection.cs | 223 + .../Input/KeyModifierCollectionConverter.cs | 122 + .../Core/InvalidContentException.cs | 37 + .../Core/InvalidTemplateException.cs | 37 + .../Xceed.Wpf.Toolkit/Core/LocationEnum.cs | 24 + .../Core/Media/Animation/AnimationRate.cs | 346 ++ .../Media/Animation/AnimationRateConverter.cs | 120 + .../Animation/IterativeAnimationEquation.cs | 49 + .../IterativeAnimationEquationDelegate.cs | 22 + .../Animation/IterativeEquationConverter.cs | 145 + .../Core/Media/Animation/PennerEquation.cs | 54 + .../Core/Media/Animation/PennerEquations.cs | 851 ++++ .../Core/Media/WindowColors.cs | 126 + .../Core/PropertyChangedEventArgs.cs | 70 + .../Core/PropertyChangedEventHandler.cs | 20 + .../Core/QueryTextFromValueEventArgs.cs | 54 + .../Core/QueryValueFromTextEventArgs.cs | 67 + .../Core/UIElementAdorner.cs | 240 + .../Core/Utilities/CalculatorUtilities.cs | 285 ++ .../Core/Utilities/ChangeTypeHelper.cs | 54 + .../Core/Utilities/ColorUtilities.cs | 206 + .../Core/Utilities/ContextMenuUtilities.cs | 75 + .../Core/Utilities/DateTimeUtilities.cs | 44 + .../Core/Utilities/DoubleHelper.cs | 97 + .../Core/Utilities/EllipseHelper.cs | 69 + .../Core/Utilities/FontUtilities.cs | 98 + .../Core/Utilities/GeneralUtilities.cs | 93 + .../Core/Utilities/KeyboardUtilities.cs | 33 + .../Core/Utilities/ListUtilities.cs | 80 + .../Core/Utilities/PointHelper.cs | 42 + .../Core/Utilities/PropertyChangedExt.cs | 127 + .../Core/Utilities/RectHelper.cs | 86 + .../Core/Utilities/ReflectionHelper.cs | 139 + .../Core/Utilities/ResourceHelper.cs | 36 + .../Core/Utilities/RoutedEventHelper.cs | 70 + .../Core/Utilities/Segment.cs | 384 ++ .../Core/Utilities/TreeHelper.cs | 235 + .../Core/Utilities/ValueChangeHelper.cs | 150 + .../Core/Utilities/VisualTreeHelperEx.cs | 135 + .../Core/Utilities/WeakEventListener.cs | 43 + .../Core/Utilities/WindowUtilities.cs | 30 + .../Core/VersionResourceDictionary.cs | 105 + .../Core/WeakCollectionChangedWrapper.cs | 150 + .../Implementation/DateTimePicker.Icon.bmp | 3 + .../Implementation/DateTimePicker.cs | 473 ++ .../Themes/Aero2.NormalColor.xaml | 277 ++ .../DateTimePicker/Themes/Generic.xaml | 285 ++ .../Implementation/DateTimeFormat.cs | 33 + .../Implementation/DateTimeInfo.cs | 52 + .../Implementation/DateTimeParser.cs | 243 + .../Implementation/DateTimePart.cs | 36 + .../Implementation/DateTimeUpDown.Icon.bmp | 3 + .../Implementation/DateTimeUpDown.cs | 994 ++++ .../Themes/Aero2.NormalColor.xaml | 116 + .../DateTimeUpDown/Themes/Generic.xaml | 128 + .../Implementation/DropDownButton.Icon.bmp | 3 + .../Implementation/DropDownButton.cs | 562 +++ .../Themes/Aero2.NormalColor.xaml | 154 + .../DropDownButton/Themes/Generic.xaml | 174 + .../Implementation/IconButton.Icon.bmp | 3 + .../IconButton/Implementation/IconButton.cs | 185 + .../IconButton/Themes/Aero2.NormalColor.xaml | 166 + .../IconButton/Themes/Generic.xaml | 166 + .../Converters/RadiusConverter.cs | 38 + .../Magnifier/Implementation/FrameType.cs | 24 + .../Implementation/Magnifier.Icon.bmp | 3 + .../Magnifier/Implementation/Magnifier.cs | 311 ++ .../Implementation/MagnifierAdorner.cs | 129 + .../Implementation/MagnifierManager.cs | 146 + .../Magnifier/Themes/Generic.xaml | 69 + .../AutoCompletingMaskEventArgs.cs | 105 + .../Implementation/InsertKeyModeEnum.cs | 29 + .../Implementation/MaskFormatEnum.cs | 30 + .../Implementation/MaskedTextBox.Icon.bmp | 3 + .../Implementation/MaskedTextBox.cs | 1955 ++++++++ .../MessageBox/Icons/Error48.png | 3 + .../MessageBox/Icons/Information48.png | 3 + .../MessageBox/Icons/Question48.png | 3 + .../MessageBox/Icons/Warning48.png | 3 + .../Implementation/MessageBox.Icon.bmp | 3 + .../MessageBox/Implementation/MessageBox.cs | 1203 +++++ .../Implementation/VisualStates.MessageBox.cs | 27 + .../MessageBox/Themes/Aero2.NormalColor.xaml | 238 + .../MessageBox/Themes/Generic.xaml | 238 + .../MultiLineTextEditor/Images/Notes16.png | 3 + .../MultiLineTextEditor.Icon.bmp | 3 + .../Implementation/MultiLineTextEditor.cs | 297 ++ .../Themes/Aero2.NormalColor.xaml | 217 + .../MultiLineTextEditor/Themes/Generic.xaml | 236 + .../AllowedSpecialValuesEnum.cs | 31 + .../Implementation/ByteUpDown.Icon.bmp | 3 + .../Implementation/ByteUpDown.cs | 53 + .../Implementation/CommonNumericUpDown.cs | 407 ++ .../Implementation/DecimalUpDown.Icon.bmp | 3 + .../Implementation/DecimalUpDown.cs | 52 + .../Implementation/DoubleUpDown.Icon.bmp | 3 + .../Implementation/DoubleUpDown.cs | 124 + .../Implementation/IntegerUpDown.Icon.bmp | 3 + .../Implementation/IntegerUpDown.cs | 52 + .../Implementation/LongUpDown.Icon.bmp | 3 + .../Implementation/LongUpDown.cs | 52 + .../Implementation/NumericUpDown.cs | 190 + .../Implementation/SByteUpDown.Icon.bmp | 3 + .../Implementation/SByteUpDown.cs | 52 + .../Implementation/ShortUpDown.Icon.bmp | 3 + .../Implementation/ShortUpDown.cs | 52 + .../Implementation/SingleUpDown.Icon.bmp | 3 + .../Implementation/SingleUpDown.cs | 124 + .../Implementation/UIntegerUpDown.Icon.bmp | 3 + .../Implementation/UIntegerUpDown.cs | 53 + .../Implementation/ULongUpDown.Icon.bmp | 3 + .../Implementation/ULongUpDown.cs | 52 + .../Implementation/UShortUpDown.Icon.bmp | 3 + .../Implementation/UShortUpDown.cs | 52 + .../Themes/Aero2.NormalColor.xaml | 214 + .../NumericUpDown/Themes/Generic.xaml | 202 + .../Implementation/MaskedTextBox.cs | 723 +++ .../Panels/AnimationPanel.cs | 1875 ++++++++ .../Panels/AnimatorConverter.cs | 144 + .../Xceed.Wpf.Toolkit/Panels/Animators.cs | 581 +++ .../Panels/ChildEnteredEventArgs.cs | 61 + .../Panels/ChildEnteredEventHandler.cs | 20 + .../Panels/ChildEnteringEventArgs.cs | 80 + .../Panels/ChildEnteringEventHandler.cs | 20 + .../Panels/ChildExitedEventArgs.cs | 46 + .../Panels/ChildExitedEventHandler.cs | 20 + .../Panels/ChildExitingEventArgs.cs | 80 + .../Panels/ChildExitingEventHandler.cs | 20 + .../Panels/DoubleAnimator.cs | 80 + .../Panels/IterativeAnimator.cs | 78 + .../Xceed.Wpf.Toolkit/Panels/PanelBase.cs | 31 + .../Panels/RandomPanel.Icon.bmp | 3 + .../Xceed.Wpf.Toolkit/Panels/RandomPanel.cs | 303 ++ .../Xceed.Wpf.Toolkit/Panels/ScrollHelper.cs | 73 + .../Xceed.Wpf.Toolkit/Panels/SwitchPanel.cs | 1383 ++++++ .../Panels/SwitchPresenter.cs | 322 ++ .../Panels/SwitchTemplate.cs | 69 + .../Panels/WrapPanel.Icon.bmp | 3 + .../Xceed.Wpf.Toolkit/Panels/WrapPanel.cs | 284 ++ .../Pie/Implementation/Pie.Icon.bmp | 3 + .../Pie/Implementation/Pie.cs | 628 +++ .../Pie/Implementation/PieModeEnum.cs | 25 + .../Pie/Themes/Aero2.NormalColor.xaml | 29 + .../Xceed.Wpf.Toolkit/Pie/Themes/Generic.xaml | 29 + .../Primitives/CachedTextInfo.cs | 54 + .../Primitives/DateTimePickerBase.cs | 192 + .../Primitives/DateTimeUpDownBase.cs | 385 ++ .../Xceed.Wpf.Toolkit/Primitives/HsvColor.cs | 32 + .../Xceed.Wpf.Toolkit/Primitives/InputBase.cs | 225 + .../Primitives/MouseWheelActiveTriggerEnum.cs | 34 + .../Primitives/SelectAllSelector.cs | 157 + .../Primitives/SelectAllSelectorItem.cs | 68 + .../Xceed.Wpf.Toolkit/Primitives/Selector.cs | 986 ++++ .../Primitives/SelectorItem.cs | 87 + .../Xceed.Wpf.Toolkit/Primitives/ShapeBase.cs | 142 + .../Primitives/Themes/Aero2/SelectorItem.xaml | 87 + .../Themes/Aero2/WindowControl.xaml | 395 ++ .../Themes/Generic/SelectorItem.xaml | 84 + .../Themes/Generic/WindowControl.xaml | 386 ++ .../Primitives/Themes/ResourceKeys.cs | 61 + .../Primitives/UpDownBase.cs | 859 ++++ .../Primitives/ValueRangeTextBox.Icon.bmp | 3 + .../Primitives/ValueRangeTextBox.cs | 1212 +++++ .../Primitives/WindowContainer.Icon.bmp | 3 + .../Primitives/WindowContainer.cs | 451 ++ .../Primitives/WindowControl.Icon.bmp | 3 + .../Primitives/WindowControl.cs | 870 ++++ .../Properties/AssemblyInfo.cs | 111 + .../Images/AdvancedProperties11.png | 3 + .../PropertyGrid/Images/Categorize16.png | 3 + .../PropertyGrid/Images/ClearFilter16.png | 3 + .../PropertyGrid/Images/Database11.png | 3 + .../PropertyGrid/Images/Inheritance11.png | 3 + .../PropertyGrid/Images/Local11.png | 3 + .../PropertyGrid/Images/Resource11.png | 3 + .../PropertyGrid/Images/SortAscending16.png | 3 + .../PropertyGrid/Images/Style11.png | 3 + .../Attributes/CategoryOrderAttribute.cs | 76 + .../Attributes/ExpandableObjectAttribute.cs | 39 + .../Implementation/Attributes/IItemsSource.cs | 58 + .../Attributes/ItemsSourceAttribute.cs | 38 + .../Attributes/NewItemTypesAttribute.cs | 45 + .../Attributes/PropertyOrderAttribute.cs | 70 + .../CategoryGroupStyleSelector.cs | 65 + .../Commands/PropertyGridCommands.cs | 32 + .../Commands/PropertyItemCommands.cs | 32 + .../CommonPropertyExceptionValidationRule.cs | 58 + .../Implementation/ContainerHelperBase.cs | 238 + .../Converters/EditorTimeSpanConverter.cs | 52 + .../ExpandableObjectMarginConverter.cs | 36 + .../Converters/IsDefaultCategoryConverter.cs | 45 + .../Converters/IsStringEmptyConverter.cs | 40 + .../Converters/ListConverter.cs | 105 + .../Converters/ObjectToUIElementConverter.cs | 43 + .../Converters/PropertyItemEditorConverter.cs | 87 + .../Converters/SelectedObjectConverter.cs | 116 + .../Implementation/CustomPropertyItem.cs | 182 + .../Definitions/DefinitionBase.cs | 64 + .../Definitions/EditorDefinitionBase.cs | 70 + .../Definitions/EditorTemplateDefinition.cs | 47 + .../Definitions/PropertyDefinitionBase.cs | 113 + .../DescriptorPropertyDefinition.cs | 267 ++ .../DescriptorPropertyDefinitionBase.cs | 693 +++ .../Implementation/EditorDefinition.cs | 100 + .../Implementation/Editors/CheckBoxEditor.cs | 47 + .../Editors/CollectionEditor.cs | 112 + .../Implementation/Editors/ColorEditor.cs | 45 + .../Implementation/Editors/ComboBoxEditor.cs | 56 + .../Editors/EnumComboBoxEditor.cs | 59 + .../Editors/FontComboBoxEditor.cs | 42 + .../Implementation/Editors/ITypeEditor.cs | 25 + .../Editors/ItemsSourceAttributeEditor.cs | 68 + .../Editors/MaskedTextBoxEditor.cs | 65 + .../Editors/PrimitiveTypeCollectionEditor.cs | 68 + .../Editors/SourceComboBoxEditor.cs | 79 + .../Implementation/Editors/TextBlockEditor.cs | 48 + .../Implementation/Editors/TextBoxEditor.cs | 56 + .../Implementation/Editors/TypeEditor.cs | 84 + .../Implementation/Editors/UpDownEditors.cs | 389 ++ .../PropertyGrid/Implementation/FilterInfo.cs | 29 + .../Implementation/IPropertyContainer.cs | 57 + .../Implementation/ObjectContainerHelper.cs | 168 + .../ObjectContainerHelperBase.cs | 565 +++ .../Implementation/PropertyDefinition.cs | 122 + .../PropertyDefinitionBaseCollection.cs | 124 + .../Implementation/PropertyGrid.Icon.bmp | 3 + .../Implementation/PropertyGrid.cs | 1654 +++++++ .../Implementation/PropertyGridUtilities.cs | 210 + .../Implementation/PropertyItem.cs | 332 ++ .../Implementation/PropertyItemBase.cs | 602 +++ .../Implementation/PropertyItemCollection.cs | 211 + .../Implementation/PropertyItemsControl.cs | 109 + .../Implementation/StringConstants.cs | 56 + .../Implementation/TargetPropertyType.cs | 59 + .../Implementation/TrimmedTextBlock.cs | 186 + .../Themes/Aero2.NormalColor.xaml | 1312 ++++++ .../PropertyGrid/Themes/Generic.xaml | 1432 ++++++ .../Converters/SliderThumbWidthConverter.cs | 49 + .../Implementation/RangeSlider.Icon.bmp | 3 + .../RangeSlider/Implementation/RangeSlider.cs | 1086 +++++ .../RangeSlider/Themes/Aero2.NormalColor.xaml | 570 +++ .../RangeSlider/Themes/Generic.xaml | 636 +++ .../RichTextBox/Formatters/ITextFormatter.cs | 26 + .../Formatters/PlainTextFormatter.cs | 36 + .../RichTextBox/Formatters/RtfFormatter.cs | 65 + .../RichTextBox/Formatters/XamlFormatter.cs | 65 + .../RichTextBox/RichTextBox.Icon.bmp | 3 + .../RichTextBox/RichTextBox.cs | 174 + .../IRichTextBoxFormatBar.cs | 43 + .../RichTextBoxFormatBar/Images/Bold16.png | 3 + .../RichTextBoxFormatBar/Images/Bullets16.png | 3 + .../Images/CenterAlign16.png | 3 + .../Images/FontColorPicker16.png | 3 + .../RichTextBoxFormatBar/Images/Italic16.png | 3 + .../Images/JustifyAlign16.png | 3 + .../Images/LeftAlign16.png | 3 + .../Images/Numbering16.png | 3 + .../Images/RightAlign16.png | 3 + .../Images/TextHighlightColorPicker16.png | 3 + .../Images/Underline16.png | 3 + .../RichTextBoxFormatBar.Icon.bmp | 3 + .../RichTextBoxFormatBar.cs | 474 ++ .../RichTextBoxFormatBarManager.cs | 272 ++ .../Themes/Aero2.NormalColor.xaml | 751 +++ .../RichTextBoxFormatBar/Themes/Generic.xaml | 750 +++ .../Implementation/SplitButton.Icon.bmp | 3 + .../SplitButton/Implementation/SplitButton.cs | 47 + .../SplitButton/Themes/Aero2.NormalColor.xaml | 171 + .../SplitButton/Themes/Generic.xaml | 197 + .../StyleableWindowClippingBorderConverter.cs | 40 + .../Implementation/StyleableWindow.Icon.bmp | 3 + .../Themes/Aero.NormalColor.xaml | 27 + .../Themes/Aero/Brushes_NormalColor.xaml | 158 + .../Themes/Aero/Buttons_NormalColor.xaml | 51 + .../Themes/Aero2.NormalColor.xaml | 64 + .../Themes/Aero2/Brushes.xaml | 90 + .../Themes/Aero2/Buttons.xaml | 51 + .../Themes/Aero2/Common.xaml | 147 + .../Themes/Aero2/Glyphs.xaml | 67 + .../Xceed.Wpf.Toolkit/Themes/Generic.xaml | 62 + .../Themes/Generic/Brushes.xaml | 216 + .../Themes/Generic/Buttons.xaml | 49 + .../Themes/Generic/Common.xaml | 234 + .../Themes/Generic/Glyphs.xaml | 67 + .../Themes/Generic/Images/close_hover.png | 3 + .../Themes/Generic/Images/close_inactive.png | 3 + .../Themes/Generic/Images/close_normal.png | 3 + .../Themes/Generic/Images/close_pressed.png | 3 + .../Generic/Images/close_rounded_hover.png | 3 + .../Generic/Images/close_rounded_inactive.png | 3 + .../Generic/Images/close_rounded_normal.png | 3 + .../Generic/Images/close_rounded_pressed.png | 3 + .../Generic/Images/close_toolwindow_hover.png | 3 + .../Images/close_toolwindow_inactive.png | 3 + .../Images/close_toolwindow_normal.png | 3 + .../Images/close_toolwindow_pressed.png | 3 + .../Generic/Images/maximize_disabled.png | 3 + .../Themes/Generic/Images/maximize_hover.png | 3 + .../Generic/Images/maximize_inactive.png | 3 + .../Themes/Generic/Images/maximize_normal.png | 3 + .../Generic/Images/maximize_pressed.png | 3 + .../Themes/Generic/Images/minimize_hover.png | 3 + .../Generic/Images/minimize_inactive.png | 3 + .../Themes/Generic/Images/minimize_normal.png | 3 + .../Generic/Images/minimize_pressed.png | 3 + .../Themes/Generic/Images/resize_grip.png | 3 + .../Generic/Images/restore_disabled.png | 3 + .../Themes/Generic/Images/restore_hover.png | 3 + .../Generic/Images/restore_inactive.png | 3 + .../Themes/Generic/Images/restore_normal.png | 3 + .../Themes/Generic/Images/restore_pressed.png | 3 + .../Xceed.Wpf.Toolkit/Themes/classic.xaml | 28 + .../Themes/luna.homestead.xaml | 28 + .../Themes/luna.metallic.xaml | 28 + .../Themes/luna.normalcolor.xaml | 28 + .../Themes/royale.normalcolor.xaml | 28 + .../TimePicker/Implementation/TimeItem.cs | 58 + .../Implementation/TimePicker.Icon.bmp | 3 + .../TimePicker/Implementation/TimePicker.cs | 532 +++ .../TimePicker/Themes/Aero2.NormalColor.xaml | 305 ++ .../TimePicker/Themes/Generic.xaml | 283 ++ .../Implementation/TimeSpanUpDown.Icon.bmp | 3 + .../Implementation/TimeSpanUpDown.cs | 872 ++++ .../Themes/Aero2.NormalColor.xaml | 139 + .../TimeSpanUpDown/Themes/Generic.xaml | 128 + .../Implementation/DateElement.cs | 127 + .../Implementation/OverlapBehavior.cs | 26 + .../Implementation/TimelinePanel.Icon.bmp | 3 + .../Implementation/TimelinePanel.cs | 1322 ++++++ .../Xceed.Wpf.Toolkit/VisualStates.cs | 23 + .../Implementation/WatermarkComboBox.Icon.bmp | 3 + .../Implementation/WatermarkComboBox.cs | 82 + .../Themes/Aero2.NormalColor.xaml | 477 ++ .../WatermarkComboBox/Themes/Generic.xaml | 477 ++ .../WatermarkPasswordBox.Icon.bmp | 3 + .../Implementation/WatermarkPasswordBox.cs | 324 ++ .../Implementation/WatermarkTextBox.Icon.bmp | 3 + .../Implementation/WatermarkTextBox.cs | 102 + .../Themes/Aero2.NormalColor.xaml | 169 + .../WatermarkTextBox/Themes/Generic.xaml | 179 + .../Wizard/Implementation/Wizard.Icon.bmp | 3 + .../Wizard/Implementation/Wizard.cs | 691 +++ .../Wizard/Implementation/WizardCommands.cs | 78 + .../Wizard/Implementation/WizardPage.cs | 362 ++ .../WizardPageButtonVisibility.cs | 26 + .../Wizard/Implementation/WizardPageType.cs | 25 + .../Wizard/Themes/Aero2.NormalColor.xaml | 303 ++ .../Wizard/Themes/Generic.xaml | 298 ++ .../Xceed.Wpf.Toolkit.csproj | 287 ++ .../Xceed.Wpf.Toolkit.csproj.old | 954 ++++ .../Zoombox/Resources/Zoom.cur | Bin 0 -> 2238 bytes .../Zoombox/Resources/ZoomRelative.cur | Bin 0 -> 2238 bytes .../Zoombox/Themes/Aero2.NormalColor.xaml | 833 ++++ .../Zoombox/Themes/Generic.xaml | 833 ++++ .../Zoombox/Zoombox.Icon.bmp | 3 + .../Xceed.Wpf.Toolkit/Zoombox/Zoombox.cs | 4058 +++++++++++++++++ .../Zoombox/ZoomboxCursors.cs | 73 + .../Xceed.Wpf.Toolkit/Zoombox/ZoomboxView.cs | 314 ++ .../Zoombox/ZoomboxViewChangedEventArgs.cs | 96 + .../Zoombox/ZoomboxViewChangedEventHandler.cs | 20 + .../Zoombox/ZoomboxViewConverter.cs | 207 + .../Zoombox/ZoomboxViewException.cs | 32 + .../Zoombox/ZoomboxViewFinderDisplay.cs | 284 ++ .../Zoombox/ZoomboxViewKind.cs | 29 + .../Zoombox/ZoomboxViewStack.cs | 555 +++ .../Zoombox/ZoomboxViewStackMode.cs | 26 + .../Zoombox/ZoomboxZoomOn.cs | 24 + 475 files changed, 81542 insertions(+) create mode 100644 third_party/ExtendedWPFToolkit/.gitignore create mode 100644 third_party/ExtendedWPFToolkit/LICENSE.md create mode 100644 third_party/ExtendedWPFToolkit/README.md create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/AssemblyVersionInfo.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/AssemblyVersionInfoCommon.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/AutoSelectTextBox/Implementation/AutoSelectBehaviorEnum.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/AutoSelectTextBox/Implementation/AutoSelectTextBox.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/AutoSelectTextBox/Implementation/AutoSelectTextBox.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/AutoSelectTextBox/Implementation/QueryMoveFocusEventArgs.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/BusyIndicator/Implementation/BusyIndicator.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/BusyIndicator/Implementation/BusyIndicator.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/BusyIndicator/Implementation/Converters/ProgressBarWidthConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/BusyIndicator/Implementation/VisualStates.BusyIndicator.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/BusyIndicator/Themes/Aero2.NormalColor.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/BusyIndicator/Themes/Generic.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ButtonSpinner/Implementation/ButtonSpinner.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ButtonSpinner/Implementation/ButtonSpinner.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ButtonSpinner/Implementation/SpinDirection.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ButtonSpinner/Implementation/SpinEventArgs.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ButtonSpinner/Implementation/Spinner.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ButtonSpinner/Implementation/ValidSpinDirections.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ButtonSpinner/Themes/Aero2.NormalColor.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ButtonSpinner/Themes/Generic.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Calculator/Implementation/Calculator.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Calculator/Implementation/Calculator.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Calculator/Implementation/CalculatorCommands.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Calculator/Themes/Aero2.NormalColor.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Calculator/Themes/Generic.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CalculatorUpDown/Implementation/CalculatorUpDown.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CalculatorUpDown/Implementation/CalculatorUpDown.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CalculatorUpDown/Themes/Aero2.NormalColor.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CalculatorUpDown/Themes/Generic.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CheckComboBox/Implementation/CheckComboBox.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CheckComboBox/Implementation/CheckComboBox.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CheckComboBox/Themes/Aero2.NormalColor.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CheckComboBox/Themes/Generic.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CheckListBox/Implementation/CheckListBox.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CheckListBox/Implementation/CheckListBox.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CheckListBox/Themes/Aero2.NormalColor.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CheckListBox/Themes/Generic.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ChildWindow/Implementation/ChildWindow.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ChildWindow/Implementation/ChildWindow.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ChildWindow/Implementation/WindowStartupLocation.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ChildWindow/Implementation/WindowState.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ChildWindow/Themes/Aero2.NormalColor.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ChildWindow/Themes/Generic.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Chromes/Implementation/ButtonChrome.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Chromes/Themes/Aero2.NormalColor.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Chromes/Themes/Generic.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Images/Delete16.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Images/Duplicate.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/CollectionControl.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/CollectionControl.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/CollectionControlButton.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/CollectionControlButton.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/CollectionControlDialog.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/CollectionControlDialog.xaml.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/Converters/NewItemTypesComboBoxConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/ItemAddingEventArgs.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/ItemDeletingEventArgs.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/ItemEventArgs.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/PrimitiveTypeCollectionControl.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/PrimitiveTypeCollectionControl.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Themes/Aero2.NormalColor.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Themes/Generic.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ColorCanvas/Implementation/ColorCanvas.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ColorCanvas/Implementation/ColorCanvas.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ColorCanvas/Implementation/ColorSpectrumSlider.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ColorCanvas/Themes/Aero2.NormalColor.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ColorCanvas/Themes/Generic.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ColorPicker/Implementation/ColorItem.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ColorPicker/Implementation/ColorPicker.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ColorPicker/Implementation/ColorPicker.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ColorPicker/Implementation/ColorPickerTabItem.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ColorPicker/Implementation/ColorSorter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ColorPicker/Themes/Aero2.NormalColor.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ColorPicker/Themes/Generic.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/CancelRoutedEventArgs.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/AditionConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/BorderThicknessToStrokeThicknessConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/CalculatorMemoryToVisibilityConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/CenterTitleConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/ColorBlendConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/ColorModeToTabItemSelectedConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/ColorToSolidColorBrushConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/CornerRadiusToDoubleConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/HalfConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/IntToThicknessConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/InverseBoolConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/NullToBoolConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/ObjectTypeToNameConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/RoundedValueConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/SolidColorBrushToColorConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/ThicknessSideRemovalConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/ThicknessToDoubleConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/VisibilityToBoolConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/WindowContentBorderMarginConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/WindowControlBackgroundConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/WizardPageButtonVisibilityConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/EditableKeyValuePair.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/ErrorMessages.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/ErrorMessages.resx create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/IndexChangedEventArgs.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/IndexChangedEventHandler.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Input/IValidateInput.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Input/InputValidationErrorEventArgs.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Input/KeyModifier.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Input/KeyModifierCollection.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Input/KeyModifierCollectionConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/InvalidContentException.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/InvalidTemplateException.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/LocationEnum.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Media/Animation/AnimationRate.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Media/Animation/AnimationRateConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Media/Animation/IterativeAnimationEquation.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Media/Animation/IterativeAnimationEquationDelegate.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Media/Animation/IterativeEquationConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Media/Animation/PennerEquation.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Media/Animation/PennerEquations.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Media/WindowColors.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/PropertyChangedEventArgs.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/PropertyChangedEventHandler.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/QueryTextFromValueEventArgs.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/QueryValueFromTextEventArgs.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/UIElementAdorner.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/CalculatorUtilities.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/ChangeTypeHelper.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/ColorUtilities.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/ContextMenuUtilities.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/DateTimeUtilities.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/DoubleHelper.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/EllipseHelper.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/FontUtilities.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/GeneralUtilities.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/KeyboardUtilities.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/ListUtilities.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/PointHelper.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/PropertyChangedExt.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/RectHelper.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/ReflectionHelper.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/ResourceHelper.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/RoutedEventHelper.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/Segment.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/TreeHelper.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/ValueChangeHelper.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/VisualTreeHelperEx.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/WeakEventListener.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/WindowUtilities.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/VersionResourceDictionary.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/WeakCollectionChangedWrapper.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimePicker/Implementation/DateTimePicker.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimePicker/Implementation/DateTimePicker.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimePicker/Themes/Aero2.NormalColor.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimePicker/Themes/Generic.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimeUpDown/Implementation/DateTimeFormat.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimeUpDown/Implementation/DateTimeInfo.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimeUpDown/Implementation/DateTimeParser.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimeUpDown/Implementation/DateTimePart.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimeUpDown/Implementation/DateTimeUpDown.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimeUpDown/Implementation/DateTimeUpDown.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimeUpDown/Themes/Aero2.NormalColor.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimeUpDown/Themes/Generic.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DropDownButton/Implementation/DropDownButton.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DropDownButton/Implementation/DropDownButton.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DropDownButton/Themes/Aero2.NormalColor.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DropDownButton/Themes/Generic.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/IconButton/Implementation/IconButton.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/IconButton/Implementation/IconButton.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/IconButton/Themes/Aero2.NormalColor.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/IconButton/Themes/Generic.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Magnifier/Implementation/Converters/RadiusConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Magnifier/Implementation/FrameType.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Magnifier/Implementation/Magnifier.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Magnifier/Implementation/Magnifier.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Magnifier/Implementation/MagnifierAdorner.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Magnifier/Implementation/MagnifierManager.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Magnifier/Themes/Generic.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MaskedTextBox/Implementation/AutoCompletingMaskEventArgs.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MaskedTextBox/Implementation/InsertKeyModeEnum.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MaskedTextBox/Implementation/MaskFormatEnum.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MaskedTextBox/Implementation/MaskedTextBox.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MaskedTextBox/Implementation/MaskedTextBox.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MessageBox/Icons/Error48.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MessageBox/Icons/Information48.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MessageBox/Icons/Question48.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MessageBox/Icons/Warning48.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MessageBox/Implementation/MessageBox.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MessageBox/Implementation/MessageBox.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MessageBox/Implementation/VisualStates.MessageBox.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MessageBox/Themes/Aero2.NormalColor.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MessageBox/Themes/Generic.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MultiLineTextEditor/Images/Notes16.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MultiLineTextEditor/Implementation/MultiLineTextEditor.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MultiLineTextEditor/Implementation/MultiLineTextEditor.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MultiLineTextEditor/Themes/Aero2.NormalColor.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MultiLineTextEditor/Themes/Generic.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/NumericUpDown/Implementation/AllowedSpecialValuesEnum.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/NumericUpDown/Implementation/ByteUpDown.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/NumericUpDown/Implementation/ByteUpDown.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/NumericUpDown/Implementation/CommonNumericUpDown.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/NumericUpDown/Implementation/DecimalUpDown.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/NumericUpDown/Implementation/DecimalUpDown.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/NumericUpDown/Implementation/DoubleUpDown.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/NumericUpDown/Implementation/DoubleUpDown.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/NumericUpDown/Implementation/IntegerUpDown.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/NumericUpDown/Implementation/IntegerUpDown.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/NumericUpDown/Implementation/LongUpDown.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/NumericUpDown/Implementation/LongUpDown.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/NumericUpDown/Implementation/NumericUpDown.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/NumericUpDown/Implementation/SByteUpDown.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/NumericUpDown/Implementation/SByteUpDown.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/NumericUpDown/Implementation/ShortUpDown.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/NumericUpDown/Implementation/ShortUpDown.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/NumericUpDown/Implementation/SingleUpDown.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/NumericUpDown/Implementation/SingleUpDown.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/NumericUpDown/Implementation/UIntegerUpDown.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/NumericUpDown/Implementation/UIntegerUpDown.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/NumericUpDown/Implementation/ULongUpDown.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/NumericUpDown/Implementation/ULongUpDown.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/NumericUpDown/Implementation/UShortUpDown.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/NumericUpDown/Implementation/UShortUpDown.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/NumericUpDown/Themes/Aero2.NormalColor.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/NumericUpDown/Themes/Generic.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Obselete/MaskedTextBox/Implementation/MaskedTextBox.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Panels/AnimationPanel.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Panels/AnimatorConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Panels/Animators.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Panels/ChildEnteredEventArgs.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Panels/ChildEnteredEventHandler.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Panels/ChildEnteringEventArgs.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Panels/ChildEnteringEventHandler.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Panels/ChildExitedEventArgs.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Panels/ChildExitedEventHandler.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Panels/ChildExitingEventArgs.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Panels/ChildExitingEventHandler.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Panels/DoubleAnimator.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Panels/IterativeAnimator.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Panels/PanelBase.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Panels/RandomPanel.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Panels/RandomPanel.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Panels/ScrollHelper.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Panels/SwitchPanel.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Panels/SwitchPresenter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Panels/SwitchTemplate.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Panels/WrapPanel.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Panels/WrapPanel.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Pie/Implementation/Pie.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Pie/Implementation/Pie.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Pie/Implementation/PieModeEnum.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Pie/Themes/Aero2.NormalColor.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Pie/Themes/Generic.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Primitives/CachedTextInfo.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Primitives/DateTimePickerBase.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Primitives/DateTimeUpDownBase.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Primitives/HsvColor.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Primitives/InputBase.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Primitives/MouseWheelActiveTriggerEnum.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Primitives/SelectAllSelector.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Primitives/SelectAllSelectorItem.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Primitives/Selector.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Primitives/SelectorItem.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Primitives/ShapeBase.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Primitives/Themes/Aero2/SelectorItem.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Primitives/Themes/Aero2/WindowControl.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Primitives/Themes/Generic/SelectorItem.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Primitives/Themes/Generic/WindowControl.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Primitives/Themes/ResourceKeys.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Primitives/UpDownBase.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Primitives/ValueRangeTextBox.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Primitives/ValueRangeTextBox.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Primitives/WindowContainer.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Primitives/WindowContainer.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Primitives/WindowControl.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Primitives/WindowControl.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Properties/AssemblyInfo.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Images/AdvancedProperties11.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Images/Categorize16.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Images/ClearFilter16.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Images/Database11.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Images/Inheritance11.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Images/Local11.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Images/Resource11.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Images/SortAscending16.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Images/Style11.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/Attributes/CategoryOrderAttribute.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/Attributes/ExpandableObjectAttribute.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/Attributes/IItemsSource.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/Attributes/ItemsSourceAttribute.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/Attributes/NewItemTypesAttribute.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/Attributes/PropertyOrderAttribute.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/CategoryGroupStyleSelector.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/Commands/PropertyGridCommands.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/Commands/PropertyItemCommands.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/CommonPropertyExceptionValidationRule.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/ContainerHelperBase.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/Converters/EditorTimeSpanConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/Converters/ExpandableObjectMarginConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/Converters/IsDefaultCategoryConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/Converters/IsStringEmptyConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/Converters/ListConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/Converters/ObjectToUIElementConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/Converters/PropertyItemEditorConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/Converters/SelectedObjectConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/CustomPropertyItem.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/Definitions/DefinitionBase.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/Definitions/EditorDefinitionBase.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/Definitions/EditorTemplateDefinition.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/Definitions/PropertyDefinitionBase.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/DescriptorPropertyDefinition.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/DescriptorPropertyDefinitionBase.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/EditorDefinition.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/Editors/CheckBoxEditor.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/Editors/CollectionEditor.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/Editors/ColorEditor.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/Editors/ComboBoxEditor.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/Editors/EnumComboBoxEditor.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/Editors/FontComboBoxEditor.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/Editors/ITypeEditor.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/Editors/ItemsSourceAttributeEditor.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/Editors/MaskedTextBoxEditor.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/Editors/PrimitiveTypeCollectionEditor.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/Editors/SourceComboBoxEditor.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/Editors/TextBlockEditor.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/Editors/TextBoxEditor.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/Editors/TypeEditor.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/Editors/UpDownEditors.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/FilterInfo.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/IPropertyContainer.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/ObjectContainerHelper.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/ObjectContainerHelperBase.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/PropertyDefinition.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/PropertyDefinitionBaseCollection.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/PropertyGrid.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/PropertyGrid.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/PropertyGridUtilities.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/PropertyItem.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/PropertyItemBase.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/PropertyItemCollection.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/PropertyItemsControl.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/StringConstants.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/TargetPropertyType.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/TrimmedTextBlock.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Themes/Aero2.NormalColor.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/PropertyGrid/Themes/Generic.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/RangeSlider/Implementation/Converters/SliderThumbWidthConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/RangeSlider/Implementation/RangeSlider.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/RangeSlider/Implementation/RangeSlider.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/RangeSlider/Themes/Aero2.NormalColor.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/RangeSlider/Themes/Generic.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/RichTextBox/Formatters/ITextFormatter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/RichTextBox/Formatters/PlainTextFormatter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/RichTextBox/Formatters/RtfFormatter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/RichTextBox/Formatters/XamlFormatter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/RichTextBox/RichTextBox.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/RichTextBox/RichTextBox.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/RichTextBoxFormatBar/IRichTextBoxFormatBar.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/RichTextBoxFormatBar/Images/Bold16.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/RichTextBoxFormatBar/Images/Bullets16.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/RichTextBoxFormatBar/Images/CenterAlign16.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/RichTextBoxFormatBar/Images/FontColorPicker16.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/RichTextBoxFormatBar/Images/Italic16.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/RichTextBoxFormatBar/Images/JustifyAlign16.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/RichTextBoxFormatBar/Images/LeftAlign16.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/RichTextBoxFormatBar/Images/Numbering16.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/RichTextBoxFormatBar/Images/RightAlign16.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/RichTextBoxFormatBar/Images/TextHighlightColorPicker16.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/RichTextBoxFormatBar/Images/Underline16.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/RichTextBoxFormatBar/RichTextBoxFormatBar.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/RichTextBoxFormatBar/RichTextBoxFormatBar.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/RichTextBoxFormatBar/RichTextBoxFormatBarManager.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/RichTextBoxFormatBar/Themes/Aero2.NormalColor.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/RichTextBoxFormatBar/Themes/Generic.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/SplitButton/Implementation/SplitButton.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/SplitButton/Implementation/SplitButton.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/SplitButton/Themes/Aero2.NormalColor.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/SplitButton/Themes/Generic.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/StyleableWindow/Implementation/Converters/StyleableWindowClippingBorderConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/StyleableWindow/Implementation/StyleableWindow.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Aero.NormalColor.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Aero/Brushes_NormalColor.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Aero/Buttons_NormalColor.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Aero2.NormalColor.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Aero2/Brushes.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Aero2/Buttons.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Aero2/Common.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Aero2/Glyphs.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Generic.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Generic/Brushes.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Generic/Buttons.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Generic/Common.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Generic/Glyphs.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Generic/Images/close_hover.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Generic/Images/close_inactive.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Generic/Images/close_normal.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Generic/Images/close_pressed.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Generic/Images/close_rounded_hover.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Generic/Images/close_rounded_inactive.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Generic/Images/close_rounded_normal.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Generic/Images/close_rounded_pressed.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Generic/Images/close_toolwindow_hover.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Generic/Images/close_toolwindow_inactive.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Generic/Images/close_toolwindow_normal.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Generic/Images/close_toolwindow_pressed.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Generic/Images/maximize_disabled.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Generic/Images/maximize_hover.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Generic/Images/maximize_inactive.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Generic/Images/maximize_normal.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Generic/Images/maximize_pressed.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Generic/Images/minimize_hover.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Generic/Images/minimize_inactive.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Generic/Images/minimize_normal.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Generic/Images/minimize_pressed.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Generic/Images/resize_grip.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Generic/Images/restore_disabled.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Generic/Images/restore_hover.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Generic/Images/restore_inactive.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Generic/Images/restore_normal.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/Generic/Images/restore_pressed.png create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/classic.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/luna.homestead.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/luna.metallic.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/luna.normalcolor.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Themes/royale.normalcolor.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/TimePicker/Implementation/TimeItem.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/TimePicker/Implementation/TimePicker.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/TimePicker/Implementation/TimePicker.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/TimePicker/Themes/Aero2.NormalColor.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/TimePicker/Themes/Generic.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/TimeSpanUpDown/Implementation/TimeSpanUpDown.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/TimeSpanUpDown/Implementation/TimeSpanUpDown.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/TimeSpanUpDown/Themes/Aero2.NormalColor.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/TimeSpanUpDown/Themes/Generic.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/TimelinePanel/Implementation/DateElement.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/TimelinePanel/Implementation/OverlapBehavior.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/TimelinePanel/Implementation/TimelinePanel.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/TimelinePanel/Implementation/TimelinePanel.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/VisualStates.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/WatermarkComboBox/Implementation/WatermarkComboBox.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/WatermarkComboBox/Implementation/WatermarkComboBox.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/WatermarkComboBox/Themes/Aero2.NormalColor.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/WatermarkComboBox/Themes/Generic.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/WatermarkPasswordBox/Implementation/WatermarkPasswordBox.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/WatermarkPasswordBox/Implementation/WatermarkPasswordBox.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/WatermarkTextBox/Implementation/WatermarkTextBox.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/WatermarkTextBox/Implementation/WatermarkTextBox.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/WatermarkTextBox/Themes/Aero2.NormalColor.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/WatermarkTextBox/Themes/Generic.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Wizard/Implementation/Wizard.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Wizard/Implementation/Wizard.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Wizard/Implementation/WizardCommands.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Wizard/Implementation/WizardPage.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Wizard/Implementation/WizardPageButtonVisibility.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Wizard/Implementation/WizardPageType.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Wizard/Themes/Aero2.NormalColor.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Wizard/Themes/Generic.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Xceed.Wpf.Toolkit.csproj create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Xceed.Wpf.Toolkit.csproj.old create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Zoombox/Resources/Zoom.cur create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Zoombox/Resources/ZoomRelative.cur create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Zoombox/Themes/Aero2.NormalColor.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Zoombox/Themes/Generic.xaml create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Zoombox/Zoombox.Icon.bmp create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Zoombox/Zoombox.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Zoombox/ZoomboxCursors.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Zoombox/ZoomboxView.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Zoombox/ZoomboxViewChangedEventArgs.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Zoombox/ZoomboxViewChangedEventHandler.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Zoombox/ZoomboxViewConverter.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Zoombox/ZoomboxViewException.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Zoombox/ZoomboxViewFinderDisplay.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Zoombox/ZoomboxViewKind.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Zoombox/ZoomboxViewStack.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Zoombox/ZoomboxViewStackMode.cs create mode 100644 third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Zoombox/ZoomboxZoomOn.cs diff --git a/copy.bara.sky b/copy.bara.sky index 7ed5ec61..1bb053c6 100644 --- a/copy.bara.sky +++ b/copy.bara.sky @@ -159,6 +159,45 @@ core.workflow( # TODO(zhangshuai.ustc): Add https://github.com/fallin/Itc4net/tree/master/src/Itc4net # and then fix Clocks.IntervalTreeClocks +# TODO(zhangshuai.ustc): WIP https://github.com/xceedsoftware/wpftoolkit +core.workflow( + name = "com_github_xceedsoftware_wpftoolkit", + origin = git.github_origin( + url = "https://github.com/xceedsoftware/wpftoolkit", + ref = "1e0b826e1fca8cdb2bb4640194c906ac23e53c2b", # 3.7.0@2019-11-26 + ), + destination = DESTINATION, + origin_files = glob( + [ + ".gitignore", + "README.md", + "license.md", + "ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/**", + ] + ), + destination_files = glob( + [ + "third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/**", + "third_party/ExtendedWPFToolkit/.gitignore", + "third_party/ExtendedWPFToolkit/README.md", + "third_party/ExtendedWPFToolkit/LICENSE.md", + ], + exclude = [ + "**/*.csproj", + ], + ), + authoring = authoring.pass_thru("Shuai Zhang "), + transformations = [ + core.move(".gitignore", "third_party/ExtendedWPFToolkit/.gitignore"), + core.move("README.md", "third_party/ExtendedWPFToolkit/README.md"), + core.move("license", "third_party/ExtendedWPFToolkit/LICENSE.md"), + core.move( + "ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/", + "third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/" + ), + ], +) + # third_party/CRC32.NET/native folder is from https://cdn.machinezoo.com/download/crc32c/crc32c-hw-1.0.5.7z core.workflow( name = "com_github_zeldafreak_crc32c_net", diff --git a/third_party/ExtendedWPFToolkit/.gitignore b/third_party/ExtendedWPFToolkit/.gitignore new file mode 100644 index 00000000..89c66054 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/.gitignore @@ -0,0 +1,295 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ +**/Properties/launchSettings.json + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Typescript v1 declaration files +typings/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush +.cr/ + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs diff --git a/third_party/ExtendedWPFToolkit/LICENSE.md b/third_party/ExtendedWPFToolkit/LICENSE.md new file mode 100644 index 00000000..d834f77f --- /dev/null +++ b/third_party/ExtendedWPFToolkit/LICENSE.md @@ -0,0 +1,31 @@ +# Microsoft Public License (Ms-PL) + +This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software. + +## 1. Definitions + +The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. + +A "contribution" is the original software, or any additions or changes to the software. + +A "contributor" is any person that distributes its contribution under this license. + +"Licensed patents" are a contributor's patent claims that read directly on its contribution. + +## 2. Grant of Rights + +(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. + +(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. + +## 3. Conditions and Limitations + +(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks. + +(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically. + +(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. + +(D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. + +(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement. diff --git a/third_party/ExtendedWPFToolkit/README.md b/third_party/ExtendedWPFToolkit/README.md new file mode 100644 index 00000000..d8dbf4d3 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/README.md @@ -0,0 +1,199 @@ +# Extended WPF Toolkit™ + +Extended WPF Toolkit™ by [Xceed](https://xceed.com) is the number one collection of WPF controls, components and utilities for creating next generation Windows applications. Use it to build professional looking, modern, and easy to use WPF applications. It has been downloaded more than 1 million times here, on Codeplex, and on [NuGet](http://www.nuget.org/packages/Extended.Wpf.Toolkit/). + +This free and open source toolkit is provided under the [Microsoft Public License](https://opensource.org/licenses/MS-PL). A summary can be found on [tl;drLegal](https://tldrlegal.com/license/microsoft-public-license-(ms-pl)). + +Learn about Xceed Toolkit Plus for WPF here on GithubXceed offers the [Plus Edition](../../wiki/Xceed-Toolkit-Plus-for-WPF) for developers that want to support the project, get additional controls and features, get updates and professional support, and work with a version a few releases ahead. + +## Latest news + +**September 27, 2019** v3.6.0 released with [36 bug fixes and improvements](../../wiki/Improvements-in-v3.6.0). + +**February 7, 2019** v3.5.0 released with [26 bug fixes and improvements](../../wiki/Improvements-in-v3.5.0). + +*January 30, 2019* v3.8.0 of the [Plus Edition](../../wiki/Xceed-Toolkit-Plus-for-WPF) released with [45 bug fixes and improvements](../../wiki/Improvements-in-v3.5.0#Plus380) + +*June 18, 2018* v3.7.0 of the [Plus Edition](../../wiki/Xceed-Toolkit-Plus-for-WPF) released with [27 bug fixes and improvements](../../wiki/Improvements-in-v3.5.0#Plus370) + +*January 15, 2018* v3.6.0 of the [Plus Edition](../../wiki/Xceed-Toolkit-Plus-for-WPF) released with [1 new control and 40 bug fixes and improvements](../../wiki/Improvements-in-v3.5.0#Plus360) + +**July 11, 2017:** The project's new home is Github. All issues from Codeplex are now located here. + + + +## Controls included + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AvalonDockAutoSelectTextBoxBusyIndicatorCalculator
CalculatorUpDownCheckComboBoxCheckListBoxChildWindow
CollectionControlButtonSpinnerByteUpDownCollectionControlDialog
ColorCanvasColorPickerDateTimePickerDateTimeUpDown
DecimalUpDownDoubleUpDownDropDownButtonIconButton
IntegerUpDownLongUpDownMagnifierMaskedTextBox
MessageBoxMultiLineTextEditorPieChartPrimitiveTypeCollEditor
PropertyGridRangeSliderRichTextBoxRichTextBoxFormatBar
ShortUpDownSingleUpDownSplitButton2 SwitchPanels
TimelinePanelTimePickerTimeSpanUpDownValueRangeTextBox
WatermarkPasswordBoxWatermarkTextBoxWatermarkComboBoxWindowContainer
WindowControlWizardZoomboxWindows 8 Theme
+ +## Additional controls and features in the Plus Edition + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ChartsChildWindow PlusExtendedTabControlDataGrid
FilePicker21 Material Design controlsMessageBox PlusMultiCalendar
MultiColumnComboBoxPileFlowPanelPropertyGrid PlusRadialGauge
RatingSlideShowStyleableWindow12 new SwitchPanels
ToggleSwitchTokenizedTextBoxUltimate ListBoxWindowControl Plus
Windows 10 theme2 Metro themes3 Office themes2+ releases ahead
+ +## Additional controls and features in the Business Suite for WPF + + + + + + + + + +
Advanced DataGrid10 new DataGrid editors3D Views for WPFMore themesAll base WPF controls themed
+ +## Release history + +* **September 27, 2019 v3.6.0 released with [36 bug fixes and improvements](../../wiki/Improvements-in-v3.6.0).** +* **February 7, 2019 v3.5.0 released with [26 bug fixes and improvements](../../wiki/Improvements-in-v3.5.0).** +* January 30, 2019, released v3.8.0 of the [Plus Edition](../../wiki/Xceed-Toolkit-Plus-for-WPF) released with [45 bug fixes and improvements](../../wiki/Improvements-in-v3.5.0#Plus380). +* **June 27, 2018 v3.4.0 released with [42 bug fixes and improvements](../../wiki/Improvements-in-v3.4.0).** +* June 18, 2018, released v3.7.0 of the [Plus Edition](../../wiki/Xceed-Toolkit-Plus-for-WPF) released with [27 bug fixes and improvements](../../wiki/Improvements-in-v3.3.0#Plus370). +* **March 5, 2018, released v3.3.0 with [a major update to the DataGrid and 35 bug fixes and improvements](../../wiki/Improvements-in-v3.3.0).** +* Jan. 15, 2018, released v3.6.0 of the [Plus Edition](../../wiki/Xceed-Toolkit-Plus-for-WPF) released with [1 new control and 40 bug fixes and improvements](../../wiki/Improvements-in-v3.2.0#Plus360). +* **September 25, 2017, released v3.2.0 with [1 new control and 24 bug fixes and improvements](../../wiki/Improvements-in-v3.2.0).** +* September 12, 2017, released [Plus Edition](../../wiki/Xceed-Toolkit-Plus-for-WPF) v3.5.0 with [29 bug fixes and improvements](../../wiki/Improvements-in-v3.2.0#Plus350). +* **July 11, 2017, released v3.1.0 with [37 bug fixes and improvements](../../wiki/Improvements-in-v3.1.0).** +* **July 11, 2017, project moved to Github from Codeplex.** Over 440K downloads on Codeplex. 800K on NuGet. +* June 5, 2017, released [Plus Edition](../../wiki/Xceed-Toolkit-Plus-for-WPF) v3.4.0 with [52 bug fixes and improvements](../../wiki/Improvements-in-v3.1.0#Plus340). +* March 1, 2017, released [Plus Edition](../../wiki/Xceed-Toolkit-Plus-for-WPF) v3.3.0 with [45 bug fixes and improvements](../../wiki/Improvements-in-v3.1.0#Plus330). +* **Dec. 13, 2016, released v3.0.0 with [1 new control and 28 bug fixes and improvements](../../wiki/Improvements-in-v3.0.0).** +* Nov. 21, 2016, released [Plus Edition](../../wiki/Xceed-Toolkit-Plus-for-WPF) v3.2.0 with [2 new controls and 44 bug fixes and improvements](../../wiki/Improvements-in-v3.0.0#Plus320). +* July 13, 2016, released [Plus Edition](../../wiki/Xceed-Toolkit-Plus-for-WPF) v3.1.0 with [Windows 10 theme and 56 bug fixes and improvements](../../wiki/Improvements-in-v2.9.0#Plus310). +* **June 14, 2016, released v2.9.0 with [32 bug fixes and improvements](../../wiki/Improvements-in-v2.9.0).** +* **May 6, 2016, released v2.8.0 with [23 bug fixes and improvements](../../wiki/Improvements-in-v2.8.0).** +* **April 6, 2016, released v2.7.0 with [31 bug fixes and improvements](../../wiki/Improvements-in-v2.7.0).** +* April 5, 2016, released [Plus Edition](../../wiki/Xceed-Toolkit-Plus-for-WPF) v3.0.0 with [2 new controls and 41 bug fixes and improvements](../../wiki/Improvements-in-v2.7.0#Plus300). +* Feb. 10, 2016, released [Plus Edition](../../wiki/Xceed-Toolkit-Plus-for-WPF) v2.9.0 with [44 bug fixes and improvements](../../wiki/Improvements-in-v2.7.0#Plus290). +* **Jan. 8, 2016, released v2.6.0 with [15 bug fixes and improvements](../../wiki/Improvements-in-v2.6.0).** +* Sept. 14, 2015, released [Plus Edition](../../wiki/Xceed-Toolkit-Plus-for-WPF) v2.8.0 with [15 new controls and 41 bug fixes and improvements](../../wiki/Improvements-in-v2.6.0#Plus280). +* **July 3, 2015, released v2.5.0 with [1 new control and 45 bug fixes and improvements](../../wiki/Improvements-in-v2.5.0#Community250).** +* **Feb. 13, 2015, released v2.4.0 with [37 bug fixes and improvements](../../wiki/Improvements-in-v2.4.0#Community240).** +* **Oct. 7, 2014, released v2.3.0 with [25 bug fixes and improvements](../../wiki/Improvements-in-v2.3.0#Community230).** +* Sept. 29, 2014, released [Plus Edition](../../wiki/Xceed-Toolkit-Plus-for-WPF) v2.4.0 with [1 new control and 42 bug fixes and improvements](../../wiki/Improvements-in-v2.3.0#Plus240). +* **June 17, 2014, released v2.2.1 with [5 bug fixes](../../wiki/Improvements-in-v2.2.0#Community221).** +* June 17, 2014, released [Plus Edition](../../wiki/Xceed-Toolkit-Plus-for-WPF) v2.3.1 with [6 bug fixes](../../wiki/Improvements-in-v2.2.0#Plus231). +* **June 2, 2014, released v2.2.0, with [2 new controls and 15 bug fixes and improvements](../../wiki/Improvements-in-v2.2.0#Community220).** +* May 12, 2014, released [Plus Edition](../../wiki/Xceed-Toolkit-Plus-for-WPF) v2.3.0 with [1 new control and 30 bug fixes and improvements](../../wiki/Improvements-in-v2.2.0#Plus230). +* **Feb 20, 2014, released v2.1.0 with [70 bug fixes and improvements](../../wiki/Improvements-in-v2.1.0#Community210).** +* Feb. 12, 2014, released [Plus Edition](../../wiki/Xceed-Toolkit-Plus-for-WPF) v2.2.0 with [4 new controls and 18 bug fixes and improvements](../../wiki/Improvements-in-v2.2.0#Plus220). + +## Action items + +* Enjoy WPF! +* Buy [Xceed Toolkit Plus for WPF](https://xceed.com/xceed-toolkit-plus-for-wpf/) +* Follow [@xceed](http://twitter.com/xceed) on Twitter for WPF and Toolkit news +* Add bugs or feature requests with the Issues tab +
+
+ diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/AssemblyVersionInfo.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/AssemblyVersionInfo.cs new file mode 100644 index 00000000..ceee86a4 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/AssemblyVersionInfo.cs @@ -0,0 +1,28 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +internal static class _XceedVersionInfo +{ + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] + public const string BaseVersion = "3.7"; + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] + public const string Version = BaseVersion + + ".0.0"; + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] + public const string PublicKeyToken = "ba83ff368b7563c6"; + + +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/AssemblyVersionInfoCommon.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/AssemblyVersionInfoCommon.cs new file mode 100644 index 00000000..9fc4c1a2 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/AssemblyVersionInfoCommon.cs @@ -0,0 +1,22 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +internal static class _XceedVersionInfoCommon +{ + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] + public const string Build = ".*"; + +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/AutoSelectTextBox/Implementation/AutoSelectBehaviorEnum.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/AutoSelectTextBox/Implementation/AutoSelectBehaviorEnum.cs new file mode 100644 index 00000000..75def91f --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/AutoSelectTextBox/Implementation/AutoSelectBehaviorEnum.cs @@ -0,0 +1,28 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Xceed.Wpf.Toolkit +{ + public enum AutoSelectBehavior + { + Never, + OnFocus + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/AutoSelectTextBox/Implementation/AutoSelectTextBox.Icon.bmp b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/AutoSelectTextBox/Implementation/AutoSelectTextBox.Icon.bmp new file mode 100644 index 00000000..ce76dc5b --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/AutoSelectTextBox/Implementation/AutoSelectTextBox.Icon.bmp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e95d8b086aa0680fa4b987fc38d9701b23c24b9d6334806e6d5a7fa0b3687373 +size 822 diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/AutoSelectTextBox/Implementation/AutoSelectTextBox.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/AutoSelectTextBox/Implementation/AutoSelectTextBox.cs new file mode 100644 index 00000000..fc609589 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/AutoSelectTextBox/Implementation/AutoSelectTextBox.cs @@ -0,0 +1,299 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System.Windows.Controls; +using System.Windows.Input; +using System.Windows; +using Xceed.Wpf.Toolkit.Core.Utilities; + +namespace Xceed.Wpf.Toolkit +{ + public class AutoSelectTextBox : TextBox + { + public AutoSelectTextBox() + { + } + + #region AutoSelectBehavior PROPERTY + + public AutoSelectBehavior AutoSelectBehavior + { + get + { + return (AutoSelectBehavior)GetValue(AutoSelectBehaviorProperty); + } + set + { + SetValue(AutoSelectBehaviorProperty, value); + } + } + + public static readonly DependencyProperty AutoSelectBehaviorProperty = + DependencyProperty.Register("AutoSelectBehavior", typeof(AutoSelectBehavior), typeof(AutoSelectTextBox), + new UIPropertyMetadata(AutoSelectBehavior.Never)); + + #endregion AutoSelectBehavior PROPERTY + + #region AutoMoveFocus PROPERTY + + public bool AutoMoveFocus + { + get + { + return (bool)GetValue(AutoMoveFocusProperty); + } + set + { + SetValue(AutoMoveFocusProperty, value); + } + } + + public static readonly DependencyProperty AutoMoveFocusProperty = + DependencyProperty.Register("AutoMoveFocus", typeof(bool), typeof(AutoSelectTextBox), new UIPropertyMetadata(false)); + + #endregion AutoMoveFocus PROPERTY + + #region QueryMoveFocus EVENT + + public static readonly RoutedEvent QueryMoveFocusEvent = EventManager.RegisterRoutedEvent("QueryMoveFocus", + RoutingStrategy.Bubble, + typeof(QueryMoveFocusEventHandler), + typeof(AutoSelectTextBox)); + #endregion QueryMoveFocus EVENT + + protected override void OnPreviewKeyDown(KeyEventArgs e) + { + if (!this.AutoMoveFocus) + { + base.OnPreviewKeyDown(e); + return; + } + + if ((e.Key == Key.Left) + && ((Keyboard.Modifiers == ModifierKeys.None) + || (Keyboard.Modifiers == ModifierKeys.Control))) + { + e.Handled = this.MoveFocusLeft(); + } + + if ((e.Key == Key.Right) + && ((Keyboard.Modifiers == ModifierKeys.None) + || (Keyboard.Modifiers == ModifierKeys.Control))) + { + e.Handled = this.MoveFocusRight(); + } + + if (((e.Key == Key.Up) || (e.Key == Key.PageUp)) + && ((Keyboard.Modifiers == ModifierKeys.None) + || (Keyboard.Modifiers == ModifierKeys.Control))) + { + e.Handled = this.MoveFocusUp(); + } + + if (((e.Key == Key.Down) || (e.Key == Key.PageDown)) + && ((Keyboard.Modifiers == ModifierKeys.None) + || (Keyboard.Modifiers == ModifierKeys.Control))) + { + e.Handled = this.MoveFocusDown(); + } + + base.OnPreviewKeyDown(e); + } + + protected override void OnPreviewGotKeyboardFocus(KeyboardFocusChangedEventArgs e) + { + base.OnPreviewGotKeyboardFocus(e); + + if (this.AutoSelectBehavior == AutoSelectBehavior.OnFocus) + { + // If the focus was not in one of our child ( or popup ), we select all the text. + if (!TreeHelper.IsDescendantOf(e.OldFocus as DependencyObject, this)) + { + this.SelectAll(); + } + } + } + + protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e) + { + base.OnPreviewMouseLeftButtonDown(e); + + if (this.AutoSelectBehavior == AutoSelectBehavior.Never) + return; + + if (this.IsKeyboardFocusWithin == false) + { + this.Focus(); + e.Handled = true; //prevent from removing the selection + } + } + + protected override void OnTextChanged(TextChangedEventArgs e) + { + base.OnTextChanged(e); + + if (!this.AutoMoveFocus) + return; + + if ((this.Text.Length != 0) + && (this.Text.Length == this.MaxLength) + && (this.CaretIndex == this.MaxLength)) + { + if (this.CanMoveFocus(FocusNavigationDirection.Right, true) == true) + { + FocusNavigationDirection direction = (this.FlowDirection == FlowDirection.LeftToRight) + ? FocusNavigationDirection.Right + : FocusNavigationDirection.Left; + + this.MoveFocus(new TraversalRequest(direction)); + } + } + } + + + private bool CanMoveFocus(FocusNavigationDirection direction, bool reachedMax) + { + QueryMoveFocusEventArgs e = new QueryMoveFocusEventArgs(direction, reachedMax); + this.RaiseEvent(e); + return e.CanMoveFocus; + } + + private bool MoveFocusLeft() + { + if (this.FlowDirection == FlowDirection.LeftToRight) + { + //occurs only if the cursor is at the beginning of the text + if ((this.CaretIndex == 0) && (this.SelectionLength == 0)) + { + if (ComponentCommands.MoveFocusBack.CanExecute(null, this)) + { + ComponentCommands.MoveFocusBack.Execute(null, this); + return true; + } + else if (this.CanMoveFocus(FocusNavigationDirection.Left, false)) + { + this.MoveFocus(new TraversalRequest(FocusNavigationDirection.Left)); + return true; + } + } + } + else + { + //occurs only if the cursor is at the end of the text + if ((this.CaretIndex == this.Text.Length) && (this.SelectionLength == 0)) + { + if (ComponentCommands.MoveFocusBack.CanExecute(null, this)) + { + ComponentCommands.MoveFocusBack.Execute(null, this); + return true; + } + else if (this.CanMoveFocus(FocusNavigationDirection.Left, false)) + { + this.MoveFocus(new TraversalRequest(FocusNavigationDirection.Left)); + return true; + } + } + } + + return false; + } + + private bool MoveFocusRight() + { + if (this.FlowDirection == FlowDirection.LeftToRight) + { + //occurs only if the cursor is at the beginning of the text + if ((this.CaretIndex == this.Text.Length) && (this.SelectionLength == 0)) + { + if (ComponentCommands.MoveFocusForward.CanExecute(null, this)) + { + ComponentCommands.MoveFocusForward.Execute(null, this); + return true; + } + else if (this.CanMoveFocus(FocusNavigationDirection.Right, false)) + { + this.MoveFocus(new TraversalRequest(FocusNavigationDirection.Right)); + return true; + } + } + } + else + { + //occurs only if the cursor is at the end of the text + if ((this.CaretIndex == 0) && (this.SelectionLength == 0)) + { + if (ComponentCommands.MoveFocusForward.CanExecute(null, this)) + { + ComponentCommands.MoveFocusForward.Execute(null, this); + return true; + } + else if (this.CanMoveFocus(FocusNavigationDirection.Right, false)) + { + this.MoveFocus(new TraversalRequest(FocusNavigationDirection.Right)); + return true; + } + } + } + + return false; + } + + private bool MoveFocusUp() + { + int lineNumber = this.GetLineIndexFromCharacterIndex(this.SelectionStart); + + //occurs only if the cursor is on the first line + if (lineNumber == 0) + { + if (ComponentCommands.MoveFocusUp.CanExecute(null, this)) + { + ComponentCommands.MoveFocusUp.Execute(null, this); + return true; + } + else if (this.CanMoveFocus(FocusNavigationDirection.Up, false)) + { + this.MoveFocus(new TraversalRequest(FocusNavigationDirection.Up)); + return true; + } + } + + return false; + } + + private bool MoveFocusDown() + { + int lineNumber = this.GetLineIndexFromCharacterIndex(this.SelectionStart); + + //occurs only if the cursor is on the first line + if (lineNumber == (this.LineCount - 1)) + { + if (ComponentCommands.MoveFocusDown.CanExecute(null, this)) + { + ComponentCommands.MoveFocusDown.Execute(null, this); + return true; + } + else if (this.CanMoveFocus(FocusNavigationDirection.Down, false)) + { + this.MoveFocus(new TraversalRequest(FocusNavigationDirection.Down)); + return true; + } + } + + return false; + } + } +} + diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/AutoSelectTextBox/Implementation/QueryMoveFocusEventArgs.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/AutoSelectTextBox/Implementation/QueryMoveFocusEventArgs.cs new file mode 100644 index 00000000..a478be6e --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/AutoSelectTextBox/Implementation/QueryMoveFocusEventArgs.cs @@ -0,0 +1,73 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System.Windows; +using System.Windows.Input; + +namespace Xceed.Wpf.Toolkit +{ + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1003:UseGenericEventHandlerInstances")] + public delegate void QueryMoveFocusEventHandler(object sender, QueryMoveFocusEventArgs e); + + public class QueryMoveFocusEventArgs : RoutedEventArgs + { + //default CTOR private to prevent its usage. + private QueryMoveFocusEventArgs() + { + } + + //internal to prevent anybody from building this type of event. + internal QueryMoveFocusEventArgs(FocusNavigationDirection direction, bool reachedMaxLength) + : base(AutoSelectTextBox.QueryMoveFocusEvent) + { + m_navigationDirection = direction; + m_reachedMaxLength = reachedMaxLength; + } + + public FocusNavigationDirection FocusNavigationDirection + { + get + { + return m_navigationDirection; + } + } + + public bool ReachedMaxLength + { + get + { + return m_reachedMaxLength; + } + } + + public bool CanMoveFocus + { + get + { + return m_canMove; + } + set + { + m_canMove = value; + } + } + + private FocusNavigationDirection m_navigationDirection; + private bool m_reachedMaxLength; + private bool m_canMove = true; //defaults to true... if nobody does nothing, then its capable of moving focus. + + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/BusyIndicator/Implementation/BusyIndicator.Icon.bmp b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/BusyIndicator/Implementation/BusyIndicator.Icon.bmp new file mode 100644 index 00000000..ce76dc5b --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/BusyIndicator/Implementation/BusyIndicator.Icon.bmp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e95d8b086aa0680fa4b987fc38d9701b23c24b9d6334806e6d5a7fa0b3687373 +size 822 diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/BusyIndicator/Implementation/BusyIndicator.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/BusyIndicator/Implementation/BusyIndicator.cs new file mode 100644 index 00000000..6966e717 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/BusyIndicator/Implementation/BusyIndicator.cs @@ -0,0 +1,360 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Shapes; +using System.Windows.Threading; + +namespace Xceed.Wpf.Toolkit +{ + /// + /// A control to provide a visual indicator when an application is busy. + /// + [TemplateVisualState(Name = VisualStates.StateIdle, GroupName = VisualStates.GroupBusyStatus)] + [TemplateVisualState(Name = VisualStates.StateBusy, GroupName = VisualStates.GroupBusyStatus)] + [TemplateVisualState(Name = VisualStates.StateVisible, GroupName = VisualStates.GroupVisibility)] + [TemplateVisualState(Name = VisualStates.StateHidden, GroupName = VisualStates.GroupVisibility)] + [StyleTypedProperty(Property = "OverlayStyle", StyleTargetType = typeof(Rectangle))] + [StyleTypedProperty(Property = "ProgressBarStyle", StyleTargetType = typeof(ProgressBar))] + public class BusyIndicator : ContentControl + { + #region Private Members + + /// + /// Timer used to delay the initial display and avoid flickering. + /// + private DispatcherTimer _displayAfterTimer = new DispatcherTimer(); + + #endregion //Private Members + + #region Constructors + + static BusyIndicator() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(BusyIndicator), new FrameworkPropertyMetadata(typeof(BusyIndicator))); + } + + public BusyIndicator() + { + _displayAfterTimer.Tick += DisplayAfterTimerElapsed; + } + + #endregion //Constructors + + #region Base Class Overrides + + /// + /// Overrides the OnApplyTemplate method. + /// + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + ChangeVisualState(false); + } + + + #endregion //Base Class Overrides + + #region Properties + + /// + /// Gets or sets a value indicating whether the BusyContent is visible. + /// + protected bool IsContentVisible + { + get; + set; + } + + #endregion //Properties + + #region Dependency Properties + + #region IsBusy + + /// + /// Identifies the IsBusy dependency property. + /// + public static readonly DependencyProperty IsBusyProperty = DependencyProperty.Register( + "IsBusy", + typeof(bool), + typeof(BusyIndicator), + new PropertyMetadata(false, new PropertyChangedCallback(OnIsBusyChanged))); + + /// + /// Gets or sets a value indicating whether the busy indicator should show. + /// + public bool IsBusy + { + get + { + return (bool)GetValue(IsBusyProperty); + } + set + { + SetValue(IsBusyProperty, value); + } + } + + /// + /// IsBusyProperty property changed handler. + /// + /// BusyIndicator that changed its IsBusy. + /// Event arguments. + private static void OnIsBusyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ((BusyIndicator)d).OnIsBusyChanged(e); + } + + /// + /// IsBusyProperty property changed handler. + /// + /// Event arguments. + protected virtual void OnIsBusyChanged(DependencyPropertyChangedEventArgs e) + { + if (IsBusy) + { + if (DisplayAfter.Equals(TimeSpan.Zero)) + { + // Go visible now + IsContentVisible = true; + } + else + { + // Set a timer to go visible + _displayAfterTimer.Interval = DisplayAfter; + _displayAfterTimer.Start(); + } + } + else + { + // No longer visible + _displayAfterTimer.Stop(); + IsContentVisible = false; + + if (this.FocusAfterBusy != null) + { + this.FocusAfterBusy.Dispatcher.BeginInvoke(DispatcherPriority.Input, new Action(() => + { + this.FocusAfterBusy.Focus(); + } + )); + } + } + + ChangeVisualState(true); + } + + #endregion //IsBusy + + #region Busy Content + + /// + /// Identifies the BusyContent dependency property. + /// + public static readonly DependencyProperty BusyContentProperty = DependencyProperty.Register( + "BusyContent", + typeof(object), + typeof(BusyIndicator), + new PropertyMetadata(null)); + + /// + /// Gets or sets a value indicating the busy content to display to the user. + /// + public object BusyContent + { + get + { + return (object)GetValue(BusyContentProperty); + } + set + { + SetValue(BusyContentProperty, value); + } + } + + #endregion //Busy Content + + #region Busy Content Template + + /// + /// Identifies the BusyTemplate dependency property. + /// + public static readonly DependencyProperty BusyContentTemplateProperty = DependencyProperty.Register( + "BusyContentTemplate", + typeof(DataTemplate), + typeof(BusyIndicator), + new PropertyMetadata(null)); + + /// + /// Gets or sets a value indicating the template to use for displaying the busy content to the user. + /// + public DataTemplate BusyContentTemplate + { + get + { + return (DataTemplate)GetValue(BusyContentTemplateProperty); + } + set + { + SetValue(BusyContentTemplateProperty, value); + } + } + + #endregion //Busy Content Template + + #region Display After + + /// + /// Identifies the DisplayAfter dependency property. + /// + public static readonly DependencyProperty DisplayAfterProperty = DependencyProperty.Register( + "DisplayAfter", + typeof(TimeSpan), + typeof(BusyIndicator), + new PropertyMetadata(TimeSpan.FromSeconds(0.1))); + + /// + /// Gets or sets a value indicating how long to delay before displaying the busy content. + /// + public TimeSpan DisplayAfter + { + get + { + return (TimeSpan)GetValue(DisplayAfterProperty); + } + set + { + SetValue(DisplayAfterProperty, value); + } + } + + #endregion //Display After + + #region FocusAfterBusy + + /// + /// Identifies the FocusAfterBusy dependency property. + /// + public static readonly DependencyProperty FocusAfterBusyProperty = DependencyProperty.Register( + "FocusAfterBusy", + typeof(Control), + typeof(BusyIndicator), + new PropertyMetadata(null)); + + /// + /// Gets or sets a Control that should get the focus when the busy indicator disapears. + /// + public Control FocusAfterBusy + { + get + { + return (Control)GetValue(FocusAfterBusyProperty); + } + set + { + SetValue(FocusAfterBusyProperty, value); + } + } + + #endregion //FocusAfterBusy + + #region Overlay Style + + /// + /// Identifies the OverlayStyle dependency property. + /// + public static readonly DependencyProperty OverlayStyleProperty = DependencyProperty.Register( + "OverlayStyle", + typeof(Style), + typeof(BusyIndicator), + new PropertyMetadata(null)); + + /// + /// Gets or sets a value indicating the style to use for the overlay. + /// + public Style OverlayStyle + { + get + { + return (Style)GetValue(OverlayStyleProperty); + } + set + { + SetValue(OverlayStyleProperty, value); + } + } + #endregion //Overlay Style + + #region ProgressBar Style + + /// + /// Identifies the ProgressBarStyle dependency property. + /// + public static readonly DependencyProperty ProgressBarStyleProperty = DependencyProperty.Register( + "ProgressBarStyle", + typeof(Style), + typeof(BusyIndicator), + new PropertyMetadata(null)); + + /// + /// Gets or sets a value indicating the style to use for the progress bar. + /// + public Style ProgressBarStyle + { + get + { + return (Style)GetValue(ProgressBarStyleProperty); + } + set + { + SetValue(ProgressBarStyleProperty, value); + } + } + + #endregion //ProgressBar Style + + #endregion //Dependency Properties + + #region Methods + + /// + /// Handler for the DisplayAfterTimer. + /// + /// Event sender. + /// Event arguments. + private void DisplayAfterTimerElapsed(object sender, EventArgs e) + { + _displayAfterTimer.Stop(); + IsContentVisible = true; + ChangeVisualState(true); + } + + /// + /// Changes the control's visual state(s). + /// + /// True if state transitions should be used. + protected virtual void ChangeVisualState(bool useTransitions) + { + VisualStateManager.GoToState(this, IsBusy ? VisualStates.StateBusy : VisualStates.StateIdle, useTransitions); + VisualStateManager.GoToState(this, IsContentVisible ? VisualStates.StateVisible : VisualStates.StateHidden, useTransitions); + } + + #endregion //Methods + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/BusyIndicator/Implementation/Converters/ProgressBarWidthConverter.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/BusyIndicator/Implementation/Converters/ProgressBarWidthConverter.cs new file mode 100644 index 00000000..d246c77b --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/BusyIndicator/Implementation/Converters/ProgressBarWidthConverter.cs @@ -0,0 +1,41 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Windows.Data; + +namespace Xceed.Wpf.Toolkit.Converters +{ + public class ProgressBarWidthConverter : IMultiValueConverter + { + public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) + { + var contentWidth = (double)values[0]; + var parentMinWidth = (double)values[1]; + + return Math.Max(contentWidth, parentMinWidth); + } + + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/BusyIndicator/Implementation/VisualStates.BusyIndicator.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/BusyIndicator/Implementation/VisualStates.BusyIndicator.cs new file mode 100644 index 00000000..ec43307f --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/BusyIndicator/Implementation/VisualStates.BusyIndicator.cs @@ -0,0 +1,51 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +namespace Xceed.Wpf.Toolkit +{ + internal static partial class VisualStates + { + /// + /// Busyness group name. + /// + public const string GroupBusyStatus = "BusyStatusStates"; + + /// + /// Busy state for BusyIndicator. + /// + public const string StateBusy = "Busy"; + + /// + /// Idle state for BusyIndicator. + /// + public const string StateIdle = "Idle"; + + /// + /// BusyDisplay group. + /// + public const string GroupVisibility = "VisibilityStates"; + + /// + /// Visible state name for BusyIndicator. + /// + public const string StateVisible = "Visible"; + + /// + /// Hidden state name for BusyIndicator. + /// + public const string StateHidden = "Hidden"; + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/BusyIndicator/Themes/Aero2.NormalColor.xaml b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/BusyIndicator/Themes/Aero2.NormalColor.xaml new file mode 100644 index 00000000..1802ccae --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/BusyIndicator/Themes/Aero2.NormalColor.xaml @@ -0,0 +1,215 @@ + + + + + + + + + + + + + + + + + + + + + + + + Collapsed + + + + + + + Collapsed + + + + + + + + + + + Visible + + + + + + + Visible + + + + + + + + + + + + + True + + + + + + + + + + + False + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/BusyIndicator/Themes/Generic.xaml b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/BusyIndicator/Themes/Generic.xaml new file mode 100644 index 00000000..83c086f7 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/BusyIndicator/Themes/Generic.xaml @@ -0,0 +1,227 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Collapsed + + + + + + + Collapsed + + + + + + + + + + + Visible + + + + + + + Visible + + + + + + + + + + + + + True + + + + + + + + + + + False + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ButtonSpinner/Implementation/ButtonSpinner.Icon.bmp b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ButtonSpinner/Implementation/ButtonSpinner.Icon.bmp new file mode 100644 index 00000000..ce76dc5b --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ButtonSpinner/Implementation/ButtonSpinner.Icon.bmp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e95d8b086aa0680fa4b987fc38d9701b23c24b9d6334806e6d5a7fa0b3687373 +size 822 diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ButtonSpinner/Implementation/ButtonSpinner.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ButtonSpinner/Implementation/ButtonSpinner.cs new file mode 100644 index 00000000..114221ee --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ButtonSpinner/Implementation/ButtonSpinner.cs @@ -0,0 +1,368 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System.Windows; +using System.Windows.Controls.Primitives; +using System.Windows.Input; +using System.Windows.Markup; + +namespace Xceed.Wpf.Toolkit +{ + public enum Location + { + Left, + Right + } + + /// + /// Represents a spinner control that includes two Buttons. + /// + [TemplatePart(Name = PART_IncreaseButton, Type = typeof(ButtonBase))] + [TemplatePart(Name = PART_DecreaseButton, Type = typeof(ButtonBase))] + [ContentProperty("Content")] + public class ButtonSpinner : Spinner + { + private const string PART_IncreaseButton = "PART_IncreaseButton"; + private const string PART_DecreaseButton = "PART_DecreaseButton"; + + #region Properties + + #region AllowSpin + + public static readonly DependencyProperty AllowSpinProperty = DependencyProperty.Register("AllowSpin", typeof(bool), typeof(ButtonSpinner), new UIPropertyMetadata(true, AllowSpinPropertyChanged)); + public bool AllowSpin + { + get + { + return (bool)GetValue(AllowSpinProperty); + } + set + { + SetValue(AllowSpinProperty, value); + } + } + + private static void AllowSpinPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ButtonSpinner source = d as ButtonSpinner; + source.OnAllowSpinChanged((bool)e.OldValue, (bool)e.NewValue); + } + + #endregion //AllowSpin + + #region ButtonSpinnerLocation + + public static readonly DependencyProperty ButtonSpinnerLocationProperty = DependencyProperty.Register("ButtonSpinnerLocation", typeof(Location), typeof(ButtonSpinner), new UIPropertyMetadata(Location.Right)); + public Location ButtonSpinnerLocation + { + get + { + return (Location)GetValue(ButtonSpinnerLocationProperty); + } + set + { + SetValue(ButtonSpinnerLocationProperty, value); + } + } + + #endregion //ButtonSpinnerLocation + + #region Content + + /// + /// Identifies the Content dependency property. + /// + public static readonly DependencyProperty ContentProperty = DependencyProperty.Register("Content", typeof(object), typeof(ButtonSpinner), new PropertyMetadata(null, OnContentPropertyChanged)); + public object Content + { + get + { + return GetValue(ContentProperty) as object; + } + set + { + SetValue(ContentProperty, value); + } + } + + /// + /// ContentProperty property changed handler. + /// + /// ButtonSpinner that changed its Content. + /// Event arguments. + private static void OnContentPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ButtonSpinner source = d as ButtonSpinner; + source.OnContentChanged(e.OldValue, e.NewValue); + } + + #endregion //Content + + #region DecreaseButton + + private ButtonBase _decreaseButton; + /// + /// Gets or sets the DecreaseButton template part. + /// + private ButtonBase DecreaseButton + { + get + { + return _decreaseButton; + } + set + { + if (_decreaseButton != null) + { + _decreaseButton.Click -= OnButtonClick; + } + + _decreaseButton = value; + + if (_decreaseButton != null) + { + _decreaseButton.Click += OnButtonClick; + } + } + } + + #endregion //DecreaseButton + + #region IncreaseButton + + private ButtonBase _increaseButton; + /// + /// Gets or sets the IncreaseButton template part. + /// + private ButtonBase IncreaseButton + { + get + { + return _increaseButton; + } + set + { + if (_increaseButton != null) + { + _increaseButton.Click -= OnButtonClick; + } + + _increaseButton = value; + + if (_increaseButton != null) + { + _increaseButton.Click += OnButtonClick; + } + } + } + + #endregion //IncreaseButton + + #region ShowButtonSpinner + + public static readonly DependencyProperty ShowButtonSpinnerProperty = DependencyProperty.Register("ShowButtonSpinner", typeof(bool), typeof(ButtonSpinner), new UIPropertyMetadata(true)); + public bool ShowButtonSpinner + { + get + { + return (bool)GetValue(ShowButtonSpinnerProperty); + } + set + { + SetValue(ShowButtonSpinnerProperty, value); + } + } + + #endregion //ShowButtonSpinner + + #endregion //Properties + + #region Constructors + + static ButtonSpinner() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(ButtonSpinner), new FrameworkPropertyMetadata(typeof(ButtonSpinner))); + } + + public ButtonSpinner() + { + } + + #endregion //Constructors + + #region Base Class Overrides + + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + IncreaseButton = GetTemplateChild(PART_IncreaseButton) as ButtonBase; + DecreaseButton = GetTemplateChild(PART_DecreaseButton) as ButtonBase; + + SetButtonUsage(); + } + + /// + /// Cancel LeftMouseButtonUp events originating from a button that has + /// been changed to disabled. + /// + /// The data for the event. + protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e) + { + base.OnMouseLeftButtonUp(e); + + Point mousePosition; + if (IncreaseButton != null && IncreaseButton.IsEnabled == false) + { + mousePosition = e.GetPosition(IncreaseButton); + if (mousePosition.X > 0 && mousePosition.X < IncreaseButton.ActualWidth && + mousePosition.Y > 0 && mousePosition.Y < IncreaseButton.ActualHeight) + { + e.Handled = true; + } + } + + if (DecreaseButton != null && DecreaseButton.IsEnabled == false) + { + mousePosition = e.GetPosition(DecreaseButton); + if (mousePosition.X > 0 && mousePosition.X < DecreaseButton.ActualWidth && + mousePosition.Y > 0 && mousePosition.Y < DecreaseButton.ActualHeight) + { + e.Handled = true; + } + } + } + + protected override void OnPreviewKeyDown(KeyEventArgs e) + { + switch (e.Key) + { + case Key.Up: + { + if (this.AllowSpin) + { + this.OnSpin(new SpinEventArgs(Spinner.SpinnerSpinEvent, SpinDirection.Increase)); + e.Handled = true; + } + + break; + } + case Key.Down: + { + if (this.AllowSpin) + { + this.OnSpin(new SpinEventArgs(Spinner.SpinnerSpinEvent, SpinDirection.Decrease)); + e.Handled = true; + } + + break; + } + case Key.Enter: + { + //Do not Spin on enter Key when spinners have focus + if (((this.IncreaseButton != null) && (this.IncreaseButton.IsFocused)) + || ((this.DecreaseButton != null) && this.DecreaseButton.IsFocused)) + { + e.Handled = true; + } + break; + } + } + } + + protected override void OnMouseWheel(MouseWheelEventArgs e) + { + base.OnMouseWheel(e); + + if (!e.Handled && this.AllowSpin) + { + if (e.Delta != 0) + { + var spinnerEventArgs = new SpinEventArgs(Spinner.SpinnerSpinEvent, (e.Delta < 0) ? SpinDirection.Decrease : SpinDirection.Increase, true); + this.OnSpin(spinnerEventArgs); + e.Handled = spinnerEventArgs.Handled; + } + } + } + + /// + /// Called when valid spin direction changed. + /// + /// The old value. + /// The new value. + protected override void OnValidSpinDirectionChanged(ValidSpinDirections oldValue, ValidSpinDirections newValue) + { + SetButtonUsage(); + } + + + #endregion //Base Class Overrides + + #region Event Handlers + + /// + /// Handle click event of IncreaseButton and DecreaseButton template parts, + /// translating Click to appropriate Spin event. + /// + /// Event sender, should be either IncreaseButton or DecreaseButton template part. + /// Event args. + private void OnButtonClick(object sender, RoutedEventArgs e) + { + if (AllowSpin) + { + SpinDirection direction = sender == IncreaseButton ? SpinDirection.Increase : SpinDirection.Decrease; + OnSpin(new SpinEventArgs(Spinner.SpinnerSpinEvent, direction)); + } + } + + #endregion //Event Handlers + + #region Methods + + /// + /// Occurs when the Content property value changed. + /// + /// The old value of the Content property. + /// The new value of the Content property. + protected virtual void OnContentChanged(object oldValue, object newValue) + { + } + + protected virtual void OnAllowSpinChanged(bool oldValue, bool newValue) + { + SetButtonUsage(); + } + + /// + /// Disables or enables the buttons based on the valid spin direction. + /// + private void SetButtonUsage() + { + // buttonspinner adds buttons that spin, so disable accordingly. + if (IncreaseButton != null) + { + IncreaseButton.IsEnabled = AllowSpin && ((ValidSpinDirection & ValidSpinDirections.Increase) == ValidSpinDirections.Increase); + } + + if (DecreaseButton != null) + { + DecreaseButton.IsEnabled = AllowSpin && ((ValidSpinDirection & ValidSpinDirections.Decrease) == ValidSpinDirections.Decrease); + } + } + + #endregion //Methods + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ButtonSpinner/Implementation/SpinDirection.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ButtonSpinner/Implementation/SpinDirection.cs new file mode 100644 index 00000000..b10d041c --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ButtonSpinner/Implementation/SpinDirection.cs @@ -0,0 +1,35 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +namespace Xceed.Wpf.Toolkit +{ + /// + /// Represents spin directions that could be initiated by the end-user. + /// + /// Preview + public enum SpinDirection + { + /// + /// Represents a spin initiated by the end-user in order to Increase a value. + /// + Increase = 0, + + /// + /// Represents a spin initiated by the end-user in order to Decrease a value. + /// + Decrease = 1 + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ButtonSpinner/Implementation/SpinEventArgs.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ButtonSpinner/Implementation/SpinEventArgs.cs new file mode 100644 index 00000000..2061e5d1 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ButtonSpinner/Implementation/SpinEventArgs.cs @@ -0,0 +1,76 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System.Windows; + +namespace Xceed.Wpf.Toolkit +{ + /// + /// Provides data for the Spinner.Spin event. + /// + /// Preview + public class SpinEventArgs : RoutedEventArgs + { + /// + /// Gets the SpinDirection for the spin that has been initiated by the + /// end-user. + /// + public SpinDirection Direction + { + get; + private set; + } + + /// + /// Get or set whheter the spin event originated from a mouse wheel event. + /// + public bool UsingMouseWheel + { + get; + private set; + } + + /// + /// Initializes a new instance of the SpinEventArgs class. + /// + /// Spin direction. + public SpinEventArgs(SpinDirection direction) + : base() + { + Direction = direction; + } + + public SpinEventArgs(RoutedEvent routedEvent, SpinDirection direction) + : base(routedEvent) + { + Direction = direction; + } + + public SpinEventArgs(SpinDirection direction, bool usingMouseWheel) + : base() + { + Direction = direction; + UsingMouseWheel = usingMouseWheel; + } + + public SpinEventArgs(RoutedEvent routedEvent, SpinDirection direction, bool usingMouseWheel) + : base(routedEvent) + { + Direction = direction; + UsingMouseWheel = usingMouseWheel; + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ButtonSpinner/Implementation/Spinner.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ButtonSpinner/Implementation/Spinner.cs new file mode 100644 index 00000000..600e5535 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ButtonSpinner/Implementation/Spinner.cs @@ -0,0 +1,119 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Windows; +using System.Windows.Controls; + +namespace Xceed.Wpf.Toolkit +{ + /// + /// Base class for controls that represents controls that can spin. + /// + public abstract class Spinner : Control + { + #region Properties + + /// + /// Identifies the ValidSpinDirection dependency property. + /// + public static readonly DependencyProperty ValidSpinDirectionProperty = DependencyProperty.Register("ValidSpinDirection", typeof(ValidSpinDirections), typeof(Spinner), new PropertyMetadata(ValidSpinDirections.Increase | ValidSpinDirections.Decrease, OnValidSpinDirectionPropertyChanged)); + public ValidSpinDirections ValidSpinDirection + { + get + { + return (ValidSpinDirections)GetValue(ValidSpinDirectionProperty); + } + set + { + SetValue(ValidSpinDirectionProperty, value); + } + } + + /// + /// ValidSpinDirectionProperty property changed handler. + /// + /// ButtonSpinner that changed its ValidSpinDirection. + /// Event arguments. + private static void OnValidSpinDirectionPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + Spinner source = (Spinner)d; + ValidSpinDirections oldvalue = (ValidSpinDirections)e.OldValue; + ValidSpinDirections newvalue = (ValidSpinDirections)e.NewValue; + source.OnValidSpinDirectionChanged(oldvalue, newvalue); + } + + #endregion //Properties + + /// + /// Occurs when spinning is initiated by the end-user. + /// + public event EventHandler Spin; + + #region Events + + public static readonly RoutedEvent SpinnerSpinEvent = EventManager.RegisterRoutedEvent("SpinnerSpin", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(Spinner)); + + public event RoutedEventHandler SpinnerSpin + { + add + { + AddHandler(SpinnerSpinEvent, value); + } + remove + { + RemoveHandler(SpinnerSpinEvent, value); + } + } + + #endregion + + /// + /// Initializes a new instance of the Spinner class. + /// + protected Spinner() + { + } + + /// + /// Raises the OnSpin event when spinning is initiated by the end-user. + /// + /// Spin event args. + protected virtual void OnSpin(SpinEventArgs e) + { + ValidSpinDirections valid = e.Direction == SpinDirection.Increase ? ValidSpinDirections.Increase : ValidSpinDirections.Decrease; + + //Only raise the event if spin is allowed. + if ((ValidSpinDirection & valid) == valid) + { + EventHandler handler = Spin; + if (handler != null) + { + handler(this, e); + } + } + } + + /// + /// Called when valid spin direction changed. + /// + /// The old value. + /// The new value. + protected virtual void OnValidSpinDirectionChanged(ValidSpinDirections oldValue, ValidSpinDirections newValue) + { + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ButtonSpinner/Implementation/ValidSpinDirections.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ButtonSpinner/Implementation/ValidSpinDirections.cs new file mode 100644 index 00000000..079a80b4 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ButtonSpinner/Implementation/ValidSpinDirections.cs @@ -0,0 +1,42 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; + +namespace Xceed.Wpf.Toolkit +{ + /// + /// Represents spin directions that are valid. + /// + [Flags] + public enum ValidSpinDirections + { + /// + /// Can not increase nor decrease. + /// + None = 0, + + /// + /// Can increase. + /// + Increase = 1, + + /// + /// Can decrease. + /// + Decrease = 2 + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ButtonSpinner/Themes/Aero2.NormalColor.xaml b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ButtonSpinner/Themes/Aero2.NormalColor.xaml new file mode 100644 index 00000000..6c23733d --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ButtonSpinner/Themes/Aero2.NormalColor.xaml @@ -0,0 +1,158 @@ + + + + + + + + + + + + + + + + + + diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ButtonSpinner/Themes/Generic.xaml b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ButtonSpinner/Themes/Generic.xaml new file mode 100644 index 00000000..77305653 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ButtonSpinner/Themes/Generic.xaml @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Calculator/Implementation/Calculator.Icon.bmp b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Calculator/Implementation/Calculator.Icon.bmp new file mode 100644 index 00000000..ce76dc5b --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Calculator/Implementation/Calculator.Icon.bmp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e95d8b086aa0680fa4b987fc38d9701b23c24b9d6334806e6d5a7fa0b3687373 +size 822 diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Calculator/Implementation/Calculator.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Calculator/Implementation/Calculator.cs new file mode 100644 index 00000000..1ae24ec5 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Calculator/Implementation/Calculator.cs @@ -0,0 +1,582 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using System.Windows.Threading; +using Xceed.Wpf.Toolkit.Core.Utilities; + +namespace Xceed.Wpf.Toolkit +{ + [TemplatePart(Name = PART_CalculatorButtonPanel, Type = typeof(ContentControl))] + public class Calculator : Control + { + private const string PART_CalculatorButtonPanel = "PART_CalculatorButtonPanel"; + + #region Members + + private ContentControl _buttonPanel; + private bool _showNewNumber = true; + private decimal _previousValue; + private Operation _lastOperation = Operation.None; + private readonly Dictionary _timers = new Dictionary(); + + #endregion //Members + + #region Enumerations + + public enum CalculatorButtonType + { + Add, + Back, + Cancel, + Clear, + Decimal, + Divide, + Eight, + Equal, + Five, + Four, + Fraction, + MAdd, + MC, + MR, + MS, + MSub, + Multiply, + Negate, + Nine, + None, + One, + Percent, + Seven, + Six, + Sqrt, + Subtract, + Three, + Two, + Zero + } + + public enum Operation + { + Add, + Subtract, + Divide, + Multiply, + Percent, + Sqrt, + Fraction, + None, + Clear, + Negate + } + + #endregion //Enumerations + + #region Properties + + #region CalculatorButtonPanelTemplate + + public static readonly DependencyProperty CalculatorButtonPanelTemplateProperty = DependencyProperty.Register("CalculatorButtonPanelTemplate" + , typeof(ControlTemplate), typeof(Calculator), new UIPropertyMetadata(null)); + public ControlTemplate CalculatorButtonPanelTemplate + { + get + { + return (ControlTemplate)GetValue(CalculatorButtonPanelTemplateProperty); + } + set + { + SetValue(CalculatorButtonPanelTemplateProperty, value); + } + } + + #endregion //CalculatorButtonPanelTemplate + + #region CalculatorButtonType + + public static readonly DependencyProperty CalculatorButtonTypeProperty = DependencyProperty.RegisterAttached("CalculatorButtonType", typeof(CalculatorButtonType), typeof(Calculator), new UIPropertyMetadata(CalculatorButtonType.None, OnCalculatorButtonTypeChanged)); + public static CalculatorButtonType GetCalculatorButtonType(DependencyObject target) + { + return (CalculatorButtonType)target.GetValue(CalculatorButtonTypeProperty); + } + public static void SetCalculatorButtonType(DependencyObject target, CalculatorButtonType value) + { + target.SetValue(CalculatorButtonTypeProperty, value); + } + private static void OnCalculatorButtonTypeChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) + { + OnCalculatorButtonTypeChanged(o, (CalculatorButtonType)e.OldValue, (CalculatorButtonType)e.NewValue); + } + private static void OnCalculatorButtonTypeChanged(DependencyObject o, CalculatorButtonType oldValue, CalculatorButtonType newValue) + { + Button button = o as Button; + button.CommandParameter = newValue; + if (button.Content == null) + { + button.Content = CalculatorUtilities.GetCalculatorButtonContent(newValue); + } + } + + #endregion //CalculatorButtonType + + #region DisplayText + + public static readonly DependencyProperty DisplayTextProperty = DependencyProperty.Register("DisplayText", typeof(string), typeof(Calculator), new UIPropertyMetadata("0", OnDisplayTextChanged)); + public string DisplayText + { + get + { + return (string)GetValue(DisplayTextProperty); + } + set + { + SetValue(DisplayTextProperty, value); + } + } + + private static void OnDisplayTextChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) + { + Calculator calculator = o as Calculator; + if (calculator != null) + calculator.OnDisplayTextChanged((string)e.OldValue, (string)e.NewValue); + } + + protected virtual void OnDisplayTextChanged(string oldValue, string newValue) + { + // TODO: Add your property changed side-effects. Descendants can override as well. + } + + #endregion //DisplayText + + #region Memory + + public static readonly DependencyProperty MemoryProperty = DependencyProperty.Register("Memory", typeof(decimal), typeof(Calculator), new UIPropertyMetadata(default(decimal))); + public decimal Memory + { + get + { + return (decimal)GetValue(MemoryProperty); + } + set + { + SetValue(MemoryProperty, value); + } + } + + #endregion //Memory + + #region Precision + + public static readonly DependencyProperty PrecisionProperty = DependencyProperty.Register("Precision", typeof(int), typeof(Calculator), new UIPropertyMetadata(6)); + public int Precision + { + get + { + return (int)GetValue(PrecisionProperty); + } + set + { + SetValue(PrecisionProperty, value); + } + } + + #endregion //Precision + + #region Value + + public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(decimal?), typeof(Calculator), new FrameworkPropertyMetadata(default(decimal), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnValueChanged)); + public decimal? Value + { + get + { + return (decimal?)GetValue(ValueProperty); + } + set + { + SetValue(ValueProperty, value); + } + } + + private static void OnValueChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) + { + Calculator calculator = o as Calculator; + if (calculator != null) + calculator.OnValueChanged((decimal?)e.OldValue, (decimal?)e.NewValue); + } + + protected virtual void OnValueChanged(decimal? oldValue, decimal? newValue) + { + SetDisplayText(newValue); + + RoutedPropertyChangedEventArgs args = new RoutedPropertyChangedEventArgs(oldValue, newValue); + args.RoutedEvent = ValueChangedEvent; + RaiseEvent(args); + } + + #endregion //Value + + #endregion //Properties + + #region Constructors + + static Calculator() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(Calculator), new FrameworkPropertyMetadata(typeof(Calculator))); + } + + public Calculator() + { + + CommandBindings.Add(new CommandBinding(CalculatorCommands.CalculatorButtonClick, ExecuteCalculatorButtonClick)); + AddHandler(MouseDownEvent, new MouseButtonEventHandler(Calculator_OnMouseDown), true); + } + + #endregion //Constructors + + #region Base Class Overrides + + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + _buttonPanel = GetTemplateChild(PART_CalculatorButtonPanel) as ContentControl; + } + + protected override void OnTextInput(TextCompositionEventArgs e) + { + var buttonType = CalculatorUtilities.GetCalculatorButtonTypeFromText(e.Text); + if (buttonType != CalculatorButtonType.None) + { + SimulateCalculatorButtonClick(buttonType); + ProcessCalculatorButton(buttonType); + } + } + + + + + #endregion //Base Class Overrides + + #region Event Handlers + + private void Calculator_OnMouseDown(object sender, MouseButtonEventArgs e) + { + if (!IsFocused) + { + Focus(); + e.Handled = true; + } + } + + void Timer_Tick(object sender, EventArgs e) + { + DispatcherTimer timer = (DispatcherTimer)sender; + timer.Stop(); + timer.Tick -= Timer_Tick; + + if (_timers.ContainsValue(timer)) + { + var button = _timers.Where(x => x.Value == timer).Select(x => x.Key).FirstOrDefault(); + if (button != null) + { + VisualStateManager.GoToState(button, button.IsMouseOver ? "MouseOver" : "Normal", true); + _timers.Remove(button); + } + } + } + + #endregion //Event Handlers + + #region Methods + + internal void InitializeToValue(decimal? value) + { + _previousValue = 0; + _lastOperation = Operation.None; + _showNewNumber = true; + Value = value; + // Since the display text may be out of sync + // with "Value", this call will force the + // text update if Value was already equal to + // the value parameter. + this.SetDisplayText(value); + } + + private void Calculate() + { + if (_lastOperation == Operation.None) + return; + + try + { + Value = Decimal.Round(CalculateValue(_lastOperation), Precision); + SetDisplayText(Value); //Set DisplayText even when Value doesn't change + } + catch + { + Value = null; + DisplayText = "ERROR"; + } + } + + private void SetDisplayText(decimal? newValue) + { + if (newValue.HasValue && (newValue.Value != 0)) + DisplayText = newValue.ToString(); + else + DisplayText = "0"; + } + + private void Calculate(Operation newOperation) + { + if (!_showNewNumber) + Calculate(); + + _lastOperation = newOperation; + } + + private void Calculate(Operation currentOperation, Operation newOperation) + { + _lastOperation = currentOperation; + Calculate(); + _lastOperation = newOperation; + } + + private decimal CalculateValue(Operation operation) + { + decimal newValue = decimal.Zero; + decimal currentValue = CalculatorUtilities.ParseDecimal(DisplayText); + + switch (operation) + { + case Operation.Add: + newValue = CalculatorUtilities.Add(_previousValue, currentValue); + break; + case Operation.Subtract: + newValue = CalculatorUtilities.Subtract(_previousValue, currentValue); + break; + case Operation.Multiply: + newValue = CalculatorUtilities.Multiply(_previousValue, currentValue); + break; + case Operation.Divide: + newValue = CalculatorUtilities.Divide(_previousValue, currentValue); + break; + //case Operation.Percent: + // newValue = CalculatorUtilities.Percent(_previousValue, currentValue); + // break; + case Operation.Sqrt: + newValue = CalculatorUtilities.SquareRoot(currentValue); + break; + case Operation.Fraction: + newValue = CalculatorUtilities.Fraction(currentValue); + break; + case Operation.Negate: + newValue = CalculatorUtilities.Negate(currentValue); + break; + default: + newValue = decimal.Zero; + break; + } + + return newValue; + } + + void ProcessBackKey() + { + string displayText; + if (DisplayText.Length > 1 && !(DisplayText.Length == 2 && DisplayText[0] == '-')) + { + displayText = DisplayText.Remove(DisplayText.Length - 1, 1); + } + else + { + displayText = "0"; + _showNewNumber = true; + } + + DisplayText = displayText; + } + + private void ProcessCalculatorButton(CalculatorButtonType buttonType) + { + if (CalculatorUtilities.IsDigit(buttonType)) + ProcessDigitKey(buttonType); + else if ((CalculatorUtilities.IsMemory(buttonType))) + ProcessMemoryKey(buttonType); + else + ProcessOperationKey(buttonType); + } + + private void ProcessDigitKey(CalculatorButtonType buttonType) + { + if (_showNewNumber) + DisplayText = CalculatorUtilities.GetCalculatorButtonContent(buttonType); + else + DisplayText += CalculatorUtilities.GetCalculatorButtonContent(buttonType); + + _showNewNumber = false; + } + + private void ProcessMemoryKey(Calculator.CalculatorButtonType buttonType) + { + decimal currentValue = CalculatorUtilities.ParseDecimal(DisplayText); + + _showNewNumber = true; + + switch (buttonType) + { + case Calculator.CalculatorButtonType.MAdd: + Memory += currentValue; + break; + case Calculator.CalculatorButtonType.MC: + Memory = decimal.Zero; + break; + case Calculator.CalculatorButtonType.MR: + DisplayText = Memory.ToString(); + _showNewNumber = false; + break; + case Calculator.CalculatorButtonType.MS: + Memory = currentValue; + break; + case Calculator.CalculatorButtonType.MSub: + Memory -= currentValue; + break; + default: + break; + } + } + + private void ProcessOperationKey(CalculatorButtonType buttonType) + { + switch (buttonType) + { + case CalculatorButtonType.Add: + Calculate(Operation.Add); + break; + case CalculatorButtonType.Subtract: + Calculate(Operation.Subtract); + break; + case CalculatorButtonType.Multiply: + Calculate(Operation.Multiply); + break; + case CalculatorButtonType.Divide: + Calculate(Operation.Divide); + break; + case CalculatorButtonType.Percent: + if (_lastOperation != Operation.None) + { + decimal currentValue = CalculatorUtilities.ParseDecimal(DisplayText); + decimal newValue = CalculatorUtilities.Percent(_previousValue, currentValue); + DisplayText = newValue.ToString(); + } + else + { + DisplayText = "0"; + _showNewNumber = true; + } + return; + case CalculatorButtonType.Sqrt: + Calculate(Operation.Sqrt, Operation.None); + break; + case CalculatorButtonType.Fraction: + Calculate(Operation.Fraction, Operation.None); + break; + case CalculatorButtonType.Negate: + Calculate(Operation.Negate, Operation.None); + break; + case CalculatorButtonType.Equal: + Calculate(Operation.None); + break; + case CalculatorButtonType.Clear: + Calculate(Operation.Clear, Operation.None); + break; + case CalculatorButtonType.Cancel: + DisplayText = _previousValue.ToString(); + _lastOperation = Operation.None; + _showNewNumber = true; + return; + case CalculatorButtonType.Back: + ProcessBackKey(); + return; + default: + break; + } + + Decimal.TryParse(DisplayText, out _previousValue); + _showNewNumber = true; + } + + private void SimulateCalculatorButtonClick(CalculatorButtonType buttonType) + { + var button = CalculatorUtilities.FindButtonByCalculatorButtonType(_buttonPanel, buttonType); + if (button != null) + { + VisualStateManager.GoToState(button, "Pressed", true); + DispatcherTimer timer; + if (_timers.ContainsKey(button)) + { + timer = _timers[button]; + timer.Stop(); + } + else + { + timer = new DispatcherTimer(); + timer.Interval = TimeSpan.FromMilliseconds(100); + timer.Tick += Timer_Tick; + _timers.Add(button, timer); + } + + timer.Start(); + } + } + + #endregion //Methods + + #region Events + + //Due to a bug in Visual Studio, you cannot create event handlers for nullable args in XAML, so I have to use object instead. + public static readonly RoutedEvent ValueChangedEvent = EventManager.RegisterRoutedEvent("ValueChanged", RoutingStrategy.Bubble, typeof(RoutedPropertyChangedEventHandler), typeof(Calculator)); + public event RoutedPropertyChangedEventHandler ValueChanged + { + add + { + AddHandler(ValueChangedEvent, value); + } + remove + { + RemoveHandler(ValueChangedEvent, value); + } + } + + #endregion //Events + + #region Commands + + private void ExecuteCalculatorButtonClick(object sender, ExecutedRoutedEventArgs e) + { + var buttonType = (CalculatorButtonType)e.Parameter; + ProcessCalculatorButton(buttonType); + } + + #endregion //Commands + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Calculator/Implementation/CalculatorCommands.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Calculator/Implementation/CalculatorCommands.cs new file mode 100644 index 00000000..88376449 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Calculator/Implementation/CalculatorCommands.cs @@ -0,0 +1,33 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System.Windows.Input; + +namespace Xceed.Wpf.Toolkit +{ + public static class CalculatorCommands + { + private static RoutedCommand _calculatorButtonClickCommand = new RoutedCommand(); + + public static RoutedCommand CalculatorButtonClick + { + get + { + return _calculatorButtonClickCommand; + } + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Calculator/Themes/Aero2.NormalColor.xaml b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Calculator/Themes/Aero2.NormalColor.xaml new file mode 100644 index 00000000..a09db4cd --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Calculator/Themes/Aero2.NormalColor.xaml @@ -0,0 +1,408 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Calculator/Themes/Generic.xaml b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Calculator/Themes/Generic.xaml new file mode 100644 index 00000000..107df5d5 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Calculator/Themes/Generic.xaml @@ -0,0 +1,832 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CalculatorUpDown/Implementation/CalculatorUpDown.Icon.bmp b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CalculatorUpDown/Implementation/CalculatorUpDown.Icon.bmp new file mode 100644 index 00000000..ce76dc5b --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CalculatorUpDown/Implementation/CalculatorUpDown.Icon.bmp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e95d8b086aa0680fa4b987fc38d9701b23c24b9d6334806e6d5a7fa0b3687373 +size 822 diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CalculatorUpDown/Implementation/CalculatorUpDown.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CalculatorUpDown/Implementation/CalculatorUpDown.cs new file mode 100644 index 00000000..bb62b030 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CalculatorUpDown/Implementation/CalculatorUpDown.cs @@ -0,0 +1,282 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Windows; +using System.Windows.Controls.Primitives; +using System.Windows.Input; +using Xceed.Wpf.Toolkit.Core.Utilities; + +namespace Xceed.Wpf.Toolkit +{ + [TemplatePart(Name = PART_CalculatorPopup, Type = typeof(Popup))] + [TemplatePart(Name = PART_Calculator, Type = typeof(Calculator))] + public class CalculatorUpDown : DecimalUpDown + { + private const string PART_CalculatorPopup = "PART_CalculatorPopup"; + private const string PART_Calculator = "PART_Calculator"; + + #region Members + + private Popup _calculatorPopup; + private Calculator _calculator; + private Decimal? _initialValue; + + #endregion //Members + + #region Properties + + #region DisplayText + + public static readonly DependencyProperty DisplayTextProperty = DependencyProperty.Register("DisplayText", typeof(string), typeof(CalculatorUpDown), new UIPropertyMetadata("0")); + public string DisplayText + { + get + { + return (string)GetValue(DisplayTextProperty); + } + set + { + SetValue(DisplayTextProperty, value); + } + } + + #endregion //DisplayText + + #region EnterClosesCalculator + + public static readonly DependencyProperty EnterClosesCalculatorProperty = DependencyProperty.Register("EnterClosesCalculator", typeof(bool), typeof(CalculatorUpDown), new UIPropertyMetadata(false)); + public bool EnterClosesCalculator + { + get + { + return (bool)GetValue(EnterClosesCalculatorProperty); + } + set + { + SetValue(EnterClosesCalculatorProperty, value); + } + } + + #endregion //EnterClosesCalculator + + #region IsOpen + + public static readonly DependencyProperty IsOpenProperty = DependencyProperty.Register("IsOpen", typeof(bool), typeof(CalculatorUpDown), new UIPropertyMetadata(false, OnIsOpenChanged)); + public bool IsOpen + { + get + { + return (bool)GetValue(IsOpenProperty); + } + set + { + SetValue(IsOpenProperty, value); + } + } + + private static void OnIsOpenChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) + { + CalculatorUpDown calculatorUpDown = o as CalculatorUpDown; + if (calculatorUpDown != null) + calculatorUpDown.OnIsOpenChanged((bool)e.OldValue, (bool)e.NewValue); + } + + protected virtual void OnIsOpenChanged(bool oldValue, bool newValue) + { + if (newValue) + _initialValue = this.UpdateValueOnEnterKey ? this.ConvertTextToValue(this.TextBox.Text) : this.Value; + } + + #endregion //IsOpen + + #region Memory + + public static readonly DependencyProperty MemoryProperty = DependencyProperty.Register("Memory", typeof(decimal), typeof(CalculatorUpDown), new UIPropertyMetadata(default(decimal))); + public decimal Memory + { + get + { + return (decimal)GetValue(MemoryProperty); + } + set + { + SetValue(MemoryProperty, value); + } + } + + #endregion //Memory + + #region Precision + + public static readonly DependencyProperty PrecisionProperty = DependencyProperty.Register("Precision", typeof(int), typeof(CalculatorUpDown), new UIPropertyMetadata(6)); + public int Precision + { + get + { + return (int)GetValue(PrecisionProperty); + } + set + { + SetValue(PrecisionProperty, value); + } + } + + #endregion //Precision + + #endregion //Properties + + #region Constructors + + static CalculatorUpDown() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(CalculatorUpDown), new FrameworkPropertyMetadata(typeof(CalculatorUpDown))); + } + + public CalculatorUpDown() + { + Keyboard.AddKeyDownHandler(this, OnKeyDown); + Mouse.AddPreviewMouseDownOutsideCapturedElementHandler(this, OnMouseDownOutsideCapturedElement); + } + + #endregion //Constructors + + #region Base Class Overrides + + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + if (_calculatorPopup != null) + _calculatorPopup.Opened -= CalculatorPopup_Opened; + + _calculatorPopup = GetTemplateChild(PART_CalculatorPopup) as Popup; + + if (_calculatorPopup != null) + _calculatorPopup.Opened += CalculatorPopup_Opened; + + if (_calculator != null) + _calculator.ValueChanged -= OnCalculatorValueChanged; + + _calculator = GetTemplateChild(PART_Calculator) as Calculator; + + if (_calculator != null) + _calculator.ValueChanged += OnCalculatorValueChanged; + } + + private void OnCalculatorValueChanged(object sender, RoutedPropertyChangedEventArgs e) + { + if (_calculator != null) + { + if (this.IsBetweenMinMax(_calculator.Value)) + { + if (this.UpdateValueOnEnterKey) + { + this.TextBox.Text = (_calculator.Value != null) ? _calculator.Value.Value.ToString(this.FormatString, this.CultureInfo) : null; + } + else + { + this.Value = _calculator.Value; + } + } + } + } + + #endregion //Base Class Overrides + + #region Event Handlers + + void CalculatorPopup_Opened(object sender, EventArgs e) + { + if (_calculator != null) + { + var initValue = this.UpdateValueOnEnterKey ? this.ConvertTextToValue(this.TextBox.Text) : this.Value; + _calculator.InitializeToValue(initValue); + _calculator.Focus(); + } + } + + protected override void OnTextInput(TextCompositionEventArgs e) + { + if (IsOpen && EnterClosesCalculator) + { + var buttonType = CalculatorUtilities.GetCalculatorButtonTypeFromText(e.Text); + if (buttonType == Calculator.CalculatorButtonType.Equal) + { + CloseCalculatorUpDown(true); + } + } + } + + private void OnKeyDown(object sender, KeyEventArgs e) + { + if (!IsOpen) + { + if (KeyboardUtilities.IsKeyModifyingPopupState(e)) + { + IsOpen = true; + // Calculator will get focus in CalculatorPopup_Opened(). + e.Handled = true; + } + } + else + { + if (KeyboardUtilities.IsKeyModifyingPopupState(e)) + { + CloseCalculatorUpDown(true); + e.Handled = true; + } + else if (e.Key == Key.Escape) + { + if (EnterClosesCalculator) + { + if (this.UpdateValueOnEnterKey) + { + this.TextBox.Text = (_initialValue != null) ? _initialValue.Value.ToString(this.FormatString, this.CultureInfo) : null; + } + else + { + this.Value = _initialValue; + } + } + CloseCalculatorUpDown(true); + e.Handled = true; + } + } + } + + private void OnMouseDownOutsideCapturedElement(object sender, MouseButtonEventArgs e) + { + CloseCalculatorUpDown(true); + } + + #endregion //Event Handlers + + #region Methods + + private void CloseCalculatorUpDown(bool isFocusOnTextBox) + { + if (IsOpen) + IsOpen = false; + ReleaseMouseCapture(); + + if (isFocusOnTextBox && (TextBox != null)) + TextBox.Focus(); + } + + #endregion //Methods + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CalculatorUpDown/Themes/Aero2.NormalColor.xaml b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CalculatorUpDown/Themes/Aero2.NormalColor.xaml new file mode 100644 index 00000000..5bac32c0 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CalculatorUpDown/Themes/Aero2.NormalColor.xaml @@ -0,0 +1,222 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CalculatorUpDown/Themes/Generic.xaml b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CalculatorUpDown/Themes/Generic.xaml new file mode 100644 index 00000000..df4f6821 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CalculatorUpDown/Themes/Generic.xaml @@ -0,0 +1,229 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CheckComboBox/Implementation/CheckComboBox.Icon.bmp b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CheckComboBox/Implementation/CheckComboBox.Icon.bmp new file mode 100644 index 00000000..ce76dc5b --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CheckComboBox/Implementation/CheckComboBox.Icon.bmp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e95d8b086aa0680fa4b987fc38d9701b23c24b9d6334806e6d5a7fa0b3687373 +size 822 diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CheckComboBox/Implementation/CheckComboBox.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CheckComboBox/Implementation/CheckComboBox.cs new file mode 100644 index 00000000..fbc955a2 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CheckComboBox/Implementation/CheckComboBox.cs @@ -0,0 +1,402 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Linq; +using System.Windows; +using System.Windows.Input; +using Xceed.Wpf.Toolkit.Core.Utilities; +using System.Windows.Controls; +using System.Collections.Generic; +using System.Windows.Controls.Primitives; +using Xceed.Wpf.Toolkit.Primitives; + +namespace Xceed.Wpf.Toolkit +{ + [TemplatePart(Name = PART_Popup, Type = typeof(Popup))] + public class CheckComboBox : SelectAllSelector + { + private const string PART_Popup = "PART_Popup"; + + #region Members + + private ValueChangeHelper _displayMemberPathValuesChangeHelper; + private bool _ignoreTextValueChanged; + private Popup _popup; + private List _initialValue = new List(); + + #endregion + + #region Constructors + + static CheckComboBox() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(CheckComboBox), new FrameworkPropertyMetadata(typeof(CheckComboBox))); + } + + public CheckComboBox() + { + + Keyboard.AddKeyDownHandler(this, OnKeyDown); + Mouse.AddPreviewMouseDownOutsideCapturedElementHandler(this, OnMouseDownOutsideCapturedElement); + _displayMemberPathValuesChangeHelper = new ValueChangeHelper(this.OnDisplayMemberPathValuesChanged); + } + + #endregion //Constructors + + #region Properties + + #region IsEditable + + public static readonly DependencyProperty IsEditableProperty = DependencyProperty.Register("IsEditable", typeof(bool), typeof(CheckComboBox) + , new UIPropertyMetadata(false)); + public bool IsEditable + { + get + { + return (bool)GetValue(IsEditableProperty); + } + set + { + SetValue(IsEditableProperty, value); + } + } + + #endregion + + #region Text + + public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(CheckComboBox) + , new UIPropertyMetadata(null, OnTextChanged)); + public string Text + { + get + { + return (string)GetValue(TextProperty); + } + set + { + SetValue(TextProperty, value); + } + } + + private static void OnTextChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) + { + var checkComboBox = o as CheckComboBox; + if (checkComboBox != null) + checkComboBox.OnTextChanged((string)e.OldValue, (string)e.NewValue); + } + + protected virtual void OnTextChanged(string oldValue, string newValue) + { + if (!this.IsInitialized || _ignoreTextValueChanged || !this.IsEditable) + return; + + this.UpdateFromText(); + } + + #endregion + + #region IsDropDownOpen + + public static readonly DependencyProperty IsDropDownOpenProperty = DependencyProperty.Register("IsDropDownOpen", typeof(bool), typeof(CheckComboBox), new UIPropertyMetadata(false, OnIsDropDownOpenChanged)); + public bool IsDropDownOpen + { + get + { + return (bool)GetValue(IsDropDownOpenProperty); + } + set + { + SetValue(IsDropDownOpenProperty, value); + } + } + + private static void OnIsDropDownOpenChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) + { + CheckComboBox comboBox = o as CheckComboBox; + if (comboBox != null) + comboBox.OnIsDropDownOpenChanged((bool)e.OldValue, (bool)e.NewValue); + } + + protected virtual void OnIsDropDownOpenChanged(bool oldValue, bool newValue) + { + if (newValue) + { + _initialValue.Clear(); + foreach (object o in SelectedItems) + { + _initialValue.Add(o); + } + base.RaiseEvent(new RoutedEventArgs(CheckComboBox.OpenedEvent, this)); + } + else + { + _initialValue.Clear(); + base.RaiseEvent(new RoutedEventArgs(CheckComboBox.ClosedEvent, this)); + } + } + + #endregion //IsDropDownOpen + + #region MaxDropDownHeight + + public static readonly DependencyProperty MaxDropDownHeightProperty = DependencyProperty.Register("MaxDropDownHeight", typeof(double), typeof(CheckComboBox), new UIPropertyMetadata(SystemParameters.PrimaryScreenHeight / 3.0, OnMaxDropDownHeightChanged)); + public double MaxDropDownHeight + { + get + { + return (double)GetValue(MaxDropDownHeightProperty); + } + set + { + SetValue(MaxDropDownHeightProperty, value); + } + } + + private static void OnMaxDropDownHeightChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) + { + CheckComboBox comboBox = o as CheckComboBox; + if (comboBox != null) + comboBox.OnMaxDropDownHeightChanged((double)e.OldValue, (double)e.NewValue); + } + + protected virtual void OnMaxDropDownHeightChanged(double oldValue, double newValue) + { + // TODO: Add your property changed side-effects. Descendants can override as well. + } + + #endregion + + #endregion //Properties + + #region Base Class Overrides + + protected override void OnSelectedValueChanged(string oldValue, string newValue) + { + base.OnSelectedValueChanged(oldValue, newValue); + UpdateText(); + } + + protected override void OnDisplayMemberPathChanged(string oldDisplayMemberPath, string newDisplayMemberPath) + { + base.OnDisplayMemberPathChanged(oldDisplayMemberPath, newDisplayMemberPath); + this.UpdateDisplayMemberPathValuesBindings(); + } + + protected override void OnItemsSourceChanged(System.Collections.IEnumerable oldValue, System.Collections.IEnumerable newValue) + { + base.OnItemsSourceChanged(oldValue, newValue); + this.UpdateDisplayMemberPathValuesBindings(); + } + + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + if (_popup != null) + _popup.Opened -= Popup_Opened; + + _popup = GetTemplateChild(PART_Popup) as Popup; + + if (_popup != null) + _popup.Opened += Popup_Opened; + } + + + #endregion //Base Class Overrides + + #region Event Handlers + + private void OnMouseDownOutsideCapturedElement(object sender, MouseButtonEventArgs e) + { + CloseDropDown(true); + } + + private void OnKeyDown(object sender, KeyEventArgs e) + { + if (!IsDropDownOpen) + { + if (KeyboardUtilities.IsKeyModifyingPopupState(e)) + { + IsDropDownOpen = true; + // Popup_Opened() will Focus on ComboBoxItem. + e.Handled = true; + } + } + else + { + if (KeyboardUtilities.IsKeyModifyingPopupState(e)) + { + CloseDropDown(true); + e.Handled = true; + } + else if (e.Key == Key.Enter) + { + CloseDropDown(true); + e.Handled = true; + } + else if (e.Key == Key.Escape) + { + SelectedItems.Clear(); + foreach (object o in _initialValue) + SelectedItems.Add(o); + CloseDropDown(true); + e.Handled = true; + } + } + } + + private void Popup_Opened(object sender, EventArgs e) + { + UIElement item = ItemContainerGenerator.ContainerFromItem(SelectedItem) as UIElement; + if ((item == null) && (Items.Count > 0)) + item = ItemContainerGenerator.ContainerFromItem(Items[0]) as UIElement; + if (item != null) + item.Focus(); + } + + #endregion //Event Handlers + + #region Closed Event + + public static readonly RoutedEvent ClosedEvent = EventManager.RegisterRoutedEvent("Closed", RoutingStrategy.Bubble, typeof(EventHandler), typeof(CheckComboBox)); + public event RoutedEventHandler Closed + { + add + { + AddHandler(ClosedEvent, value); + } + remove + { + RemoveHandler(ClosedEvent, value); + } + } + + #endregion //Closed Event + + #region Opened Event + + public static readonly RoutedEvent OpenedEvent = EventManager.RegisterRoutedEvent("Opened", RoutingStrategy.Bubble, typeof(EventHandler), typeof(CheckComboBox)); + public event RoutedEventHandler Opened + { + add + { + AddHandler(OpenedEvent, value); + } + remove + { + RemoveHandler(OpenedEvent, value); + } + } + + #endregion //Opened Event + + #region Methods + + protected virtual void UpdateText() + { +#if VS2008 + string newValue = String.Join( Delimiter, SelectedItems.Cast().Select( x => GetItemDisplayValue( x ).ToString() ).ToArray() ); +#else + string newValue = String.Join(Delimiter, SelectedItems.Cast().Select(x => GetItemDisplayValue(x))); +#endif + + if (String.IsNullOrEmpty(Text) || !Text.Equals(newValue)) + { + _ignoreTextValueChanged = true; +#if VS2008 + Text = newValue; +#else + this.SetCurrentValue(CheckComboBox.TextProperty, newValue); +#endif + _ignoreTextValueChanged = false; + } + } + + private void UpdateDisplayMemberPathValuesBindings() + { + _displayMemberPathValuesChangeHelper.UpdateValueSource(ItemsCollection, this.DisplayMemberPath); + } + + private void OnDisplayMemberPathValuesChanged() + { + this.UpdateText(); + } + + /// + /// Updates the SelectedItems collection based on the content of + /// the Text property. + /// + private void UpdateFromText() + { + List selectedValues = null; + if (!String.IsNullOrEmpty(this.Text)) + { + selectedValues = this.Text.Replace(" ", string.Empty).Split(new string[] { Delimiter }, StringSplitOptions.RemoveEmptyEntries).ToList(); + } + + this.UpdateFromList(selectedValues, this.GetItemDisplayValue); + } + + protected object GetItemDisplayValue(object item) + { + if (String.IsNullOrEmpty(this.DisplayMemberPath)) + return item; + + string[] nameParts = this.DisplayMemberPath.Split('.'); + if (nameParts.Length == 1) + { + var property = item.GetType().GetProperty(this.DisplayMemberPath); + if (property != null) + return property.GetValue(item, null); + return item; + } + + for (int i = 0; i < nameParts.Count(); ++i) + { + var type = item.GetType(); + var info = type.GetProperty(nameParts[i]); + if (info == null) + { + return item; + } + + if (i == nameParts.Count() - 1) + { + return info.GetValue(item, null); + } + else + { + item = info.GetValue(item, null); + } + } + return item; + } + + private void CloseDropDown(bool isFocusOnComboBox) + { + if (IsDropDownOpen) + IsDropDownOpen = false; + ReleaseMouseCapture(); + + if (isFocusOnComboBox) + Focus(); + } + + #endregion //Methods + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CheckComboBox/Themes/Aero2.NormalColor.xaml b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CheckComboBox/Themes/Aero2.NormalColor.xaml new file mode 100644 index 00000000..c5d194ad --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CheckComboBox/Themes/Aero2.NormalColor.xaml @@ -0,0 +1,237 @@ + + + + + + + + M 0,1 C0,1 0,0 0,0 0,0 3,0 3,0 3,0 3,1 3,1 3,1 4,1 4,1 4,1 4,0 4,0 4,0 7,0 7,0 7,0 7,1 7,1 7,1 6,1 6,1 6,1 6,2 6,2 6,2 5,2 5,2 5,2 5,3 5,3 5,3 4,3 4,3 4,3 4,4 4,4 4,4 3,4 3,4 3,4 3,3 3,3 3,3 2,3 2,3 2,3 2,2 2,2 2,2 1,2 1,2 1,2 1,1 1,1 1,1 0,1 0,1 z + + + + + + diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CheckComboBox/Themes/Generic.xaml b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CheckComboBox/Themes/Generic.xaml new file mode 100644 index 00000000..0bc40af7 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CheckComboBox/Themes/Generic.xaml @@ -0,0 +1,229 @@ + + + + + + + + + + M 0,1 C0,1 0,0 0,0 0,0 3,0 3,0 3,0 3,1 3,1 3,1 4,1 4,1 4,1 4,0 4,0 4,0 7,0 7,0 7,0 7,1 7,1 7,1 6,1 6,1 6,1 6,2 6,2 6,2 5,2 5,2 5,2 5,3 5,3 5,3 4,3 4,3 4,3 4,4 4,4 4,4 3,4 3,4 3,4 3,3 3,3 3,3 2,3 2,3 2,3 2,2 2,2 2,2 1,2 1,2 1,2 1,1 1,1 1,1 0,1 0,1 z + + + + + + diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CheckListBox/Implementation/CheckListBox.Icon.bmp b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CheckListBox/Implementation/CheckListBox.Icon.bmp new file mode 100644 index 00000000..ce76dc5b --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CheckListBox/Implementation/CheckListBox.Icon.bmp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e95d8b086aa0680fa4b987fc38d9701b23c24b9d6334806e6d5a7fa0b3687373 +size 822 diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CheckListBox/Implementation/CheckListBox.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CheckListBox/Implementation/CheckListBox.cs new file mode 100644 index 00000000..ded9cb80 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CheckListBox/Implementation/CheckListBox.cs @@ -0,0 +1,42 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System.Windows; +using Xceed.Wpf.Toolkit.Primitives; + +namespace Xceed.Wpf.Toolkit +{ + public class CheckListBox : SelectAllSelector + { + #region Constructors + + static CheckListBox() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(CheckListBox), new FrameworkPropertyMetadata(typeof(CheckListBox))); + } + + public CheckListBox() + { + } + + #endregion //Constructors + + #region Base Class Override + + + #endregion + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CheckListBox/Themes/Aero2.NormalColor.xaml b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CheckListBox/Themes/Aero2.NormalColor.xaml new file mode 100644 index 00000000..8ade1442 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CheckListBox/Themes/Aero2.NormalColor.xaml @@ -0,0 +1,69 @@ + + + + + + + + + diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CheckListBox/Themes/Generic.xaml b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CheckListBox/Themes/Generic.xaml new file mode 100644 index 00000000..9e78bc89 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CheckListBox/Themes/Generic.xaml @@ -0,0 +1,55 @@ + + + + + + + + + diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ChildWindow/Implementation/ChildWindow.Icon.bmp b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ChildWindow/Implementation/ChildWindow.Icon.bmp new file mode 100644 index 00000000..ce76dc5b --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ChildWindow/Implementation/ChildWindow.Icon.bmp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e95d8b086aa0680fa4b987fc38d9701b23c24b9d6334806e6d5a7fa0b3687373 +size 822 diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ChildWindow/Implementation/ChildWindow.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ChildWindow/Implementation/ChildWindow.cs new file mode 100644 index 00000000..8c3681b2 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ChildWindow/Implementation/ChildWindow.cs @@ -0,0 +1,875 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.ComponentModel; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Controls.Primitives; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Shapes; +using System.Windows.Threading; +using Xceed.Wpf.Toolkit.Primitives; +using Xceed.Wpf.Toolkit.Core; +using Xceed.Wpf.Toolkit.Core.Utilities; + +namespace Xceed.Wpf.Toolkit +{ +#pragma warning disable 0809 +#pragma warning disable 0618 + + [TemplatePart(Name = PART_WindowRoot, Type = typeof(Grid))] + [TemplatePart(Name = PART_Root, Type = typeof(Grid))] + [TemplatePart(Name = PART_WindowControl, Type = typeof(WindowControl))] + public class ChildWindow : WindowControl + { + private const string PART_WindowRoot = "PART_WindowRoot"; + private const string PART_Root = "PART_Root"; + private const string PART_WindowControl = "PART_WindowControl"; + private const int _horizontalOffset = 3; + private const int _verticalOffset = 3; + + #region Private Members + + private Grid _root; + private TranslateTransform _moveTransform = new TranslateTransform(); + private bool _startupPositionInitialized; + private FrameworkElement _parentContainer; + private Rectangle _modalLayer = new Rectangle(); + private Canvas _modalLayerPanel = new Canvas(); + private Grid _windowRoot; + private WindowControl _windowControl; + private bool _ignorePropertyChanged; + private bool _hasChildren; + private bool _hasWindowContainer; + + #endregion //Private Members + + #region Public Properties + + #region DialogResult + + private bool? _dialogResult; + /// + /// Gets or sets a value indicating whether the ChildWindow was accepted or canceled. + /// + /// + /// True if the child window was accepted; false if the child window was + /// canceled. The default is null. + /// + [TypeConverter(typeof(NullableBoolConverter))] + public bool? DialogResult + { + get + { + return _dialogResult; + } + set + { + if (_dialogResult != value) + { + _dialogResult = value; + this.Close(); + } + } + } + + #endregion //DialogResult + + #region DesignerWindowState + + public static readonly DependencyProperty DesignerWindowStateProperty = DependencyProperty.Register("DesignerWindowState", typeof(WindowState), typeof(ChildWindow), new PropertyMetadata(WindowState.Closed, OnDesignerWindowStatePropertyChanged)); + public WindowState DesignerWindowState + { + get + { + return (WindowState)GetValue(DesignerWindowStateProperty); + } + set + { + SetValue(DesignerWindowStateProperty, value); + } + } + + private static void OnDesignerWindowStatePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ChildWindow childWindow = d as ChildWindow; + if (childWindow != null) + childWindow.OnDesignerWindowStatePropertyChanged((WindowState)e.OldValue, (WindowState)e.NewValue); + } + + protected virtual void OnDesignerWindowStatePropertyChanged(WindowState oldValue, WindowState newValue) + { + if (DesignerProperties.GetIsInDesignMode(this)) + { + Visibility = newValue == Xceed.Wpf.Toolkit.WindowState.Open ? Visibility.Visible : Visibility.Collapsed; + } + } + + #endregion //DesignerWindowState + + #region FocusedElement + + public static readonly DependencyProperty FocusedElementProperty = DependencyProperty.Register("FocusedElement", typeof(FrameworkElement), typeof(ChildWindow), new UIPropertyMetadata(null)); + public FrameworkElement FocusedElement + { + get + { + return (FrameworkElement)GetValue(FocusedElementProperty); + } + set + { + SetValue(FocusedElementProperty, value); + } + } + + #endregion + + #region IsModal + + public static readonly DependencyProperty IsModalProperty = DependencyProperty.Register("IsModal", typeof(bool), typeof(ChildWindow), new UIPropertyMetadata(false, new PropertyChangedCallback(OnIsModalPropertyChanged))); + public bool IsModal + { + get + { + return (bool)GetValue(IsModalProperty); + } + set + { + SetValue(IsModalProperty, value); + } + } + + private static void OnIsModalPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ChildWindow childWindow = d as ChildWindow; + if (childWindow != null) + childWindow.OnIsModalChanged((bool)e.OldValue, (bool)e.NewValue); + } + + internal event EventHandler IsModalChanged; + + private void OnIsModalChanged(bool oldValue, bool newValue) + { + EventHandler handler = IsModalChanged; + if (handler != null) + { + handler(this, EventArgs.Empty); + } + + if (!_hasWindowContainer) + { + if (newValue) + { + KeyboardNavigation.SetTabNavigation(this, KeyboardNavigationMode.Cycle); + ShowModalLayer(); + } + else + { + KeyboardNavigation.SetTabNavigation(this, KeyboardNavigationMode.Continue); + HideModalLayer(); + } + } + } + + #endregion //IsModal + + #region OverlayBrush (Obsolete) + + [Obsolete("This property is obsolete and should no longer be used. Use WindowContainer.ModalBackgroundBrushProperty instead.")] + public static readonly DependencyProperty OverlayBrushProperty = DependencyProperty.Register("OverlayBrush", typeof(Brush), typeof(ChildWindow), new PropertyMetadata(Brushes.Gray, OnOverlayBrushChanged)); + [Obsolete("This property is obsolete and should no longer be used. Use WindowContainer.ModalBackgroundBrushProperty instead.")] + public Brush OverlayBrush + { + get + { + return (Brush)GetValue(OverlayBrushProperty); + } + set + { + SetValue(OverlayBrushProperty, value); + } + } + + private static void OnOverlayBrushChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ChildWindow childWindow = d as ChildWindow; + if (childWindow != null) + childWindow.OnOverlayBrushChanged((Brush)e.OldValue, (Brush)e.NewValue); + } + + [Obsolete("This method is obsolete and should no longer be used. Use WindowContainer.ModalBackgroundBrushProperty instead.")] + protected virtual void OnOverlayBrushChanged(Brush oldValue, Brush newValue) + { + _modalLayer.Fill = newValue; + } + + #endregion //OverlayBrush + + #region OverlayOpacity (Obsolete) + + [Obsolete("This property is obsolete and should no longer be used. Use WindowContainer.ModalBackgroundBrushProperty instead.")] + public static readonly DependencyProperty OverlayOpacityProperty = DependencyProperty.Register("OverlayOpacity", typeof(double), typeof(ChildWindow), new PropertyMetadata(0.5, OnOverlayOpacityChanged)); + [Obsolete("This property is obsolete and should no longer be used. Use WindowContainer.ModalBackgroundBrushProperty instead.")] + public double OverlayOpacity + { + get + { + return (double)GetValue(OverlayOpacityProperty); + } + set + { + SetValue(OverlayOpacityProperty, value); + } + } + + private static void OnOverlayOpacityChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ChildWindow childWindow = d as ChildWindow; + if (childWindow != null) + childWindow.OnOverlayOpacityChanged((double)e.OldValue, (double)e.NewValue); + } + + [Obsolete("This method is obsolete and should no longer be used. Use WindowContainer.ModalBackgroundBrushProperty instead.")] + protected virtual void OnOverlayOpacityChanged(double oldValue, double newValue) + { + _modalLayer.Opacity = newValue; + } + + #endregion //OverlayOpacity + + #region WindowStartupLocation + + public static readonly DependencyProperty WindowStartupLocationProperty = DependencyProperty.Register("WindowStartupLocation", typeof(WindowStartupLocation), typeof(ChildWindow), new UIPropertyMetadata(WindowStartupLocation.Manual, OnWindowStartupLocationChanged)); + public WindowStartupLocation WindowStartupLocation + { + get + { + return (WindowStartupLocation)GetValue(WindowStartupLocationProperty); + } + set + { + SetValue(WindowStartupLocationProperty, value); + } + } + + private static void OnWindowStartupLocationChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) + { + ChildWindow childWindow = o as ChildWindow; + if (childWindow != null) + childWindow.OnWindowStartupLocationChanged((WindowStartupLocation)e.OldValue, (WindowStartupLocation)e.NewValue); + } + + protected virtual void OnWindowStartupLocationChanged(WindowStartupLocation oldValue, WindowStartupLocation newValue) + { + // TODO: Add your property changed side-effects. Descendants can override as well. + } + + #endregion //WindowStartupLocation + + #region WindowState + + public static readonly DependencyProperty WindowStateProperty = DependencyProperty.Register("WindowState", typeof(WindowState), typeof(ChildWindow), new FrameworkPropertyMetadata(WindowState.Closed, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnWindowStatePropertyChanged)); + public WindowState WindowState + { + get + { + return (WindowState)GetValue(WindowStateProperty); + } + set + { + SetValue(WindowStateProperty, value); + } + } + + private static void OnWindowStatePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ChildWindow childWindow = d as ChildWindow; + if (childWindow != null) + childWindow.OnWindowStatePropertyChanged((WindowState)e.OldValue, (WindowState)e.NewValue); + } + + protected virtual void OnWindowStatePropertyChanged(WindowState oldValue, WindowState newValue) + { + if (!DesignerProperties.GetIsInDesignMode(this)) + { + if (!_ignorePropertyChanged) + SetWindowState(newValue); + } + else + { + Visibility = DesignerWindowState == Xceed.Wpf.Toolkit.WindowState.Open ? Visibility.Visible : System.Windows.Visibility.Collapsed; + } + } + + #endregion //WindowState + + #endregion //Public Properties + + #region Constructors + + static ChildWindow() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(ChildWindow), new FrameworkPropertyMetadata(typeof(ChildWindow))); + } + + public ChildWindow() + { + DesignerWindowState = Xceed.Wpf.Toolkit.WindowState.Open; + + _modalLayer.Fill = OverlayBrush; + _modalLayer.Opacity = OverlayOpacity; + + this.IsVisibleChanged += this.ChildWindow_IsVisibleChanged; + } + + #endregion //Constructors + + #region Base Class Overrides + + internal override bool AllowPublicIsActiveChange + { + get { return false; } + } + + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + if (_windowControl != null) + { + _windowControl.HeaderDragDelta -= (o, e) => this.OnHeaderDragDelta(e); + _windowControl.HeaderIconDoubleClicked -= (o, e) => this.OnHeaderIconDoubleClick(e); + _windowControl.CloseButtonClicked -= (o, e) => this.OnCloseButtonClicked(e); + } + _windowControl = this.GetTemplateChild(PART_WindowControl) as WindowControl; + if (_windowControl != null) + { + _windowControl.HeaderDragDelta += (o, e) => this.OnHeaderDragDelta(e); + _windowControl.HeaderIconDoubleClicked += (o, e) => this.OnHeaderIconDoubleClick(e); + _windowControl.CloseButtonClicked += (o, e) => this.OnCloseButtonClicked(e); + } + + this.UpdateBlockMouseInputsPanel(); + + _windowRoot = this.GetTemplateChild(PART_WindowRoot) as Grid; + if (_windowRoot != null) + { + _windowRoot.RenderTransform = _moveTransform; + } + _hasWindowContainer = (VisualTreeHelper.GetParent(this) as WindowContainer) != null; + + if (!_hasWindowContainer) + { + _parentContainer = VisualTreeHelper.GetParent(this) as FrameworkElement; + if (_parentContainer != null) + { + _parentContainer.LayoutUpdated += ParentContainer_LayoutUpdated; + _parentContainer.SizeChanged += ParentContainer_SizeChanged; + + //this is for XBAP applications only. When inside an XBAP the parent container has no height or width until it has loaded. Therefore + //we need to handle the loaded event and reposition the window. + if (System.Windows.Interop.BrowserInteropHelper.IsBrowserHosted) + { + _parentContainer.Loaded += (o, e) => + { + ExecuteOpen(); + }; + } + } + + this.Unloaded += new RoutedEventHandler(ChildWindow_Unloaded); + + //initialize our modal background width/height + _modalLayer.Height = _parentContainer.ActualHeight; + _modalLayer.Width = _parentContainer.ActualWidth; + + _root = this.GetTemplateChild(PART_Root) as Grid; + +#if VS2008 + FocusVisualStyle = null; +#else + Style focusStyle = (_root != null) ? _root.Resources["FocusVisualStyle"] as Style : null; + if (focusStyle != null) + { + Setter focusStyleDataContext = new Setter(Control.DataContextProperty, this); + focusStyle.Setters.Add(focusStyleDataContext); + FocusVisualStyle = focusStyle; + } +#endif + if (_root != null) + { + _root.Children.Add(_modalLayerPanel); + } + } + } + + protected override void OnGotFocus(RoutedEventArgs e) + { + base.OnGotFocus(e); + + Action action = () => + { + if (FocusedElement != null) + { + _hasChildren = true; + FocusedElement.Focus(); + } + else + { + //Focus first Focusable Child element of ChildWindow + var focusableChild = TreeHelper.FindChild(this.Content as DependencyObject, x => x.Focusable); + if (focusableChild != null) + { + _hasChildren = true; + focusableChild.Focus(); + } + else + { + _hasChildren = false; + } + } + }; + + Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, action); + } + + protected override void OnPreviewKeyDown(KeyEventArgs e) + { + base.OnPreviewKeyDown(e); + + if (this.IsModal) + { + // Prevent MenuItem shortcuts while ChildWindow is modal. + if (Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt)) + { + e.Handled = true; + } + // Prevent Tab when no children + else if ((e.Key == Key.Tab) && !_hasChildren) + { + e.Handled = true; + } + } + } + + protected override void OnKeyDown(KeyEventArgs e) + { + base.OnKeyDown(e); + + if (WindowState == WindowState.Open) + { + switch (e.Key) + { + case Key.Left: + this.Left -= _horizontalOffset; + e.Handled = true; + break; + + case Key.Right: + this.Left += _horizontalOffset; + e.Handled = true; + break; + + case Key.Down: + this.Top += _verticalOffset; + e.Handled = true; + break; + + case Key.Up: + this.Top -= _verticalOffset; + e.Handled = true; + break; + } + } + } + + protected override void OnLeftPropertyChanged(double oldValue, double newValue) + { + base.OnLeftPropertyChanged(oldValue, newValue); + + _hasWindowContainer = (VisualTreeHelper.GetParent(this) as WindowContainer) != null; + if (!_hasWindowContainer) + { + Left = GetRestrictedLeft(); + ProcessMove(newValue - oldValue, 0); + } + } + + protected override void OnTopPropertyChanged(double oldValue, double newValue) + { + base.OnTopPropertyChanged(oldValue, newValue); + + _hasWindowContainer = (VisualTreeHelper.GetParent(this) as WindowContainer) != null; + if (!_hasWindowContainer) + { + Top = GetRestrictedTop(); + ProcessMove(0, newValue - oldValue); + } + } + + internal override void UpdateBlockMouseInputsPanel() + { + if (_windowControl != null) + { + _windowControl.IsBlockMouseInputsPanelActive = this.IsBlockMouseInputsPanelActive; + } + } + + + + + #endregion //Base Class Overrides + + #region Event Handlers + + protected virtual void OnHeaderDragDelta(DragDeltaEventArgs e) + { + if (!this.IsCurrentWindow(e.OriginalSource)) + return; + + e.Handled = true; + + DragDeltaEventArgs args = new DragDeltaEventArgs(e.HorizontalChange, e.VerticalChange); + args.RoutedEvent = HeaderDragDeltaEvent; + args.Source = this; + this.RaiseEvent(args); + + if (!args.Handled) + { + if (object.Equals(e.OriginalSource, _windowControl)) + { + double left = 0.0; + + if (this.FlowDirection == FlowDirection.RightToLeft) + left = this.Left - e.HorizontalChange; + else + left = this.Left + e.HorizontalChange; + + this.Left = left; + this.Top += e.VerticalChange; + } + } + } + + protected virtual void OnHeaderIconDoubleClick(MouseButtonEventArgs e) + { + if (!this.IsCurrentWindow(e.OriginalSource)) + return; + + e.Handled = true; + + MouseButtonEventArgs args = new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, MouseButton.Left); + args.RoutedEvent = HeaderIconDoubleClickedEvent; + args.Source = this; + this.RaiseEvent(args); + + if (!args.Handled) + { + this.Close(); + } + } + + protected virtual void OnCloseButtonClicked(RoutedEventArgs e) + { + if (!this.IsCurrentWindow(e.OriginalSource)) + return; + + e.Handled = true; + + RoutedEventArgs args = new RoutedEventArgs(CloseButtonClickedEvent, this); + this.RaiseEvent(args); + + if (!args.Handled) + { + this.Close(); + } + } + + + + + + + + + + + + + + [Obsolete("This method is obsolete and should no longer be used.")] + private void ParentContainer_LayoutUpdated(object sender, EventArgs e) + { + if (DesignerProperties.GetIsInDesignMode(this)) + return; + + //we only want to set the start position if this is the first time the control has bee initialized + if (!_startupPositionInitialized) + { + ExecuteOpen(); + _startupPositionInitialized = true; + } + } + + [Obsolete("This method is obsolete and should no longer be used.")] + private void ChildWindow_Unloaded(object sender, RoutedEventArgs e) + { + if (_parentContainer != null) + { + _parentContainer.LayoutUpdated -= ParentContainer_LayoutUpdated; + _parentContainer.SizeChanged -= ParentContainer_SizeChanged; + + //this is for XBAP applications only. When inside an XBAP the parent container has no height or width until it has loaded. Therefore + //we need to handle the loaded event and reposition the window. + if (System.Windows.Interop.BrowserInteropHelper.IsBrowserHosted) + { + _parentContainer.Loaded -= (o, ev) => + { + ExecuteOpen(); + }; + } + } + } + + [Obsolete("This method is obsolete and should no longer be used.")] + void ParentContainer_SizeChanged(object sender, SizeChangedEventArgs e) + { + //resize our modal layer + _modalLayer.Height = e.NewSize.Height; + _modalLayer.Width = e.NewSize.Width; + + //reposition our window + Left = GetRestrictedLeft(); + Top = GetRestrictedTop(); + } + + private void ChildWindow_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) + { + if ((bool)e.NewValue && this.IsModal) + { + this.Focus(); + } + } + + + + #endregion //Event Handlers + + #region Methods + + #region Private + + + + [Obsolete("This method is obsolete and should no longer be used. Use WindowContainer.GetRestrictedLeft() instead.")] + private double GetRestrictedLeft() + { + if (Left < 0) + return 0; + + if ((_parentContainer != null) && (_windowRoot != null)) + { + if (Left + _windowRoot.ActualWidth > _parentContainer.ActualWidth && _parentContainer.ActualWidth != 0) + { + double left = _parentContainer.ActualWidth - _windowRoot.ActualWidth; + return left < 0 ? 0 : left; + } + } + + return Left; + } + + [Obsolete("This method is obsolete and should no longer be used. Use WindowContainer.GetRestrictedTop() instead.")] + private double GetRestrictedTop() + { + if (Top < 0) + return 0; + + if ((_parentContainer != null) && (_windowRoot != null)) + { + if (Top + _windowRoot.ActualHeight > _parentContainer.ActualHeight && _parentContainer.ActualHeight != 0) + { + double top = _parentContainer.ActualHeight - _windowRoot.ActualHeight; + return top < 0 ? 0 : top; + } + } + + return Top; + } + + private void SetWindowState(WindowState state) + { + switch (state) + { + case WindowState.Closed: + { + ExecuteClose(); + break; + } + case WindowState.Open: + { + ExecuteOpen(); + break; + } + } + } + + private void ExecuteClose() + { + CancelEventArgs e = new CancelEventArgs(); + OnClosing(e); + + if (!e.Cancel) + { + if (!_dialogResult.HasValue) + _dialogResult = false; + + OnClosed(EventArgs.Empty); + } + else + { + CancelClose(); + } + } + + private void CancelClose() + { + _dialogResult = null; //when the close is cancelled, DialogResult should be null + + _ignorePropertyChanged = true; + WindowState = WindowState.Open; //now reset the window state to open because the close was cancelled + _ignorePropertyChanged = false; + } + + private void ExecuteOpen() + { + _dialogResult = null; //reset the dialogResult to null each time the window is opened + + if (!_hasWindowContainer) + if (WindowStartupLocation == Xceed.Wpf.Toolkit.WindowStartupLocation.Center) + CenterChildWindow(); + + if (!_hasWindowContainer) + BringToFront(); + } + + private bool IsCurrentWindow(object windowtoTest) + { + return object.Equals(_windowControl, windowtoTest); + } + + [Obsolete("This method is obsolete and should no longer be used. Use WindowContainer.BringToFront() instead.")] + private void BringToFront() + { + int index = 0; + + if (_parentContainer != null) + index = (int)_parentContainer.GetValue(Canvas.ZIndexProperty); + + SetValue(Canvas.ZIndexProperty, ++index); + + if (IsModal) + Canvas.SetZIndex(_modalLayerPanel, index - 2); + } + + [Obsolete("This method is obsolete and should no longer be used. Use WindowContainer.CenterChild() instead.")] + private void CenterChildWindow() + { + if ((_parentContainer != null) && (_windowRoot != null)) + { + _windowRoot.UpdateLayout(); + + Left = (_parentContainer.ActualWidth - _windowRoot.ActualWidth) / 2.0; + Top = (_parentContainer.ActualHeight - _windowRoot.ActualHeight) / 2.0; + } + } + + [Obsolete("This method is obsolete and should no longer be used.")] + private void ShowModalLayer() + { + if (!DesignerProperties.GetIsInDesignMode(this)) + { + if (!_modalLayerPanel.Children.Contains(_modalLayer)) + _modalLayerPanel.Children.Add(_modalLayer); + + _modalLayer.Visibility = System.Windows.Visibility.Visible; + } + } + + [Obsolete("This method is obsolete and should no longer be used.")] + private void HideModalLayer() + { + _modalLayer.Visibility = System.Windows.Visibility.Collapsed; + } + + [Obsolete("This method is obsolete and should no longer be used. Use the ChildWindow in a WindowContainer instead.")] + private void ProcessMove(double x, double y) + { + _moveTransform.X += x; + _moveTransform.Y += y; + + InvalidateArrange(); + } + + #endregion //Private + + #region Public + + public void Show() + { + WindowState = WindowState.Open; + } + + public void Close() + { + WindowState = WindowState.Closed; + } + + #endregion //Public + + #endregion //Methods + + #region Events + + /// + /// Occurs when the ChildWindow is closed. + /// + public event EventHandler Closed; + protected virtual void OnClosed(EventArgs e) + { + if (Closed != null) + Closed(this, e); + } + + /// + /// Occurs when the ChildWindow is closing. + /// + public event EventHandler Closing; + protected virtual void OnClosing(CancelEventArgs e) + { + if (Closing != null) + Closing(this, e); + } + + #endregion //Events + + } + +#pragma warning restore 0809 +#pragma warning restore 0618 +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ChildWindow/Implementation/WindowStartupLocation.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ChildWindow/Implementation/WindowStartupLocation.cs new file mode 100644 index 00000000..384c7dd3 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ChildWindow/Implementation/WindowStartupLocation.cs @@ -0,0 +1,24 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +namespace Xceed.Wpf.Toolkit +{ + public enum WindowStartupLocation + { + Center, + Manual + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ChildWindow/Implementation/WindowState.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ChildWindow/Implementation/WindowState.cs new file mode 100644 index 00000000..1261a986 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ChildWindow/Implementation/WindowState.cs @@ -0,0 +1,24 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +namespace Xceed.Wpf.Toolkit +{ + public enum WindowState + { + Closed, + Open + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ChildWindow/Themes/Aero2.NormalColor.xaml b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ChildWindow/Themes/Aero2.NormalColor.xaml new file mode 100644 index 00000000..f7286fd0 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ChildWindow/Themes/Aero2.NormalColor.xaml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ChildWindow/Themes/Generic.xaml b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ChildWindow/Themes/Generic.xaml new file mode 100644 index 00000000..53f7b08e --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ChildWindow/Themes/Generic.xaml @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Chromes/Implementation/ButtonChrome.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Chromes/Implementation/ButtonChrome.cs new file mode 100644 index 00000000..e8d4f386 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Chromes/Implementation/ButtonChrome.cs @@ -0,0 +1,272 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Windows; +using System.Windows.Controls; + +namespace Xceed.Wpf.Toolkit.Chromes +{ + public class ButtonChrome : ContentControl + { + #region CornerRadius + + public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.Register("CornerRadius", typeof(CornerRadius), typeof(ButtonChrome), new UIPropertyMetadata(default(CornerRadius), new PropertyChangedCallback(OnCornerRadiusChanged))); + public CornerRadius CornerRadius + { + get + { + return (CornerRadius)GetValue(CornerRadiusProperty); + } + set + { + SetValue(CornerRadiusProperty, value); + } + } + + private static void OnCornerRadiusChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) + { + ButtonChrome buttonChrome = o as ButtonChrome; + if (buttonChrome != null) + buttonChrome.OnCornerRadiusChanged((CornerRadius)e.OldValue, (CornerRadius)e.NewValue); + } + + protected virtual void OnCornerRadiusChanged(CornerRadius oldValue, CornerRadius newValue) + { + //we always want the InnerBorderRadius to be one less than the CornerRadius + CornerRadius newInnerCornerRadius = new CornerRadius(Math.Max(0, newValue.TopLeft - 1), + Math.Max(0, newValue.TopRight - 1), + Math.Max(0, newValue.BottomRight - 1), + Math.Max(0, newValue.BottomLeft - 1)); + + InnerCornerRadius = newInnerCornerRadius; + } + + #endregion //CornerRadius + + #region InnerCornerRadius + + public static readonly DependencyProperty InnerCornerRadiusProperty = DependencyProperty.Register("InnerCornerRadius", typeof(CornerRadius), typeof(ButtonChrome), new UIPropertyMetadata(default(CornerRadius), new PropertyChangedCallback(OnInnerCornerRadiusChanged))); + public CornerRadius InnerCornerRadius + { + get + { + return (CornerRadius)GetValue(InnerCornerRadiusProperty); + } + set + { + SetValue(InnerCornerRadiusProperty, value); + } + } + + private static void OnInnerCornerRadiusChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) + { + ButtonChrome buttonChrome = o as ButtonChrome; + if (buttonChrome != null) + buttonChrome.OnInnerCornerRadiusChanged((CornerRadius)e.OldValue, (CornerRadius)e.NewValue); + } + + protected virtual void OnInnerCornerRadiusChanged(CornerRadius oldValue, CornerRadius newValue) + { + // TODO: Add your property changed side-effects. Descendants can override as well. + } + + #endregion //InnerCornerRadius + + #region RenderChecked + + public static readonly DependencyProperty RenderCheckedProperty = DependencyProperty.Register("RenderChecked", typeof(bool), typeof(ButtonChrome), new UIPropertyMetadata(false, OnRenderCheckedChanged)); + public bool RenderChecked + { + get + { + return (bool)GetValue(RenderCheckedProperty); + } + set + { + SetValue(RenderCheckedProperty, value); + } + } + + private static void OnRenderCheckedChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) + { + ButtonChrome buttonChrome = o as ButtonChrome; + if (buttonChrome != null) + buttonChrome.OnRenderCheckedChanged((bool)e.OldValue, (bool)e.NewValue); + } + + protected virtual void OnRenderCheckedChanged(bool oldValue, bool newValue) + { + // TODO: Add your property changed side-effects. Descendants can override as well. + } + + #endregion //RenderChecked + + #region RenderEnabled + + public static readonly DependencyProperty RenderEnabledProperty = DependencyProperty.Register("RenderEnabled", typeof(bool), typeof(ButtonChrome), new UIPropertyMetadata(true, OnRenderEnabledChanged)); + public bool RenderEnabled + { + get + { + return (bool)GetValue(RenderEnabledProperty); + } + set + { + SetValue(RenderEnabledProperty, value); + } + } + + private static void OnRenderEnabledChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) + { + ButtonChrome buttonChrome = o as ButtonChrome; + if (buttonChrome != null) + buttonChrome.OnRenderEnabledChanged((bool)e.OldValue, (bool)e.NewValue); + } + + protected virtual void OnRenderEnabledChanged(bool oldValue, bool newValue) + { + // TODO: Add your property changed side-effects. Descendants can override as well. + } + + #endregion //RenderEnabled + + #region RenderFocused + + public static readonly DependencyProperty RenderFocusedProperty = DependencyProperty.Register("RenderFocused", typeof(bool), typeof(ButtonChrome), new UIPropertyMetadata(false, OnRenderFocusedChanged)); + public bool RenderFocused + { + get + { + return (bool)GetValue(RenderFocusedProperty); + } + set + { + SetValue(RenderFocusedProperty, value); + } + } + + private static void OnRenderFocusedChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) + { + ButtonChrome buttonChrome = o as ButtonChrome; + if (buttonChrome != null) + buttonChrome.OnRenderFocusedChanged((bool)e.OldValue, (bool)e.NewValue); + } + + protected virtual void OnRenderFocusedChanged(bool oldValue, bool newValue) + { + // TODO: Add your property changed side-effects. Descendants can override as well. + } + + #endregion //RenderFocused + + #region RenderMouseOver + + public static readonly DependencyProperty RenderMouseOverProperty = DependencyProperty.Register("RenderMouseOver", typeof(bool), typeof(ButtonChrome), new UIPropertyMetadata(false, OnRenderMouseOverChanged)); + public bool RenderMouseOver + { + get + { + return (bool)GetValue(RenderMouseOverProperty); + } + set + { + SetValue(RenderMouseOverProperty, value); + } + } + + private static void OnRenderMouseOverChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) + { + ButtonChrome buttonChrome = o as ButtonChrome; + if (buttonChrome != null) + buttonChrome.OnRenderMouseOverChanged((bool)e.OldValue, (bool)e.NewValue); + } + + protected virtual void OnRenderMouseOverChanged(bool oldValue, bool newValue) + { + // TODO: Add your property changed side-effects. Descendants can override as well. + } + + #endregion //RenderMouseOver + + #region RenderNormal + + public static readonly DependencyProperty RenderNormalProperty = DependencyProperty.Register("RenderNormal", typeof(bool), typeof(ButtonChrome), new UIPropertyMetadata(true, OnRenderNormalChanged)); + public bool RenderNormal + { + get + { + return (bool)GetValue(RenderNormalProperty); + } + set + { + SetValue(RenderNormalProperty, value); + } + } + + private static void OnRenderNormalChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) + { + ButtonChrome buttonChrome = o as ButtonChrome; + if (buttonChrome != null) + buttonChrome.OnRenderNormalChanged((bool)e.OldValue, (bool)e.NewValue); + } + + protected virtual void OnRenderNormalChanged(bool oldValue, bool newValue) + { + // TODO: Add your property changed side-effects. Descendants can override as well. + } + + #endregion //RenderNormal + + #region RenderPressed + + public static readonly DependencyProperty RenderPressedProperty = DependencyProperty.Register("RenderPressed", typeof(bool), typeof(ButtonChrome), new UIPropertyMetadata(false, OnRenderPressedChanged)); + public bool RenderPressed + { + get + { + return (bool)GetValue(RenderPressedProperty); + } + set + { + SetValue(RenderPressedProperty, value); + } + } + + private static void OnRenderPressedChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) + { + ButtonChrome buttonChrome = o as ButtonChrome; + if (buttonChrome != null) + buttonChrome.OnRenderPressedChanged((bool)e.OldValue, (bool)e.NewValue); + } + + protected virtual void OnRenderPressedChanged(bool oldValue, bool newValue) + { + // TODO: Add your property changed side-effects. Descendants can override as well. + } + + #endregion //RenderPressed + + #region Contsructors + + static ButtonChrome() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(ButtonChrome), new FrameworkPropertyMetadata(typeof(ButtonChrome))); + } + + #endregion //Contsructors + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Chromes/Themes/Aero2.NormalColor.xaml b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Chromes/Themes/Aero2.NormalColor.xaml new file mode 100644 index 00000000..4b4535cc --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Chromes/Themes/Aero2.NormalColor.xaml @@ -0,0 +1,177 @@ + + + + + + + + + + + + diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Chromes/Themes/Generic.xaml b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Chromes/Themes/Generic.xaml new file mode 100644 index 00000000..8b225b64 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Chromes/Themes/Generic.xaml @@ -0,0 +1,228 @@ + + + + + + + + + + + diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Images/Delete16.png b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Images/Delete16.png new file mode 100644 index 00000000..6b24b1bd --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Images/Delete16.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:10009cf8854c08f93496707a728757786bdb7af3dbbd4e9fec4bbe09417df016 +size 682 diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Images/Duplicate.png b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Images/Duplicate.png new file mode 100644 index 00000000..b9f8ca98 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Images/Duplicate.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b4ff86f5213bb5e8809e86a97b0c6ac02497a56e9a48440591d42a06823c4939 +size 262 diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/CollectionControl.Icon.bmp b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/CollectionControl.Icon.bmp new file mode 100644 index 00000000..ce76dc5b --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/CollectionControl.Icon.bmp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e95d8b086aa0680fa4b987fc38d9701b23c24b9d6334806e6d5a7fa0b3687373 +size 822 diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/CollectionControl.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/CollectionControl.cs new file mode 100644 index 00000000..f71dc0b4 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/CollectionControl.cs @@ -0,0 +1,712 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using Xceed.Wpf.Toolkit.Core.Utilities; +using Xceed.Wpf.Toolkit.PropertyGrid; +using System.Windows.Threading; +using System.Reflection; + +namespace Xceed.Wpf.Toolkit +{ + [TemplatePart(Name = PART_NewItemTypesComboBox, Type = typeof(ComboBox))] + [TemplatePart(Name = PART_PropertyGrid, Type = typeof(PropertyGrid.PropertyGrid))] + [TemplatePart(Name = PART_ListBox, Type = typeof(ListBox))] + public class CollectionControl : Control + { + private const string PART_NewItemTypesComboBox = "PART_NewItemTypesComboBox"; + private const string PART_PropertyGrid = "PART_PropertyGrid"; + private const string PART_ListBox = "PART_ListBox"; + + #region Private Members + + private ComboBox _newItemTypesComboBox; + private PropertyGrid.PropertyGrid _propertyGrid; + private ListBox _listBox; + private bool _isCollectionUpdated; + + #endregion + + #region Properties + + #region IsReadOnly Property + + public static readonly DependencyProperty IsReadOnlyProperty = DependencyProperty.Register("IsReadOnly", typeof(bool), typeof(CollectionControl), new UIPropertyMetadata(false)); + public bool IsReadOnly + { + get + { + return (bool)GetValue(IsReadOnlyProperty); + } + set + { + SetValue(IsReadOnlyProperty, value); + } + } + + #endregion //Items + + #region Items Property + + public static readonly DependencyProperty ItemsProperty = DependencyProperty.Register("Items", typeof(ObservableCollection), typeof(CollectionControl), new UIPropertyMetadata(null)); + public ObservableCollection Items + { + get + { + return (ObservableCollection)GetValue(ItemsProperty); + } + set + { + SetValue(ItemsProperty, value); + } + } + + #endregion //Items + + #region ItemsSource Property + + public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(CollectionControl), new UIPropertyMetadata(null, OnItemsSourceChanged)); + public IEnumerable ItemsSource + { + get + { + return (IEnumerable)GetValue(ItemsSourceProperty); + } + set + { + SetValue(ItemsSourceProperty, value); + } + } + + private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var CollectionControl = (CollectionControl)d; + if (CollectionControl != null) + CollectionControl.OnItemSourceChanged((IEnumerable)e.OldValue, (IEnumerable)e.NewValue); + } + + public void OnItemSourceChanged(IEnumerable oldValue, IEnumerable newValue) + { + if (newValue != null) + { + var dict = newValue as IDictionary; + if (dict != null) + { + // A Dictionary contains KeyValuePair that can't be edited. + // We need to Add EditableKeyValuePairs from DictionaryEntries. + foreach (DictionaryEntry item in dict) + { + var keyType = (item.Key != null) + ? item.Key.GetType() + : (dict.GetType().GetGenericArguments().Count() > 0) ? dict.GetType().GetGenericArguments()[0] : typeof(object); + var valueType = (item.Value != null) + ? item.Value.GetType() + : (dict.GetType().GetGenericArguments().Count() > 1) ? dict.GetType().GetGenericArguments()[1] : typeof(object); + var editableKeyValuePair = ListUtilities.CreateEditableKeyValuePair(item.Key + , keyType + , item.Value + , valueType); + this.Items.Add(editableKeyValuePair); + } + } + else + { + foreach (var item in newValue) + { + if (item != null) + { + Items.Add(item); + } + } + } + } + } + + #endregion //ItemsSource + + #region ItemsSourceType Property + + public static readonly DependencyProperty ItemsSourceTypeProperty = DependencyProperty.Register("ItemsSourceType", typeof(Type), typeof(CollectionControl), new UIPropertyMetadata(null)); + public Type ItemsSourceType + { + get + { + return (Type)GetValue(ItemsSourceTypeProperty); + } + set + { + SetValue(ItemsSourceTypeProperty, value); + } + } + + #endregion //ItemsSourceType + + #region NewItemType Property + + public static readonly DependencyProperty NewItemTypesProperty = DependencyProperty.Register("NewItemTypes", typeof(IList), typeof(CollectionControl), new UIPropertyMetadata(null)); + public IList NewItemTypes + { + get + { + return (IList)GetValue(NewItemTypesProperty); + } + set + { + SetValue(NewItemTypesProperty, value); + } + } + + #endregion //NewItemType + + #region PropertiesLabel Property + + public static readonly DependencyProperty PropertiesLabelProperty = DependencyProperty.Register("PropertiesLabel", typeof(object), typeof(CollectionControl), new UIPropertyMetadata("Properties:")); + public object PropertiesLabel + { + get + { + return (object)GetValue(PropertiesLabelProperty); + } + set + { + SetValue(PropertiesLabelProperty, value); + } + } + + #endregion //PropertiesLabel + + #region SelectedItem Property + + public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register("SelectedItem", typeof(object), typeof(CollectionControl), new UIPropertyMetadata(null)); + public object SelectedItem + { + get + { + return (object)GetValue(SelectedItemProperty); + } + set + { + SetValue(SelectedItemProperty, value); + } + } + + #endregion //EditorDefinitions + + #region TypeSelectionLabel Property + + public static readonly DependencyProperty TypeSelectionLabelProperty = DependencyProperty.Register("TypeSelectionLabel", typeof(object), typeof(CollectionControl), new UIPropertyMetadata("Select type:")); + public object TypeSelectionLabel + { + get + { + return (object)GetValue(TypeSelectionLabelProperty); + } + set + { + SetValue(TypeSelectionLabelProperty, value); + } + } + + #endregion //TypeSelectionLabel + + #region EditorDefinitions Property + + public static readonly DependencyProperty EditorDefinitionsProperty = DependencyProperty.Register("EditorDefinitions", typeof(EditorDefinitionCollection), typeof(CollectionControl), new UIPropertyMetadata(null)); + public EditorDefinitionCollection EditorDefinitions + { + get + { + return (EditorDefinitionCollection)GetValue(EditorDefinitionsProperty); + } + set + { + SetValue(EditorDefinitionsProperty, value); + } + } + + #endregion //EditorDefinitions + + #endregion //Properties + + #region Override Methods + + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + if (_newItemTypesComboBox != null) + { + _newItemTypesComboBox.Loaded -= new RoutedEventHandler(this.NewItemTypesComboBox_Loaded); + } + _newItemTypesComboBox = GetTemplateChild(PART_NewItemTypesComboBox) as ComboBox; + if (_newItemTypesComboBox != null) + { + _newItemTypesComboBox.Loaded += new RoutedEventHandler(this.NewItemTypesComboBox_Loaded); + } + + _listBox = this.GetTemplateChild(PART_ListBox) as ListBox; + + if (_propertyGrid != null) + { + _propertyGrid.PropertyValueChanged -= this.PropertyGrid_PropertyValueChanged; + } + _propertyGrid = GetTemplateChild(PART_PropertyGrid) as PropertyGrid.PropertyGrid; + if (_propertyGrid != null) + { + _propertyGrid.PropertyValueChanged += this.PropertyGrid_PropertyValueChanged; + } + } + + public PropertyGrid.PropertyGrid PropertyGrid + { + get + { + if (_propertyGrid == null) + { + this.ApplyTemplate(); + } + return _propertyGrid; + } + } + + + + + #endregion + + #region Constructors + + static CollectionControl() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(CollectionControl), new FrameworkPropertyMetadata(typeof(CollectionControl))); + } + + public CollectionControl() + { + Items = new ObservableCollection(); + CommandBindings.Add(new CommandBinding(ApplicationCommands.New, this.AddNew, this.CanAddNew)); + CommandBindings.Add(new CommandBinding(ApplicationCommands.Delete, this.Delete, this.CanDelete)); + CommandBindings.Add(new CommandBinding(ApplicationCommands.Copy, this.Duplicate, this.CanDuplicate)); + CommandBindings.Add(new CommandBinding(ComponentCommands.MoveDown, this.MoveDown, this.CanMoveDown)); + CommandBindings.Add(new CommandBinding(ComponentCommands.MoveUp, this.MoveUp, this.CanMoveUp)); + } + + #endregion //Constructors + + #region Events + + #region ItemDeleting Event + + public delegate void ItemDeletingRoutedEventHandler(object sender, ItemDeletingEventArgs e); + + public static readonly RoutedEvent ItemDeletingEvent = EventManager.RegisterRoutedEvent("ItemDeleting", RoutingStrategy.Bubble, typeof(ItemDeletingRoutedEventHandler), typeof(CollectionControl)); + public event ItemDeletingRoutedEventHandler ItemDeleting + { + add + { + AddHandler(ItemDeletingEvent, value); + } + remove + { + RemoveHandler(ItemDeletingEvent, value); + } + } + + #endregion //ItemDeleting Event + + #region ItemDeleted Event + + public delegate void ItemDeletedRoutedEventHandler(object sender, ItemEventArgs e); + + public static readonly RoutedEvent ItemDeletedEvent = EventManager.RegisterRoutedEvent("ItemDeleted", RoutingStrategy.Bubble, typeof(ItemDeletedRoutedEventHandler), typeof(CollectionControl)); + public event ItemDeletedRoutedEventHandler ItemDeleted + { + add + { + AddHandler(ItemDeletedEvent, value); + } + remove + { + RemoveHandler(ItemDeletedEvent, value); + } + } + + #endregion //ItemDeleted Event + + #region ItemAdding Event + + public delegate void ItemAddingRoutedEventHandler(object sender, ItemAddingEventArgs e); + + public static readonly RoutedEvent ItemAddingEvent = EventManager.RegisterRoutedEvent("ItemAdding", RoutingStrategy.Bubble, typeof(ItemAddingRoutedEventHandler), typeof(CollectionControl)); + public event ItemAddingRoutedEventHandler ItemAdding + { + add + { + AddHandler(ItemAddingEvent, value); + } + remove + { + RemoveHandler(ItemAddingEvent, value); + } + } + + #endregion //ItemAdding Event + + #region ItemAdded Event + + public delegate void ItemAddedRoutedEventHandler(object sender, ItemEventArgs e); + + public static readonly RoutedEvent ItemAddedEvent = EventManager.RegisterRoutedEvent("ItemAdded", RoutingStrategy.Bubble, typeof(ItemAddedRoutedEventHandler), typeof(CollectionControl)); + public event ItemAddedRoutedEventHandler ItemAdded + { + add + { + AddHandler(ItemAddedEvent, value); + } + remove + { + RemoveHandler(ItemAddedEvent, value); + } + } + + #endregion //ItemAdded Event + + #region ItemMovedDown Event + + public delegate void ItemMovedDownRoutedEventHandler(object sender, ItemEventArgs e); + + public static readonly RoutedEvent ItemMovedDownEvent = EventManager.RegisterRoutedEvent("ItemMovedDown", RoutingStrategy.Bubble, typeof(ItemMovedDownRoutedEventHandler), typeof(CollectionControl)); + public event ItemMovedDownRoutedEventHandler ItemMovedDown + { + add + { + AddHandler(ItemMovedDownEvent, value); + } + remove + { + RemoveHandler(ItemMovedDownEvent, value); + } + } + + #endregion //ItemMovedDown Event + + #region ItemMovedUp Event + + public delegate void ItemMovedUpRoutedEventHandler(object sender, ItemEventArgs e); + + public static readonly RoutedEvent ItemMovedUpEvent = EventManager.RegisterRoutedEvent("ItemMovedUp", RoutingStrategy.Bubble, typeof(ItemMovedUpRoutedEventHandler), typeof(CollectionControl)); + public event ItemMovedUpRoutedEventHandler ItemMovedUp + { + add + { + AddHandler(ItemMovedUpEvent, value); + } + remove + { + RemoveHandler(ItemMovedUpEvent, value); + } + } + + #endregion //ItemMovedUp Event + + #endregion + + #region EventHandlers + + void NewItemTypesComboBox_Loaded(object sender, RoutedEventArgs e) + { + if (_newItemTypesComboBox != null) + _newItemTypesComboBox.SelectedIndex = 0; + } + + private void PropertyGrid_PropertyValueChanged(object sender, PropertyGrid.PropertyValueChangedEventArgs e) + { + if (_listBox != null) + { + _isCollectionUpdated = true; + _listBox.Dispatcher.BeginInvoke(DispatcherPriority.Input, new Action(() => + { + _listBox.Items.Refresh(); + } + )); + } + } + + #endregion + + #region Commands + + private void AddNew(object sender, ExecutedRoutedEventArgs e) + { + var newItem = this.CreateNewItem((Type)e.Parameter); + + this.AddNewCore(newItem); + } + + private void CanAddNew(object sender, CanExecuteRoutedEventArgs e) + { + var t = e.Parameter as Type; + this.CanAddNewCore(t, e); + } + + private void CanAddNewCore(Type t, CanExecuteRoutedEventArgs e) + { + if ((t != null) && !this.IsReadOnly) + { + var isComplexStruct = t.IsValueType && !t.IsEnum && !t.IsPrimitive; + + if (isComplexStruct || (t.GetConstructor(Type.EmptyTypes) != null)) + { + e.CanExecute = true; + } + } + } + + private void AddNewCore(object newItem) + { + if (newItem == null) + throw new ArgumentNullException("newItem"); + + var eventArgs = new ItemAddingEventArgs(ItemAddingEvent, newItem); + this.RaiseEvent(eventArgs); + if (eventArgs.Cancel) + return; + newItem = eventArgs.Item; + + this.Items.Add(newItem); + + this.RaiseEvent(new ItemEventArgs(ItemAddedEvent, newItem)); + _isCollectionUpdated = true; + + this.SelectedItem = newItem; + } + + private void Delete(object sender, ExecutedRoutedEventArgs e) + { + var eventArgs = new ItemDeletingEventArgs(ItemDeletingEvent, e.Parameter); + this.RaiseEvent(eventArgs); + if (eventArgs.Cancel) + return; + + this.Items.Remove(e.Parameter); + + this.RaiseEvent(new ItemEventArgs(ItemDeletedEvent, e.Parameter)); + _isCollectionUpdated = true; + } + + private void CanDelete(object sender, CanExecuteRoutedEventArgs e) + { + e.CanExecute = e.Parameter != null && !this.IsReadOnly; + } + + private void Duplicate(object sender, ExecutedRoutedEventArgs e) + { + var newItem = this.DuplicateItem(e); + this.AddNewCore(newItem); + } + + private void CanDuplicate(object sender, CanExecuteRoutedEventArgs e) + { + var t = (e.Parameter != null) ? e.Parameter.GetType() : null; + this.CanAddNewCore(t, e); + } + + private object DuplicateItem(ExecutedRoutedEventArgs e) + { + if (e == null) + throw new ArgumentNullException("e"); + + var baseItem = e.Parameter; + var newItemType = baseItem.GetType(); + var newItem = this.CreateNewItem(newItemType); + + var type = newItemType; + while (type != null) + { + var baseProperties = type.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); + foreach (var prop in baseProperties) + { + prop.SetValue(newItem, prop.GetValue(baseItem)); + } + type = type.BaseType; + } + + return newItem; + } + + private void MoveDown(object sender, ExecutedRoutedEventArgs e) + { + var selectedItem = e.Parameter; + var index = Items.IndexOf(selectedItem); + Items.RemoveAt(index); + Items.Insert(++index, selectedItem); + + this.RaiseEvent(new ItemEventArgs(ItemMovedDownEvent, selectedItem)); + _isCollectionUpdated = true; + + this.SelectedItem = selectedItem; + } + + private void CanMoveDown(object sender, CanExecuteRoutedEventArgs e) + { + if (e.Parameter != null && Items.IndexOf(e.Parameter) < (Items.Count - 1) && !this.IsReadOnly) + e.CanExecute = true; + } + + private void MoveUp(object sender, ExecutedRoutedEventArgs e) + { + var selectedItem = e.Parameter; + var index = Items.IndexOf(selectedItem); + this.Items.RemoveAt(index); + this.Items.Insert(--index, selectedItem); + + this.RaiseEvent(new ItemEventArgs(ItemMovedUpEvent, selectedItem)); + _isCollectionUpdated = true; + + this.SelectedItem = selectedItem; + } + + private void CanMoveUp(object sender, CanExecuteRoutedEventArgs e) + { + if (e.Parameter != null && Items.IndexOf(e.Parameter) > 0 && !this.IsReadOnly) + e.CanExecute = true; + } + + #endregion //Commands + + #region Methods + + public bool PersistChanges() + { + this.PersistChanges(this.Items); + return _isCollectionUpdated; + } + + internal void PersistChanges(IList sourceList) + { + var collection = ComputeItemsSource(); + if (collection == null) + return; + + //IDictionary and IDictionary + if (collection is IDictionary) + { + //For a Dictionary, we need to parse the list of EditableKeyValuePair and add KeyValuePair to the Dictionary. + var dict = (IDictionary)collection; + //the easiest way to persist changes to the source is to just clear the source list and then add all items to it. + dict.Clear(); + + foreach (var item in sourceList) + { + var propInfoKey = item.GetType().GetProperty("Key"); + var propInfoValue = item.GetType().GetProperty("Value"); + if ((propInfoKey != null) && (propInfoValue != null)) + { + dict.Add(propInfoKey.GetValue(item, null), propInfoValue.GetValue(item, null)); + } + } + } + //IList + else if (collection is IList) + { + var list = (IList)collection; + + //the easiest way to persist changes to the source is to just clear the source list and then add all items to it. + list.Clear(); + + if (list.IsFixedSize) + { + if (sourceList.Count > list.Count) + throw new IndexOutOfRangeException("Exceeding array size."); + + for (int i = 0; i < sourceList.Count; ++i) + list[i] = sourceList[i]; + } + else + { + foreach (var item in sourceList) + { + list.Add(item); + } + } + } + else + { + //ICollection (or IList) + var collectionType = collection.GetType(); + var iCollectionOfTInterface = collectionType.GetInterfaces().FirstOrDefault(x => x.IsGenericType && (x.GetGenericTypeDefinition() == typeof(ICollection<>))); + if (iCollectionOfTInterface != null) + { + var argumentType = iCollectionOfTInterface.GetGenericArguments().FirstOrDefault(); + if (argumentType != null) + { + var iCollectionOfTType = typeof(ICollection<>).MakeGenericType(argumentType); + + //the easiest way to persist changes to the source is to just clear the source list and then add all items to it. + iCollectionOfTType.GetMethod("Clear").Invoke(collection, null); + + foreach (var item in sourceList) + { + iCollectionOfTType.GetMethod("Add").Invoke(collection, new object[] { item }); + } + } + } + } + } + + private IEnumerable CreateItemsSource() + { + IEnumerable collection = null; + + if (ItemsSourceType != null) + { + var constructor = ItemsSourceType.GetConstructor(Type.EmptyTypes); + if (constructor != null) + { + collection = (IEnumerable)constructor.Invoke(null); + } + else if (ItemsSourceType.IsArray) + { + collection = Array.CreateInstance(ItemsSourceType.GetElementType(), Items.Count); + } + } + + return collection; + } + + private object CreateNewItem(Type type) + { + return Activator.CreateInstance(type); + } + + private IEnumerable ComputeItemsSource() + { + if (ItemsSource == null) + ItemsSource = CreateItemsSource(); + + return ItemsSource; + } + + #endregion //Methods + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/CollectionControlButton.Icon.bmp b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/CollectionControlButton.Icon.bmp new file mode 100644 index 00000000..ce76dc5b --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/CollectionControlButton.Icon.bmp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e95d8b086aa0680fa4b987fc38d9701b23c24b9d6334806e6d5a7fa0b3687373 +size 822 diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/CollectionControlButton.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/CollectionControlButton.cs new file mode 100644 index 00000000..2c819ca0 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/CollectionControlButton.cs @@ -0,0 +1,178 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using Xceed.Wpf.Toolkit.PropertyGrid; + +namespace Xceed.Wpf.Toolkit +{ + public class CollectionControlButton : Button + { + #region Constructors + + static CollectionControlButton() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(CollectionControlButton), new FrameworkPropertyMetadata(typeof(CollectionControlButton))); + } + + public CollectionControlButton() + { + this.Click += this.CollectionControlButton_Click; + } + + #endregion //Constructors + + #region Properties + + #region EditorDefinitions Property + + public static readonly DependencyProperty EditorDefinitionsProperty = DependencyProperty.Register("EditorDefinitions", typeof(EditorDefinitionCollection), typeof(CollectionControlButton), new UIPropertyMetadata(null)); + public EditorDefinitionCollection EditorDefinitions + { + get + { + return (EditorDefinitionCollection)GetValue(EditorDefinitionsProperty); + } + set + { + SetValue(EditorDefinitionsProperty, value); + } + } + + #endregion //EditorDefinitions + + #region IsReadOnly Property + + public static readonly DependencyProperty IsReadOnlyProperty = DependencyProperty.Register("IsReadOnly", typeof(bool), typeof(CollectionControlButton), new UIPropertyMetadata(false)); + public bool IsReadOnly + { + get + { + return (bool)GetValue(IsReadOnlyProperty); + } + set + { + SetValue(IsReadOnlyProperty, value); + } + } + + #endregion //IsReadOnly + + #region ItemsSource Property + + public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(CollectionControlButton), new UIPropertyMetadata(null)); + public IEnumerable ItemsSource + { + get + { + return (IEnumerable)GetValue(ItemsSourceProperty); + } + set + { + SetValue(ItemsSourceProperty, value); + } + } + + #endregion //ItemsSource + + #region ItemsSourceType Property + + public static readonly DependencyProperty ItemsSourceTypeProperty = DependencyProperty.Register("ItemsSourceType", typeof(Type), typeof(CollectionControlButton), new UIPropertyMetadata(null)); + public Type ItemsSourceType + { + get + { + return (Type)GetValue(ItemsSourceTypeProperty); + } + set + { + SetValue(ItemsSourceTypeProperty, value); + } + } + + #endregion //ItemsSourceType + + #region NewItemTypes Property + + public static readonly DependencyProperty NewItemTypesProperty = DependencyProperty.Register("NewItemTypes", typeof(IList), typeof(CollectionControlButton), new UIPropertyMetadata(null)); + public IList NewItemTypes + { + get + { + return (IList)GetValue(NewItemTypesProperty); + } + set + { + SetValue(NewItemTypesProperty, value); + } + } + + #endregion //NewItemTypes + + #endregion + + #region Base Class Overrides + + + #endregion + + #region Methods + + private void CollectionControlButton_Click(object sender, RoutedEventArgs e) + { + var collectionControlDialog = new CollectionControlDialog(); + var binding = new Binding("ItemsSource") { Source = this, Mode = BindingMode.TwoWay }; + BindingOperations.SetBinding(collectionControlDialog, CollectionControlDialog.ItemsSourceProperty, binding); + collectionControlDialog.NewItemTypes = this.NewItemTypes; + collectionControlDialog.ItemsSourceType = this.ItemsSourceType; + collectionControlDialog.IsReadOnly = this.IsReadOnly; + collectionControlDialog.EditorDefinitions = this.EditorDefinitions; + var collectionUpdated = collectionControlDialog.ShowDialog(); + if (collectionUpdated.HasValue && collectionUpdated.Value) + { + this.RaiseEvent(new RoutedEventArgs(CollectionControlButton.CollectionUpdatedEvent, this)); + } + } + + #endregion + + #region Events + + #region CollectionUpdated Event + + public static readonly RoutedEvent CollectionUpdatedEvent = EventManager.RegisterRoutedEvent("CollectionUpdated", RoutingStrategy.Bubble, typeof(EventHandler), typeof(CollectionControlButton)); + public event RoutedEventHandler CollectionUpdated + { + add + { + AddHandler(CollectionUpdatedEvent, value); + } + remove + { + RemoveHandler(CollectionUpdatedEvent, value); + } + } + + #endregion //CollectionUpdated Event + + #endregion + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/CollectionControlDialog.xaml b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/CollectionControlDialog.xaml new file mode 100644 index 00000000..a7ab9a36 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/CollectionControlDialog.xaml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/CollectionControlDialog.xaml.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/CollectionControlDialog.xaml.cs new file mode 100644 index 00000000..a986d0d5 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/CollectionControlDialog.xaml.cs @@ -0,0 +1,353 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; +using System.Windows; +using System.Windows.Media; +using Xceed.Wpf.Toolkit.Core.Utilities; +using System.Linq; +using System.Runtime.Serialization; +using System.Security; +using System.IO; +using System.Runtime.Serialization.Formatters.Binary; +using Xceed.Wpf.Toolkit.PropertyGrid; + +namespace Xceed.Wpf.Toolkit +{ + public partial class CollectionControlDialogBase : + Window + { + } + + /// + /// Interaction logic for CollectionControlDialog.xaml + /// + public partial class CollectionControlDialog : CollectionControlDialogBase + { + #region Private Members + + private IList originalData = new List(); + + #endregion + + #region Properties + + public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(CollectionControlDialog), new UIPropertyMetadata(null)); + public IEnumerable ItemsSource + { + get + { + return (IEnumerable)GetValue(ItemsSourceProperty); + } + set + { + SetValue(ItemsSourceProperty, value); + } + } + + public static readonly DependencyProperty ItemsSourceTypeProperty = DependencyProperty.Register("ItemsSourceType", typeof(Type), typeof(CollectionControlDialog), new UIPropertyMetadata(null)); + public Type ItemsSourceType + { + get + { + return (Type)GetValue(ItemsSourceTypeProperty); + } + set + { + SetValue(ItemsSourceTypeProperty, value); + } + } + + public static readonly DependencyProperty NewItemTypesProperty = DependencyProperty.Register("NewItemTypes", typeof(IList), typeof(CollectionControlDialog), new UIPropertyMetadata(null)); + public IList NewItemTypes + { + get + { + return (IList)GetValue(NewItemTypesProperty); + } + set + { + SetValue(NewItemTypesProperty, value); + } + } + + public static readonly DependencyProperty IsReadOnlyProperty = DependencyProperty.Register("IsReadOnly", typeof(bool), typeof(CollectionControlDialog), new UIPropertyMetadata(false)); + public bool IsReadOnly + { + get + { + return (bool)GetValue(IsReadOnlyProperty); + } + set + { + SetValue(IsReadOnlyProperty, value); + } + } + + public static readonly DependencyProperty EditorDefinitionsProperty = DependencyProperty.Register("EditorDefinitions", typeof(EditorDefinitionCollection), typeof(CollectionControlDialog), new UIPropertyMetadata(null)); + public EditorDefinitionCollection EditorDefinitions + { + get + { + return (EditorDefinitionCollection)GetValue(EditorDefinitionsProperty); + } + set + { + SetValue(EditorDefinitionsProperty, value); + } + } + + public CollectionControl CollectionControl + { + get + { + return _collectionControl; + } + } + + #endregion //Properties + + #region Constructors + + public CollectionControlDialog() + { + InitializeComponent(); + } + + public CollectionControlDialog(Type itemsourceType) + : this() + { + ItemsSourceType = itemsourceType; + } + + public CollectionControlDialog(Type itemsourceType, IList newItemTypes) + : this(itemsourceType) + { + NewItemTypes = newItemTypes; + } + + #endregion //Constructors + + #region Overrides + + protected override void OnSourceInitialized(EventArgs e) + { + base.OnSourceInitialized(e); + + //Backup data if case "Cancel" is clicked. + if (this.ItemsSource != null) + { + foreach (var item in this.ItemsSource) + { + originalData.Add(this.Clone(item)); + } + } + } + + #endregion + + #region Event Handlers + + private void OkButton_Click(object sender, RoutedEventArgs e) + { + if (this.ItemsSource is IDictionary) + { + if (!this.AreDictionaryKeysValid()) + { + MessageBox.Show("All dictionary items should have distinct non-null Key values.", "Warning"); + return; + } + } + + this.DialogResult = _collectionControl.PersistChanges(); + this.Close(); + } + + private void CancelButton_Click(object sender, RoutedEventArgs e) + { + _collectionControl.PersistChanges(originalData); + this.DialogResult = false; + this.Close(); + } + + #endregion //Event Hanlders + + #region Private Methods + + [SecuritySafeCritical] + private object Clone(object source) + { + if (source == null) + return null; + + object result = null; + var sourceType = source.GetType(); + + if (source is Array) + { + using (var stream = new MemoryStream()) + { + var formatter = new BinaryFormatter(); + formatter.Serialize(stream, source); + stream.Seek(0, SeekOrigin.Begin); + result = (Array)formatter.Deserialize(stream); + } + } + // For IDictionary, we need to create EditableKeyValuePair to edit the Key-Value. + else if ((this.ItemsSource is IDictionary) + && sourceType.IsGenericType + && typeof(KeyValuePair<,>).IsAssignableFrom(sourceType.GetGenericTypeDefinition())) + { + result = this.GenerateEditableKeyValuePair(source); + } + else + { + // Initialized a new object with default values + try + { + result = FormatterServices.GetUninitializedObject(sourceType); + } + catch (Exception) + { + } + + var constructor = sourceType.GetConstructor(Type.EmptyTypes); + if (constructor != null) + { + constructor.Invoke(result, null); + } + else + { + result = source; + } + } + Debug.Assert(result != null); + if (result != null) + { + var properties = sourceType.GetProperties(); + + foreach (var propertyInfo in properties) + { + try + { + var parameters = propertyInfo.GetIndexParameters(); + var index = parameters.GetLength(0) == 0 ? null : new object[] { parameters.GetLength(0) - 1 }; + var propertyInfoValue = propertyInfo.GetValue(source, index); + + if (propertyInfo.CanWrite) + { + // Look for nested object + if (propertyInfo.PropertyType.IsClass + && (propertyInfo.PropertyType != typeof(Transform)) + && !propertyInfo.PropertyType.Equals(typeof(string))) + { + // We have a Collection/List of T. + if (propertyInfo.PropertyType.IsGenericType) + { + // Clone sub-objects if the T are non-primitive types objects. + var arg = propertyInfo.PropertyType.GetGenericArguments().FirstOrDefault(); + if ((arg != null) && !arg.IsPrimitive && !arg.Equals(typeof(String)) && !arg.IsEnum) + { + var nestedObject = this.Clone(propertyInfoValue); + propertyInfo.SetValue(result, nestedObject, null); + } + else + { + // copy object if the T are primitive types objects. + propertyInfo.SetValue(result, propertyInfoValue, null); + } + } + else + { + var nestedObject = this.Clone(propertyInfoValue); + if (nestedObject != null) + { + // For T object included in List/Collections, Add it to the List/Collection of T. + if (index != null) + { + result.GetType().GetMethod("Add").Invoke(result, new[] { nestedObject }); + } + else + { + propertyInfo.SetValue(result, nestedObject, null); + } + } + } + } + else + { + // For T object included in List/Collections, Add it to the List/Collection of T. + if (index != null) + { + result.GetType().GetMethod("Add").Invoke(result, new[] { propertyInfoValue }); + } + else + { + // copy regular object + propertyInfo.SetValue(result, propertyInfoValue, null); + } + } + } + } + catch (Exception) + { + } + } + } + + return result; + } + + private object GenerateEditableKeyValuePair(object source) + { + var sourceType = source.GetType(); + if ((sourceType.GetGenericArguments() == null) || (sourceType.GetGenericArguments().GetLength(0) != 2)) + return null; + + var propInfoKey = sourceType.GetProperty("Key"); + var propInfoValue = sourceType.GetProperty("Value"); + if ((propInfoKey != null) && (propInfoValue != null)) + { + return ListUtilities.CreateEditableKeyValuePair(propInfoKey.GetValue(source, null) + , sourceType.GetGenericArguments()[0] + , propInfoValue.GetValue(source, null) + , sourceType.GetGenericArguments()[1]); + } + return null; + } + + private bool AreDictionaryKeysValid() + { + var keys = _collectionControl.Items.Select(x => + { + var keyType = x.GetType().GetProperty("Key"); + if (keyType != null) + { + return keyType.GetValue(x, null); + } + return null; + }); + + return (keys.Distinct().Count() == _collectionControl.Items.Count) + && keys.All(x => x != null); + } + + #endregion + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/Converters/NewItemTypesComboBoxConverter.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/Converters/NewItemTypesComboBoxConverter.cs new file mode 100644 index 00000000..6a539fc9 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/Converters/NewItemTypesComboBoxConverter.cs @@ -0,0 +1,74 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Data; +using System.Globalization; +using Xceed.Wpf.Toolkit.Core.Utilities; + +namespace Xceed.Wpf.Toolkit.Converters +{ + /// + /// This multi-value converter is used in the CollectionControl template + /// to determine the list of possible new item types that will be shown in the combo box. + /// + /// If the second value (i.e., CollectionControl.NewItemTypes) is not null, this list will be used. + /// Otherwise, if the first value (i.e., CollectionControl.ItemsSourceType) is a "IList<T>" + /// type, the new item type list will contain "T". + /// + /// + public class NewItemTypesComboBoxConverter : IMultiValueConverter + { + public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) + { + + if (values.Length != 2) + throw new ArgumentException("The 'values' argument should contain 2 objects."); + + if (values[1] != null) + { + if (!values[1].GetType().IsGenericType || !(values[1].GetType().GetGenericArguments().First().GetType() is Type)) + throw new ArgumentException("The 'value' argument is not of the correct type."); + + return values[1]; + } + else if (values[0] != null) + { + if (!(values[0].GetType() is Type)) + throw new ArgumentException("The 'value' argument is not of the correct type."); + + List types = new List(); + Type listType = ListUtilities.GetListItemType((Type)values[0]); + if (listType != null) + { + types.Add(listType); + } + + return types; + } + + return null; + } + + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/ItemAddingEventArgs.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/ItemAddingEventArgs.cs new file mode 100644 index 00000000..044b7a09 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/ItemAddingEventArgs.cs @@ -0,0 +1,52 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Xceed.Wpf.Toolkit.Core; +using System.Windows; + +namespace Xceed.Wpf.Toolkit +{ + public class ItemAddingEventArgs : CancelRoutedEventArgs + { + #region Constructor + + public ItemAddingEventArgs(RoutedEvent itemAddingEvent, object itemAdding) + : base(itemAddingEvent) + { + Item = itemAdding; + } + + #endregion + + #region Properties + + #region Item Property + + public object Item + { + get; + set; + } + + #endregion + + #endregion //Properties + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/ItemDeletingEventArgs.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/ItemDeletingEventArgs.cs new file mode 100644 index 00000000..288e3a08 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/ItemDeletingEventArgs.cs @@ -0,0 +1,56 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Xceed.Wpf.Toolkit.Core; +using System.Windows; + +namespace Xceed.Wpf.Toolkit +{ + public class ItemDeletingEventArgs : CancelRoutedEventArgs + { + #region Private Members + + private object _item; + + #endregion + + #region Constructor + + public ItemDeletingEventArgs(RoutedEvent itemDeletingEvent, object itemDeleting) + : base(itemDeletingEvent) + { + _item = itemDeleting; + } + + #region Property Item + + public object Item + { + get + { + return _item; + } + } + + #endregion + + #endregion + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/ItemEventArgs.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/ItemEventArgs.cs new file mode 100644 index 00000000..59b63f94 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/ItemEventArgs.cs @@ -0,0 +1,55 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows; + +namespace Xceed.Wpf.Toolkit +{ + public class ItemEventArgs : RoutedEventArgs + { + #region Protected Members + + private object _item; + + #endregion + + #region Constructor + + internal ItemEventArgs(RoutedEvent routedEvent, object newItem) + : base(routedEvent) + { + _item = newItem; + } + + #endregion + + #region Property Item + + public object Item + { + get + { + return _item; + } + } + + #endregion + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/PrimitiveTypeCollectionControl.Icon.bmp b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/PrimitiveTypeCollectionControl.Icon.bmp new file mode 100644 index 00000000..ce76dc5b --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/PrimitiveTypeCollectionControl.Icon.bmp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e95d8b086aa0680fa4b987fc38d9701b23c24b9d6334806e6d5a7fa0b3687373 +size 822 diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/PrimitiveTypeCollectionControl.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/PrimitiveTypeCollectionControl.cs new file mode 100644 index 00000000..f8bb3a4f --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Implementation/PrimitiveTypeCollectionControl.cs @@ -0,0 +1,314 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using System.Windows; +using System.Windows.Controls; + +namespace Xceed.Wpf.Toolkit +{ + public class PrimitiveTypeCollectionControl : ContentControl + { + #region Members + + bool _surpressTextChanged; + bool _conversionFailed; + + #endregion //Members + + #region Properties + + #region IsOpen + + public static readonly DependencyProperty IsOpenProperty = DependencyProperty.Register("IsOpen", typeof(bool), typeof(PrimitiveTypeCollectionControl), new UIPropertyMetadata(false, OnIsOpenChanged)); + public bool IsOpen + { + get + { + return (bool)GetValue(IsOpenProperty); + } + set + { + SetValue(IsOpenProperty, value); + } + } + + private static void OnIsOpenChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) + { + PrimitiveTypeCollectionControl primitiveTypeCollectionControl = o as PrimitiveTypeCollectionControl; + if (primitiveTypeCollectionControl != null) + primitiveTypeCollectionControl.OnIsOpenChanged((bool)e.OldValue, (bool)e.NewValue); + } + + protected virtual void OnIsOpenChanged(bool oldValue, bool newValue) + { + + } + + #endregion //IsOpen + + #region ItemsSource + + public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(IList), typeof(PrimitiveTypeCollectionControl), new UIPropertyMetadata(null, OnItemsSourceChanged)); + public IList ItemsSource + { + get + { + return (IList)GetValue(ItemsSourceProperty); + } + set + { + SetValue(ItemsSourceProperty, value); + } + } + + private static void OnItemsSourceChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) + { + PrimitiveTypeCollectionControl primitiveTypeCollectionControl = o as PrimitiveTypeCollectionControl; + if (primitiveTypeCollectionControl != null) + primitiveTypeCollectionControl.OnItemsSourceChanged((IList)e.OldValue, (IList)e.NewValue); + } + + protected virtual void OnItemsSourceChanged(IList oldValue, IList newValue) + { + if (newValue == null) + return; + + if (ItemsSourceType == null) + ItemsSourceType = newValue.GetType(); + + if (ItemType == null && newValue.GetType().ContainsGenericParameters) + ItemType = newValue.GetType().GetGenericArguments()[0]; + + SetText(newValue); + } + + #endregion //ItemsSource + + #region IsReadOnly + + public static readonly DependencyProperty IsReadOnlyProperty = + DependencyProperty.Register("IsReadOnly", typeof(bool), typeof(PrimitiveTypeCollectionControl), new UIPropertyMetadata(false)); + + public bool IsReadOnly + { + get { return (bool)GetValue(IsReadOnlyProperty); } + set { SetValue(IsReadOnlyProperty, value); } + } + + #endregion //IsReadOnly + + #region ItemsSourceType + + public static readonly DependencyProperty ItemsSourceTypeProperty = DependencyProperty.Register("ItemsSourceType", typeof(Type), typeof(PrimitiveTypeCollectionControl), new UIPropertyMetadata(null)); + public Type ItemsSourceType + { + get + { + return (Type)GetValue(ItemsSourceTypeProperty); + } + set + { + SetValue(ItemsSourceTypeProperty, value); + } + } + + #endregion ItemsSourceType + + #region ItemType + + public static readonly DependencyProperty ItemTypeProperty = DependencyProperty.Register("ItemType", typeof(Type), typeof(PrimitiveTypeCollectionControl), new UIPropertyMetadata(null)); + public Type ItemType + { + get + { + return (Type)GetValue(ItemTypeProperty); + } + set + { + SetValue(ItemTypeProperty, value); + } + } + + #endregion ItemType + + #region Text + + public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(PrimitiveTypeCollectionControl), new UIPropertyMetadata(null, OnTextChanged)); + public string Text + { + get + { + return (string)GetValue(TextProperty); + } + set + { + SetValue(TextProperty, value); + } + } + + private static void OnTextChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) + { + PrimitiveTypeCollectionControl primitiveTypeCollectionControl = o as PrimitiveTypeCollectionControl; + if (primitiveTypeCollectionControl != null) + primitiveTypeCollectionControl.OnTextChanged((string)e.OldValue, (string)e.NewValue); + } + + protected virtual void OnTextChanged(string oldValue, string newValue) + { + if (!_surpressTextChanged) + PersistChanges(); + } + + #endregion //Text + + #endregion //Properties + + #region Constructors + + static PrimitiveTypeCollectionControl() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(PrimitiveTypeCollectionControl), new FrameworkPropertyMetadata(typeof(PrimitiveTypeCollectionControl))); + } + + public PrimitiveTypeCollectionControl() + { + } + + #endregion //Constructors + + #region Overrides + + + #endregion + + #region Methods + + private void PersistChanges() + { + IList list = ComputeItemsSource(); + if (list == null) + return; + + IList items = ComputeItems(); + + //the easiest way to persist changes to the source is to just clear the source list and then add all items to it. + list.Clear(); + + int counter = 0; + foreach (var item in items) + { + if (list is Array) + { + ((Array)list).SetValue(item, counter++); + } + else + { + list.Add(item); + } + }; + + // if something went wrong during conversion we want to reload the text to show only valid entries + if (_conversionFailed) + SetText(list); + } + + private IList ComputeItems() + { + IList items = new List(); + + if (ItemType == null) + return items; + + string[] textArray = Text.Split('\n'); + + foreach (string s in textArray) + { + string valueString = s.TrimEnd('\r'); + if (!String.IsNullOrEmpty(valueString)) + { + object value = null; + try + { + if (ItemType.IsEnum) + { + value = Enum.Parse(ItemType, valueString); + } + else + { + value = Convert.ChangeType(valueString, ItemType); + } + } + catch + { + //a conversion failed + _conversionFailed = true; + } + + if (value != null) + items.Add(value); + } + } + + return items; + } + + private IList ComputeItemsSource() + { + if (ItemsSource == null) + { + // Save current text since creating the ItemsSource will reset it + string currentText = this.Text; + ItemsSource = CreateItemsSource(); + this.Text = currentText; + } + + return ItemsSource; + } + + private IList CreateItemsSource() + { + IList list = null; + + if (ItemsSourceType != null) + { + ConstructorInfo constructor = ItemsSourceType.GetConstructor(Type.EmptyTypes); + list = (IList)constructor.Invoke(null); + } + + return list; + } + + private void SetText(IEnumerable collection) + { + _surpressTextChanged = true; + StringBuilder builder = new StringBuilder(); + foreach (object obj2 in collection) + { + builder.Append(obj2.ToString()); + builder.AppendLine(); + } + Text = builder.ToString().Trim(); + _surpressTextChanged = false; + } + + #endregion //Methods + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Themes/Aero2.NormalColor.xaml b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Themes/Aero2.NormalColor.xaml new file mode 100644 index 00000000..3caf98f0 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/CollectionControl/Themes/Aero2.NormalColor.xaml @@ -0,0 +1,334 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ColorCanvas/Themes/Generic.xaml b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ColorCanvas/Themes/Generic.xaml new file mode 100644 index 00000000..63555637 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ColorCanvas/Themes/Generic.xaml @@ -0,0 +1,622 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ColorPicker/Implementation/ColorItem.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ColorPicker/Implementation/ColorItem.cs new file mode 100644 index 00000000..85f21a57 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ColorPicker/Implementation/ColorItem.cs @@ -0,0 +1,53 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System.Windows.Media; + +namespace Xceed.Wpf.Toolkit +{ + public class ColorItem + { + public Color? Color + { + get; + set; + } + public string Name + { + get; + set; + } + + public ColorItem(Color? color, string name) + { + Color = color; + Name = name; + } + + public override bool Equals(object obj) + { + var ci = obj as ColorItem; + if (ci == null) + return false; + return (ci.Color.Equals(Color) && ci.Name.Equals(Name)); + } + + public override int GetHashCode() + { + return this.Color.GetHashCode() ^ this.Name.GetHashCode(); + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ColorPicker/Implementation/ColorPicker.Icon.bmp b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ColorPicker/Implementation/ColorPicker.Icon.bmp new file mode 100644 index 00000000..ce76dc5b --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ColorPicker/Implementation/ColorPicker.Icon.bmp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e95d8b086aa0680fa4b987fc38d9701b23c24b9d6334806e6d5a7fa0b3687373 +size 822 diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ColorPicker/Implementation/ColorPicker.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ColorPicker/Implementation/ColorPicker.cs new file mode 100644 index 00000000..c7817dd4 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ColorPicker/Implementation/ColorPicker.cs @@ -0,0 +1,891 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.ObjectModel; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using System.Windows.Media; +using Xceed.Wpf.Toolkit.Core.Utilities; +using System.Windows.Controls.Primitives; +using System.Windows.Data; + +namespace Xceed.Wpf.Toolkit +{ + public enum ColorMode + { + ColorPalette, + ColorCanvas + } + + public enum ColorSortingMode + { + Alphabetical, + HueSaturationBrightness + } + + [TemplatePart(Name = PART_AvailableColors, Type = typeof(ListBox))] + [TemplatePart(Name = PART_StandardColors, Type = typeof(ListBox))] + [TemplatePart(Name = PART_RecentColors, Type = typeof(ListBox))] + [TemplatePart(Name = PART_ColorPickerToggleButton, Type = typeof(ToggleButton))] + [TemplatePart(Name = PART_ColorPickerPalettePopup, Type = typeof(Popup))] + public class ColorPicker : Control + { + private const string PART_AvailableColors = "PART_AvailableColors"; + private const string PART_StandardColors = "PART_StandardColors"; + private const string PART_RecentColors = "PART_RecentColors"; + private const string PART_ColorPickerToggleButton = "PART_ColorPickerToggleButton"; + private const string PART_ColorPickerPalettePopup = "PART_ColorPickerPalettePopup"; + + #region Members + + private ListBox _availableColors; + private ListBox _standardColors; + private ListBox _recentColors; + private ToggleButton _toggleButton; + private Popup _popup; + private Color? _initialColor; + private bool _selectionChanged; + + #endregion //Members + + #region Properties + + #region AdvancedTabHeader + + public static readonly DependencyProperty AdvancedTabHeaderProperty = DependencyProperty.Register("AdvancedTabHeader", typeof(string), typeof(ColorPicker), new UIPropertyMetadata("Advanced")); + public string AdvancedTabHeader + { + get + { + return (string)GetValue(AdvancedTabHeaderProperty); + } + set + { + SetValue(AdvancedTabHeaderProperty, value); + } + } + + #endregion //AdvancedTabHeader + + #region AvailableColors + + public static readonly DependencyProperty AvailableColorsProperty = DependencyProperty.Register("AvailableColors", typeof(ObservableCollection), typeof(ColorPicker), new UIPropertyMetadata(CreateAvailableColors())); + public ObservableCollection AvailableColors + { + get + { + return (ObservableCollection)GetValue(AvailableColorsProperty); + } + set + { + SetValue(AvailableColorsProperty, value); + } + } + + #endregion //AvailableColors + + #region AvailableColorsSortingMode + + public static readonly DependencyProperty AvailableColorsSortingModeProperty = DependencyProperty.Register("AvailableColorsSortingMode", typeof(ColorSortingMode), typeof(ColorPicker), new UIPropertyMetadata(ColorSortingMode.Alphabetical, OnAvailableColorsSortingModeChanged)); + public ColorSortingMode AvailableColorsSortingMode + { + get + { + return (ColorSortingMode)GetValue(AvailableColorsSortingModeProperty); + } + set + { + SetValue(AvailableColorsSortingModeProperty, value); + } + } + + private static void OnAvailableColorsSortingModeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ColorPicker colorPicker = (ColorPicker)d; + if (colorPicker != null) + colorPicker.OnAvailableColorsSortingModeChanged((ColorSortingMode)e.OldValue, (ColorSortingMode)e.NewValue); + } + + private void OnAvailableColorsSortingModeChanged(ColorSortingMode oldValue, ColorSortingMode newValue) + { + ListCollectionView lcv = (ListCollectionView)(CollectionViewSource.GetDefaultView(this.AvailableColors)); + if (lcv != null) + { + lcv.CustomSort = (AvailableColorsSortingMode == ColorSortingMode.HueSaturationBrightness) + ? new ColorSorter() + : null; + } + } + + #endregion //AvailableColorsSortingMode + + #region AvailableColorsHeader + + public static readonly DependencyProperty AvailableColorsHeaderProperty = DependencyProperty.Register("AvailableColorsHeader", typeof(string), typeof(ColorPicker), new UIPropertyMetadata("Available Colors")); + public string AvailableColorsHeader + { + get + { + return (string)GetValue(AvailableColorsHeaderProperty); + } + set + { + SetValue(AvailableColorsHeaderProperty, value); + } + } + + #endregion //AvailableColorsHeader + + #region ButtonStyle + + public static readonly DependencyProperty ButtonStyleProperty = DependencyProperty.Register("ButtonStyle", typeof(Style), typeof(ColorPicker)); + public Style ButtonStyle + { + get + { + return (Style)GetValue(ButtonStyleProperty); + } + set + { + SetValue(ButtonStyleProperty, value); + } + } + + #endregion //ButtonStyle + + #region DisplayColorAndName + + public static readonly DependencyProperty DisplayColorAndNameProperty = DependencyProperty.Register("DisplayColorAndName", typeof(bool), typeof(ColorPicker), new UIPropertyMetadata(false)); + public bool DisplayColorAndName + { + get + { + return (bool)GetValue(DisplayColorAndNameProperty); + } + set + { + SetValue(DisplayColorAndNameProperty, value); + } + } + + #endregion //DisplayColorAndName + + #region DisplayColorTooltip + + public static readonly DependencyProperty DisplayColorTooltipProperty = DependencyProperty.Register("DisplayColorTooltip", typeof(bool), typeof(ColorPicker), new UIPropertyMetadata(true)); + public bool DisplayColorTooltip + { + get + { + return (bool)GetValue(DisplayColorTooltipProperty); + } + set + { + SetValue(DisplayColorTooltipProperty, value); + } + } + + #endregion //DisplayColorTooltip + + #region ColorMode + + public static readonly DependencyProperty ColorModeProperty = DependencyProperty.Register("ColorMode", typeof(ColorMode), typeof(ColorPicker), new UIPropertyMetadata(ColorMode.ColorPalette)); + public ColorMode ColorMode + { + get + { + return (ColorMode)GetValue(ColorModeProperty); + } + set + { + SetValue(ColorModeProperty, value); + } + } + + #endregion //ColorMode + + #region DropDownBackground + + public static readonly DependencyProperty DropDownBackgroundProperty = DependencyProperty.Register("DropDownBackground", typeof(Brush), typeof(ColorPicker), new UIPropertyMetadata(null)); + public Brush DropDownBackground + { + get + { + return (Brush)GetValue(DropDownBackgroundProperty); + } + set + { + SetValue(DropDownBackgroundProperty, value); + } + } + + #endregion //DropDownBackground + + #region HeaderBackground + + public static readonly DependencyProperty HeaderBackgroundProperty = DependencyProperty.Register("HeaderBackground", typeof(Brush), typeof(ColorPicker), new UIPropertyMetadata(null)); + public Brush HeaderBackground + { + get + { + return (Brush)GetValue(HeaderBackgroundProperty); + } + set + { + SetValue(HeaderBackgroundProperty, value); + } + } + + #endregion //HeaderBackground + + #region HeaderForeground + + public static readonly DependencyProperty HeaderForegroundProperty = DependencyProperty.Register("HeaderForeground", typeof(Brush), typeof(ColorPicker), new UIPropertyMetadata(Brushes.Black)); + public Brush HeaderForeground + { + get + { + return (Brush)GetValue(HeaderForegroundProperty); + } + set + { + SetValue(HeaderForegroundProperty, value); + } + } + + #endregion //HeaderForeground + + #region IsOpen + + public static readonly DependencyProperty IsOpenProperty = DependencyProperty.Register("IsOpen", typeof(bool), typeof(ColorPicker), new UIPropertyMetadata(false, OnIsOpenChanged)); + public bool IsOpen + { + get + { + return (bool)GetValue(IsOpenProperty); + } + set + { + SetValue(IsOpenProperty, value); + } + } + + private static void OnIsOpenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ColorPicker colorPicker = (ColorPicker)d; + if (colorPicker != null) + colorPicker.OnIsOpenChanged((bool)e.OldValue, (bool)e.NewValue); + } + + private void OnIsOpenChanged(bool oldValue, bool newValue) + { + if (newValue) + { + _initialColor = this.SelectedColor; + } + RoutedEventArgs args = new RoutedEventArgs(newValue ? OpenedEvent : ClosedEvent, this); + this.RaiseEvent(args); + } + + #endregion //IsOpen + + #region MaxDropDownWidth + + public static readonly DependencyProperty MaxDropDownWidthProperty = DependencyProperty.Register("MaxDropDownWidth", typeof(double) + , typeof(ColorPicker), new UIPropertyMetadata(214d)); + public double MaxDropDownWidth + { + get + { + return (double)GetValue(MaxDropDownWidthProperty); + } + set + { + SetValue(MaxDropDownWidthProperty, value); + } + } + + private static void OnMaxDropDownWidthChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) + { + var colorPicker = o as ColorPicker; + if (colorPicker != null) + colorPicker.OnMaxDropDownWidthChanged((double)e.OldValue, (double)e.NewValue); + } + + protected virtual void OnMaxDropDownWidthChanged(double oldValue, double newValue) + { + + } + + #endregion + + #region RecentColors + + public static readonly DependencyProperty RecentColorsProperty = DependencyProperty.Register("RecentColors", typeof(ObservableCollection), typeof(ColorPicker), new UIPropertyMetadata(null)); + public ObservableCollection RecentColors + { + get + { + return (ObservableCollection)GetValue(RecentColorsProperty); + } + set + { + SetValue(RecentColorsProperty, value); + } + } + + #endregion //RecentColors + + #region RecentColorsHeader + + public static readonly DependencyProperty RecentColorsHeaderProperty = DependencyProperty.Register("RecentColorsHeader", typeof(string), typeof(ColorPicker), new UIPropertyMetadata("Recent Colors")); + public string RecentColorsHeader + { + get + { + return (string)GetValue(RecentColorsHeaderProperty); + } + set + { + SetValue(RecentColorsHeaderProperty, value); + } + } + + #endregion //RecentColorsHeader + + #region SelectedColor + + public static readonly DependencyProperty SelectedColorProperty = DependencyProperty.Register("SelectedColor", typeof(Color?), typeof(ColorPicker), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(OnSelectedColorPropertyChanged))); + public Color? SelectedColor + { + get + { + return (Color?)GetValue(SelectedColorProperty); + } + set + { + SetValue(SelectedColorProperty, value); + } + } + + private static void OnSelectedColorPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ColorPicker colorPicker = (ColorPicker)d; + if (colorPicker != null) + colorPicker.OnSelectedColorChanged((Color?)e.OldValue, (Color?)e.NewValue); + } + + private void OnSelectedColorChanged(Color? oldValue, Color? newValue) + { + SelectedColorText = GetFormatedColorString(newValue); + + RoutedPropertyChangedEventArgs args = new RoutedPropertyChangedEventArgs(oldValue, newValue); + args.RoutedEvent = ColorPicker.SelectedColorChangedEvent; + RaiseEvent(args); + } + + #endregion //SelectedColor + + #region SelectedColorText + + public static readonly DependencyProperty SelectedColorTextProperty = DependencyProperty.Register("SelectedColorText", typeof(string), typeof(ColorPicker), new UIPropertyMetadata("")); + public string SelectedColorText + { + get + { + return (string)GetValue(SelectedColorTextProperty); + } + protected set + { + SetValue(SelectedColorTextProperty, value); + } + } + + #endregion //SelectedColorText + + #region ShowTabHeaders + + public static readonly DependencyProperty ShowTabHeadersProperty = DependencyProperty.Register("ShowTabHeaders", typeof(bool), typeof(ColorPicker), new UIPropertyMetadata(true)); + public bool ShowTabHeaders + { + get + { + return (bool)GetValue(ShowTabHeadersProperty); + } + set + { + SetValue(ShowTabHeadersProperty, value); + } + } + + #endregion //ShowTabHeaders + + #region ShowAvailableColors + + public static readonly DependencyProperty ShowAvailableColorsProperty = DependencyProperty.Register("ShowAvailableColors", typeof(bool), typeof(ColorPicker), new UIPropertyMetadata(true)); + public bool ShowAvailableColors + { + get + { + return (bool)GetValue(ShowAvailableColorsProperty); + } + set + { + SetValue(ShowAvailableColorsProperty, value); + } + } + + #endregion //ShowAvailableColors + + #region ShowRecentColors + + public static readonly DependencyProperty ShowRecentColorsProperty = DependencyProperty.Register("ShowRecentColors", typeof(bool), typeof(ColorPicker), new UIPropertyMetadata(false)); + public bool ShowRecentColors + { + get + { + return (bool)GetValue(ShowRecentColorsProperty); + } + set + { + SetValue(ShowRecentColorsProperty, value); + } + } + + #endregion //DisplayRecentColors + + #region ShowStandardColors + + public static readonly DependencyProperty ShowStandardColorsProperty = DependencyProperty.Register("ShowStandardColors", typeof(bool), typeof(ColorPicker), new UIPropertyMetadata(true)); + public bool ShowStandardColors + { + get + { + return (bool)GetValue(ShowStandardColorsProperty); + } + set + { + SetValue(ShowStandardColorsProperty, value); + } + } + + #endregion //DisplayStandardColors + + #region ShowDropDownButton + + public static readonly DependencyProperty ShowDropDownButtonProperty = DependencyProperty.Register("ShowDropDownButton", typeof(bool), typeof(ColorPicker), new UIPropertyMetadata(true)); + public bool ShowDropDownButton + { + get + { + return (bool)GetValue(ShowDropDownButtonProperty); + } + set + { + SetValue(ShowDropDownButtonProperty, value); + } + } + + #endregion //ShowDropDownButton + + #region StandardTabHeader + + public static readonly DependencyProperty StandardTabHeaderProperty = DependencyProperty.Register("StandardTabHeader", typeof(string), typeof(ColorPicker), new UIPropertyMetadata("Standard")); + public string StandardTabHeader + { + get + { + return (string)GetValue(StandardTabHeaderProperty); + } + set + { + SetValue(StandardTabHeaderProperty, value); + } + } + + #endregion //StandardTabHeader + + #region StandardColors + + public static readonly DependencyProperty StandardColorsProperty = DependencyProperty.Register("StandardColors", typeof(ObservableCollection), typeof(ColorPicker), new UIPropertyMetadata(CreateStandardColors())); + public ObservableCollection StandardColors + { + get + { + return (ObservableCollection)GetValue(StandardColorsProperty); + } + set + { + SetValue(StandardColorsProperty, value); + } + } + + #endregion //StandardColors + + #region StandardColorsHeader + + public static readonly DependencyProperty StandardColorsHeaderProperty = DependencyProperty.Register("StandardColorsHeader", typeof(string), typeof(ColorPicker), new UIPropertyMetadata("Standard Colors")); + public string StandardColorsHeader + { + get + { + return (string)GetValue(StandardColorsHeaderProperty); + } + set + { + SetValue(StandardColorsHeaderProperty, value); + } + } + + #endregion //StandardColorsHeader + + #region TabBackground + + public static readonly DependencyProperty TabBackgroundProperty = DependencyProperty.Register("TabBackground", typeof(Brush), typeof(ColorPicker), new UIPropertyMetadata(null)); + public Brush TabBackground + { + get + { + return (Brush)GetValue(TabBackgroundProperty); + } + set + { + SetValue(TabBackgroundProperty, value); + } + } + + #endregion //TabBackground + + #region TabForeground + + public static readonly DependencyProperty TabForegroundProperty = DependencyProperty.Register("TabForeground", typeof(Brush), typeof(ColorPicker), new UIPropertyMetadata(Brushes.Black)); + public Brush TabForeground + { + get + { + return (Brush)GetValue(TabForegroundProperty); + } + set + { + SetValue(TabForegroundProperty, value); + } + } + + #endregion //TabForeground + + #region UsingAlphaChannel + + public static readonly DependencyProperty UsingAlphaChannelProperty = DependencyProperty.Register("UsingAlphaChannel", typeof(bool), typeof(ColorPicker), new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(OnUsingAlphaChannelPropertyChanged))); + public bool UsingAlphaChannel + { + get + { + return (bool)GetValue(UsingAlphaChannelProperty); + } + set + { + SetValue(UsingAlphaChannelProperty, value); + } + } + + private static void OnUsingAlphaChannelPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ColorPicker colorPicker = (ColorPicker)d; + if (colorPicker != null) + colorPicker.OnUsingAlphaChannelChanged(); + } + + private void OnUsingAlphaChannelChanged() + { + SelectedColorText = GetFormatedColorString(SelectedColor); + } + + #endregion //UsingAlphaChannel + + #endregion //Properties + + #region Constructors + + static ColorPicker() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(ColorPicker), new FrameworkPropertyMetadata(typeof(ColorPicker))); + } + + public ColorPicker() + { + +#if VS2008 + this.RecentColors = new ObservableCollection(); +#else + this.SetCurrentValue(ColorPicker.RecentColorsProperty, new ObservableCollection()); +#endif + + Keyboard.AddKeyDownHandler(this, OnKeyDown); + Mouse.AddPreviewMouseDownOutsideCapturedElementHandler(this, OnMouseDownOutsideCapturedElement); + } + + #endregion //Constructors + + #region Base Class Overrides + + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + if (_availableColors != null) + _availableColors.SelectionChanged -= Color_SelectionChanged; + + _availableColors = GetTemplateChild(PART_AvailableColors) as ListBox; + if (_availableColors != null) + _availableColors.SelectionChanged += Color_SelectionChanged; + + if (_standardColors != null) + _standardColors.SelectionChanged -= Color_SelectionChanged; + + _standardColors = GetTemplateChild(PART_StandardColors) as ListBox; + if (_standardColors != null) + _standardColors.SelectionChanged += Color_SelectionChanged; + + if (_recentColors != null) + _recentColors.SelectionChanged -= Color_SelectionChanged; + + _recentColors = GetTemplateChild(PART_RecentColors) as ListBox; + if (_recentColors != null) + _recentColors.SelectionChanged += Color_SelectionChanged; + + if (_popup != null) + _popup.Opened -= Popup_Opened; + + _popup = GetTemplateChild(PART_ColorPickerPalettePopup) as Popup; + if (_popup != null) + _popup.Opened += Popup_Opened; + + _toggleButton = this.Template.FindName(PART_ColorPickerToggleButton, this) as ToggleButton; + } + + protected override void OnMouseUp(MouseButtonEventArgs e) + { + base.OnMouseUp(e); + + // Close ColorPicker on MouseUp to prevent action of MouseUp on controls behind the ColorPicker. + if (_selectionChanged) + { + CloseColorPicker(true); + _selectionChanged = false; + } + } + + + #endregion //Base Class Overrides + + #region Event Handlers + + private void OnKeyDown(object sender, KeyEventArgs e) + { + if (!IsOpen) + { + if (KeyboardUtilities.IsKeyModifyingPopupState(e)) + { + IsOpen = true; + // Focus will be on ListBoxItem in Popup_Opened(). + e.Handled = true; + } + } + else + { + if (KeyboardUtilities.IsKeyModifyingPopupState(e)) + { + CloseColorPicker(true); + e.Handled = true; + } + else if (e.Key == Key.Escape) + { + this.SelectedColor = _initialColor; + CloseColorPicker(true); + e.Handled = true; + } + } + } + + private void OnMouseDownOutsideCapturedElement(object sender, MouseButtonEventArgs e) + { + CloseColorPicker(true); + } + + private void Color_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + ListBox lb = (ListBox)sender; + + if (e.AddedItems.Count > 0) + { + var colorItem = (ColorItem)e.AddedItems[0]; + SelectedColor = colorItem.Color; + if (!string.IsNullOrEmpty(colorItem.Name)) + { + this.SelectedColorText = colorItem.Name; + } + UpdateRecentColors(colorItem); + _selectionChanged = true; + lb.SelectedIndex = -1; //for now I don't care about keeping track of the selected color + } + } + + private void Popup_Opened(object sender, EventArgs e) + { + if ((_availableColors != null) && ShowAvailableColors) + { + FocusOnListBoxItem(_availableColors); + } + else if ((_standardColors != null) && ShowStandardColors) + FocusOnListBoxItem(_standardColors); + else if ((_recentColors != null) && ShowRecentColors) + FocusOnListBoxItem(_recentColors); + } + + private void FocusOnListBoxItem(ListBox listBox) + { + ListBoxItem listBoxItem = (ListBoxItem)listBox.ItemContainerGenerator.ContainerFromItem(listBox.SelectedItem); + if ((listBoxItem == null) && (listBox.Items.Count > 0)) + listBoxItem = (ListBoxItem)listBox.ItemContainerGenerator.ContainerFromItem(listBox.Items[0]); + if (listBoxItem != null) + listBoxItem.Focus(); + } + + #endregion //Event Handlers + + #region Events + + #region SelectedColorChangedEvent + + public static readonly RoutedEvent SelectedColorChangedEvent = EventManager.RegisterRoutedEvent("SelectedColorChanged", RoutingStrategy.Bubble, typeof(RoutedPropertyChangedEventHandler), typeof(ColorPicker)); + public event RoutedPropertyChangedEventHandler SelectedColorChanged + { + add + { + AddHandler(SelectedColorChangedEvent, value); + } + remove + { + RemoveHandler(SelectedColorChangedEvent, value); + } + } + + #endregion + + #region OpenedEvent + + public static readonly RoutedEvent OpenedEvent = EventManager.RegisterRoutedEvent("OpenedEvent", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(ColorPicker)); + public event RoutedEventHandler Opened + { + add + { + AddHandler(OpenedEvent, value); + } + remove + { + RemoveHandler(OpenedEvent, value); + } + } + + #endregion //OpenedEvent + + #region ClosedEvent + + public static readonly RoutedEvent ClosedEvent = EventManager.RegisterRoutedEvent("ClosedEvent", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(ColorPicker)); + public event RoutedEventHandler Closed + { + add + { + AddHandler(ClosedEvent, value); + } + remove + { + RemoveHandler(ClosedEvent, value); + } + } + + #endregion //ClosedEvent + + #endregion //Events + + #region Methods + + private void CloseColorPicker(bool isFocusOnColorPicker) + { + if (IsOpen) + IsOpen = false; + ReleaseMouseCapture(); + + if (isFocusOnColorPicker && (_toggleButton != null)) + _toggleButton.Focus(); + this.UpdateRecentColors(new ColorItem(SelectedColor, SelectedColorText)); + } + + private void UpdateRecentColors(ColorItem colorItem) + { + if (!RecentColors.Contains(colorItem)) + RecentColors.Add(colorItem); + + if (RecentColors.Count > 10) //don't allow more than ten, maybe make a property that can be set by the user. + RecentColors.RemoveAt(0); + } + + private string GetFormatedColorString(Color? colorToFormat) + { + if ((colorToFormat == null) || !colorToFormat.HasValue) + return string.Empty; + + return ColorUtilities.FormatColorString(colorToFormat.Value.GetColorName(), UsingAlphaChannel); + } + + private static ObservableCollection CreateStandardColors() + { + ObservableCollection standardColors = new ObservableCollection(); + standardColors.Add(new ColorItem(Colors.Transparent, "Transparent")); + standardColors.Add(new ColorItem(Colors.White, "White")); + standardColors.Add(new ColorItem(Colors.Gray, "Gray")); + standardColors.Add(new ColorItem(Colors.Black, "Black")); + standardColors.Add(new ColorItem(Colors.Red, "Red")); + standardColors.Add(new ColorItem(Colors.Green, "Green")); + standardColors.Add(new ColorItem(Colors.Blue, "Blue")); + standardColors.Add(new ColorItem(Colors.Yellow, "Yellow")); + standardColors.Add(new ColorItem(Colors.Orange, "Orange")); + standardColors.Add(new ColorItem(Colors.Purple, "Purple")); + return standardColors; + } + + private static ObservableCollection CreateAvailableColors() + { + ObservableCollection standardColors = new ObservableCollection(); + + foreach (var item in ColorUtilities.KnownColors) + { + if (!String.Equals(item.Key, "Transparent")) + { + var colorItem = new ColorItem(item.Value, item.Key); + if (!standardColors.Contains(colorItem)) + standardColors.Add(colorItem); + } + } + + return standardColors; + } + + #endregion //Methods + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ColorPicker/Implementation/ColorPickerTabItem.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ColorPicker/Implementation/ColorPickerTabItem.cs new file mode 100644 index 00000000..0df0cb02 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ColorPicker/Implementation/ColorPickerTabItem.cs @@ -0,0 +1,43 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System.Windows.Controls; +using System.Windows.Input; + +namespace Xceed.Wpf.Toolkit +{ + public class ColorPickerTabItem : TabItem + { + protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) + { + if (e.Source == this || !this.IsSelected) + return; + + base.OnMouseLeftButtonDown(e); + } + + protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e) + { + //Selection on Mouse Up + if (e.Source == this || !this.IsSelected) + { + base.OnMouseLeftButtonDown(e); + } + + base.OnMouseLeftButtonUp(e); + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ColorPicker/Implementation/ColorSorter.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ColorPicker/Implementation/ColorSorter.cs new file mode 100644 index 00000000..9b0bc522 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ColorPicker/Implementation/ColorSorter.cs @@ -0,0 +1,77 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Media; + +namespace Xceed.Wpf.Toolkit +{ + internal class ColorSorter : IComparer + { + public int Compare(object firstItem, object secondItem) + { + if (firstItem == null || secondItem == null) + return -1; + + ColorItem colorItem1 = (ColorItem)firstItem; + ColorItem colorItem2 = (ColorItem)secondItem; + + if ((colorItem1.Color == null) || !colorItem1.Color.HasValue || + (colorItem2.Color == null) || !colorItem2.Color.HasValue) + return -1; + + System.Drawing.Color drawingColor1 = System.Drawing.Color.FromArgb(colorItem1.Color.Value.A, colorItem1.Color.Value.R, colorItem1.Color.Value.G, colorItem1.Color.Value.B); + System.Drawing.Color drawingColor2 = System.Drawing.Color.FromArgb(colorItem2.Color.Value.A, colorItem2.Color.Value.R, colorItem2.Color.Value.G, colorItem2.Color.Value.B); + + // Compare Hue + double hueColor1 = Math.Round((double)drawingColor1.GetHue(), 3); + double hueColor2 = Math.Round((double)drawingColor2.GetHue(), 3); + + if (hueColor1 > hueColor2) + return 1; + else if (hueColor1 < hueColor2) + return -1; + else + { + // Hue is equal, compare Saturation + double satColor1 = Math.Round((double)drawingColor1.GetSaturation(), 3); + double satColor2 = Math.Round((double)drawingColor2.GetSaturation(), 3); + + if (satColor1 > satColor2) + return 1; + else if (satColor1 < satColor2) + return -1; + else + { + // Saturation is equal, compare Brightness + double brightColor1 = Math.Round((double)drawingColor1.GetBrightness(), 3); + double brightColor2 = Math.Round((double)drawingColor2.GetBrightness(), 3); + + if (brightColor1 > brightColor2) + return 1; + else if (brightColor1 < brightColor2) + return -1; + } + } + + return 0; + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ColorPicker/Themes/Aero2.NormalColor.xaml b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ColorPicker/Themes/Aero2.NormalColor.xaml new file mode 100644 index 00000000..91bf6500 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/ColorPicker/Themes/Aero2.NormalColor.xaml @@ -0,0 +1,523 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/CancelRoutedEventArgs.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/CancelRoutedEventArgs.cs new file mode 100644 index 00000000..a5c63efc --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/CancelRoutedEventArgs.cs @@ -0,0 +1,59 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows; + +namespace Xceed.Wpf.Toolkit.Core +{ + public delegate void CancelRoutedEventHandler(object sender, CancelRoutedEventArgs e); + + /// + /// An event data class that allows to inform the sender that the handler wants to cancel + /// the ongoing action. + /// + /// The handler can set the "Cancel" property to false to cancel the action. + /// + public class CancelRoutedEventArgs : RoutedEventArgs + { + public CancelRoutedEventArgs() + : base() + { + } + + public CancelRoutedEventArgs(RoutedEvent routedEvent) + : base(routedEvent) + { + } + + public CancelRoutedEventArgs(RoutedEvent routedEvent, object source) + : base(routedEvent, source) + { + } + + #region Cancel Property + + public bool Cancel + { + get; + set; + } + + #endregion Cancel Property + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/AditionConverter.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/AditionConverter.cs new file mode 100644 index 00000000..30f88959 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/AditionConverter.cs @@ -0,0 +1,46 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Windows.Data; + +namespace Xceed.Wpf.Toolkit.Core.Converters +{ + public class AdditionConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if ((value != null) && (parameter != null)) + { + var firstValue = (double)value; + var secondValue = double.Parse(parameter as string); + + return firstValue + secondValue; + } + + return 0d; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/BorderThicknessToStrokeThicknessConverter.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/BorderThicknessToStrokeThicknessConverter.cs new file mode 100644 index 00000000..334bab4b --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/BorderThicknessToStrokeThicknessConverter.cs @@ -0,0 +1,43 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Windows; +using System.Windows.Data; + +namespace Xceed.Wpf.Toolkit.Core.Converters +{ + public class BorderThicknessToStrokeThicknessConverter : IValueConverter + { + #region IValueConverter Members + + public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + Thickness thickness = (Thickness)value; + return (thickness.Bottom + thickness.Left + thickness.Right + thickness.Top) / 4; + } + + public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + int? thick = (int?)value; + int thickValue = thick.HasValue ? thick.Value : 0; + + return new Thickness(thickValue, thickValue, thickValue, thickValue); + } + + #endregion + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/CalculatorMemoryToVisibilityConverter.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/CalculatorMemoryToVisibilityConverter.cs new file mode 100644 index 00000000..f2881dc5 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/CalculatorMemoryToVisibilityConverter.cs @@ -0,0 +1,35 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Windows; +using System.Windows.Data; + +namespace Xceed.Wpf.Toolkit.Core.Converters +{ + public class CalculatorMemoryToVisibilityConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + return (decimal)value == decimal.Zero ? Visibility.Hidden : Visibility.Visible; + } + + public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/CenterTitleConverter.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/CenterTitleConverter.cs new file mode 100644 index 00000000..c86687e7 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/CenterTitleConverter.cs @@ -0,0 +1,59 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Data; +using System.Globalization; +using System.Windows; +using System.Windows.Media; +using System.Windows.Controls; + +namespace Xceed.Wpf.Toolkit.Core.Converters +{ + public class CenterTitleConverter : IMultiValueConverter + { + public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) + { + // Parameters: DesiredSize, WindowWidth, HeaderColumns + double titleTextWidth = ((Size)values[0]).Width; + double windowWidth = (double)values[1]; + + ColumnDefinitionCollection headerColumns = (ColumnDefinitionCollection)values[2]; + double titleColWidth = headerColumns[2].ActualWidth; + double buttonsColWidth = headerColumns[3].ActualWidth; + + + // Result (1) Title is Centered across all HeaderColumns + if ((titleTextWidth + buttonsColWidth * 2) < windowWidth) + return 1; + + // Result (2) Title is Centered in HeaderColumns[2] + if (titleTextWidth < titleColWidth) + return 2; + + // Result (3) Title is Left-Aligned in HeaderColumns[2] + return 3; + } + + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/ColorBlendConverter.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/ColorBlendConverter.cs new file mode 100644 index 00000000..94187544 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/ColorBlendConverter.cs @@ -0,0 +1,82 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Windows.Data; +using System.Windows.Media; + +namespace Xceed.Wpf.Toolkit.Core.Converters +{ + /// + /// This converter allow to blend two colors into one based on a specified ratio + /// + public class ColorBlendConverter : IValueConverter + { + private double _blendedColorRatio = 0; + + /// + /// The ratio of the blended color. Must be between 0 and 1. + /// + public double BlendedColorRatio + { + get { return _blendedColorRatio; } + + set + { + if (value < 0d || value > 1d) + throw new ArgumentException("BlendedColorRatio must be greater than or equal to 0 and lower than or equal to 1 "); + + _blendedColorRatio = value; + } + } + + /// + /// The color to blend with the source color + /// + public Color BlendedColor { get; set; } + + public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + if (value == null || value.GetType() != typeof(Color)) + return null; + + Color color = (Color)value; + return new Color() + { + A = this.BlendValue(color.A, this.BlendedColor.A), + R = this.BlendValue(color.R, this.BlendedColor.R), + G = this.BlendValue(color.G, this.BlendedColor.G), + B = this.BlendValue(color.B, this.BlendedColor.B) + }; + } + + private byte BlendValue(byte original, byte blend) + { + double blendRatio = this.BlendedColorRatio; + double sourceRatio = 1 - blendRatio; + + double result = (((double)original) * sourceRatio) + (((double)blend) * blendRatio); + result = Math.Round(result); + result = Math.Min(255d, Math.Max(0d, result)); + return System.Convert.ToByte(result); + } + + public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/ColorModeToTabItemSelectedConverter.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/ColorModeToTabItemSelectedConverter.cs new file mode 100644 index 00000000..189d882a --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/ColorModeToTabItemSelectedConverter.cs @@ -0,0 +1,37 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Globalization; +using System.Windows.Data; + +namespace Xceed.Wpf.Toolkit.Core.Converters +{ + public class ColorModeToTabItemSelectedConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + var colorMode = (ColorMode)value; + return (colorMode == ColorMode.ColorPalette) ? 0 : 1; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + var index = (int)value; + return (index == 0) ? ColorMode.ColorPalette : ColorMode.ColorCanvas; + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/ColorToSolidColorBrushConverter.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/ColorToSolidColorBrushConverter.cs new file mode 100644 index 00000000..89cb5d48 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/ColorToSolidColorBrushConverter.cs @@ -0,0 +1,67 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Windows.Data; +using System.Windows.Media; + +namespace Xceed.Wpf.Toolkit.Core.Converters +{ + public class ColorToSolidColorBrushConverter : IValueConverter + { + #region IValueConverter Members + + /// + /// Converts a Color to a SolidColorBrush. + /// + /// The Color produced by the binding source. + /// The type of the binding target property. + /// The converter parameter to use. + /// The culture to use in the converter. + /// + /// A converted SolidColorBrush. If the method returns null, the valid null value is used. + /// + public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + if (value != null) + return new SolidColorBrush((Color)value); + + return value; + } + + + /// + /// Converts a SolidColorBrush to a Color. + /// + /// Currently not used in toolkit, but provided for developer use in their own projects + /// The SolidColorBrush that is produced by the binding target. + /// The type to convert to. + /// The converter parameter to use. + /// The culture to use in the converter. + /// + /// A converted value. If the method returns null, the valid null value is used. + /// + public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + if (value != null) + return ((SolidColorBrush)value).Color; + + return value; + } + + #endregion + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/CornerRadiusToDoubleConverter.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/CornerRadiusToDoubleConverter.cs new file mode 100644 index 00000000..c6d6e5a8 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/CornerRadiusToDoubleConverter.cs @@ -0,0 +1,48 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Data; +using System.Windows; + +namespace Xceed.Wpf.Toolkit.Core.Converters +{ + public class CornerRadiusToDoubleConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + double radius = 0.0; + + if (value != null) + radius = ((CornerRadius)value).TopLeft; + + return radius; + } + + public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + double radius = 0.0; + + if (value != null) + radius = (double)value; + + return new CornerRadius(radius); + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/HalfConverter.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/HalfConverter.cs new file mode 100644 index 00000000..fcdf45f9 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/HalfConverter.cs @@ -0,0 +1,43 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Windows.Data; + +namespace Xceed.Wpf.Toolkit.Core.Converters +{ + public class HalfConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + double size = (double)value; + double modifier = (parameter != null) ? double.Parse((string)parameter) : 0d; + if (modifier != 0) + return Math.Max(0, size - modifier) / 2; + + return (size / 2); + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/IntToThicknessConverter.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/IntToThicknessConverter.cs new file mode 100644 index 00000000..f7c92ddb --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/IntToThicknessConverter.cs @@ -0,0 +1,48 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Data; +using System.Windows; + +namespace Xceed.Wpf.Toolkit.Core.Converters +{ + public class IntToThicknessConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + int thickValue = 0; + if (value != null) + thickValue = (int)value; + + if (parameter != null) + { + if (parameter.ToString().ToUpper() == "LEFT") + return new Thickness(thickValue, 0, 0, 0); + } + + return new Thickness(thickValue); + } + + public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/InverseBoolConverter.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/InverseBoolConverter.cs new file mode 100644 index 00000000..74ee1f37 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/InverseBoolConverter.cs @@ -0,0 +1,38 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Windows.Data; + +namespace Xceed.Wpf.Toolkit.Core.Converters +{ + public class InverseBoolConverter : IValueConverter + { + #region IValueConverter Members + + public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + return !(bool)value; + } + + public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + throw new NotImplementedException(); + } + + #endregion + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/NullToBoolConverter.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/NullToBoolConverter.cs new file mode 100644 index 00000000..cbfbdb56 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/NullToBoolConverter.cs @@ -0,0 +1,35 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Globalization; +using System.Windows.Data; + +namespace Xceed.Wpf.Toolkit.Core.Converters +{ + public class NullToBoolConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + return (value == null); + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/ObjectTypeToNameConverter.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/ObjectTypeToNameConverter.cs new file mode 100644 index 00000000..9cf532c6 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/ObjectTypeToNameConverter.cs @@ -0,0 +1,54 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.ComponentModel; +using System.Linq; +using System.Windows.Data; + +namespace Xceed.Wpf.Toolkit.Core.Converters +{ + public class ObjectTypeToNameConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + if (value != null) + { + if (value is Type) + { + var displayNameAttribute = ((Type)value).GetCustomAttributes(false).OfType().FirstOrDefault(); + return (displayNameAttribute != null) ? displayNameAttribute.DisplayName : ((Type)value).Name; + } + + var type = value.GetType(); + var valueString = value.ToString(); + if (string.IsNullOrEmpty(valueString) + || (valueString == type.UnderlyingSystemType.ToString())) + { + var displayNameAttribute = type.GetCustomAttributes(false).OfType().FirstOrDefault(); + return (displayNameAttribute != null) ? displayNameAttribute.DisplayName : type.Name; + } + + return value; + } + return null; + } + public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/RoundedValueConverter.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/RoundedValueConverter.cs new file mode 100644 index 00000000..3685220f --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/RoundedValueConverter.cs @@ -0,0 +1,65 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Globalization; +using System.Windows; +using System.Windows.Data; + +namespace Xceed.Wpf.Toolkit.Core.Converters +{ + public class RoundedValueConverter : IValueConverter + { + #region Precision Property + + public int Precision + { + get + { + return _precision; + } + set + { + _precision = value; + } + } + + private int _precision = 0; + + #endregion + + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value is double) + { + return Math.Round((double)value, _precision); + } + else if (value is Point) + { + return new Point(Math.Round(((Point)value).X, _precision), Math.Round(((Point)value).Y, _precision)); + } + else + { + return value; + } + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + return value; + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/SolidColorBrushToColorConverter.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/SolidColorBrushToColorConverter.cs new file mode 100644 index 00000000..5f82e929 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/SolidColorBrushToColorConverter.cs @@ -0,0 +1,49 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Windows.Data; +using System.Windows.Media; + +namespace Xceed.Wpf.Toolkit.Core.Converters +{ + public class SolidColorBrushToColorConverter : IValueConverter + { + #region IValueConverter Members + + public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + SolidColorBrush brush = value as SolidColorBrush; + if (brush != null) + return brush.Color; + + return default(Color?); + } + + public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + if (value != null) + { + Color color = (Color)value; + return new SolidColorBrush(color); + } + + return default(SolidColorBrush); + } + + #endregion + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/ThicknessSideRemovalConverter.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/ThicknessSideRemovalConverter.cs new file mode 100644 index 00000000..3bbe4602 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/ThicknessSideRemovalConverter.cs @@ -0,0 +1,50 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Globalization; +using System.Windows; +using System.Windows.Data; + +namespace Xceed.Wpf.Toolkit.Core.Converters +{ + public class ThicknessSideRemovalConverter : IValueConverter + { + #region IValueConverter Members + + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + var thickness = (Thickness)value; + var sideToRemove = int.Parse((string)parameter); + switch (sideToRemove) + { + case 0: thickness.Left = 0d; break; + case 1: thickness.Top = 0d; break; + case 2: thickness.Right = 0d; break; + case 3: thickness.Bottom = 0d; break; + default: throw new InvalidContentException("parameter should be from 0 to 3 to specify the side to remove."); + } + return thickness; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + + #endregion + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/ThicknessToDoubleConverter.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/ThicknessToDoubleConverter.cs new file mode 100644 index 00000000..780eb922 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/ThicknessToDoubleConverter.cs @@ -0,0 +1,48 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Data; +using System.Windows; + +namespace Xceed.Wpf.Toolkit.Core.Converters +{ + public class ThicknessToDoubleConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + double thickness = 1.0; + + if (value != null) + thickness = ((Thickness)value).Top; + + return thickness; + } + + public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + double thickness = 1.0; + + if (value != null) + thickness = (double)value; + + return new Thickness(thickness); + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/VisibilityToBoolConverter.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/VisibilityToBoolConverter.cs new file mode 100644 index 00000000..aaaacbc6 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/VisibilityToBoolConverter.cs @@ -0,0 +1,89 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Globalization; +using System.Windows; +using System.Windows.Data; +using Xceed.Wpf.Toolkit.Core; + +namespace Xceed.Wpf.Toolkit.Core.Converters +{ + public class VisibilityToBoolConverter : IValueConverter + { + #region Inverted Property + + public bool Inverted + { + get + { + return _inverted; + } + set + { + _inverted = value; + } + } + + private bool _inverted; //false + + #endregion + + #region Not Property + + public bool Not + { + get + { + return _not; + } + set + { + _not = value; + } + } + + private bool _not; //false + + #endregion + + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + return this.Inverted ? this.BoolToVisibility(value) : this.VisibilityToBool(value); + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + return this.Inverted ? this.VisibilityToBool(value) : this.BoolToVisibility(value); + } + + private object VisibilityToBool(object value) + { + if (!(value is Visibility)) + throw new InvalidOperationException(ErrorMessages.GetMessage("SuppliedValueWasNotVisibility")); + + return (((Visibility)value) == Visibility.Visible) ^ Not; + } + + private object BoolToVisibility(object value) + { + if (!(value is bool)) + throw new InvalidOperationException(ErrorMessages.GetMessage("SuppliedValueWasNotBool")); + + return ((bool)value ^ Not) ? Visibility.Visible : Visibility.Collapsed; + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/WindowContentBorderMarginConverter.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/WindowContentBorderMarginConverter.cs new file mode 100644 index 00000000..d0753535 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/WindowContentBorderMarginConverter.cs @@ -0,0 +1,67 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Data; +using System.Globalization; +using System.Windows; + +namespace Xceed.Wpf.Toolkit.Core.Converters +{ + /// + /// Sets the margin for the thumb grip, the top buttons, or for the content border in the WindowControl. + /// + public class WindowContentBorderMarginConverter : IMultiValueConverter + { + public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) + { + double horizontalContentBorderOffset = (double)values[0]; + double verticalContentBorderOffset = (double)values[1]; + + switch ((string)parameter) + { + // Content Border Margin in the WindowControl + case "0": + return new Thickness(horizontalContentBorderOffset + , 0d + , horizontalContentBorderOffset + , verticalContentBorderOffset); + // Thumb Grip Margin in the WindowControl + case "1": + return new Thickness(0d + , 0d + , horizontalContentBorderOffset + , verticalContentBorderOffset); + // Header Buttons Margin in the WindowControl + case "2": + return new Thickness(0d + , 0d + , horizontalContentBorderOffset + , 0d); + default: + throw new NotSupportedException("'parameter' for WindowContentBorderMarginConverter is not valid."); + } + } + + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/WindowControlBackgroundConverter.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/WindowControlBackgroundConverter.cs new file mode 100644 index 00000000..b7d5618b --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/WindowControlBackgroundConverter.cs @@ -0,0 +1,61 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Data; +using System.Globalization; +using System.Windows.Media; + +namespace Xceed.Wpf.Toolkit.Core.Converters +{ + public class WindowControlBackgroundConverter : IMultiValueConverter + { + /// + /// Used in the WindowContainer Template to calculate the resulting background brush + /// from the WindowBackground (values[0]) and WindowOpacity (values[1]) propreties. + /// + /// + /// + /// + /// + /// + public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) + { + Brush backgroundColor = (Brush)values[0]; + double opacity = (double)values[1]; + + if (backgroundColor != null) + { + // Do not override any possible opacity value specifically set by the user. + // Only use WindowOpacity value if the user did not set an opacity first. + if (backgroundColor.ReadLocalValue(Brush.OpacityProperty) == System.Windows.DependencyProperty.UnsetValue) + { + backgroundColor = backgroundColor.Clone(); + backgroundColor.Opacity = opacity; + } + } + return backgroundColor; + } + + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/WizardPageButtonVisibilityConverter.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/WizardPageButtonVisibilityConverter.cs new file mode 100644 index 00000000..dc08649d --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Converters/WizardPageButtonVisibilityConverter.cs @@ -0,0 +1,64 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Windows; +using System.Windows.Data; + +namespace Xceed.Wpf.Toolkit.Core.Converters +{ + public class WizardPageButtonVisibilityConverter : IMultiValueConverter + { + public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + if (values == null || values.Length != 2) + throw new ArgumentException("Wrong number of arguments for WizardPageButtonVisibilityConverter."); + + Visibility wizardVisibility = ((values[0] == null) || (values[0] == DependencyProperty.UnsetValue)) + ? Visibility.Hidden + : (Visibility)values[0]; + + WizardPageButtonVisibility wizardPageVisibility = ((values[1] == null) || (values[1] == DependencyProperty.UnsetValue)) + ? WizardPageButtonVisibility.Hidden + : (WizardPageButtonVisibility)values[1]; + + Visibility visibility = Visibility.Visible; + + switch (wizardPageVisibility) + { + case WizardPageButtonVisibility.Inherit: + visibility = wizardVisibility; + break; + case WizardPageButtonVisibility.Collapsed: + visibility = Visibility.Collapsed; + break; + case WizardPageButtonVisibility.Hidden: + visibility = Visibility.Hidden; + break; + case WizardPageButtonVisibility.Visible: + visibility = Visibility.Visible; + break; + } + + return visibility; + } + + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/EditableKeyValuePair.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/EditableKeyValuePair.cs new file mode 100644 index 00000000..289f0c35 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/EditableKeyValuePair.cs @@ -0,0 +1,96 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.ComponentModel; + +namespace Xceed.Wpf.Toolkit.Core +{ + public class EditableKeyValuePair : CustomTypeDescriptor + { + #region Members + + private PropertyDescriptorCollection _properties; + + #endregion + + #region Properties + + public TKey Key + { + get; + set; + } + + public TValue Value + { + get; + set; + } + + #endregion + + #region Constructors + + //Necessary for adding new items in CollectionEditor + public EditableKeyValuePair() + { + var propertyList = new List(); + + var KeyDescriptor = TypeDescriptor.CreateProperty(this.GetType(), "Key", typeof(TKey)); + propertyList.Add(KeyDescriptor); + + var ValueDescriptor = TypeDescriptor.CreateProperty(this.GetType(), "Value", typeof(TValue)); + propertyList.Add(ValueDescriptor); + + _properties = new PropertyDescriptorCollection(propertyList.ToArray()); + } + + public EditableKeyValuePair(TKey key, TValue value) + : this() + { + this.Key = key; + this.Value = value; + } + + #endregion + + #region Overrides + + public override PropertyDescriptorCollection GetProperties(Attribute[] attributes) + { + return this.GetProperties(); + } + + public override PropertyDescriptorCollection GetProperties() + { + return _properties; + } + + public override object GetPropertyOwner(PropertyDescriptor pd) + { + return this; + } + + public override string ToString() + { + return "[" + this.Key + "," + this.Value + "]"; + } + + #endregion + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/ErrorMessages.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/ErrorMessages.cs new file mode 100644 index 00000000..d3e45c77 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/ErrorMessages.cs @@ -0,0 +1,88 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System.Resources; + +namespace Xceed.Wpf.Toolkit.Core +{ + internal static class ErrorMessages + { + #region Static Fields + + + public const string EndAngleCannotBeSetDirectlyInSlice = "EndAngleCannotBeSetDirectlyInSlice"; + public const string SliceCannotBeSetDirectlyInEndAngle = "SliceCannotBeSetDirectlyInEndAngle"; + public const string SliceOOR = "SliceOOR"; + public const string AnimationAccelerationRatioOOR = "AnimationAccelerationRatioOOR"; + public const string AnimationDecelerationRatioOOR = "AnimationDecelerationRatioOOR"; + public const string ZoomboxContentMustBeUIElement = "ZoomboxContentMustBeUIElement"; + public const string ViewModeInvalidForSource = "ViewModeInvalidForSource"; + public const string ZoomboxTemplateNeedsContent = "ZoomboxTemplateNeedsContent"; + public const string ZoomboxHasViewFinderButNotDisplay = "ZoomboxHasViewFinderButNotDisplay"; + public const string PositionOnlyAccessibleOnAbsolute = "PositionOnlyAccessibleOnAbsolute"; + public const string ZoomboxViewAlreadyInitialized = "ZoomboxViewAlreadyInitialized"; + public const string ScaleOnlyAccessibleOnAbsolute = "ScaleOnlyAccessibleOnAbsolute"; + public const string RegionOnlyAccessibleOnRegionalView = "RegionOnlyAccessibleOnRegionalView"; + public const string UnableToConvertToZoomboxView = "UnableToConvertToZoomboxView"; + public const string ViewStackCannotBeManipulatedNow = "ViewStackCannotBeManipulatedNow"; + + + public const string SuppliedValueWasNotVisibility = "SuppliedValueWasNotVisibility"; + public const string NegativeTimeSpanNotSupported = "NegativeTimeSpanNotSupported"; + public const string NegativeSpeedNotSupported = "NegativeSpeedNotSupported"; + public const string InvalidRatePropertyAccessed = "InvalidRatePropertyAccessed"; + + public const string AlreadyInColumnCollection = "Value already belongs to another 'ColumnDefinitionCollection'."; + public const string AlreadyInRowCollection = "Value already belongs to another 'RowDefinitionCollection'."; + public const string AlreadyInStackDefinition = "Value already belongs to another 'StackDefinitionCollection'."; + public const string ArrayDestTooShort = "'array' destination not long enough."; + public const string CollectionDisposed = "Collection was disposed, enumerator operations not valid."; + public const string CollectionModified = "Collection was modified; enumeration operation may not execute."; + public const string ColumnValueIsReadOnly = "Cannot modify 'ColumnDefinitionCollection' in read-only state."; + public const string DefaultAnimatorCantAnimate = "DefaultAnimatorCantAnimate"; + public const string DefaultAnimationRateAnimationRateDefault = "DefaultAnimationRateAnimationRateDefault"; + public const string DefaultAnimatorIterativeAnimationDefault = "DefaultAnimatorIterativeAnimationDefault"; + public const string DestMultidimensional = "Destination is multidimensional. Expected array of rank 1."; + public const string EnumerationFinished = "Enumeration already finished."; + public const string EnumerationNotStarted = "Enumeration has not started. Call MoveNext."; + public const string InvalidDefaultStackLength = "The default stack length must be Auto or an explicit value."; + public const string MustBeColumnDefinition = "'ColumnDefinitionCollection' must be type 'ColumnDefinition'."; + public const string MustBeRowDefinition = "'RowDefinitionCollection' must be type 'RowDefinition'."; + public const string MustBeStackDefinition = "'StackDefinitionCollection' must be type 'StackDefinition'."; + public const string RowValueIsReadOnly = "Cannot modify 'StackDefinitionCollection' in read-only state."; + public const string StackValueIsReadOnly = "Cannot modify 'StackDefinitionCollection' in read-only state."; + public const string UnexpectedType = "Expected type '{0}', got '{1}'."; + + + private static readonly ResourceManager _resourceManager; + + #endregion + + #region Constructor + + static ErrorMessages() + { + _resourceManager = new ResourceManager("Xceed.Wpf.Toolkit.Core.ErrorMessages", typeof(ErrorMessages).Assembly); + } + + #endregion + + public static string GetMessage(string msgId) + { + return _resourceManager.GetString(msgId); + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/ErrorMessages.resx b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/ErrorMessages.resx new file mode 100644 index 00000000..8addfd76 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/ErrorMessages.resx @@ -0,0 +1,228 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + AnimationAccelerationRatio must be between 0.0 and 1.0. + + + AnimationDecelerationRatio must be between 0.0 and 1.0. + + + ItemAnimationState can only be used once the animation helper has been assigned + + + Cannot convert back to a range. + + + Container model was already removed from children collection. + + + The DefaultAnimationRate property cannot be set to AnimationRate.Default. It must have a valid AnimationRate value. + + + The DefaultAnimator cannot actually be used for animation. + + + The DefaultAnimator property cannot be set to IterativeAnimation.Default. It must be a valid IterativeAnimator value or null. + + + The EndAngle property cannot be set directly while a Pie's Mode is Slice. You must set the Slice property instead. + + + GlassEnabled can be set only in Full Trust enviornments + + + Unable to return a {0} value for an AnimationRate value of '{1}'. This AnimationRate is represented as a {2} value. + + + item must be a Visual + + + item must be either a Model3D or a Visual3D. + + + The method or operation is not implemented. + + + Speed must be greater than or equal to zero. + + + Duration (TimeSpan) must be greater than or equal to zero. + + + Operation not supported on the platform + + + orderedItems must contain every item in the visible items. + + + The Position property can only be accessed on an absolute view. + + + The Region property can only be accessed on a region-based view. + + + The Scale property can only be accessed on an absolute view. + + + SetNewToValue set on a completed animation helper + + + The Slice property cannot be set directly while a Pie's Mode is EndAngle. You must set the EndAngle property instead. + + + Slice must be between 0.0 and 1.0. + + + Error converting from bool value to Visibility value. Supplied value was not of type bool. + + + Error converting from Visibility value to bool value. Supplied value was not of type Visibility. + + + To and from matrix are equal + + + Unable to convert object '{0}' to ZoomboxView. + + + Value to convert must be a number. + + + The ViewStackMode must be Default or Manual while ViewStackSource is in use. + + + The ViewStack cannot be directly manipulated. Operation is not valid while ViewStackSource is in use. Access and modify members of the Zoombox.ViewStackSource instead. + + + VisibleItemCount and orderedItems count must be equal. + + + The Content property of a Zoombox control must specify a UIElement. + + + The Zoombox template contains a ViewFinder element but it does not contain a ZoomboxViewFinderDisplay element + + + The Zoombox template does not contain a content presenter. + + + The ZoomboxView instance is already initialized for a different type of view: {0} + + \ No newline at end of file diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/IndexChangedEventArgs.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/IndexChangedEventArgs.cs new file mode 100644 index 00000000..11e83518 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/IndexChangedEventArgs.cs @@ -0,0 +1,38 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Windows; + +namespace Xceed.Wpf.Toolkit.Core +{ + public class IndexChangedEventArgs : PropertyChangedEventArgs + { + #region Constructors + + public IndexChangedEventArgs(RoutedEvent routedEvent, int oldIndex, int newIndex) + : base(routedEvent, oldIndex, newIndex) + { + } + + #endregion + + protected override void InvokeEventHandler(Delegate genericHandler, object genericTarget) + { + ((IndexChangedEventHandler)genericHandler)(genericTarget, this); + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/IndexChangedEventHandler.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/IndexChangedEventHandler.cs new file mode 100644 index 00000000..ab9af191 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/IndexChangedEventHandler.cs @@ -0,0 +1,20 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +namespace Xceed.Wpf.Toolkit.Core +{ + public delegate void IndexChangedEventHandler(object sender, IndexChangedEventArgs e); +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Input/IValidateInput.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Input/IValidateInput.cs new file mode 100644 index 00000000..7caa7053 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Input/IValidateInput.cs @@ -0,0 +1,29 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Xceed.Wpf.Toolkit.Core.Input +{ + public interface IValidateInput + { + event InputValidationErrorEventHandler InputValidationError; + bool CommitInput(); + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Input/InputValidationErrorEventArgs.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Input/InputValidationErrorEventArgs.cs new file mode 100644 index 00000000..56266ef0 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Input/InputValidationErrorEventArgs.cs @@ -0,0 +1,73 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Xceed.Wpf.Toolkit.Core.Input +{ + public delegate void InputValidationErrorEventHandler(object sender, InputValidationErrorEventArgs e); + + public class InputValidationErrorEventArgs : EventArgs + { + #region Constructors + + public InputValidationErrorEventArgs(Exception e) + { + Exception = e; + } + + #endregion + + #region Exception Property + + public Exception Exception + { + get + { + return exception; + } + private set + { + exception = value; + } + } + + private Exception exception; + + #endregion + + #region ThrowException Property + + public bool ThrowException + { + get + { + return _throwException; + } + set + { + _throwException = value; + } + } + + private bool _throwException; + + #endregion + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Input/KeyModifier.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Input/KeyModifier.cs new file mode 100644 index 00000000..9ce9147f --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Input/KeyModifier.cs @@ -0,0 +1,35 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + + +namespace Xceed.Wpf.Toolkit.Core.Input +{ + public enum KeyModifier + { + None, + Blocked, + Ctrl, + LeftCtrl, + RightCtrl, + Shift, + LeftShift, + RightShift, + Alt, + LeftAlt, + RightAlt, + Exact, + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Input/KeyModifierCollection.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Input/KeyModifierCollection.cs new file mode 100644 index 00000000..01cdc795 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Input/KeyModifierCollection.cs @@ -0,0 +1,223 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Windows.Input; + +namespace Xceed.Wpf.Toolkit.Core.Input +{ + [TypeConverter(typeof(KeyModifierCollectionConverter))] + public class KeyModifierCollection : Collection + { + #region AreActive Property + + public bool AreActive + { + get + { + if (this.Count == 0) + return true; + + // if the Blocked modifier is present, then the action is not allowed + // so simply return false + if (this.Contains(KeyModifier.Blocked)) + return false; + + if (this.Contains(KeyModifier.Exact)) + return this.IsExactMatch(); + + return this.MatchAny(); + } + } + + #endregion + + private static bool IsKeyPressed(KeyModifier modifier, ICollection keys) + { + switch (modifier) + { + case KeyModifier.Alt: + return keys.Contains(Key.LeftAlt) + || keys.Contains(Key.RightAlt); + + case KeyModifier.LeftAlt: + return keys.Contains(Key.LeftAlt); + + case KeyModifier.RightAlt: + return keys.Contains(Key.RightAlt); + + case KeyModifier.Ctrl: + return keys.Contains(Key.LeftCtrl) + || keys.Contains(Key.RightCtrl); + + case KeyModifier.LeftCtrl: + return keys.Contains(Key.LeftCtrl); + + case KeyModifier.RightCtrl: + return keys.Contains(Key.RightCtrl); + + case KeyModifier.Shift: + return keys.Contains(Key.LeftShift) + || keys.Contains(Key.RightShift); + + case KeyModifier.LeftShift: + return keys.Contains(Key.LeftShift); + + case KeyModifier.RightShift: + return keys.Contains(Key.RightShift); + + case KeyModifier.None: + return true; + + default: + throw new NotSupportedException("Unknown modifier"); + } + } + + private static bool HasModifier(Key key, ICollection modifiers) + { + switch (key) + { + case Key.LeftAlt: + return modifiers.Contains(KeyModifier.Alt) + || modifiers.Contains(KeyModifier.LeftAlt); + + case Key.RightAlt: + return modifiers.Contains(KeyModifier.Alt) + || modifiers.Contains(KeyModifier.RightAlt); + + case Key.LeftCtrl: + return modifiers.Contains(KeyModifier.Ctrl) + || modifiers.Contains(KeyModifier.LeftCtrl); + + case Key.RightCtrl: + return modifiers.Contains(KeyModifier.Ctrl) + || modifiers.Contains(KeyModifier.RightCtrl); + + case Key.LeftShift: + return modifiers.Contains(KeyModifier.Shift) + || modifiers.Contains(KeyModifier.LeftShift); + + case Key.RightShift: + return modifiers.Contains(KeyModifier.Shift) + || modifiers.Contains(KeyModifier.RightShift); + + default: + throw new NotSupportedException("Unknown key"); + } + } + + private bool IsExactMatch() + { + HashSet modifiers = this.GetKeyModifiers(); + HashSet keys = this.GetKeysPressed(); + + // No key must be pressed for the modifier None. + if (this.Contains(KeyModifier.None)) + return (modifiers.Count == 0) + && (keys.Count == 0); + + // Make sure every modifier has a matching key pressed. + foreach (KeyModifier modifier in modifiers) + { + if (!KeyModifierCollection.IsKeyPressed(modifier, keys)) + return false; + } + + // Make sure every key pressed has a matching modifier. + foreach (Key key in keys) + { + if (!KeyModifierCollection.HasModifier(key, modifiers)) + return false; + } + + return true; + } + + private bool MatchAny() + { + if (this.Contains(KeyModifier.None)) + return true; + + HashSet modifiers = this.GetKeyModifiers(); + HashSet keys = this.GetKeysPressed(); + + foreach (KeyModifier modifier in modifiers) + { + if (KeyModifierCollection.IsKeyPressed(modifier, keys)) + return true; + } + + return false; + } + + private HashSet GetKeyModifiers() + { + HashSet modifiers = new HashSet(); + + foreach (KeyModifier modifier in this) + { + switch (modifier) + { + case KeyModifier.Alt: + case KeyModifier.LeftAlt: + case KeyModifier.RightAlt: + case KeyModifier.Ctrl: + case KeyModifier.LeftCtrl: + case KeyModifier.RightCtrl: + case KeyModifier.Shift: + case KeyModifier.LeftShift: + case KeyModifier.RightShift: + { + if (!modifiers.Contains(modifier)) + { + modifiers.Add(modifier); + } + } + break; + + default: + break; + } + } + + return modifiers; + } + + private HashSet GetKeysPressed() + { + HashSet keys = new HashSet(); + + if (Keyboard.IsKeyDown(Key.LeftAlt)) + keys.Add(Key.LeftAlt); + if (Keyboard.IsKeyDown(Key.RightAlt)) + keys.Add(Key.RightAlt); + if (Keyboard.IsKeyDown(Key.LeftCtrl)) + keys.Add(Key.LeftCtrl); + if (Keyboard.IsKeyDown(Key.RightCtrl)) + keys.Add(Key.RightCtrl); + if (Keyboard.IsKeyDown(Key.LeftShift)) + keys.Add(Key.LeftShift); + if (Keyboard.IsKeyDown(Key.RightShift)) + keys.Add(Key.RightShift); + + return keys; + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Input/KeyModifierCollectionConverter.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Input/KeyModifierCollectionConverter.cs new file mode 100644 index 00000000..a089ec7a --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Input/KeyModifierCollectionConverter.cs @@ -0,0 +1,122 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.ComponentModel; +using System.ComponentModel.Design.Serialization; +using System.Globalization; +using System.Reflection; +using System.Security; + +namespace Xceed.Wpf.Toolkit.Core.Input +{ + public sealed class KeyModifierCollectionConverter : TypeConverter + { + #region Static Fields + + private static readonly TypeConverter _keyModifierConverter = TypeDescriptor.GetConverter(typeof(KeyModifier)); + + #endregion + + public override bool CanConvertFrom(ITypeDescriptorContext typeDescriptorContext, Type type) + { + return _keyModifierConverter.CanConvertFrom(typeDescriptorContext, type); + } + + public override bool CanConvertTo(ITypeDescriptorContext typeDescriptorContext, Type type) + { + return (type == typeof(InstanceDescriptor) + || type == typeof(KeyModifierCollection) + || type == typeof(string)); + } + + public override object ConvertFrom(ITypeDescriptorContext typeDescriptorContext, + CultureInfo cultureInfo, object value) + { + KeyModifierCollection result = new KeyModifierCollection(); + string stringValue = value as string; + + // convert null as None + if (value == null + || (stringValue != null && stringValue.Trim() == string.Empty)) + { + result.Add(KeyModifier.None); + } + else + { + // respect the following separators: '+', ' ', '|', or ',' + foreach (string token in stringValue.Split(new char[] { '+', ' ', '|', ',' }, + StringSplitOptions.RemoveEmptyEntries)) + result.Add((KeyModifier)_keyModifierConverter.ConvertFrom(typeDescriptorContext, cultureInfo, token)); + + // if nothing added, assume None + if (result.Count == 0) + result.Add(KeyModifier.None); + } + return result; + } + + public override object ConvertTo(ITypeDescriptorContext typeDescriptorContext, + CultureInfo cultureInfo, object value, Type destinationType) + { + // special handling for null or an empty collection + if (value == null || ((KeyModifierCollection)value).Count == 0) + { + if (destinationType == typeof(InstanceDescriptor)) + { + object result = null; + try + { + result = ConstructInstanceDescriptor(); + } + catch (SecurityException) + { + } + return result; + } + else if (destinationType == typeof(string)) + { + return _keyModifierConverter.ConvertTo(typeDescriptorContext, + cultureInfo, KeyModifier.None, destinationType); + } + } + + // return a '+' delimited string containing the modifiers + if (destinationType == typeof(string)) + { + string result = string.Empty; + foreach (KeyModifier modifier in (KeyModifierCollection)value) + { + if (result != string.Empty) + result = result + '+'; + + result = result + _keyModifierConverter.ConvertTo(typeDescriptorContext, + cultureInfo, modifier, destinationType); + } + return result; + } + + // unexpected type requested so return null + return null; + } + + private static object ConstructInstanceDescriptor() + { + ConstructorInfo ci = typeof(KeyModifierCollection).GetConstructor(new Type[] { }); + return new InstanceDescriptor(ci, new Object[] { }); + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/InvalidContentException.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/InvalidContentException.cs new file mode 100644 index 00000000..c975f223 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/InvalidContentException.cs @@ -0,0 +1,37 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; + +namespace Xceed.Wpf.Toolkit.Core +{ + public class InvalidContentException : Exception + { + #region Constructors + + public InvalidContentException(string message) + : base(message) + { + } + + public InvalidContentException(string message, Exception innerException) + : base(message, innerException) + { + } + + #endregion + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/InvalidTemplateException.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/InvalidTemplateException.cs new file mode 100644 index 00000000..22b5b0cd --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/InvalidTemplateException.cs @@ -0,0 +1,37 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; + +namespace Xceed.Wpf.Toolkit.Core +{ + public class InvalidTemplateException : Exception + { + #region Constructors + + public InvalidTemplateException(string message) + : base(message) + { + } + + public InvalidTemplateException(string message, Exception innerException) + : base(message, innerException) + { + } + + #endregion + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/LocationEnum.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/LocationEnum.cs new file mode 100644 index 00000000..ba885ac6 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/LocationEnum.cs @@ -0,0 +1,24 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +namespace Xceed.Wpf.Toolkit.Core +{ + public enum Location + { + Left, + Right + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Media/Animation/AnimationRate.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Media/Animation/AnimationRate.cs new file mode 100644 index 00000000..a8fee8b3 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Media/Animation/AnimationRate.cs @@ -0,0 +1,346 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.ComponentModel; +using System.Runtime.InteropServices; +using Xceed.Wpf.Toolkit.Core.Utilities; +using Xceed.Wpf.Toolkit.Core; + +namespace Xceed.Wpf.Toolkit.Media.Animation +{ + [TypeConverter(typeof(AnimationRateConverter))] + [StructLayout(LayoutKind.Explicit)] + public struct AnimationRate + { + #region Static Fields + + private static AnimationRate _default = new AnimationRate(true); + + #endregion + + #region Constructors + + public AnimationRate(TimeSpan duration) + { + if (duration < TimeSpan.Zero) + { + throw new ArgumentException(ErrorMessages.GetMessage(ErrorMessages.NegativeTimeSpanNotSupported)); + } + _speed = 0d; + _duration = duration.Ticks; + _rateType = RateType.TimeSpan; + } + + public AnimationRate(double speed) + { + if (DoubleHelper.IsNaN(speed) || speed < 0d) + { + throw new ArgumentException(ErrorMessages.GetMessage(ErrorMessages.NegativeSpeedNotSupported)); + } + _duration = 0; + _speed = speed; + _rateType = RateType.Speed; + } + + private AnimationRate(bool ignore) + { + _duration = 0; + _speed = double.NaN; + _rateType = RateType.Speed; + } + + #endregion + + #region Default Property + + public static AnimationRate Default + { + get + { + return _default; + } + } + + #endregion + + #region HasDuration Property + + public bool HasDuration + { + get + { + return (_rateType == RateType.TimeSpan); + } + } + + #endregion + + #region Duration Property + + public TimeSpan Duration + { + get + { + if (this.HasDuration) + return TimeSpan.FromTicks(_duration); + + throw new InvalidOperationException( + string.Format( + ErrorMessages.GetMessage(ErrorMessages.InvalidRatePropertyAccessed), + "Duration", + this, + "Speed")); + } + } + + #endregion + + #region HasSpeed Property + + public bool HasSpeed + { + get + { + return (_rateType == RateType.Speed); + } + } + + #endregion + + #region Speed Property + + public double Speed + { + get + { + if (this.HasSpeed) + return _speed; + + throw new InvalidOperationException( + string.Format( + ErrorMessages.GetMessage(ErrorMessages.InvalidRatePropertyAccessed), + "Speed", + this, + "Duration")); + } + } + + #endregion + + public AnimationRate Add(AnimationRate animationRate) + { + return this + animationRate; + } + + public override bool Equals(Object value) + { + if (value == null) + return false; + + if (value is AnimationRate) + return this.Equals((AnimationRate)value); + + return false; + } + + public bool Equals(AnimationRate animationRate) + { + if (this.HasDuration) + { + if (animationRate.HasDuration) + return _duration == animationRate._duration; + + return false; + } + else // HasSpeed + { + if (animationRate.HasSpeed) + { + if (DoubleHelper.IsNaN(_speed)) + return DoubleHelper.IsNaN(animationRate._speed); + + return _speed == animationRate._speed; + } + + return false; + } + } + + public static bool Equals(AnimationRate t1, AnimationRate t2) + { + return t1.Equals(t2); + } + + public override int GetHashCode() + { + if (this.HasDuration) + return _duration.GetHashCode(); + + return _speed.GetHashCode(); + } + + public AnimationRate Subtract(AnimationRate animationRate) + { + return this - animationRate; + } + + public override string ToString() + { + if (this.HasDuration) + return TypeDescriptor.GetConverter(_duration).ConvertToString(_duration); + + return TypeDescriptor.GetConverter(_speed).ConvertToString(_speed); + } + + #region Operators Methods + + public static implicit operator AnimationRate(TimeSpan duration) + { + if (duration < TimeSpan.Zero) + throw new ArgumentException(ErrorMessages.GetMessage(ErrorMessages.NegativeTimeSpanNotSupported)); + + return new AnimationRate(duration); + } + + public static implicit operator AnimationRate(double speed) + { + if (DoubleHelper.IsNaN(speed) || speed < 0) + throw new ArgumentException(ErrorMessages.GetMessage(ErrorMessages.NegativeSpeedNotSupported)); + + return new AnimationRate(speed); + } + + public static implicit operator AnimationRate(int speed) + { + if (DoubleHelper.IsNaN(speed) || speed < 0) + throw new ArgumentException(ErrorMessages.GetMessage(ErrorMessages.NegativeSpeedNotSupported)); + + return new AnimationRate((double)speed); + } + + public static AnimationRate operator +(AnimationRate t1, AnimationRate t2) + { + if (t1.HasDuration && t2.HasDuration) + return new AnimationRate(t1._duration + t2._duration); + + if (t1.HasSpeed && t2.HasSpeed) + return new AnimationRate(t1._speed + t2._speed); + + return (AnimationRate)0d; + } + + public static AnimationRate operator -(AnimationRate t1, AnimationRate t2) + { + if (t1.HasDuration && t2.HasDuration) + return new AnimationRate(t1._duration - t2._duration); + + if (t1.HasSpeed && t2.HasSpeed) + return new AnimationRate(t1._speed - t2._speed); + + return (AnimationRate)0d; + } + + public static bool operator ==(AnimationRate t1, AnimationRate t2) + { + return t1.Equals(t2); + } + + public static bool operator !=(AnimationRate t1, AnimationRate t2) + { + return !(t1.Equals(t2)); + } + + public static bool operator >(AnimationRate t1, AnimationRate t2) + { + if (t1.HasDuration && t2.HasDuration) + return t1._duration > t2._duration; + + if (t1.HasSpeed && t2.HasSpeed) + return (t1._speed > t2._speed) && !DoubleHelper.AreVirtuallyEqual(t1._speed, t2._speed); + + // arbitrary: assume a Speed is greater than a Duration + return t1.HasSpeed; + } + + public static bool operator >=(AnimationRate t1, AnimationRate t2) + { + return !(t1 < t2); + } + + public static bool operator <(AnimationRate t1, AnimationRate t2) + { + if (t1.HasDuration && t2.HasDuration) + return t1._duration < t2._duration; + + if (t1.HasSpeed && t2.HasSpeed) + return (t1._speed < t2._speed) && !DoubleHelper.AreVirtuallyEqual(t1._speed, t2._speed); + + // arbitrary: assume a Speed is greater than a Duration + return t1.HasDuration; + } + + public static bool operator <=(AnimationRate t1, AnimationRate t2) + { + return !(t1 > t2); + } + + public static int Compare(AnimationRate t1, AnimationRate t2) + { + if (t1 < t2) + return -1; + + if (t1 > t2) + return 1; + + // Neither is greater than the other + return 0; + } + + public static AnimationRate Plus(AnimationRate animationRate) + { + return animationRate; + } + + public static AnimationRate operator +(AnimationRate animationRate) + { + return animationRate; + } + + #endregion + + #region Private Fields + + [FieldOffset(0)] + long _duration; + [FieldOffset(0)] + double _speed; + [FieldOffset(8)] + RateType _rateType; + + #endregion + + #region RateType Nested Type + + private enum RateType + { + TimeSpan, + Speed, + } + + #endregion + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Media/Animation/AnimationRateConverter.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Media/Animation/AnimationRateConverter.cs new file mode 100644 index 00000000..08aa7b81 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Media/Animation/AnimationRateConverter.cs @@ -0,0 +1,120 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.ComponentModel; +using System.ComponentModel.Design.Serialization; +using System.Globalization; +using System.Reflection; + +namespace Xceed.Wpf.Toolkit.Media.Animation +{ + public class AnimationRateConverter : TypeConverter + { + public override bool CanConvertFrom(ITypeDescriptorContext td, Type t) + { + return (t == typeof(string)) + || (t == typeof(double)) + || (t == typeof(int)) + || (t == typeof(TimeSpan)); + } + + public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) + { + return (destinationType == typeof(InstanceDescriptor)) + || (destinationType == typeof(string)) + || (destinationType == typeof(double)) + || (destinationType == typeof(TimeSpan)); + } + + public override object ConvertFrom( + ITypeDescriptorContext td, + CultureInfo cultureInfo, + object value) + { + Type valueType = value.GetType(); + if (value is string) + { + string stringValue = value as string; + if ((value as string).Contains(":")) + { + TimeSpan duration = TimeSpan.Zero; + duration = (TimeSpan)TypeDescriptor.GetConverter(duration).ConvertFrom(td, cultureInfo, value); + return new AnimationRate(duration); + } + else + { + double speed = 0; + speed = (double)TypeDescriptor.GetConverter(speed).ConvertFrom(td, cultureInfo, value); + return new AnimationRate(speed); + } + } + else if (valueType == typeof(double)) + { + return (AnimationRate)(double)value; + } + else if (valueType == typeof(int)) + { + return (AnimationRate)(int)value; + } + else // TimeSpan + { + return (AnimationRate)(TimeSpan)value; + } + } + + public override object ConvertTo( + ITypeDescriptorContext context, + CultureInfo cultureInfo, + object value, + Type destinationType) + { + if (destinationType != null && value is AnimationRate) + { + AnimationRate rateValue = (AnimationRate)value; + + if (destinationType == typeof(InstanceDescriptor)) + { + MemberInfo mi; + if (rateValue.HasDuration) + { + mi = typeof(AnimationRate).GetConstructor(new Type[] { typeof(TimeSpan) }); + return new InstanceDescriptor(mi, new object[] { rateValue.Duration }); + } + else if (rateValue.HasSpeed) + { + mi = typeof(AnimationRate).GetConstructor(new Type[] { typeof(double) }); + return new InstanceDescriptor(mi, new object[] { rateValue.Speed }); + } + } + else if (destinationType == typeof(string)) + { + return rateValue.ToString(); + } + else if (destinationType == typeof(double)) + { + return rateValue.HasSpeed ? rateValue.Speed : 0.0d; + } + else if (destinationType == typeof(TimeSpan)) + { + return rateValue.HasDuration ? rateValue.Duration : TimeSpan.FromSeconds(0); + } + } + + return base.ConvertTo(context, cultureInfo, value, destinationType); + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Media/Animation/IterativeAnimationEquation.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Media/Animation/IterativeAnimationEquation.cs new file mode 100644 index 00000000..fefc6ab6 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Media/Animation/IterativeAnimationEquation.cs @@ -0,0 +1,49 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.ComponentModel; + +namespace Xceed.Wpf.Toolkit.Media.Animation +{ + [TypeConverter(typeof(IterativeEquationConverter))] + public class IterativeEquation + { + #region Constructors + + public IterativeEquation(IterativeAnimationEquationDelegate equation) + { + _equation = equation; + } + + internal IterativeEquation() + { + } + + #endregion + + public virtual T Evaluate(TimeSpan currentTime, T from, T to, TimeSpan duration) + { + return _equation(currentTime, from, to, duration); + } + + #region Private Fields + + private readonly IterativeAnimationEquationDelegate _equation; + + #endregion + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Media/Animation/IterativeAnimationEquationDelegate.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Media/Animation/IterativeAnimationEquationDelegate.cs new file mode 100644 index 00000000..f2f5690f --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Media/Animation/IterativeAnimationEquationDelegate.cs @@ -0,0 +1,22 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; + +namespace Xceed.Wpf.Toolkit.Media.Animation +{ + public delegate T IterativeAnimationEquationDelegate(TimeSpan currentTime, T from, T to, TimeSpan duration); +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Media/Animation/IterativeEquationConverter.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Media/Animation/IterativeEquationConverter.cs new file mode 100644 index 00000000..0963abac --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Media/Animation/IterativeEquationConverter.cs @@ -0,0 +1,145 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.ComponentModel; +using System.Globalization; + +namespace Xceed.Wpf.Toolkit.Media.Animation +{ + public class IterativeEquationConverter : TypeConverter + { + public override bool CanConvertFrom(ITypeDescriptorContext typeDescriptorContext, Type type) + { + return type == typeof(string); + } + + public override bool CanConvertTo(ITypeDescriptorContext typeDescriptorContext, Type type) + { + return type == typeof(IterativeEquation); + } + + public override object ConvertFrom( + ITypeDescriptorContext typeDescriptorContext, + CultureInfo cultureInfo, + object value) + { + IterativeEquation result = null; + + if (value is string) + { + switch (value as string) + { + case "BackEaseIn": + result = PennerEquations.BackEaseIn as IterativeEquation; + break; + case "BackEaseInOut": + result = PennerEquations.BackEaseInOut as IterativeEquation; + break; + case "BackEaseOut": + result = PennerEquations.BackEaseOut as IterativeEquation; + break; + case "BounceEaseIn": + result = PennerEquations.BounceEaseIn as IterativeEquation; + break; + case "BounceEaseInOut": + result = PennerEquations.BounceEaseInOut as IterativeEquation; + break; + case "BounceEaseOut": + result = PennerEquations.BounceEaseOut as IterativeEquation; + break; + case "CircEaseIn": + result = PennerEquations.CircEaseIn as IterativeEquation; + break; + case "CircEaseInOut": + result = PennerEquations.CircEaseInOut as IterativeEquation; + break; + case "CircEaseOut": + result = PennerEquations.CircEaseOut as IterativeEquation; + break; + case "CubicEaseIn": + result = PennerEquations.CubicEaseIn as IterativeEquation; + break; + case "CubicEaseInOut": + result = PennerEquations.CubicEaseInOut as IterativeEquation; + break; + case "CubicEaseOut": + result = PennerEquations.CubicEaseOut as IterativeEquation; + break; + case "ElasticEaseIn": + result = PennerEquations.ElasticEaseIn as IterativeEquation; + break; + case "ElasticEaseInOut": + result = PennerEquations.ElasticEaseInOut as IterativeEquation; + break; + case "ElasticEaseOut": + result = PennerEquations.ElasticEaseOut as IterativeEquation; + break; + case "ExpoEaseIn": + result = PennerEquations.ExpoEaseIn as IterativeEquation; + break; + case "ExpoEaseInOut": + result = PennerEquations.ExpoEaseInOut as IterativeEquation; + break; + case "ExpoEaseOut": + result = PennerEquations.ExpoEaseOut as IterativeEquation; + break; + case "Linear": + result = PennerEquations.Linear as IterativeEquation; + break; + case "QuadEaseIn": + result = PennerEquations.QuadEaseIn as IterativeEquation; + break; + case "QuadEaseInOut": + result = PennerEquations.QuadEaseInOut as IterativeEquation; + break; + case "QuadEaseOut": + result = PennerEquations.QuadEaseOut as IterativeEquation; + break; + case "QuartEaseIn": + result = PennerEquations.QuartEaseIn as IterativeEquation; + break; + case "QuartEaseInOut": + result = PennerEquations.QuartEaseInOut as IterativeEquation; + break; + case "QuartEaseOut": + result = PennerEquations.QuartEaseOut as IterativeEquation; + break; + case "QuintEaseIn": + result = PennerEquations.QuintEaseIn as IterativeEquation; + break; + case "QuintEaseInOut": + result = PennerEquations.QuintEaseInOut as IterativeEquation; + break; + case "QuintEaseOut": + result = PennerEquations.QuintEaseOut as IterativeEquation; + break; + case "SineEaseIn": + result = PennerEquations.SineEaseIn as IterativeEquation; + break; + case "SineEaseInOut": + result = PennerEquations.SineEaseInOut as IterativeEquation; + break; + case "SineEaseOut": + result = PennerEquations.SineEaseOut as IterativeEquation; + break; + } + } + + return result; + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Media/Animation/PennerEquation.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Media/Animation/PennerEquation.cs new file mode 100644 index 00000000..74e65ee8 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Media/Animation/PennerEquation.cs @@ -0,0 +1,54 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; + +namespace Xceed.Wpf.Toolkit.Media.Animation +{ + public class PennerEquation : IterativeEquation + { + #region Constructors + + internal PennerEquation(PennerEquationDelegate pennerImpl) + { + _pennerImpl = pennerImpl; + } + + #endregion + + public override double Evaluate(TimeSpan currentTime, double from, double to, TimeSpan duration) + { + double t = currentTime.TotalSeconds; + double b = from; + double c = to - from; + double d = duration.TotalSeconds; + + return _pennerImpl(t, b, c, d); + } + + #region Private Fields + + private readonly PennerEquationDelegate _pennerImpl; + + #endregion + + #region PennerEquationDelegate Delegate + + internal delegate double PennerEquationDelegate(double t, double b, double c, double d); + + #endregion + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Media/Animation/PennerEquations.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Media/Animation/PennerEquations.cs new file mode 100644 index 00000000..37847818 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Media/Animation/PennerEquations.cs @@ -0,0 +1,851 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; + +namespace Xceed.Wpf.Toolkit.Media.Animation +{ + public static class PennerEquations + { + #region BackEaseIn Static Property + + public static PennerEquation BackEaseIn + { + get + { + if (_backEaseIn == null) + { + _backEaseIn = new PennerEquation(BackEaseInImpl); + } + return _backEaseIn; + } + } + + private static PennerEquation _backEaseIn; + + #endregion + + #region BackEaseInOut Static Property + + public static PennerEquation BackEaseInOut + { + get + { + if (_backEaseInOut == null) + { + _backEaseInOut = new PennerEquation(BackEaseInOutImpl); + } + return _backEaseInOut; + } + } + + private static PennerEquation _backEaseInOut; + + #endregion + + #region BackEaseOut Static Property + + public static PennerEquation BackEaseOut + { + get + { + if (_backEaseOut == null) + { + _backEaseOut = new PennerEquation(BackEaseOutImpl); + } + return _backEaseOut; + } + } + + private static PennerEquation _backEaseOut; + + #endregion + + #region BounceEaseIn Static Property + + public static PennerEquation BounceEaseIn + { + get + { + if (_bounceEaseIn == null) + { + _bounceEaseIn = new PennerEquation(BounceEaseInImpl); + } + return _bounceEaseIn; + } + } + + private static PennerEquation _bounceEaseIn; + + #endregion + + #region BounceEaseInOut Static Property + + public static PennerEquation BounceEaseInOut + { + get + { + if (_bounceEaseInOut == null) + { + _bounceEaseInOut = new PennerEquation(BounceEaseInOutImpl); + } + return _bounceEaseInOut; + } + } + + private static PennerEquation _bounceEaseInOut; + + #endregion + + #region BounceEaseOut Static Property + + public static PennerEquation BounceEaseOut + { + get + { + if (_bounceEaseOut == null) + { + _bounceEaseOut = new PennerEquation(BounceEaseOutImpl); + } + return _bounceEaseOut; + } + } + + private static PennerEquation _bounceEaseOut; + + #endregion + + #region CircEaseIn Static Property + + public static PennerEquation CircEaseIn + { + get + { + if (_circEaseIn == null) + { + _circEaseIn = new PennerEquation(CircEaseInImpl); + } + return _circEaseIn; + } + } + + private static PennerEquation _circEaseIn; + + #endregion + + #region CircEaseInOut Static Property + + public static PennerEquation CircEaseInOut + { + get + { + if (_circEaseInOut == null) + { + _circEaseInOut = new PennerEquation(CircEaseInOutImpl); + } + return _circEaseInOut; + } + } + + private static PennerEquation _circEaseInOut; + + #endregion + + #region CircEaseOut Static Property + + public static PennerEquation CircEaseOut + { + get + { + if (_circEaseOut == null) + { + _circEaseOut = new PennerEquation(CircEaseOutImpl); + } + return _circEaseOut; + } + } + + private static PennerEquation _circEaseOut; + + #endregion + + #region CubicEaseIn Static Property + + public static PennerEquation CubicEaseIn + { + get + { + if (_cubicEaseIn == null) + { + _cubicEaseIn = new PennerEquation(CubicEaseInImpl); + } + return _cubicEaseIn; + } + } + + private static PennerEquation _cubicEaseIn; + + #endregion + + #region CubicEaseInOut Static Property + + public static PennerEquation CubicEaseInOut + { + get + { + if (_cubicEaseInOut == null) + { + _cubicEaseInOut = new PennerEquation(CubicEaseInOutImpl); + } + return _cubicEaseInOut; + } + } + + private static PennerEquation _cubicEaseInOut; + + #endregion + + #region CubicEaseOut Static Property + + public static PennerEquation CubicEaseOut + { + get + { + if (_cubicEaseOut == null) + { + _cubicEaseOut = new PennerEquation(CubicEaseOutImpl); + } + return _cubicEaseOut; + } + } + + private static PennerEquation _cubicEaseOut; + + #endregion + + #region ElasticEaseIn Static Property + + public static PennerEquation ElasticEaseIn + { + get + { + if (_elasticEaseIn == null) + { + _elasticEaseIn = new PennerEquation(ElasticEaseInImpl); + } + return _elasticEaseIn; + } + } + + private static PennerEquation _elasticEaseIn; + + #endregion + + #region ElasticEaseInOut Static Property + + public static PennerEquation ElasticEaseInOut + { + get + { + if (_elasticEaseInOut == null) + { + _elasticEaseInOut = new PennerEquation(ElasticEaseInOutImpl); + } + return _elasticEaseInOut; + } + } + + private static PennerEquation _elasticEaseInOut; + + #endregion + + #region ElasticEaseOut Static Property + + public static PennerEquation ElasticEaseOut + { + get + { + if (_elasticEaseOut == null) + { + _elasticEaseOut = new PennerEquation(ElasticEaseOutImpl); + } + return _elasticEaseOut; + } + } + + private static PennerEquation _elasticEaseOut; + + #endregion + + #region ExpoEaseIn Static Property + + public static PennerEquation ExpoEaseIn + { + get + { + if (_expoEaseIn == null) + { + _expoEaseIn = new PennerEquation(ExpoEaseInImpl); + } + return _expoEaseIn; + } + } + + private static PennerEquation _expoEaseIn; + + #endregion + + #region ExpoEaseInOut Static Property + + public static PennerEquation ExpoEaseInOut + { + get + { + if (_expoEaseInOut == null) + { + _expoEaseInOut = new PennerEquation(ExpoEaseInOutImpl); + } + return _expoEaseInOut; + } + } + + private static PennerEquation _expoEaseInOut; + + #endregion + + #region ExpoEaseOut Static Property + + public static PennerEquation ExpoEaseOut + { + get + { + if (_expoEaseOut == null) + { + _expoEaseOut = new PennerEquation(ExpoEaseOutImpl); + } + return _expoEaseOut; + } + } + + private static PennerEquation _expoEaseOut; + + #endregion + + #region Linear Static Property + + public static PennerEquation Linear + { + get + { + if (_linear == null) + { + _linear = new PennerEquation(LinearImpl); + } + return _linear; + } + } + + private static PennerEquation _linear; + + #endregion + + #region QuadEaseIn Static Property + + public static PennerEquation QuadEaseIn + { + get + { + if (_quadEaseIn == null) + { + _quadEaseIn = new PennerEquation(QuadEaseInImpl); + } + return _quadEaseIn; + } + } + + private static PennerEquation _quadEaseIn; + + #endregion + + #region QuadEaseInOut Static Property + + public static PennerEquation QuadEaseInOut + { + get + { + if (_quadEaseInOut == null) + { + _quadEaseInOut = new PennerEquation(QuadEaseInOutImpl); + } + return _quadEaseInOut; + } + } + + private static PennerEquation _quadEaseInOut; + + #endregion + + #region QuadEaseOut Static Property + + public static PennerEquation QuadEaseOut + { + get + { + if (_quadEaseOut == null) + { + _quadEaseOut = new PennerEquation(QuadEaseOutImpl); + } + return _quadEaseOut; + } + } + + private static PennerEquation _quadEaseOut; + + #endregion + + #region QuartEaseIn Static Property + + public static PennerEquation QuartEaseIn + { + get + { + if (_quartEaseIn == null) + { + _quartEaseIn = new PennerEquation(QuartEaseInImpl); + } + return _quartEaseIn; + } + } + + private static PennerEquation _quartEaseIn; + + #endregion + + #region QuartEaseInOut Static Property + + public static PennerEquation QuartEaseInOut + { + get + { + if (_quartEaseInOut == null) + { + _quartEaseInOut = new PennerEquation(QuartEaseInOutImpl); + } + return _quartEaseInOut; + } + } + + private static PennerEquation _quartEaseInOut; + + #endregion + + #region QuartEaseOut Static Property + + public static PennerEquation QuartEaseOut + { + get + { + if (_quartEaseOut == null) + { + _quartEaseOut = new PennerEquation(QuartEaseOutImpl); + } + return _quartEaseOut; + } + } + + private static PennerEquation _quartEaseOut; + + #endregion + + #region QuintEaseIn Static Property + + public static PennerEquation QuintEaseIn + { + get + { + if (_quintEaseIn == null) + { + _quintEaseIn = new PennerEquation(QuintEaseInImpl); + } + return _quintEaseIn; + } + } + + private static PennerEquation _quintEaseIn; + + #endregion + + #region QuintEaseInOut Static Property + + public static PennerEquation QuintEaseInOut + { + get + { + if (_quintEaseInOut == null) + { + _quintEaseInOut = new PennerEquation(QuintEaseInOutImpl); + } + return _quintEaseInOut; + } + } + + private static PennerEquation _quintEaseInOut; + + #endregion + + #region QuintEaseOut Static Property + + public static PennerEquation QuintEaseOut + { + get + { + if (_quintEaseOut == null) + { + _quintEaseOut = new PennerEquation(QuintEaseOutImpl); + } + return _quintEaseOut; + } + } + + private static PennerEquation _quintEaseOut; + + #endregion + + #region SineEaseIn Static Property + + public static PennerEquation SineEaseIn + { + get + { + if (_sineEaseIn == null) + { + _sineEaseIn = new PennerEquation(SineEaseInImpl); + } + return _sineEaseIn; + } + } + + private static PennerEquation _sineEaseIn; + + #endregion + + #region SineEaseInOut Static Property + + public static PennerEquation SineEaseInOut + { + get + { + if (_sineEaseInOut == null) + { + _sineEaseInOut = new PennerEquation(SineEaseInOutImpl); + } + return _sineEaseInOut; + } + } + + private static PennerEquation _sineEaseInOut; + + #endregion + + #region SineEaseOut Static Property + + public static PennerEquation SineEaseOut + { + get + { + if (_sineEaseOut == null) + { + _sineEaseOut = new PennerEquation(SineEaseOutImpl); + } + return _sineEaseOut; + } + } + + private static PennerEquation _sineEaseOut; + + #endregion + + #region Back Equations Methods + + private static double BackEaseOutImpl(double t, double b, double c, double d) + { + return c * ((t = t / d - 1) * t * ((1.70158 + 1) * t + 1.70158) + 1) + b; + } + + private static double BackEaseInImpl(double t, double b, double c, double d) + { + return c * (t /= d) * t * ((1.70158 + 1) * t - 1.70158) + b; + } + + private static double BackEaseInOutImpl(double t, double b, double c, double d) + { + double s = 1.70158; + if ((t /= d / 2) < 1) + return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b; + return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b; + } + + #endregion + + #region Bounce Equations Methods + + private static double BounceEaseOutImpl(double t, double b, double c, double d) + { + if ((t /= d) < (1 / 2.75)) + { + return c * (7.5625 * t * t) + b; + } + else if (t < (2 / 2.75)) + { + return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b; + } + else if (t < (2.5 / 2.75)) + { + return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b; + } + else + { + return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b; + } + } + + private static double BounceEaseInImpl(double t, double b, double c, double d) + { + return c - PennerEquations.BounceEaseOutImpl(d - t, 0, c, d) + b; + } + + private static double BounceEaseInOutImpl(double t, double b, double c, double d) + { + if (t < d / 2) + { + return PennerEquations.BounceEaseInImpl(t * 2, 0, c, d) * .5 + b; + } + else + { + return PennerEquations.BounceEaseOutImpl(t * 2 - d, 0, c, d) * .5 + c * .5 + b; + } + } + + #endregion + + #region Circular Equations Methods + + private static double CircEaseOutImpl(double t, double b, double c, double d) + { + return c * Math.Sqrt(1 - (t = t / d - 1) * t) + b; + } + + private static double CircEaseInImpl(double t, double b, double c, double d) + { + return -c * (Math.Sqrt(1 - (t /= d) * t) - 1) + b; + } + + private static double CircEaseInOutImpl(double t, double b, double c, double d) + { + if ((t /= d / 2) < 1) + return -c / 2 * (Math.Sqrt(1 - t * t) - 1) + b; + + return c / 2 * (Math.Sqrt(1 - (t -= 2) * t) + 1) + b; + } + + #endregion + + #region Cubic Equations Methods + + private static double CubicEaseOutImpl(double t, double b, double c, double d) + { + return c * ((t = t / d - 1) * t * t + 1) + b; + } + + private static double CubicEaseInImpl(double t, double b, double c, double d) + { + return c * (t /= d) * t * t + b; + } + + private static double CubicEaseInOutImpl(double t, double b, double c, double d) + { + if ((t /= d / 2) < 1) + return c / 2 * t * t * t + b; + + return c / 2 * ((t -= 2) * t * t + 2) + b; + } + + #endregion + + #region Elastic Equations Methods + + private static double ElasticEaseOutImpl(double t, double b, double c, double d) + { + if ((t /= d) == 1) + return b + c; + + double p = d * .3; + double s = p / 4; + + return (c * Math.Pow(2, -10 * t) * Math.Sin((t * d - s) * (2 * Math.PI) / p) + c + b); + } + + private static double ElasticEaseInImpl(double t, double b, double c, double d) + { + if ((t /= d) == 1) + return b + c; + + double p = d * .3; + double s = p / 4; + + return -(c * Math.Pow(2, 10 * (t -= 1)) * Math.Sin((t * d - s) * (2 * Math.PI) / p)) + b; + } + + private static double ElasticEaseInOutImpl(double t, double b, double c, double d) + { + if ((t /= d / 2) == 2) + return b + c; + + double p = d * (.3 * 1.5); + double s = p / 4; + + if (t < 1) + return -.5 * (c * Math.Pow(2, 10 * (t -= 1)) * Math.Sin((t * d - s) * (2 * Math.PI) / p)) + b; + return c * Math.Pow(2, -10 * (t -= 1)) * Math.Sin((t * d - s) * (2 * Math.PI) / p) * .5 + c + b; + } + + #endregion + + #region Expo Equations Methods + + private static double ExpoEaseOutImpl(double t, double b, double c, double d) + { + return (t == d) ? b + c : c * (-Math.Pow(2, -10 * t / d) + 1) + b; + } + + private static double ExpoEaseInImpl(double t, double b, double c, double d) + { + return (t == 0) ? b : c * Math.Pow(2, 10 * (t / d - 1)) + b; + } + + private static double ExpoEaseInOutImpl(double t, double b, double c, double d) + { + if (t == 0) + return b; + + if (t == d) + return b + c; + + if ((t /= d / 2) < 1) + return c / 2 * Math.Pow(2, 10 * (t - 1)) + b; + + return c / 2 * (-Math.Pow(2, -10 * --t) + 2) + b; + } + + #endregion + + #region Linear Equations Methods + + private static double LinearImpl(double t, double b, double c, double d) + { + return c * (t / d) + b; + } + + #endregion + + #region Quad Equations Methods + + private static double QuadEaseOutImpl(double t, double b, double c, double d) + { + return -c * (t /= d) * (t - 2) + b; + } + + private static double QuadEaseInImpl(double t, double b, double c, double d) + { + return c * (t /= d) * t + b; + } + + private static double QuadEaseInOutImpl(double t, double b, double c, double d) + { + if ((t /= d / 2) < 1) + return c / 2 * t * t + b; + + return -c / 2 * ((--t) * (t - 2) - 1) + b; + } + + #endregion + + #region Quartic Equations Methods + + private static double QuartEaseOutImpl(double t, double b, double c, double d) + { + return -c * ((t = t / d - 1) * t * t * t - 1) + b; + } + + private static double QuartEaseInImpl(double t, double b, double c, double d) + { + return c * (t /= d) * t * t * t + b; + } + + private static double QuartEaseInOutImpl(double t, double b, double c, double d) + { + if ((t /= d / 2) < 1) + return c / 2 * t * t * t * t + b; + + return -c / 2 * ((t -= 2) * t * t * t - 2) + b; + } + + #endregion + + #region Quintic Equations Methods + + private static double QuintEaseOutImpl(double t, double b, double c, double d) + { + return c * ((t = t / d - 1) * t * t * t * t + 1) + b; + } + + private static double QuintEaseInImpl(double t, double b, double c, double d) + { + return c * (t /= d) * t * t * t * t + b; + } + + private static double QuintEaseInOutImpl(double t, double b, double c, double d) + { + if ((t /= d / 2) < 1) + return c / 2 * t * t * t * t * t + b; + return c / 2 * ((t -= 2) * t * t * t * t + 2) + b; + } + + #endregion + + #region Sine Equations Methods + + private static double SineEaseOutImpl(double t, double b, double c, double d) + { + return c * Math.Sin(t / d * (Math.PI / 2)) + b; + } + + private static double SineEaseInImpl(double t, double b, double c, double d) + { + return -c * Math.Cos(t / d * (Math.PI / 2)) + c + b; + } + + private static double SineEaseInOutImpl(double t, double b, double c, double d) + { + if ((t /= d / 2) < 1) + return c / 2 * (Math.Sin(Math.PI * t / 2)) + b; + + return -c / 2 * (Math.Cos(Math.PI * --t / 2) - 2) + b; + } + + #endregion + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Media/WindowColors.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Media/WindowColors.cs new file mode 100644 index 00000000..aa9f6040 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Media/WindowColors.cs @@ -0,0 +1,126 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Media; + +namespace Xceed.Wpf.Toolkit.Core.Media +{ + /// + /// Contains system colors and configurations that can be used by the control themes. + /// + /// Mainly extracted from the registry because theses values are not exposed by the standard .NET API. + /// + public static class WindowColors + { + private static Color? _colorizationMode; + private static bool? _colorizationOpaqueBlend; + + /// + /// Relative to the \HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM\ColorizationColor Registry key. + /// + /// Gets the window chrome color. + /// + public static Color ColorizationColor + { + get + { + if (_colorizationMode.HasValue) + return _colorizationMode.Value; + + try + { + _colorizationMode = WindowColors.GetDWMColorValue("ColorizationColor"); + } + catch + { + // If for any reason (for example, a SecurityException for XBAP apps) + // we cannot read the value in the registry, fall back on some color. + _colorizationMode = Color.FromArgb(255, 175, 175, 175); + } + + return _colorizationMode.Value; + } + } + + /// + /// Relative to the \HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM\ColorizationOpaqueBlend Registry key: + /// + /// Gets whether transparency is disabled. + /// + /// Returns true if transparency is disabled; false otherwise. + /// + public static bool ColorizationOpaqueBlend + { + get + { + if (_colorizationOpaqueBlend.HasValue) + return _colorizationOpaqueBlend.Value; + + try + { + _colorizationOpaqueBlend = WindowColors.GetDWMBoolValue("ColorizationOpaqueBlend"); + } + catch + { + // If for any reason (for example, a SecurityException for XBAP apps) + // we cannot read the value in the registry, fall back on some color. + _colorizationOpaqueBlend = false; + } + + return _colorizationOpaqueBlend.Value; + } + } + + private static int GetDWMIntValue(string keyName) + { + // This value is not accessible throught the standard WPF API. + // We must dig into the registry to get the value. + var curUser = Microsoft.Win32.Registry.CurrentUser; + var subKey = curUser.CreateSubKey( + @"Software\Microsoft\Windows\DWM", + Microsoft.Win32.RegistryKeyPermissionCheck.ReadSubTree +#if VS2008 + ); +#else + , Microsoft.Win32.RegistryOptions.None); +#endif + return (int)subKey.GetValue(keyName); + } + + private static Color GetDWMColorValue(string keyName) + { + int value = WindowColors.GetDWMIntValue(keyName); + byte[] bytes = BitConverter.GetBytes(value); + return new Color() + { + B = bytes[0], + G = bytes[1], + R = bytes[2], + A = 255 + }; + } + + private static bool GetDWMBoolValue(string keyName) + { + int value = WindowColors.GetDWMIntValue(keyName); + return (value != 0); + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/PropertyChangedEventArgs.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/PropertyChangedEventArgs.cs new file mode 100644 index 00000000..a0f6676d --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/PropertyChangedEventArgs.cs @@ -0,0 +1,70 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Windows; + +namespace Xceed.Wpf.Toolkit.Core +{ + public class PropertyChangedEventArgs : RoutedEventArgs + { + #region Constructors + + public PropertyChangedEventArgs(RoutedEvent Event, T oldValue, T newValue) + : base() + { + _oldValue = oldValue; + _newValue = newValue; + this.RoutedEvent = Event; + } + + #endregion + + #region NewValue Property + + public T NewValue + { + get + { + return _newValue; + } + } + + private readonly T _newValue; + + #endregion + + #region OldValue Property + + public T OldValue + { + get + { + return _oldValue; + } + } + + private readonly T _oldValue; + + #endregion + + protected override void InvokeEventHandler(Delegate genericHandler, object genericTarget) + { + PropertyChangedEventHandler handler = (PropertyChangedEventHandler)genericHandler; + handler(genericTarget, this); + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/PropertyChangedEventHandler.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/PropertyChangedEventHandler.cs new file mode 100644 index 00000000..36a27568 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/PropertyChangedEventHandler.cs @@ -0,0 +1,20 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +namespace Xceed.Wpf.Toolkit.Core +{ + public delegate void PropertyChangedEventHandler(object sender, PropertyChangedEventArgs e); +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/QueryTextFromValueEventArgs.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/QueryTextFromValueEventArgs.cs new file mode 100644 index 00000000..b024515d --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/QueryTextFromValueEventArgs.cs @@ -0,0 +1,54 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Xceed.Wpf.Toolkit.Core +{ + public class QueryTextFromValueEventArgs : EventArgs + { + public QueryTextFromValueEventArgs(object value, string text) + { + m_value = value; + m_text = text; + } + + #region Value Property + + private object m_value; + + public object Value + { + get { return m_value; } + } + + #endregion Value Property + + #region Text Property + + private string m_text; + + public string Text + { + get { return m_text; } + set { m_text = value; } + } + + #endregion Text Property + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/QueryValueFromTextEventArgs.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/QueryValueFromTextEventArgs.cs new file mode 100644 index 00000000..359af71d --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/QueryValueFromTextEventArgs.cs @@ -0,0 +1,67 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Xceed.Wpf.Toolkit.Core +{ + public class QueryValueFromTextEventArgs : EventArgs + { + public QueryValueFromTextEventArgs(string text, object value) + { + m_text = text; + m_value = value; + } + + #region Text Property + + private string m_text; + + public string Text + { + get { return m_text; } + } + + #endregion Text Property + + #region Value Property + + private object m_value; + + public object Value + { + get { return m_value; } + set { m_value = value; } + } + + #endregion Value Property + + #region HasParsingError Property + + private bool m_hasParsingError; + + public bool HasParsingError + { + get { return m_hasParsingError; } + set { m_hasParsingError = value; } + } + + #endregion HasParsingError Property + + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/UIElementAdorner.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/UIElementAdorner.cs new file mode 100644 index 00000000..1543c54f --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/UIElementAdorner.cs @@ -0,0 +1,240 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System.Collections; +using System.Windows; +using System.Windows.Documents; +using System.Windows.Media; + +namespace Xceed.Wpf.Toolkit.Core +{ + /// + /// An adorner that can display one and only one UIElement. + /// That element can be a panel, which contains multiple other elements. + /// The element is added to the adorner's visual and logical trees, enabling it to + /// particpate in dependency property value inheritance, amongst other things. + /// + internal class UIElementAdorner : Adorner where TElement : UIElement + { + #region Fields + + TElement _child = null; + double _offsetLeft = 0; + double _offsetTop = 0; + + #endregion // Fields + + #region Constructor + + /// + /// Constructor. + /// + /// The element to which the adorner will be bound. + public UIElementAdorner(UIElement adornedElement) + : base(adornedElement) + { + } + + #endregion // Constructor + + #region Public Interface + + #region Child + + /// + /// Gets/sets the child element hosted in the adorner. + /// + public TElement Child + { + get + { + return _child; + } + set + { + if (value == _child) + return; + + if (_child != null) + { + base.RemoveLogicalChild(_child); + base.RemoveVisualChild(_child); + } + + _child = value; + + if (_child != null) + { + base.AddLogicalChild(_child); + base.AddVisualChild(_child); + } + } + } + + #endregion // Child + + #region GetDesiredTransform + + /// + /// Override. + /// + /// + /// + public override GeneralTransform GetDesiredTransform(GeneralTransform transform) + { + GeneralTransformGroup result = new GeneralTransformGroup(); + result.Children.Add(base.GetDesiredTransform(transform)); + result.Children.Add(new TranslateTransform(_offsetLeft, _offsetTop)); + return result; + } + + #endregion // GetDesiredTransform + + #region OffsetLeft + + /// + /// Gets/sets the horizontal offset of the adorner. + /// + public double OffsetLeft + { + get + { + return _offsetLeft; + } + set + { + _offsetLeft = value; + UpdateLocation(); + } + } + + #endregion // OffsetLeft + + #region SetOffsets + + /// + /// Updates the location of the adorner in one atomic operation. + /// + public void SetOffsets(double left, double top) + { + _offsetLeft = left; + _offsetTop = top; + this.UpdateLocation(); + } + + #endregion // SetOffsets + + #region OffsetTop + + /// + /// Gets/sets the vertical offset of the adorner. + /// + public double OffsetTop + { + get + { + return _offsetTop; + } + set + { + _offsetTop = value; + UpdateLocation(); + } + } + + #endregion // OffsetTop + + #endregion // Public Interface + + #region Protected Overrides + + /// + /// Override. + /// + /// + /// + protected override Size MeasureOverride(Size constraint) + { + if (_child == null) + return base.MeasureOverride(constraint); + + _child.Measure(constraint); + return _child.DesiredSize; + } + + /// + /// Override. + /// + /// + /// + protected override Size ArrangeOverride(Size finalSize) + { + if (_child == null) + return base.ArrangeOverride(finalSize); + + _child.Arrange(new Rect(finalSize)); + return finalSize; + } + + /// + /// Override. + /// + protected override IEnumerator LogicalChildren + { + get + { + ArrayList list = new ArrayList(); + if (_child != null) + list.Add(_child); + return list.GetEnumerator(); + } + } + + /// + /// Override. + /// + /// + /// + protected override Visual GetVisualChild(int index) + { + return _child; + } + + /// + /// Override. + /// + protected override int VisualChildrenCount + { + get + { + return _child == null ? 0 : 1; + } + } + + #endregion // Protected Overrides + + #region Private Helpers + + void UpdateLocation() + { + AdornerLayer adornerLayer = base.Parent as AdornerLayer; + if (adornerLayer != null) + adornerLayer.Update(base.AdornedElement); + } + + #endregion // Private Helpers + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/CalculatorUtilities.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/CalculatorUtilities.cs new file mode 100644 index 00000000..0ce79ec8 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/CalculatorUtilities.cs @@ -0,0 +1,285 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Globalization; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Media; + +namespace Xceed.Wpf.Toolkit.Core.Utilities +{ + static class CalculatorUtilities + { + public static Calculator.CalculatorButtonType GetCalculatorButtonTypeFromText(string text) + { + switch (text) + { + case "0": + return Calculator.CalculatorButtonType.Zero; + case "1": + return Calculator.CalculatorButtonType.One; + case "2": + return Calculator.CalculatorButtonType.Two; + case "3": + return Calculator.CalculatorButtonType.Three; + case "4": + return Calculator.CalculatorButtonType.Four; + case "5": + return Calculator.CalculatorButtonType.Five; + case "6": + return Calculator.CalculatorButtonType.Six; + case "7": + return Calculator.CalculatorButtonType.Seven; + case "8": + return Calculator.CalculatorButtonType.Eight; + case "9": + return Calculator.CalculatorButtonType.Nine; + case "+": + return Calculator.CalculatorButtonType.Add; + case "-": + return Calculator.CalculatorButtonType.Subtract; + case "*": + return Calculator.CalculatorButtonType.Multiply; + case "/": + return Calculator.CalculatorButtonType.Divide; + case "%": + return Calculator.CalculatorButtonType.Percent; + case "\b": + return Calculator.CalculatorButtonType.Back; + case "\r": + case "=": + return Calculator.CalculatorButtonType.Equal; + } + + //the check for the decimal is not in the switch statement. To help localize we check against the current culture's decimal seperator + if (text == CultureInfo.CurrentCulture.NumberFormat.CurrencyDecimalSeparator) + return Calculator.CalculatorButtonType.Decimal; + + //check for the escape key + if (text == ((char)27).ToString()) + return Calculator.CalculatorButtonType.Clear; + + return Calculator.CalculatorButtonType.None; + } + + public static Button FindButtonByCalculatorButtonType(DependencyObject parent, Calculator.CalculatorButtonType type) + { + if (parent == null) + return null; + + for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++) + { + var child = VisualTreeHelper.GetChild(parent, i); + if (child == null) + continue; + + object buttonType = child.GetValue(Button.CommandParameterProperty); + + if (buttonType != null && (Calculator.CalculatorButtonType)buttonType == type) + { + return child as Button; + } + else + { + var result = FindButtonByCalculatorButtonType(child, type); + + if (result != null) + return result; + } + } + return null; + } + + public static string GetCalculatorButtonContent(Calculator.CalculatorButtonType type) + { + string content = string.Empty; + switch (type) + { + case Calculator.CalculatorButtonType.Add: + content = "+"; + break; + case Calculator.CalculatorButtonType.Back: + content = "Back"; + break; + case Calculator.CalculatorButtonType.Cancel: + content = "CE"; + break; + case Calculator.CalculatorButtonType.Clear: + content = "C"; + break; + case Calculator.CalculatorButtonType.Decimal: + content = CultureInfo.CurrentCulture.NumberFormat.CurrencyDecimalSeparator; + break; + case Calculator.CalculatorButtonType.Divide: + content = "/"; + break; + case Calculator.CalculatorButtonType.Eight: + content = "8"; + break; + case Calculator.CalculatorButtonType.Equal: + content = "="; + break; + case Calculator.CalculatorButtonType.Five: + content = "5"; + break; + case Calculator.CalculatorButtonType.Four: + content = "4"; + break; + case Calculator.CalculatorButtonType.Fraction: + content = "1/x"; + break; + case Calculator.CalculatorButtonType.MAdd: + content = "M+"; + break; + case Calculator.CalculatorButtonType.MC: + content = "MC"; + break; + case Calculator.CalculatorButtonType.MR: + content = "MR"; + break; + case Calculator.CalculatorButtonType.MS: + content = "MS"; + break; + case Calculator.CalculatorButtonType.MSub: + content = "M-"; + break; + case Calculator.CalculatorButtonType.Multiply: + content = "*"; + break; + case Calculator.CalculatorButtonType.Nine: + content = "9"; + break; + case Calculator.CalculatorButtonType.None: + break; + case Calculator.CalculatorButtonType.One: + content = "1"; + break; + case Calculator.CalculatorButtonType.Percent: + content = "%"; + break; + case Calculator.CalculatorButtonType.Seven: + content = "7"; + break; + case Calculator.CalculatorButtonType.Negate: + content = "+/-"; + break; + case Calculator.CalculatorButtonType.Six: + content = "6"; + break; + case Calculator.CalculatorButtonType.Sqrt: + content = "Sqrt"; + break; + case Calculator.CalculatorButtonType.Subtract: + content = "-"; + break; + case Calculator.CalculatorButtonType.Three: + content = "3"; + break; + case Calculator.CalculatorButtonType.Two: + content = "2"; + break; + case Calculator.CalculatorButtonType.Zero: + content = "0"; + break; + } + return content; + } + + public static bool IsDigit(Calculator.CalculatorButtonType buttonType) + { + switch (buttonType) + { + case Calculator.CalculatorButtonType.Zero: + case Calculator.CalculatorButtonType.One: + case Calculator.CalculatorButtonType.Two: + case Calculator.CalculatorButtonType.Three: + case Calculator.CalculatorButtonType.Four: + case Calculator.CalculatorButtonType.Five: + case Calculator.CalculatorButtonType.Six: + case Calculator.CalculatorButtonType.Seven: + case Calculator.CalculatorButtonType.Eight: + case Calculator.CalculatorButtonType.Nine: + case Calculator.CalculatorButtonType.Decimal: + return true; + default: + return false; + } + } + + public static bool IsMemory(Calculator.CalculatorButtonType buttonType) + { + switch (buttonType) + { + case Calculator.CalculatorButtonType.MAdd: + case Calculator.CalculatorButtonType.MC: + case Calculator.CalculatorButtonType.MR: + case Calculator.CalculatorButtonType.MS: + case Calculator.CalculatorButtonType.MSub: + return true; + default: + return false; + } + } + + public static decimal ParseDecimal(string text) + { + decimal result; + var success = Decimal.TryParse(text, NumberStyles.Any, CultureInfo.CurrentCulture, out result); + return success ? result : decimal.Zero; + } + + public static decimal Add(decimal firstNumber, decimal secondNumber) + { + return firstNumber + secondNumber; + } + + public static decimal Subtract(decimal firstNumber, decimal secondNumber) + { + return firstNumber - secondNumber; + } + + public static decimal Multiply(decimal firstNumber, decimal secondNumber) + { + return firstNumber * secondNumber; + } + + public static decimal Divide(decimal firstNumber, decimal secondNumber) + { + return firstNumber / secondNumber; + } + + public static decimal Percent(decimal firstNumber, decimal secondNumber) + { + return firstNumber * secondNumber / 100M; + } + + public static decimal SquareRoot(decimal operand) + { + return Convert.ToDecimal(Math.Sqrt(Convert.ToDouble(operand))); + } + + public static decimal Fraction(decimal operand) + { + return 1 / operand; + } + + public static decimal Negate(decimal operand) + { + return operand * -1M; + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/ChangeTypeHelper.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/ChangeTypeHelper.cs new file mode 100644 index 00000000..a1716842 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/ChangeTypeHelper.cs @@ -0,0 +1,54 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; + +namespace Xceed.Wpf.Toolkit.Core.Utilities +{ + internal static class ChangeTypeHelper + { + internal static object ChangeType(object value, Type conversionType, IFormatProvider provider) + { + if (conversionType == null) + { + throw new ArgumentNullException("conversionType"); + } + if (conversionType == typeof(Guid)) + { + return new Guid(value.ToString()); + } + else if (conversionType == typeof(Guid?)) + { + if (value == null) + return null; + return new Guid(value.ToString()); + } + else if (conversionType.IsGenericType && conversionType.GetGenericTypeDefinition().Equals(typeof(Nullable<>))) + { + if (value == null) + return null; + NullableConverter nullableConverter = new NullableConverter(conversionType); + conversionType = nullableConverter.UnderlyingType; + } + + return System.Convert.ChangeType(value, conversionType, provider); + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/ColorUtilities.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/ColorUtilities.cs new file mode 100644 index 00000000..9c04c51e --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/ColorUtilities.cs @@ -0,0 +1,206 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Windows.Media; +using Xceed.Wpf.Toolkit.Primitives; + +namespace Xceed.Wpf.Toolkit.Core.Utilities +{ + static class ColorUtilities + { + public static readonly Dictionary KnownColors = GetKnownColors(); + + public static string GetColorName(this Color color) + { + string colorName = KnownColors.Where(kvp => kvp.Value.Equals(color)).Select(kvp => kvp.Key).FirstOrDefault(); + + if (String.IsNullOrEmpty(colorName)) + colorName = color.ToString(); + + return colorName; + } + + public static string FormatColorString(string stringToFormat, bool isUsingAlphaChannel) + { + if (!isUsingAlphaChannel && (stringToFormat.Length == 9)) + return stringToFormat.Remove(1, 2); + return stringToFormat; + } + + private static Dictionary GetKnownColors() + { + var colorProperties = typeof(Colors).GetProperties(BindingFlags.Static | BindingFlags.Public); + return colorProperties.ToDictionary(p => p.Name, p => (Color)p.GetValue(null, null)); + } + + /// + /// Converts an RGB color to an HSV color. + /// + /// + /// + /// + /// + public static HsvColor ConvertRgbToHsv(int r, int g, int b) + { + double delta, min; + double h = 0, s, v; + + min = Math.Min(Math.Min(r, g), b); + v = Math.Max(Math.Max(r, g), b); + delta = v - min; + + if (v == 0.0) + { + s = 0; + } + else + s = delta / v; + + if (s == 0) + h = 0.0; + + else + { + if (r == v) + h = (g - b) / delta; + else if (g == v) + h = 2 + (b - r) / delta; + else if (b == v) + h = 4 + (r - g) / delta; + + h *= 60; + if (h < 0.0) + h = h + 360; + + } + + return new HsvColor + { + H = h, + S = s, + V = v / 255 + }; + } + + /// + /// Converts an HSV color to an RGB color. + /// + /// + /// + /// + /// + public static Color ConvertHsvToRgb(double h, double s, double v) + { + double r = 0, g = 0, b = 0; + + if (s == 0) + { + r = v; + g = v; + b = v; + } + else + { + int i; + double f, p, q, t; + + if (h == 360) + h = 0; + else + h = h / 60; + + i = (int)Math.Truncate(h); + f = h - i; + + p = v * (1.0 - s); + q = v * (1.0 - (s * f)); + t = v * (1.0 - (s * (1.0 - f))); + + switch (i) + { + case 0: + { + r = v; + g = t; + b = p; + break; + } + case 1: + { + r = q; + g = v; + b = p; + break; + } + case 2: + { + r = p; + g = v; + b = t; + break; + } + case 3: + { + r = p; + g = q; + b = v; + break; + } + case 4: + { + r = t; + g = p; + b = v; + break; + } + default: + { + r = v; + g = p; + b = q; + break; + } + } + + } + + return Color.FromArgb(255, (byte)(Math.Round(r * 255)), (byte)(Math.Round(g * 255)), (byte)(Math.Round(b * 255))); + } + + /// + /// Generates a list of colors with hues ranging from 0 360 and a saturation and value of 1. + /// + /// + public static List GenerateHsvSpectrum() + { + var colorsList = new List(); + int hStep = 60; + + for (int h = 0; h < 360; h += hStep) + { + colorsList.Add(ColorUtilities.ConvertHsvToRgb(h, 1, 1)); + } + + colorsList.Add(ColorUtilities.ConvertHsvToRgb(0, 1, 1)); + + return colorsList; + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/ContextMenuUtilities.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/ContextMenuUtilities.cs new file mode 100644 index 00000000..003eecb1 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/ContextMenuUtilities.cs @@ -0,0 +1,75 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System.Windows; +using System.Windows.Media; +using Xceed.Wpf.Toolkit.PropertyGrid; + +namespace Xceed.Wpf.Toolkit.Core.Utilities +{ + public class ContextMenuUtilities + { + public static readonly DependencyProperty OpenOnMouseLeftButtonClickProperty = DependencyProperty.RegisterAttached("OpenOnMouseLeftButtonClick", typeof(bool), typeof(ContextMenuUtilities), new FrameworkPropertyMetadata(false, OpenOnMouseLeftButtonClickChanged)); + public static void SetOpenOnMouseLeftButtonClick(FrameworkElement element, bool value) + { + element.SetValue(OpenOnMouseLeftButtonClickProperty, value); + } + public static bool GetOpenOnMouseLeftButtonClick(FrameworkElement element) + { + return (bool)element.GetValue(OpenOnMouseLeftButtonClickProperty); + } + + public static void OpenOnMouseLeftButtonClickChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) + { + var control = sender as FrameworkElement; + if (control != null) + { + if ((bool)e.NewValue) + { + control.PreviewMouseLeftButtonDown += ContextMenuUtilities.Control_PreviewMouseLeftButtonDown; + } + else + { + control.PreviewMouseLeftButtonDown -= ContextMenuUtilities.Control_PreviewMouseLeftButtonDown; + } + } + } + + private static void Control_PreviewMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e) + { + var control = sender as FrameworkElement; + if ((control != null) && (control.ContextMenu != null)) + { + // Get PropertyItemBase parent + var parent = VisualTreeHelper.GetParent(control); + while (parent != null) + { + var propertyItemBase = parent as PropertyItemBase; + if (propertyItemBase != null) + { + // Set the ContextMenu.DataContext to the PropertyItem associated to the clicked image. + control.ContextMenu.DataContext = propertyItemBase; + break; + } + parent = VisualTreeHelper.GetParent(parent); + } + + control.ContextMenu.PlacementTarget = control; + control.ContextMenu.IsOpen = true; + } + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/DateTimeUtilities.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/DateTimeUtilities.cs new file mode 100644 index 00000000..2eb9adb8 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/DateTimeUtilities.cs @@ -0,0 +1,44 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Xceed.Wpf.Toolkit.Core.Utilities +{ + internal static class DateTimeUtilities + { + public static DateTime GetContextNow(DateTimeKind kind) + { + if (kind == DateTimeKind.Unspecified) + return DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Unspecified); + + return (kind == DateTimeKind.Utc) + ? DateTime.UtcNow + : DateTime.Now; + } + + public static bool IsSameDate(DateTime? date1, DateTime? date2) + { + if (date1 == null || date2 == null) + return false; + + return (date1.Value.Date == date2.Value.Date); + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/DoubleHelper.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/DoubleHelper.cs new file mode 100644 index 00000000..f037f38b --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/DoubleHelper.cs @@ -0,0 +1,97 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Runtime.InteropServices; +using System.Windows; + +namespace Xceed.Wpf.Toolkit.Core.Utilities +{ + internal static class DoubleHelper + { + public static bool AreVirtuallyEqual(double d1, double d2) + { + if (double.IsPositiveInfinity(d1)) + return double.IsPositiveInfinity(d2); + + if (double.IsNegativeInfinity(d1)) + return double.IsNegativeInfinity(d2); + + if (IsNaN(d1)) + return IsNaN(d2); + + double n = d1 - d2; + double d = (Math.Abs(d1) + Math.Abs(d2) + 10) * 1.0e-15; + return (-d < n) && (d > n); + } + + public static bool AreVirtuallyEqual(Size s1, Size s2) + { + return (AreVirtuallyEqual(s1.Width, s2.Width) + && AreVirtuallyEqual(s1.Height, s2.Height)); + } + + public static bool AreVirtuallyEqual(Point p1, Point p2) + { + return (AreVirtuallyEqual(p1.X, p2.X) + && AreVirtuallyEqual(p1.Y, p2.Y)); + } + + public static bool AreVirtuallyEqual(Rect r1, Rect r2) + { + return (AreVirtuallyEqual(r1.TopLeft, r2.TopLeft) + && AreVirtuallyEqual(r1.BottomRight, r2.BottomRight)); + } + + public static bool AreVirtuallyEqual(Vector v1, Vector v2) + { + return (AreVirtuallyEqual(v1.X, v2.X) + && AreVirtuallyEqual(v1.Y, v2.Y)); + } + + public static bool AreVirtuallyEqual(Segment s1, Segment s2) + { + // note: Segment struct already uses "virtually equal" approach + return (s1 == s2); + } + + public static bool IsNaN(double value) + { + // used reflector to borrow the high performance IsNan function + // from the WPF MS.Internal namespace + NanUnion t = new NanUnion(); + t.DoubleValue = value; + + UInt64 exp = t.UintValue & 0xfff0000000000000; + UInt64 man = t.UintValue & 0x000fffffffffffff; + + return (exp == 0x7ff0000000000000 || exp == 0xfff0000000000000) && (man != 0); + } + + #region NanUnion Nested Types + + [StructLayout(LayoutKind.Explicit)] + private struct NanUnion + { + [FieldOffset(0)] + internal double DoubleValue; + [FieldOffset(0)] + internal UInt64 UintValue; + } + + #endregion + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/EllipseHelper.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/EllipseHelper.cs new file mode 100644 index 00000000..600b7690 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/EllipseHelper.cs @@ -0,0 +1,69 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Windows; + +namespace Xceed.Wpf.Toolkit.Core.Utilities +{ + internal static class EllipseHelper + { + public static Point PointOfRadialIntersection(Rect ellipseRect, double angle) + { + // given by the formula: + // + // x = a cos q, + // y = b sin q, + // + // where a is the elliptical radius along the major axis + // b is the elliptical radius along the minor axis + // q is the central angle from the major axis + + double a = ellipseRect.Width / 2; + double b = ellipseRect.Height / 2; + + // since this is WPF, we can assume angle is currently specified in degrees, so convert to radians + double q = angle * Math.PI / 180; + + return RectHelper.Center(ellipseRect) + new Vector(a * Math.Cos(q), b * Math.Sin(q)); + } + + public static double RadialDistanceFromCenter(Rect ellipseRect, double angle) + { + // given by the formula: + // + // 2 2 + // 2 a b + // r = ----------------- + // 2 2 2 2 + // a sin q + b cos q + // + // where a is the elliptical radius along the major axis + // b is the elliptical radius along the minor axis + // q is the central angle from the major axis + + double a = ellipseRect.Width / 2; + double b = ellipseRect.Height / 2; + + // since this is WPF, we can assume angle is currently specified in degrees, so convert to radians + double q = angle * Math.PI / 180; + + double sinq = Math.Sin(q); + double cosq = Math.Cos(q); + return Math.Sqrt((a * a * b * b) / ((a * a * sinq * sinq) + (b * b * cosq * cosq))); + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/FontUtilities.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/FontUtilities.cs new file mode 100644 index 00000000..5f68a584 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/FontUtilities.cs @@ -0,0 +1,98 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Media; +using System.Windows; + +namespace Xceed.Wpf.Toolkit.Core.Utilities +{ + internal class FontUtilities + { + internal static IEnumerable Families + { + get + { +#if !VS2008 + // Workaround for a WPF 4 bug. + foreach (FontFamily font in Fonts.SystemFontFamilies) + { + try + { + // In WPF 4, this will throw an exception. + var throwAcess = font.FamilyNames; + } + catch + { + // It throws. Go to the next font family. + continue; + } + + // If it does not throw, return the font. + yield return font; + } +#else + return Fonts.SystemFontFamilies; +#endif + } + } + + internal static IEnumerable Weights + { + get + { + yield return FontWeights.Black; + yield return FontWeights.Bold; + yield return FontWeights.ExtraBlack; + yield return FontWeights.ExtraBold; + yield return FontWeights.ExtraLight; + yield return FontWeights.Light; + yield return FontWeights.Medium; + yield return FontWeights.Normal; + yield return FontWeights.SemiBold; + yield return FontWeights.Thin; + } + } + + internal static IEnumerable Styles + { + get + { + yield return FontStyles.Italic; + yield return FontStyles.Normal; + } + } + + internal static IEnumerable Stretches + { + get + { + yield return FontStretches.Condensed; + yield return FontStretches.Expanded; + yield return FontStretches.ExtraCondensed; + yield return FontStretches.ExtraExpanded; + yield return FontStretches.Normal; + yield return FontStretches.SemiCondensed; + yield return FontStretches.SemiExpanded; + yield return FontStretches.UltraCondensed; + yield return FontStretches.UltraExpanded; + } + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/GeneralUtilities.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/GeneralUtilities.cs new file mode 100644 index 00000000..851bd36a --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/GeneralUtilities.cs @@ -0,0 +1,93 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Media; + +namespace Xceed.Wpf.Toolkit.Core.Utilities +{ + internal sealed class GeneralUtilities : DependencyObject + { + private GeneralUtilities() { } + + #region StubValue attached property + + internal static readonly DependencyProperty StubValueProperty = DependencyProperty.RegisterAttached( + "StubValue", + typeof(object), + typeof(GeneralUtilities), + new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); + + internal static object GetStubValue(DependencyObject obj) + { + return (object)obj.GetValue(GeneralUtilities.StubValueProperty); + } + + internal static void SetStubValue(DependencyObject obj, object value) + { + obj.SetValue(GeneralUtilities.StubValueProperty, value); + } + + #endregion StubValue attached property + + public static object GetPathValue(object sourceObject, string path) + { + var targetObj = new GeneralUtilities(); + BindingOperations.SetBinding(targetObj, GeneralUtilities.StubValueProperty, new Binding(path) { Source = sourceObject }); + object value = GeneralUtilities.GetStubValue(targetObj); + BindingOperations.ClearBinding(targetObj, GeneralUtilities.StubValueProperty); + return value; + } + + public static object GetBindingValue(object sourceObject, Binding binding) + { + Binding bindingClone = new Binding() + { + BindsDirectlyToSource = binding.BindsDirectlyToSource, + Converter = binding.Converter, + ConverterCulture = binding.ConverterCulture, + ConverterParameter = binding.ConverterParameter, + FallbackValue = binding.FallbackValue, + Mode = BindingMode.OneTime, + Path = binding.Path, + StringFormat = binding.StringFormat, + TargetNullValue = binding.TargetNullValue, + XPath = binding.XPath + }; + + bindingClone.Source = sourceObject; + + var targetObj = new GeneralUtilities(); + BindingOperations.SetBinding(targetObj, GeneralUtilities.StubValueProperty, bindingClone); + object value = GeneralUtilities.GetStubValue(targetObj); + BindingOperations.ClearBinding(targetObj, GeneralUtilities.StubValueProperty); + return value; + } + + internal static bool CanConvertValue(object value, object targetType) + { + return ((value != null) + && (!object.Equals(value.GetType(), targetType)) + && (!object.Equals(targetType, typeof(object)))); + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/KeyboardUtilities.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/KeyboardUtilities.cs new file mode 100644 index 00000000..bd6bab5f --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/KeyboardUtilities.cs @@ -0,0 +1,33 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Input; + +namespace Xceed.Wpf.Toolkit.Core.Utilities +{ + internal class KeyboardUtilities + { + internal static bool IsKeyModifyingPopupState(KeyEventArgs e) + { + return ((((Keyboard.Modifiers & ModifierKeys.Alt) == ModifierKeys.Alt) && ((e.SystemKey == Key.Down) || (e.SystemKey == Key.Up))) + || (e.Key == Key.F4)); + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/ListUtilities.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/ListUtilities.cs new file mode 100644 index 00000000..8a14dd0e --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/ListUtilities.cs @@ -0,0 +1,80 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Xceed.Wpf.Toolkit.PropertyGrid.Editors; + +namespace Xceed.Wpf.Toolkit.Core.Utilities +{ + internal class ListUtilities + { + internal static Type GetListItemType(Type listType) + { + Type iListOfT = listType.GetInterfaces().FirstOrDefault( + (i) => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IList<>)); + + return (iListOfT != null) + ? iListOfT.GetGenericArguments()[0] + : null; + } + + internal static Type GetCollectionItemType(Type colType) + { + Type iCollectionOfT = null; + var isCollectionOfT = colType.IsGenericType && (colType.GetGenericTypeDefinition() == typeof(ICollection<>)); + if (isCollectionOfT) + { + iCollectionOfT = colType; + } + else + { + iCollectionOfT = colType.GetInterfaces().FirstOrDefault((i) => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(ICollection<>)); + } + + return (iCollectionOfT != null) + ? iCollectionOfT.GetGenericArguments()[0] + : null; + } + + internal static Type[] GetDictionaryItemsType(Type dictType) + { + var isDict = dictType.IsGenericType + && ((dictType.GetGenericTypeDefinition() == typeof(Dictionary<,>)) || (dictType.GetGenericTypeDefinition() == typeof(IDictionary<,>))); + + return isDict + ? new Type[] { dictType.GetGenericArguments()[0], dictType.GetGenericArguments()[1] } + : null; + } + + internal static object CreateEditableKeyValuePair(object key, Type keyType, object value, Type valueType) + { + var itemType = ListUtilities.CreateEditableKeyValuePairType(keyType, valueType); + return Activator.CreateInstance(itemType, key, value); + } + + internal static Type CreateEditableKeyValuePairType(Type keyType, Type valueType) + { + //return an EditableKeyValuePair< TKey, TValue> Type from keyType and valueType + var itemGenType = typeof(EditableKeyValuePair<,>); + Type[] itemGenTypeArgs = { keyType, valueType }; + return itemGenType.MakeGenericType(itemGenTypeArgs); + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/PointHelper.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/PointHelper.cs new file mode 100644 index 00000000..dd7b7028 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/PointHelper.cs @@ -0,0 +1,42 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Windows; + +namespace Xceed.Wpf.Toolkit.Core.Utilities +{ + internal static class PointHelper + { + public static double DistanceBetween(Point p1, Point p2) + { + return Math.Sqrt(Math.Pow(p1.X - p2.X, 2) + Math.Pow(p1.Y - p2.Y, 2)); + } + + public static Point Empty + { + get + { + return new Point(double.NaN, double.NaN); + } + } + + public static bool IsEmpty(Point point) + { + return DoubleHelper.IsNaN(point.X) && DoubleHelper.IsNaN(point.Y); + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/PropertyChangedExt.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/PropertyChangedExt.cs new file mode 100644 index 00000000..24dad14e --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/PropertyChangedExt.cs @@ -0,0 +1,127 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.ComponentModel; +using System.Linq.Expressions; + +namespace Xceed.Wpf.Toolkit.Core.Utilities +{ + internal static class PropertyChangedExt + { + #region Notify Methods + + public static void Notify( + this INotifyPropertyChanged sender, + PropertyChangedEventHandler handler, + Expression> expression) + { + if (sender == null) + throw new ArgumentNullException("sender"); + + if (expression == null) + throw new ArgumentNullException("expression"); + + var body = expression.Body as MemberExpression; + if (body == null) + throw new ArgumentException("The expression must target a property or field.", "expression"); + + string propertyName = PropertyChangedExt.GetPropertyName(body, sender.GetType()); + + PropertyChangedExt.NotifyCore(sender, handler, propertyName); + } + + public static void Notify(this INotifyPropertyChanged sender, PropertyChangedEventHandler handler, string propertyName) + { + if (sender == null) + throw new ArgumentNullException("sender"); + + if (propertyName == null) + throw new ArgumentNullException("propertyName"); + + ReflectionHelper.ValidatePropertyName(sender, propertyName); + + PropertyChangedExt.NotifyCore(sender, handler, propertyName); + } + + private static void NotifyCore(INotifyPropertyChanged sender, PropertyChangedEventHandler handler, string propertyName) + { + if (handler != null) + { + handler(sender, new PropertyChangedEventArgs(propertyName)); + } + } + + #endregion + + #region PropertyChanged Verification Methods + + internal static bool PropertyChanged(string propertyName, PropertyChangedEventArgs e, bool targetPropertyOnly) + { + string target = e.PropertyName; + if (target == propertyName) + return true; + + return (!targetPropertyOnly) + && (string.IsNullOrEmpty(target)); + } + + internal static bool PropertyChanged( + Expression> expression, + PropertyChangedEventArgs e, + bool targetPropertyOnly) + { + var body = expression.Body as MemberExpression; + if (body == null) + throw new ArgumentException("The expression must target a property or field.", "expression"); + + return PropertyChangedExt.PropertyChanged(body, typeof(TOwner), e, targetPropertyOnly); + } + + internal static bool PropertyChanged( + Expression> expression, + PropertyChangedEventArgs e, + bool targetPropertyOnly) + { + var body = expression.Body as MemberExpression; + if (body == null) + throw new ArgumentException("The expression must target a property or field.", "expression"); + + return PropertyChangedExt.PropertyChanged(body, typeof(TOwner), e, targetPropertyOnly); + } + + private static bool PropertyChanged(MemberExpression expression, Type ownerType, PropertyChangedEventArgs e, bool targetPropertyOnly) + { + var propertyName = PropertyChangedExt.GetPropertyName(expression, ownerType); + + return PropertyChangedExt.PropertyChanged(propertyName, e, targetPropertyOnly); + } + + #endregion + + private static string GetPropertyName(MemberExpression expression, Type ownerType) + { + var targetType = expression.Expression.Type; + if (!targetType.IsAssignableFrom(ownerType)) + throw new ArgumentException("The expression must target a property or field on the appropriate owner.", "expression"); + + return ReflectionHelper.GetPropertyOrFieldName(expression); + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/RectHelper.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/RectHelper.cs new file mode 100644 index 00000000..eaea758e --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/RectHelper.cs @@ -0,0 +1,86 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Windows; + +namespace Xceed.Wpf.Toolkit.Core.Utilities +{ + internal static class RectHelper + { + public static Point Center(Rect rect) + { + return new Point(rect.Left + rect.Width / 2, rect.Top + rect.Height / 2); + } + + public static Nullable GetNearestPointOfIntersectionBetweenRectAndSegment(Rect rect, Segment segment, Point point) + { + Nullable result = null; + double distance = double.PositiveInfinity; + + Segment leftIntersection = segment.Intersection(new Segment(rect.BottomLeft, rect.TopLeft)); + Segment topIntersection = segment.Intersection(new Segment(rect.TopLeft, rect.TopRight)); + Segment rightIntersection = segment.Intersection(new Segment(rect.TopRight, rect.BottomRight)); + Segment bottomIntersection = segment.Intersection(new Segment(rect.BottomRight, rect.BottomLeft)); + + RectHelper.AdjustResultForIntersectionWithSide(ref result, ref distance, leftIntersection, point); + RectHelper.AdjustResultForIntersectionWithSide(ref result, ref distance, topIntersection, point); + RectHelper.AdjustResultForIntersectionWithSide(ref result, ref distance, rightIntersection, point); + RectHelper.AdjustResultForIntersectionWithSide(ref result, ref distance, bottomIntersection, point); + + return result; + } + + public static Rect GetRectCenteredOnPoint(Point center, Size size) + { + return new Rect(new Point(center.X - size.Width / 2, center.Y - size.Height / 2), size); + } + + private static void AdjustResultForIntersectionWithSide(ref Nullable result, ref double distance, Segment intersection, Point point) + { + if (!intersection.IsEmpty) + { + if (intersection.Contains(point)) + { + distance = 0; + result = point; + return; + } + + double p1Distance = PointHelper.DistanceBetween(point, intersection.P1); + double p2Distance = double.PositiveInfinity; + if (!intersection.IsPoint) + { + p2Distance = PointHelper.DistanceBetween(point, intersection.P2); + } + + if (Math.Min(p1Distance, p2Distance) < distance) + { + if (p1Distance < p2Distance) + { + distance = p1Distance; + result = intersection.P1; + } + else + { + distance = p2Distance; + result = intersection.P2; + } + } + } + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/ReflectionHelper.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/ReflectionHelper.cs new file mode 100644 index 00000000..e6ea6c1b --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/ReflectionHelper.cs @@ -0,0 +1,139 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.ComponentModel; +using System.Diagnostics; +using System.Linq.Expressions; +using System.Reflection; + +namespace Xceed.Wpf.Toolkit.Core.Utilities +{ + internal static class ReflectionHelper + { + /// + /// Check the existence of the specified public instance (i.e. non static) property against + /// the type of the specified source object. If the property is not defined by the type, + /// a debug assertion will fail. Typically used to validate the parameter of a + /// RaisePropertyChanged method. + /// + /// The object for which the type will be checked. + /// The name of the property. + [System.Diagnostics.Conditional("DEBUG")] + internal static void ValidatePublicPropertyName(object sourceObject, string propertyName) + { + if (sourceObject == null) + throw new ArgumentNullException("sourceObject"); + + if (propertyName == null) + throw new ArgumentNullException("propertyName"); + + System.Diagnostics.Debug.Assert(sourceObject.GetType().GetProperty(propertyName, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.FlattenHierarchy | System.Reflection.BindingFlags.Public) != null, + string.Format("Public property {0} not found on object of type {1}.", propertyName, sourceObject.GetType().FullName)); + } + + /// + /// Check the existence of the specified instance (i.e. non static) property against + /// the type of the specified source object. If the property is not defined by the type, + /// a debug assertion will fail. Typically used to validate the parameter of a + /// RaisePropertyChanged method. + /// + /// The object for which the type will be checked. + /// The name of the property. + [System.Diagnostics.Conditional("DEBUG")] + internal static void ValidatePropertyName(object sourceObject, string propertyName) + { + if (sourceObject == null) + throw new ArgumentNullException("sourceObject"); + + if (propertyName == null) + throw new ArgumentNullException("propertyName"); + + System.Diagnostics.Debug.Assert(sourceObject.GetType().GetProperty(propertyName, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.FlattenHierarchy | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic) != null, + string.Format("Public property {0} not found on object of type {1}.", propertyName, sourceObject.GetType().FullName)); + } + + internal static bool TryGetEnumDescriptionAttributeValue(Enum enumeration, out string description) + { + try + { + FieldInfo fieldInfo = enumeration.GetType().GetField(enumeration.ToString()); + DescriptionAttribute[] attributes = fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), true) as DescriptionAttribute[]; + if ((attributes != null) && (attributes.Length > 0)) + { + description = attributes[0].Description; + return true; + } + } + catch + { + } + + description = String.Empty; + return false; + } + + [DebuggerStepThrough] + internal static string GetPropertyOrFieldName(MemberExpression expression) + { + string propertyOrFieldName; + if (!ReflectionHelper.TryGetPropertyOrFieldName(expression, out propertyOrFieldName)) + throw new InvalidOperationException("Unable to retrieve the property or field name."); + + return propertyOrFieldName; + } + + [DebuggerStepThrough] + internal static string GetPropertyOrFieldName(Expression> expression) + { + string propertyOrFieldName; + if (!ReflectionHelper.TryGetPropertyOrFieldName(expression, out propertyOrFieldName)) + throw new InvalidOperationException("Unable to retrieve the property or field name."); + + return propertyOrFieldName; + } + + [DebuggerStepThrough] + internal static bool TryGetPropertyOrFieldName(MemberExpression expression, out string propertyOrFieldName) + { + propertyOrFieldName = null; + + if (expression == null) + return false; + + propertyOrFieldName = expression.Member.Name; + + return true; + } + + [DebuggerStepThrough] + internal static bool TryGetPropertyOrFieldName(Expression> expression, out string propertyOrFieldName) + { + propertyOrFieldName = null; + + if (expression == null) + return false; + + return ReflectionHelper.TryGetPropertyOrFieldName(expression.Body as MemberExpression, out propertyOrFieldName); + } + + public static bool IsPublicInstanceProperty(Type type, string propertyName) + { + BindingFlags flags = (System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.FlattenHierarchy | System.Reflection.BindingFlags.Public); + return type.GetProperty(propertyName, flags) != null; + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/ResourceHelper.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/ResourceHelper.cs new file mode 100644 index 00000000..a03b7d00 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/ResourceHelper.cs @@ -0,0 +1,36 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System.IO; +using System.Reflection; +using System.Resources; + +namespace Xceed.Wpf.Toolkit.Core.Utilities +{ + internal class ResourceHelper + { + internal static Stream LoadResourceStream(Assembly assembly, string resId) + { + string basename = System.IO.Path.GetFileNameWithoutExtension(assembly.ManifestModule.Name) + ".g"; + ResourceManager resourceManager = new ResourceManager(basename, assembly); + + // resource names are lower case and contain only forward slashes + resId = resId.ToLower(); + resId = resId.Replace('\\', '/'); + return (resourceManager.GetObject(resId) as Stream); + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/RoutedEventHelper.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/RoutedEventHelper.cs new file mode 100644 index 00000000..2791aa0e --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/RoutedEventHelper.cs @@ -0,0 +1,70 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Windows; + +namespace Xceed.Wpf.Toolkit.Core.Utilities +{ + internal static class RoutedEventHelper + { + internal static void RaiseEvent(DependencyObject target, RoutedEventArgs args) + { + if (target is UIElement) + { + (target as UIElement).RaiseEvent(args); + } + else if (target is ContentElement) + { + (target as ContentElement).RaiseEvent(args); + } + } + + internal static void AddHandler(DependencyObject element, RoutedEvent routedEvent, Delegate handler) + { + UIElement uie = element as UIElement; + if (uie != null) + { + uie.AddHandler(routedEvent, handler); + } + else + { + ContentElement ce = element as ContentElement; + if (ce != null) + { + ce.AddHandler(routedEvent, handler); + } + } + } + + internal static void RemoveHandler(DependencyObject element, RoutedEvent routedEvent, Delegate handler) + { + UIElement uie = element as UIElement; + if (uie != null) + { + uie.RemoveHandler(routedEvent, handler); + } + else + { + ContentElement ce = element as ContentElement; + if (ce != null) + { + ce.RemoveHandler(routedEvent, handler); + } + } + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/Segment.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/Segment.cs new file mode 100644 index 00000000..ef720f0e --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/Segment.cs @@ -0,0 +1,384 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Windows; + +namespace Xceed.Wpf.Toolkit.Core.Utilities +{ + internal struct Segment + { + #region Constructors + + public Segment(Point point) + { + _p1 = point; + _p2 = point; + _isP1Excluded = false; + _isP2Excluded = false; + } + + public Segment(Point p1, Point p2) + { + _p1 = p1; + _p2 = p2; + _isP1Excluded = false; + _isP2Excluded = false; + } + + public Segment(Point p1, Point p2, bool excludeP1, bool excludeP2) + { + _p1 = p1; + _p2 = p2; + _isP1Excluded = excludeP1; + _isP2Excluded = excludeP2; + } + + #endregion + + #region Empty Static Properties + + public static Segment Empty + { + get + { + Segment result = new Segment(new Point(0, 0)); + result._isP1Excluded = true; + result._isP2Excluded = true; + return result; + } + } + + #endregion + + #region P1 Property + + public Point P1 + { + get + { + return _p1; + } + } + + #endregion + + #region P2 Property + + public Point P2 + { + get + { + return _p2; + } + } + + #endregion + + #region IsP1Excluded Property + + public bool IsP1Excluded + { + get + { + return _isP1Excluded; + } + } + + #endregion + + #region IsP2Excluded Property + + public bool IsP2Excluded + { + get + { + return _isP2Excluded; + } + } + + #endregion + + #region IsEmpty Property + + public bool IsEmpty + { + get + { + return DoubleHelper.AreVirtuallyEqual(_p1, _p2) && (_isP1Excluded || _isP2Excluded); + } + } + + #endregion + + #region IsPoint Property + + public bool IsPoint + { + get + { + return DoubleHelper.AreVirtuallyEqual(_p1, _p2); + } + } + + #endregion + + #region Length Property + + public double Length + { + get + { + return (this.P2 - this.P1).Length; + } + } + + #endregion + + #region Slope Property + + public double Slope + { + get + { + return (this.P2.X == this.P1.X) ? double.NaN : (this.P2.Y - this.P1.Y) / (this.P2.X - this.P1.X); + } + } + + #endregion + + public bool Contains(Point point) + { + if (IsEmpty) + return false; + + // if the point is an endpoint, ensure that it is not excluded + if (DoubleHelper.AreVirtuallyEqual(_p1, point)) + return _isP1Excluded; + + if (DoubleHelper.AreVirtuallyEqual(_p2, point)) + return _isP2Excluded; + + bool result = false; + + // ensure that a line through P1 and the point is parallel to the current segment + if (DoubleHelper.AreVirtuallyEqual(Slope, new Segment(_p1, point).Slope)) + { + // finally, ensure that the point is between the segment's endpoints + result = (point.X >= Math.Min(_p1.X, _p2.X)) + && (point.X <= Math.Max(_p1.X, _p2.X)) + && (point.Y >= Math.Min(_p1.Y, _p2.Y)) + && (point.Y <= Math.Max(_p1.Y, _p2.Y)); + } + return result; + } + + public bool Contains(Segment segment) + { + return (segment == this.Intersection(segment)); + } + + public override bool Equals(object o) + { + if (!(o is Segment)) + return false; + + Segment other = (Segment)o; + + // empty segments are always considered equal + if (this.IsEmpty) + return other.IsEmpty; + + // segments are considered equal if + // 1) the endpoints are equal and equally excluded + // 2) the opposing endpoints are equal and equally excluded + if (DoubleHelper.AreVirtuallyEqual(_p1, other._p1)) + { + return (DoubleHelper.AreVirtuallyEqual(_p2, other._p2) + && _isP1Excluded == other._isP1Excluded + && _isP2Excluded == other._isP2Excluded); + } + else + { + return (DoubleHelper.AreVirtuallyEqual(_p1, other._p2) + && DoubleHelper.AreVirtuallyEqual(_p2, other._p1) + && _isP1Excluded == other._isP2Excluded + && _isP2Excluded == other._isP1Excluded); + } + } + + public override int GetHashCode() + { + return _p1.GetHashCode() ^ _p2.GetHashCode() ^ _isP1Excluded.GetHashCode() ^ _isP2Excluded.GetHashCode(); + } + + public Segment Intersection(Segment segment) + { + // if either segment is empty, the intersection is also empty + if (this.IsEmpty || segment.IsEmpty) + return Segment.Empty; + + // if the segments are equal, just return a new equal segment + if (this == segment) + return new Segment(this._p1, this._p2, this._isP1Excluded, this._isP2Excluded); + + // if either segment is a Point, just see if the point is contained in the other segment + if (this.IsPoint) + return segment.Contains(this._p1) ? new Segment(this._p1) : Segment.Empty; + + if (segment.IsPoint) + return this.Contains(segment._p1) ? new Segment(segment._p1) : Segment.Empty; + + // okay, no easy answer, so let's do the math... + Point p1 = this._p1; + Vector v1 = this._p2 - this._p1; + Point p2 = segment._p1; + Vector v2 = segment._p2 - segment._p1; + Vector endpointVector = p2 - p1; + + double xProd = Vector.CrossProduct(v1, v2); + + // if segments are not parallel, then look for intersection on each segment + if (!DoubleHelper.AreVirtuallyEqual(Slope, segment.Slope)) + { + // check for intersection on other segment + double s = (Vector.CrossProduct(endpointVector, v1)) / xProd; + if (s < 0 || s > 1) + return Segment.Empty; + + // check for intersection on this segment + s = (Vector.CrossProduct(endpointVector, v2)) / xProd; + if (s < 0 || s > 1) + return Segment.Empty; + + // intersection of segments is a point + return new Segment(p1 + s * v1); + } + + // segments are parallel + xProd = Vector.CrossProduct(endpointVector, v1); + if (xProd * xProd > 1.0e-06 * v1.LengthSquared * endpointVector.LengthSquared) + { + // segments do not intersect + return Segment.Empty; + } + + // intersection is overlapping segment + Segment result = new Segment(); + + // to determine the overlapping segment, create reference segments where the endpoints are *not* excluded + Segment refThis = new Segment(this._p1, this._p2); + Segment refSegment = new Segment(segment._p1, segment._p2); + + // check whether this segment is contained in the other segment + bool includeThisP1 = refSegment.Contains(refThis._p1); + bool includeThisP2 = refSegment.Contains(refThis._p2); + if (includeThisP1 && includeThisP2) + { + result._p1 = this._p1; + result._p2 = this._p2; + result._isP1Excluded = this._isP1Excluded || !segment.Contains(this._p1); + result._isP2Excluded = this._isP2Excluded || !segment.Contains(this._p2); + return result; + } + + // check whether the other segment is contained in this segment + bool includeSegmentP1 = refThis.Contains(refSegment._p1); + bool includeSegmentP2 = refThis.Contains(refSegment._p2); + if (includeSegmentP1 && includeSegmentP2) + { + result._p1 = segment._p1; + result._p2 = segment._p2; + result._isP1Excluded = segment._isP1Excluded || !this.Contains(segment._p1); + result._isP2Excluded = segment._isP2Excluded || !this.Contains(segment._p2); + return result; + } + + // the intersection must include one endpoint from this segment and one endpoint from the other segment + if (includeThisP1) + { + result._p1 = this._p1; + result._isP1Excluded = this._isP1Excluded || !segment.Contains(this._p1); + } + else + { + result._p1 = this._p2; + result._isP1Excluded = this._isP2Excluded || !segment.Contains(this._p2); + } + if (includeSegmentP1) + { + result._p2 = segment._p1; + result._isP2Excluded = segment._isP1Excluded || !this.Contains(segment._p1); + } + else + { + result._p2 = segment._p2; + result._isP2Excluded = segment._isP2Excluded || !this.Contains(segment._p2); + } + return result; + } + + public override string ToString() + { + string s = base.ToString(); + + if (this.IsEmpty) + { + s = s + ": {Empty}"; + } + else if (this.IsPoint) + { + s = s + ", Point: " + _p1.ToString(); + } + else + { + s = s + ": " + _p1.ToString() + (_isP1Excluded ? " (excl)" : " (incl)") + + " to " + _p2.ToString() + (_isP2Excluded ? " (excl)" : " (incl)"); + } + + return s; + } + + #region Operators Methods + + public static bool operator ==(Segment s1, Segment s2) + { + if ((object)s1 == null) + return (object)s2 == null; + + if ((object)s2 == null) + return (object)s1 == null; + + return s1.Equals(s2); + } + + public static bool operator !=(Segment s1, Segment s2) + { + return !(s1 == s2); + } + + #endregion + + #region Private Fields + + private bool _isP1Excluded; + private bool _isP2Excluded; + private Point _p1; + private Point _p2; + + #endregion + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/TreeHelper.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/TreeHelper.cs new file mode 100644 index 00000000..df58d468 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/TreeHelper.cs @@ -0,0 +1,235 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Windows; +using System.Windows.Media; +using System.Windows.Controls.Primitives; + +namespace Xceed.Wpf.Toolkit.Core.Utilities +{ + internal static class TreeHelper + { + /// + /// Tries its best to return the specified element's parent. It will + /// try to find, in this order, the VisualParent, LogicalParent, LogicalTemplatedParent. + /// It only works for Visual, FrameworkElement or FrameworkContentElement. + /// + /// The element to which to return the parent. It will only + /// work if element is a Visual, a FrameworkElement or a FrameworkContentElement. + /// If the logical parent is not found (Parent), we check the TemplatedParent + /// (see FrameworkElement.Parent documentation). But, we never actually witnessed + /// this situation. + public static DependencyObject GetParent(DependencyObject element) + { + return TreeHelper.GetParent(element, true); + } + + private static DependencyObject GetParent(DependencyObject element, bool recurseIntoPopup) + { + if (recurseIntoPopup) + { + // Case 126732 : To correctly detect parent of a popup we must do that exception case + Popup popup = element as Popup; + + if ((popup != null) && (popup.PlacementTarget != null)) + return popup.PlacementTarget; + } + + Visual visual = element as Visual; + DependencyObject parent = (visual == null) ? null : VisualTreeHelper.GetParent(visual); + + if (parent == null) + { + // No Visual parent. Check in the logical tree. + FrameworkElement fe = element as FrameworkElement; + + if (fe != null) + { + parent = fe.Parent; + + if (parent == null) + { + parent = fe.TemplatedParent; + } + } + else + { + FrameworkContentElement fce = element as FrameworkContentElement; + + if (fce != null) + { + parent = fce.Parent; + + if (parent == null) + { + parent = fce.TemplatedParent; + } + } + } + } + + return parent; + } + + /// + /// This will search for a parent of the specified type. + /// + /// The type of the element to find + /// The node where the search begins. This element is not checked. + /// Returns the found element. Null if nothing is found. + public static T FindParent(DependencyObject startingObject) where T : DependencyObject + { + return TreeHelper.FindParent(startingObject, false, null); + } + + /// + /// This will search for a parent of the specified type. + /// + /// The type of the element to find + /// The node where the search begins. + /// Should the specified startingObject be checked first. + /// Returns the found element. Null if nothing is found. + public static T FindParent(DependencyObject startingObject, bool checkStartingObject) where T : DependencyObject + { + return TreeHelper.FindParent(startingObject, checkStartingObject, null); + } + + /// + /// This will search for a parent of the specified type. + /// + /// The type of the element to find + /// The node where the search begins. + /// Should the specified startingObject be checked first. + /// Provide a callback to check additional properties + /// of the found elements. Can be left Null if no additional criteria are needed. + /// Returns the found element. Null if nothing is found. + /// Button button = TreeHelper.FindParent<Button>( this, foundChild => foundChild.Focusable ); + public static T FindParent(DependencyObject startingObject, bool checkStartingObject, Func additionalCheck) where T : DependencyObject + { + T foundElement; + DependencyObject parent = (checkStartingObject ? startingObject : TreeHelper.GetParent(startingObject, true)); + + while (parent != null) + { + foundElement = parent as T; + + if (foundElement != null) + { + if (additionalCheck == null) + { + return foundElement; + } + else + { + if (additionalCheck(foundElement)) + return foundElement; + } + } + + parent = TreeHelper.GetParent(parent, true); + } + + return null; + } + + /// + /// This will search for a child of the specified type. The search is performed + /// hierarchically, breadth first (as opposed to depth first). + /// + /// The type of the element to find + /// The root of the tree to search for. This element itself is not checked. + /// Returns the found element. Null if nothing is found. + public static T FindChild(DependencyObject parent) where T : DependencyObject + { + return TreeHelper.FindChild(parent, null); + } + + /// + /// This will search for a child of the specified type. The search is performed + /// hierarchically, breadth first (as opposed to depth first). + /// + /// The type of the element to find + /// The root of the tree to search for. This element itself is not checked. + /// Provide a callback to check additional properties + /// of the found elements. Can be left Null if no additional criteria are needed. + /// Returns the found element. Null if nothing is found. + /// Button button = TreeHelper.FindChild<Button>( this, foundChild => foundChild.Focusable ); + public static T FindChild(DependencyObject parent, Func additionalCheck) where T : DependencyObject + { + int childrenCount = VisualTreeHelper.GetChildrenCount(parent); + T child; + + for (int index = 0; index < childrenCount; index++) + { + child = VisualTreeHelper.GetChild(parent, index) as T; + + if (child != null) + { + if (additionalCheck == null) + { + return child; + } + else + { + if (additionalCheck(child)) + return child; + } + } + } + + for (int index = 0; index < childrenCount; index++) + { + child = TreeHelper.FindChild(VisualTreeHelper.GetChild(parent, index), additionalCheck); + + if (child != null) + return child; + } + + return null; + } + + /// + /// Returns true if the specified element is a child of parent somewhere in the visual + /// tree. This method will work for Visual, FrameworkElement and FrameworkContentElement. + /// + /// The element that is potentially a child of the specified parent. + /// The element that is potentially a parent of the specified element. + public static bool IsDescendantOf(DependencyObject element, DependencyObject parent) + { + return TreeHelper.IsDescendantOf(element, parent, true); + } + + /// + /// Returns true if the specified element is a child of parent somewhere in the visual + /// tree. This method will work for Visual, FrameworkElement and FrameworkContentElement. + /// + /// The element that is potentially a child of the specified parent. + /// The element that is potentially a parent of the specified element. + public static bool IsDescendantOf(DependencyObject element, DependencyObject parent, bool recurseIntoPopup) + { + while (element != null) + { + if (element == parent) + return true; + + element = TreeHelper.GetParent(element, recurseIntoPopup); + } + + return false; + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/ValueChangeHelper.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/ValueChangeHelper.cs new file mode 100644 index 00000000..9c49e9a7 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/ValueChangeHelper.cs @@ -0,0 +1,150 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows; +using System.Collections; +using System.Windows.Data; + +namespace Xceed.Wpf.Toolkit.Core.Utilities +{ + /// + /// This helper class will raise events when a specific + /// path value on one or many items changes. + /// + internal class ValueChangeHelper : DependencyObject + { + + #region Value Property + /// + /// This private property serves as the target of a binding that monitors the value of the binding + /// of each item in the source. + /// + private static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(object), typeof(ValueChangeHelper), new UIPropertyMetadata(null, OnValueChanged)); + private object Value + { + get + { + return (object)GetValue(ValueProperty); + } + set + { + SetValue(ValueProperty, value); + } + } + + private static void OnValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) + { + ((ValueChangeHelper)sender).RaiseValueChanged(); + } + #endregion + + public event EventHandler ValueChanged; + + #region Constructor + + public ValueChangeHelper(Action changeCallback) + { + if (changeCallback == null) + throw new ArgumentNullException("changeCallback"); + + this.ValueChanged += (s, args) => changeCallback(); + } + + #endregion + + #region Methods + + public void UpdateValueSource(object sourceItem, string path) + { + BindingBase binding = null; + if (sourceItem != null && path != null) + { + binding = new Binding(path) { Source = sourceItem }; + } + + this.UpdateBinding(binding); + } + + public void UpdateValueSource(IEnumerable sourceItems, string path) + { + BindingBase binding = null; + if (sourceItems != null && path != null) + { + MultiBinding multiBinding = new MultiBinding(); + multiBinding.Converter = new BlankMultiValueConverter(); + + foreach (var item in sourceItems) + { + multiBinding.Bindings.Add(new Binding(path) { Source = item }); + } + + binding = multiBinding; + } + + this.UpdateBinding(binding); + } + + private void UpdateBinding(BindingBase binding) + { + if (binding != null) + { + BindingOperations.SetBinding(this, ValueChangeHelper.ValueProperty, binding); + } + else + { + this.ClearBinding(); + } + } + + private void ClearBinding() + { + BindingOperations.ClearBinding(this, ValueChangeHelper.ValueProperty); + } + + private void RaiseValueChanged() + { + if (this.ValueChanged != null) + { + this.ValueChanged(this, EventArgs.Empty); + } + } + + #endregion + + #region BlankMultiValueConverter private class + + private class BlankMultiValueConverter : IMultiValueConverter + { + public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + // We will not use the result anyway. We just want the change notification to kick in. + // Return a new object to have a different value. + return new object(); + } + + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) + { + throw new InvalidOperationException(); + } + } + + #endregion + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/VisualTreeHelperEx.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/VisualTreeHelperEx.cs new file mode 100644 index 00000000..39e5164f --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/VisualTreeHelperEx.cs @@ -0,0 +1,135 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Windows; +using System.Windows.Media; + +namespace Xceed.Wpf.Toolkit.Core.Utilities +{ + public static class VisualTreeHelperEx + { + public static DependencyObject FindAncestorByType(DependencyObject element, Type type, bool specificTypeOnly) + { + if (element == null) + return null; + + if (specificTypeOnly ? (element.GetType() == type) + : (element.GetType() == type) || (element.GetType().IsSubclassOf(type))) + return element; + + return VisualTreeHelperEx.FindAncestorByType(VisualTreeHelper.GetParent(element), type, specificTypeOnly); + } + + public static T FindAncestorByType(DependencyObject depObj) where T : DependencyObject + { + if (depObj == null) + { + return default(T); + } + if (depObj is T) + { + return (T)depObj; + } + + T parent = default(T); + + parent = VisualTreeHelperEx.FindAncestorByType(VisualTreeHelper.GetParent(depObj)); + + return parent; + } + + public static Visual FindDescendantByName(Visual element, string name) + { + if (element != null && (element is FrameworkElement) && (element as FrameworkElement).Name == name) + return element; + + Visual foundElement = null; + if (element is FrameworkElement) + (element as FrameworkElement).ApplyTemplate(); + + for (int i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++) + { + Visual visual = VisualTreeHelper.GetChild(element, i) as Visual; + foundElement = VisualTreeHelperEx.FindDescendantByName(visual, name); + if (foundElement != null) + break; + } + + return foundElement; + } + + public static Visual FindDescendantByType(Visual element, Type type) + { + return VisualTreeHelperEx.FindDescendantByType(element, type, true); + } + + public static Visual FindDescendantByType(Visual element, Type type, bool specificTypeOnly) + { + if (element == null) + return null; + + if (specificTypeOnly ? (element.GetType() == type) + : (element.GetType() == type) || (element.GetType().IsSubclassOf(type))) + return element; + + Visual foundElement = null; + if (element is FrameworkElement) + (element as FrameworkElement).ApplyTemplate(); + + for (int i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++) + { + Visual visual = VisualTreeHelper.GetChild(element, i) as Visual; + foundElement = VisualTreeHelperEx.FindDescendantByType(visual, type, specificTypeOnly); + if (foundElement != null) + break; + } + + return foundElement; + } + + public static T FindDescendantByType(Visual element) where T : Visual + { + Visual temp = VisualTreeHelperEx.FindDescendantByType(element, typeof(T)); + + return (T)temp; + } + + public static Visual FindDescendantWithPropertyValue(Visual element, + DependencyProperty dp, object value) + { + if (element == null) + return null; + + if (element.GetValue(dp).Equals(value)) + return element; + + Visual foundElement = null; + if (element is FrameworkElement) + (element as FrameworkElement).ApplyTemplate(); + + for (int i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++) + { + Visual visual = VisualTreeHelper.GetChild(element, i) as Visual; + foundElement = VisualTreeHelperEx.FindDescendantWithPropertyValue(visual, dp, value); + if (foundElement != null) + break; + } + + return foundElement; + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/WeakEventListener.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/WeakEventListener.cs new file mode 100644 index 00000000..8d53f2f4 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/WeakEventListener.cs @@ -0,0 +1,43 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows; + +namespace Xceed.Wpf.Toolkit.Core.Utilities +{ + internal class WeakEventListener : IWeakEventListener where TArgs : EventArgs + { + private Action _callback; + + public WeakEventListener(Action callback) + { + if (callback == null) + throw new ArgumentNullException("callback"); + + _callback = callback; + } + + public bool ReceiveWeakEvent(Type managerType, object sender, EventArgs e) + { + _callback(sender, (TArgs)e); + return true; + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/WindowUtilities.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/WindowUtilities.cs new file mode 100644 index 00000000..836fa2c9 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/Utilities/WindowUtilities.cs @@ -0,0 +1,30 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows; + +namespace Xceed.Wpf.Toolkit.Core.Utilities +{ + internal class WindowUtilities + { + + + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/VersionResourceDictionary.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/VersionResourceDictionary.cs new file mode 100644 index 00000000..e0dbeec3 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/VersionResourceDictionary.cs @@ -0,0 +1,105 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows; +using System.ComponentModel; +using System.Diagnostics; + +namespace Xceed.Wpf.Toolkit.Core +{ + public class VersionResourceDictionary : ResourceDictionary, ISupportInitialize + { + private int _initializingCount; + private string _assemblyName; + private string _sourcePath; + + + public VersionResourceDictionary() { } + + public VersionResourceDictionary(string assemblyName, string sourcePath) + { + ((ISupportInitialize)this).BeginInit(); + this.AssemblyName = assemblyName; + this.SourcePath = sourcePath; + ((ISupportInitialize)this).EndInit(); + } + + public string AssemblyName + { + get { return _assemblyName; } + set + { + this.EnsureInitialization(); + _assemblyName = value; + } + } + + public string SourcePath + { + get { return _sourcePath; } + set + { + this.EnsureInitialization(); + _sourcePath = value; + } + } + + private void EnsureInitialization() + { + if (_initializingCount <= 0) + throw new InvalidOperationException("VersionResourceDictionary properties can only be set while initializing."); + } + + void ISupportInitialize.BeginInit() + { + base.BeginInit(); + _initializingCount++; + } + + void ISupportInitialize.EndInit() + { + _initializingCount--; + Debug.Assert(_initializingCount >= 0); + + if (_initializingCount <= 0) + { + if (this.Source != null) + throw new InvalidOperationException("Source property cannot be initialized on the VersionResourceDictionary"); + + if (string.IsNullOrEmpty(this.AssemblyName) || string.IsNullOrEmpty(this.SourcePath)) + throw new InvalidOperationException("AssemblyName and SourcePath must be set during initialization"); + + //Using an absolute path is necessary in VS2015 for themes different than Windows 8. + string uriStr = string.Format(@"pack://application:,,,/{0};v{1};component/{2}", this.AssemblyName, _XceedVersionInfo.Version, this.SourcePath); + this.Source = new Uri(uriStr, UriKind.Absolute); + } + + base.EndInit(); + } + + + private enum InitState + { + NotInitialized, + Initializing, + Initialized + }; + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/WeakCollectionChangedWrapper.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/WeakCollectionChangedWrapper.cs new file mode 100644 index 00000000..380c1304 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Core/WeakCollectionChangedWrapper.cs @@ -0,0 +1,150 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Collections; +using System.Collections.Specialized; +using Xceed.Wpf.Toolkit.Core.Utilities; + +namespace Xceed.Wpf.Toolkit.Core +{ + internal class WeakCollectionChangedWrapper : IList, ICollection, INotifyCollectionChanged + { + private WeakEventListener _innerListListener; + private IList _innerList; + + public WeakCollectionChangedWrapper(IList sourceList) + { + _innerList = sourceList; + var notifyList = _innerList as INotifyCollectionChanged; + if (notifyList != null) + { + _innerListListener = new WeakEventListener(OnInnerCollectionChanged); + CollectionChangedEventManager.AddListener(notifyList, _innerListListener); + } + } + + public event NotifyCollectionChangedEventHandler CollectionChanged; + + private void OnInnerCollectionChanged(object sender, NotifyCollectionChangedEventArgs args) + { + if (this.CollectionChanged != null) + { + this.CollectionChanged(this, args); + } + } + + internal void ReleaseEvents() + { + if (_innerListListener != null) + { + CollectionChangedEventManager.RemoveListener((INotifyCollectionChanged)_innerList, _innerListListener); + _innerListListener = null; + } + } + + #region IList Members + + int IList.Add(object value) + { + return _innerList.Add(value); + } + + void IList.Clear() + { + _innerList.Clear(); + } + + bool IList.Contains(object value) + { + return _innerList.Contains(value); + } + + int IList.IndexOf(object value) + { + return _innerList.IndexOf(value); + } + + void IList.Insert(int index, object value) + { + _innerList.Insert(index, value); + } + + bool IList.IsFixedSize + { + get { return _innerList.IsFixedSize; } + } + + bool IList.IsReadOnly + { + get { return _innerList.IsReadOnly; } + } + + void IList.Remove(object value) + { + _innerList.Remove(value); + } + + void IList.RemoveAt(int index) + { + _innerList.RemoveAt(index); + } + + object IList.this[int index] + { + get { return _innerList[index]; } + set { _innerList[index] = value; } + } + #endregion + + #region ICollection Members + + void ICollection.CopyTo(Array array, int index) + { + _innerList.CopyTo(array, index); + } + + int ICollection.Count + { + get { return _innerList.Count; } + } + + bool ICollection.IsSynchronized + { + get { return _innerList.IsSynchronized; } + } + + object ICollection.SyncRoot + { + get { return _innerList.SyncRoot; } + } + + #endregion + + #region IEnumerable Members + + IEnumerator IEnumerable.GetEnumerator() + { + return _innerList.GetEnumerator(); + } + + #endregion + + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimePicker/Implementation/DateTimePicker.Icon.bmp b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimePicker/Implementation/DateTimePicker.Icon.bmp new file mode 100644 index 00000000..ce76dc5b --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimePicker/Implementation/DateTimePicker.Icon.bmp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e95d8b086aa0680fa4b987fc38d9701b23c24b9d6334806e6d5a7fa0b3687373 +size 822 diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimePicker/Implementation/DateTimePicker.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimePicker/Implementation/DateTimePicker.cs new file mode 100644 index 00000000..db7769d8 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimePicker/Implementation/DateTimePicker.cs @@ -0,0 +1,473 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using System.Windows.Controls.Primitives; +using Xceed.Wpf.Toolkit.Core.Utilities; +using Xceed.Wpf.Toolkit.Primitives; +#if VS2008 +using Microsoft.Windows.Controls; +using Microsoft.Windows.Controls.Primitives; +#endif + +namespace Xceed.Wpf.Toolkit +{ + [TemplatePart(Name = PART_Calendar, Type = typeof(Calendar))] + [TemplatePart(Name = PART_TimeUpDown, Type = typeof(TimePicker))] + public class DateTimePicker : DateTimePickerBase + { + private const string PART_Calendar = "PART_Calendar"; + private const string PART_TimeUpDown = "PART_TimeUpDown"; + + #region Members + + private Calendar _calendar; + private TimePicker _timePicker; + private DateTime? _calendarTemporaryDateTime; + private DateTime? _calendarIntendedDateTime; + + #endregion //Members + + #region Properties + + #region AutoCloseCalendar + + public static readonly DependencyProperty AutoCloseCalendarProperty = DependencyProperty.Register("AutoCloseCalendar", typeof(bool), typeof(DateTimePicker), new UIPropertyMetadata(false)); + public bool AutoCloseCalendar + { + get + { + return (bool)GetValue(AutoCloseCalendarProperty); + } + set + { + SetValue(AutoCloseCalendarProperty, value); + } + } + + #endregion //AutoCloseCalendar + + #region CalendarDisplayMode + + public static readonly DependencyProperty CalendarDisplayModeProperty = DependencyProperty.Register("CalendarDisplayMode", typeof(CalendarMode) + , typeof(DateTimePicker), new UIPropertyMetadata(CalendarMode.Month)); + public CalendarMode CalendarDisplayMode + { + get + { + return (CalendarMode)GetValue(CalendarDisplayModeProperty); + } + set + { + SetValue(CalendarDisplayModeProperty, value); + } + } + + #endregion //CalendarDisplayMode + + #region CalendarWidth + + public static readonly DependencyProperty CalendarWidthProperty = DependencyProperty.Register("CalendarWidth", typeof(double) + , typeof(DateTimePicker), new UIPropertyMetadata(178d)); + public double CalendarWidth + { + get + { + return (double)GetValue(CalendarWidthProperty); + } + set + { + SetValue(CalendarWidthProperty, value); + } + } + + #endregion //CalendarWidth + + #region TimeFormat + + public static readonly DependencyProperty TimeFormatProperty = DependencyProperty.Register("TimeFormat", typeof(DateTimeFormat), typeof(DateTimePicker), new UIPropertyMetadata(DateTimeFormat.ShortTime)); + public DateTimeFormat TimeFormat + { + get + { + return (DateTimeFormat)GetValue(TimeFormatProperty); + } + set + { + SetValue(TimeFormatProperty, value); + } + } + + #endregion //TimeFormat + + #region TimeFormatString + + public static readonly DependencyProperty TimeFormatStringProperty = DependencyProperty.Register("TimeFormatString", typeof(string), typeof(DateTimePicker), new UIPropertyMetadata(default(String)), IsTimeFormatStringValid); + public string TimeFormatString + { + get + { + return (string)GetValue(TimeFormatStringProperty); + } + set + { + SetValue(TimeFormatStringProperty, value); + } + } + + private static bool IsTimeFormatStringValid(object value) + { + return DateTimeUpDown.IsFormatStringValid(value); + } + + #endregion //TimeFormatString + + #region TimePickerAllowSpin + + public static readonly DependencyProperty TimePickerAllowSpinProperty = DependencyProperty.Register("TimePickerAllowSpin", typeof(bool), typeof(DateTimePicker), new UIPropertyMetadata(true)); + public bool TimePickerAllowSpin + { + get + { + return (bool)GetValue(TimePickerAllowSpinProperty); + } + set + { + SetValue(TimePickerAllowSpinProperty, value); + } + } + + #endregion //TimePickerAllowSpin + + #region TimePickerShowButtonSpinner + + public static readonly DependencyProperty TimePickerShowButtonSpinnerProperty = DependencyProperty.Register("TimePickerShowButtonSpinner", typeof(bool), typeof(DateTimePicker), new UIPropertyMetadata(true)); + public bool TimePickerShowButtonSpinner + { + get + { + return (bool)GetValue(TimePickerShowButtonSpinnerProperty); + } + set + { + SetValue(TimePickerShowButtonSpinnerProperty, value); + } + } + + #endregion //TimePickerShowButtonSpinner + + #region TimePickerVisibility + + public static readonly DependencyProperty TimePickerVisibilityProperty = DependencyProperty.Register("TimePickerVisibility", typeof(Visibility), typeof(DateTimePicker), new UIPropertyMetadata(Visibility.Visible)); + public Visibility TimePickerVisibility + { + get + { + return (Visibility)GetValue(TimePickerVisibilityProperty); + } + set + { + SetValue(TimePickerVisibilityProperty, value); + } + } + + #endregion //TimePickerVisibility + + #region TimeWatermark + + public static readonly DependencyProperty TimeWatermarkProperty = DependencyProperty.Register("TimeWatermark", typeof(object), typeof(DateTimePicker), new UIPropertyMetadata(null)); + public object TimeWatermark + { + get + { + return (object)GetValue(TimeWatermarkProperty); + } + set + { + SetValue(TimeWatermarkProperty, value); + } + } + + #endregion //TimeWatermark + + #region TimeWatermarkTemplate + + public static readonly DependencyProperty TimeWatermarkTemplateProperty = DependencyProperty.Register("TimeWatermarkTemplate", typeof(DataTemplate), typeof(DateTimePicker), new UIPropertyMetadata(null)); + public DataTemplate TimeWatermarkTemplate + { + get + { + return (DataTemplate)GetValue(TimeWatermarkTemplateProperty); + } + set + { + SetValue(TimeWatermarkTemplateProperty, value); + } + } + + #endregion //TimeWatermarkTemplate + + #endregion //Properties + + #region Constructors + + static DateTimePicker() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(DateTimePicker), new FrameworkPropertyMetadata(typeof(DateTimePicker))); + UpdateValueOnEnterKeyProperty.OverrideMetadata(typeof(DateTimePicker), new FrameworkPropertyMetadata(true)); + } + + public DateTimePicker() + { + } + + #endregion //Constructors + + #region Base Class Overrides + + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + if (_calendar != null) + _calendar.SelectedDatesChanged -= Calendar_SelectedDatesChanged; + + _calendar = GetTemplateChild(PART_Calendar) as Calendar; + + if (_calendar != null) + { + _calendar.SelectedDatesChanged += Calendar_SelectedDatesChanged; + _calendar.SelectedDate = Value ?? null; + _calendar.DisplayDate = Value ?? this.ContextNow; + this.SetBlackOutDates(); + } + + if (_timePicker != null) + { + _timePicker.ValueChanged -= this.TimePicker_ValueChanged; + } + _timePicker = GetTemplateChild(PART_TimeUpDown) as TimePicker; + if (_timePicker != null) + { + _timePicker.ValueChanged += this.TimePicker_ValueChanged; + } + } + + protected override void OnPreviewMouseUp(MouseButtonEventArgs e) + { + if (Mouse.Captured is CalendarItem) + { + Mouse.Capture(null); + + // Do not close calendar on Year/Month Selection. Close only on Day selection. + if (AutoCloseCalendar && (_calendar != null) && (_calendar.DisplayMode == CalendarMode.Month)) + { + ClosePopup(true); + } + } + base.OnPreviewMouseUp(e); + } + + protected override void OnValueChanged(DateTime? oldValue, DateTime? newValue) + { + //The calendar only select the Date part, not the time part. + DateTime? newValueDate = (newValue != null) + ? newValue.Value.Date + : (DateTime?)null; + + if (_calendar != null && _calendar.SelectedDate != newValueDate) + { + _calendar.SelectedDate = newValueDate; + _calendar.DisplayDate = newValue.GetValueOrDefault(this.ContextNow); + } + + //If we change any part of the datetime without + //using the calendar when the actual date is temporary, + //clear the temporary value. + if ((_calendar != null) && (_calendarTemporaryDateTime != null) && (newValue != _calendarTemporaryDateTime)) + { + _calendarTemporaryDateTime = null; + _calendarIntendedDateTime = null; + } + + base.OnValueChanged(oldValue, newValue); + } + + protected override void OnIsOpenChanged(bool oldValue, bool newValue) + { + base.OnIsOpenChanged(oldValue, newValue); + + if (!newValue) + { + _calendarTemporaryDateTime = null; + _calendarIntendedDateTime = null; + } + } + + protected override void OnPreviewKeyDown(KeyEventArgs e) + { + //if the calendar is open then we don't want to modify the behavior of navigating the calendar control with the Up/Down keys. + if (!IsOpen) + base.OnPreviewKeyDown(e); + } + + protected override void OnMaximumChanged(DateTime? oldValue, DateTime? newValue) + { + base.OnMaximumChanged(oldValue, newValue); + + this.SetBlackOutDates(); + } + + protected override void OnMinimumChanged(DateTime? oldValue, DateTime? newValue) + { + base.OnMinimumChanged(oldValue, newValue); + + this.SetBlackOutDates(); + } + + #endregion //Base Class Overrides + + #region Event Handlers + + protected override void HandleKeyDown(object sender, KeyEventArgs e) + { + // The base call will handle the Ctrl+Down, Enter and Esc keys + // in order to open or close the popup. + // Do not close the Calendar if the call is handled + // by the TimePicker inside the DateTimePicker template. + if (IsOpen + && (_timePicker != null) + && _timePicker.IsKeyboardFocusWithin + && (_timePicker.IsOpen || e.Handled)) + return; + + base.HandleKeyDown(sender, e); + } + + private void TimePicker_ValueChanged(object sender, RoutedPropertyChangedEventArgs e) + { + e.Handled = true; + + // if UpdateValueOnEnterKey is true, + // Sync Value on Text only when Enter Key is pressed. + if (this.UpdateValueOnEnterKey) + { + var newTime = e.NewValue as DateTime?; + if (newTime != null) + { + _fireSelectionChangedEvent = false; + var currentDate = this.ConvertTextToValue(this.TextBox.Text); + var date = currentDate ?? this.ContextNow; + var newValue = new DateTime(date.Year, date.Month, date.Day, newTime.Value.Hour, newTime.Value.Minute, newTime.Value.Second, newTime.Value.Millisecond, date.Kind); + this.TextBox.Text = newValue.ToString(this.GetFormatString(this.Format), this.CultureInfo); + _fireSelectionChangedEvent = true; + } + } + } + + private void Calendar_SelectedDatesChanged(object sender, SelectionChangedEventArgs e) + { + if (e.AddedItems.Count > 0) + { + var newDate = (DateTime?)e.AddedItems[0]; + + if (newDate != null) + { + //The Calendar will always return a date with an "Unspecified" Kind. + //Force the expected kind to the value. + newDate = DateTime.SpecifyKind(newDate.Value, this.Kind); + + // Only change the year, month, and day part of the value. Keep everything to the last "tick." + // "Milliseconds" aren't precise enough. Use a mathematical scheme instead. + if (_calendarIntendedDateTime != null) + { + newDate = newDate.Value.Date + _calendarIntendedDateTime.Value.TimeOfDay; + _calendarTemporaryDateTime = null; + _calendarIntendedDateTime = null; + } + else if (Value != null) + { + newDate = newDate.Value.Date + Value.Value.TimeOfDay; + } + + // Always be sure that the time part of the selected value is always + // within the bound of the min max. The time part could be altered + // if the calendar's selected date match the Minimum or Maximum date. + // Keep in memory the intended time of day, in case that the selected + // calendar date is only transitory (browsing the calendar with the keyboard) + var limitedDateTime = this.GetClippedMinMaxValue(newDate); + + if (limitedDateTime.Value != newDate.Value) + { + _calendarTemporaryDateTime = limitedDateTime; + _calendarIntendedDateTime = newDate; + newDate = limitedDateTime; + } + } + + if (this.UpdateValueOnEnterKey) + { + _fireSelectionChangedEvent = false; + this.TextBox.Text = newDate.Value.ToString(this.GetFormatString(this.Format), this.CultureInfo); + _fireSelectionChangedEvent = true; + } + else + { + if (!object.Equals(newDate, Value)) + { + this.Value = newDate; + } + } + } + } + + protected override void Popup_Opened(object sender, EventArgs e) + { + base.Popup_Opened(sender, e); + + if (_calendar != null) + _calendar.Focus(); + } + + #endregion //Event Handlers + + #region Methods + + private void SetBlackOutDates() + { + if (_calendar != null) + { + _calendar.BlackoutDates.Clear(); + + if ((this.Minimum != null) && this.Minimum.HasValue && (this.Minimum.Value != System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.Calendar.MinSupportedDateTime)) + { + DateTime minDate = this.Minimum.Value; + _calendar.BlackoutDates.Add(new CalendarDateRange(System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.Calendar.MinSupportedDateTime, minDate.AddDays(-1))); + } + if ((this.Maximum != null) && this.Maximum.HasValue && (this.Maximum.Value != System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.Calendar.MaxSupportedDateTime)) + { + DateTime maxDate = this.Maximum.Value; + _calendar.BlackoutDates.Add(new CalendarDateRange(maxDate.AddDays(1), System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.Calendar.MaxSupportedDateTime)); + } + } + } + + #endregion //Methods + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimePicker/Themes/Aero2.NormalColor.xaml b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimePicker/Themes/Aero2.NormalColor.xaml new file mode 100644 index 00000000..e0204d1a --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimePicker/Themes/Aero2.NormalColor.xaml @@ -0,0 +1,277 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimePicker/Themes/Generic.xaml b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimePicker/Themes/Generic.xaml new file mode 100644 index 00000000..cd0f3e36 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimePicker/Themes/Generic.xaml @@ -0,0 +1,285 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimeUpDown/Implementation/DateTimeFormat.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimeUpDown/Implementation/DateTimeFormat.cs new file mode 100644 index 00000000..d672130b --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimeUpDown/Implementation/DateTimeFormat.cs @@ -0,0 +1,33 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +namespace Xceed.Wpf.Toolkit +{ + public enum DateTimeFormat + { + Custom, + FullDateTime, + LongDate, + LongTime, + MonthDay, + RFC1123, + ShortDate, + ShortTime, + SortableDateTime, + UniversalSortableDateTime, + YearMonth + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimeUpDown/Implementation/DateTimeInfo.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimeUpDown/Implementation/DateTimeInfo.cs new file mode 100644 index 00000000..b5be1a97 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimeUpDown/Implementation/DateTimeInfo.cs @@ -0,0 +1,52 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +namespace Xceed.Wpf.Toolkit +{ + internal class DateTimeInfo + { + public string Content + { + get; + set; + } + public string Format + { + get; + set; + } + public bool IsReadOnly + { + get; + set; + } + public int Length + { + get; + set; + } + public int StartPosition + { + get; + set; + } + public DateTimePart Type + { + get; + set; + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimeUpDown/Implementation/DateTimeParser.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimeUpDown/Implementation/DateTimeParser.cs new file mode 100644 index 00000000..3731e998 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimeUpDown/Implementation/DateTimeParser.cs @@ -0,0 +1,243 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; + +namespace Xceed.Wpf.Toolkit +{ + internal class DateTimeParser + { + public static bool TryParse(string value, string format, DateTime currentDate, CultureInfo cultureInfo, bool autoClipTimeParts, out DateTime result) + { + bool success = false; + result = currentDate; + + if (string.IsNullOrEmpty(value) || string.IsNullOrEmpty(format)) + return false; + + DateTimeParser.UpdateValueFormatForQuotes(ref value, ref format); + + var dateTimeString = ComputeDateTimeString(value, format, currentDate, cultureInfo, autoClipTimeParts).Trim(); + + if (!String.IsNullOrEmpty(dateTimeString)) + success = DateTime.TryParse(dateTimeString, cultureInfo.DateTimeFormat, DateTimeStyles.None, out result); + + if (!success) + result = currentDate; + + return success; + } + + private static void UpdateValueFormatForQuotes(ref string value, ref string format) + { + var quoteStart = format.IndexOf("'"); + if (quoteStart > -1) + { + var quoteEnd = format.IndexOf("'", quoteStart + 1); + if (quoteEnd > -1) + { + var quoteContent = format.Substring(quoteStart + 1, quoteEnd - quoteStart - 1); + value = value.Replace(quoteContent, ""); + format = format.Remove(quoteStart, quoteEnd - quoteStart + 1); + + // Use recursive calls for many quote text. + DateTimeParser.UpdateValueFormatForQuotes(ref value, ref format); + } + } + } + + private static string ComputeDateTimeString(string dateTime, string format, DateTime currentDate, CultureInfo cultureInfo, bool autoClipTimeParts) + { + Dictionary dateParts = GetDateParts(currentDate, cultureInfo); + string[] timeParts = new string[3] { currentDate.Hour.ToString(), currentDate.Minute.ToString(), currentDate.Second.ToString() }; + string millisecondsPart = currentDate.Millisecond.ToString(); + string designator = ""; + string[] dateTimeSeparators = new string[] { ",", " ", "-", ".", "/", cultureInfo.DateTimeFormat.DateSeparator, cultureInfo.DateTimeFormat.TimeSeparator }; + var forcePMDesignator = false; + + UpdateSortableDateTimeString(ref dateTime, ref format, cultureInfo); + + var dateTimeParts = new List(); + var formats = new List(); + var isContainingDateTimeSeparators = dateTimeSeparators.Any(s => dateTime.Contains(s)); + if (isContainingDateTimeSeparators) + { + dateTimeParts = dateTime.Split(dateTimeSeparators, StringSplitOptions.RemoveEmptyEntries).ToList(); + formats = format.Split(dateTimeSeparators, StringSplitOptions.RemoveEmptyEntries).ToList(); + } + else + { + string currentformat = ""; + string currentString = ""; + var formatArray = format.ToCharArray(); + for (int i = 0; i < formatArray.Count(); ++i) + { + var c = formatArray[i]; + if (!currentformat.Contains(c)) + { + if (!string.IsNullOrEmpty(currentformat)) + { + formats.Add(currentformat); + dateTimeParts.Add(currentString); + } + currentformat = c.ToString(); + currentString = (i < dateTime.Length) ? dateTime[i].ToString() : ""; + } + else + { + currentformat = string.Concat(currentformat, c); + currentString = string.Concat(currentString, (i < dateTime.Length) ? dateTime[i] : '\0'); + } + } + if (!string.IsNullOrEmpty(currentformat)) + { + formats.Add(currentformat); + dateTimeParts.Add(currentString); + } + } + + //Auto-complete missing date parts + if (dateTimeParts.Count < formats.Count) + { + while (dateTimeParts.Count != formats.Count) + { + dateTimeParts.Add("0"); + } + } + + //something went wrong + if (dateTimeParts.Count != formats.Count) + return string.Empty; + + for (int i = 0; i < formats.Count; i++) + { + var f = formats[i]; + if (!f.Contains("ddd") && !f.Contains("GMT")) + { + if (f.Contains("M")) + dateParts["Month"] = dateTimeParts[i]; + else if (f.Contains("d")) + dateParts["Day"] = dateTimeParts[i]; + else if (f.Contains("y")) + { + dateParts["Year"] = dateTimeParts[i] != "0" ? dateTimeParts[i] : "0000"; + + if (dateParts["Year"].Length == 2) + { + var yearDigits = int.Parse(dateParts["Year"]); + var twoDigitYearMax = cultureInfo.Calendar.TwoDigitYearMax; + var hundredDigits = (yearDigits <= twoDigitYearMax % 100) ? twoDigitYearMax / 100 : (twoDigitYearMax / 100) - 1; + + dateParts["Year"] = string.Format("{0}{1}", hundredDigits, dateParts["Year"]); + } + } + else if (f.Contains("hh") || f.Contains("HH")) + { + var hourValue = Convert.ToInt32(dateTimeParts[i]) % 24; + timeParts[0] = autoClipTimeParts ? hourValue.ToString() : dateTimeParts[i]; + } + else if (f.Contains("h") || f.Contains("H")) + { + if (autoClipTimeParts) + { + var hourValue = Convert.ToInt32(dateTimeParts[i]) % 24; + if (hourValue > 11) + { + hourValue -= 12; + forcePMDesignator = true; + } + timeParts[0] = hourValue.ToString(); + } + else + { + timeParts[0] = dateTimeParts[i]; + } + } + else if (f.Contains("m")) + { + var minuteValue = Convert.ToInt32(dateTimeParts[i]) % 60; + timeParts[1] = autoClipTimeParts ? minuteValue.ToString() : dateTimeParts[i]; + } + else if (f.Contains("s")) + { + var secondValue = Convert.ToInt32(dateTimeParts[i]) % 60; + timeParts[2] = autoClipTimeParts ? secondValue.ToString() : dateTimeParts[i]; + } + else if (f.Contains("f")) + millisecondsPart = dateTimeParts[i]; + else if (f.Contains("t")) + designator = forcePMDesignator ? "PM" : dateTimeParts[i]; + } + } + + var date = string.Join(cultureInfo.DateTimeFormat.DateSeparator, dateParts.Select(x => x.Value).ToArray()); + var time = string.Join(cultureInfo.DateTimeFormat.TimeSeparator, timeParts); + time += "." + millisecondsPart; + + return String.Format("{0} {1} {2}", date, time, designator); + } + + private static void UpdateSortableDateTimeString(ref string dateTime, ref string format, CultureInfo cultureInfo) + { + if (format == cultureInfo.DateTimeFormat.SortableDateTimePattern) + { + format = format.Replace("'", "").Replace("T", " "); + dateTime = dateTime.Replace("'", "").Replace("T", " "); + } + else if (format == cultureInfo.DateTimeFormat.UniversalSortableDateTimePattern) + { + format = format.Replace("'", "").Replace("Z", ""); + dateTime = dateTime.Replace("'", "").Replace("Z", ""); + } + } + + private static Dictionary GetDateParts(DateTime currentDate, CultureInfo cultureInfo) + { + Dictionary dateParts = new Dictionary(); + var dateTimeSeparators = new[] { ",", " ", "-", ".", "/", cultureInfo.DateTimeFormat.DateSeparator, cultureInfo.DateTimeFormat.TimeSeparator }; + var dateFormatParts = cultureInfo.DateTimeFormat.ShortDatePattern.Split(dateTimeSeparators, StringSplitOptions.RemoveEmptyEntries).ToList(); + dateFormatParts.ForEach(item => + { + string key = string.Empty; + string value = string.Empty; + + if (item.Contains("M")) + { + key = "Month"; + value = currentDate.Month.ToString(); + } + else if (item.Contains("d")) + { + key = "Day"; + value = currentDate.Day.ToString(); + } + else if (item.Contains("y")) + { + key = "Year"; + value = currentDate.Year.ToString("D4"); + } + if (!dateParts.ContainsKey(key)) + { + dateParts.Add(key, value); + } + }); + return dateParts; + } + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimeUpDown/Implementation/DateTimePart.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimeUpDown/Implementation/DateTimePart.cs new file mode 100644 index 00000000..0988e7c7 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimeUpDown/Implementation/DateTimePart.cs @@ -0,0 +1,36 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +namespace Xceed.Wpf.Toolkit +{ + public enum DateTimePart + { + Day, + DayName, + AmPmDesignator, + Millisecond, + Hour12, + Hour24, + Minute, + Month, + MonthName, + Other, + Period, + TimeZone, + Second, + Year + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimeUpDown/Implementation/DateTimeUpDown.Icon.bmp b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimeUpDown/Implementation/DateTimeUpDown.Icon.bmp new file mode 100644 index 00000000..ce76dc5b --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimeUpDown/Implementation/DateTimeUpDown.Icon.bmp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e95d8b086aa0680fa4b987fc38d9701b23c24b9d6334806e6d5a7fa0b3687373 +size 822 diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimeUpDown/Implementation/DateTimeUpDown.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimeUpDown/Implementation/DateTimeUpDown.cs new file mode 100644 index 00000000..68cbd916 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimeUpDown/Implementation/DateTimeUpDown.cs @@ -0,0 +1,994 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Globalization; +using System.Windows; +using Xceed.Wpf.Toolkit.Primitives; +using System.Windows.Controls; +using Xceed.Wpf.Toolkit.Core.Utilities; +using System.Windows.Input; + +namespace Xceed.Wpf.Toolkit +{ + public class DateTimeUpDown : DateTimeUpDownBase + { + #region Members + + private DateTime? _lastValidDate; //null + private bool _setKindInternal = false; + + #endregion + + #region Properties + + #region AutoClipTimeParts + + public static readonly DependencyProperty AutoClipTimePartsProperty = DependencyProperty.Register("AutoClipTimeParts", typeof(bool), typeof(DateTimeUpDown), new UIPropertyMetadata(false)); + public bool AutoClipTimeParts + { + get + { + return (bool)GetValue(AutoClipTimePartsProperty); + } + set + { + SetValue(AutoClipTimePartsProperty, value); + } + } + + #endregion //AutoClipTimeParts + + #region Format + + public static readonly DependencyProperty FormatProperty = DependencyProperty.Register("Format", typeof(DateTimeFormat), typeof(DateTimeUpDown), new UIPropertyMetadata(DateTimeFormat.FullDateTime, OnFormatChanged)); + public DateTimeFormat Format + { + get + { + return (DateTimeFormat)GetValue(FormatProperty); + } + set + { + SetValue(FormatProperty, value); + } + } + + private static void OnFormatChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) + { + DateTimeUpDown dateTimeUpDown = o as DateTimeUpDown; + if (dateTimeUpDown != null) + dateTimeUpDown.OnFormatChanged((DateTimeFormat)e.OldValue, (DateTimeFormat)e.NewValue); + } + + protected virtual void OnFormatChanged(DateTimeFormat oldValue, DateTimeFormat newValue) + { + FormatUpdated(); + } + + #endregion //Format + + #region FormatString + + public static readonly DependencyProperty FormatStringProperty = DependencyProperty.Register("FormatString", typeof(string), typeof(DateTimeUpDown), new UIPropertyMetadata(default(String), OnFormatStringChanged), IsFormatStringValid); + public string FormatString + { + get + { + return (string)GetValue(FormatStringProperty); + } + set + { + SetValue(FormatStringProperty, value); + } + } + + internal static bool IsFormatStringValid(object value) + { + try + { + // Test the format string if it is used. + CultureInfo.CurrentCulture.DateTimeFormat.Calendar.MinSupportedDateTime.ToString((string)value, CultureInfo.CurrentCulture); + } + catch + { + return false; + } + + return true; + } + + private static void OnFormatStringChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) + { + DateTimeUpDown dateTimeUpDown = o as DateTimeUpDown; + if (dateTimeUpDown != null) + dateTimeUpDown.OnFormatStringChanged((string)e.OldValue, (string)e.NewValue); + } + + protected virtual void OnFormatStringChanged(string oldValue, string newValue) + { + FormatUpdated(); + } + + #endregion //FormatString + + #region Kind + + public static readonly DependencyProperty KindProperty = DependencyProperty.Register("Kind", typeof(DateTimeKind), typeof(DateTimeUpDown), + new FrameworkPropertyMetadata(DateTimeKind.Unspecified, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnKindChanged)); + public DateTimeKind Kind + { + get + { + return (DateTimeKind)GetValue(KindProperty); + } + set + { + SetValue(KindProperty, value); + } + } + + private static void OnKindChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) + { + DateTimeUpDown dateTimeUpDown = o as DateTimeUpDown; + if (dateTimeUpDown != null) + dateTimeUpDown.OnKindChanged((DateTimeKind)e.OldValue, (DateTimeKind)e.NewValue); + } + + protected virtual void OnKindChanged(DateTimeKind oldValue, DateTimeKind newValue) + { + //Upate the value based on kind. (Postpone to EndInit if not yet initialized) + if (!_setKindInternal + && this.Value != null + && this.IsInitialized) + { + this.Value = this.ConvertToKind(this.Value.Value, newValue); + } + } + + private void SetKindInternal(DateTimeKind kind) + { + _setKindInternal = true; + try + { +#if VS2008 + // Warning : Binding could be lost + this.Kind = kind; +#else + //We use SetCurrentValue to not erase the possible underlying + //OneWay Binding. (This will also update correctly any + //possible TwoWay bindings). + this.SetCurrentValue(DateTimeUpDown.KindProperty, kind); +#endif + } + finally + { + _setKindInternal = false; + } + } + + #endregion //Kind + + #region ContextNow (Private) + + internal DateTime ContextNow + { + get + { + return DateTimeUtilities.GetContextNow(this.Kind); + } + } + + #endregion + + #endregion //Properties + + #region Constructors + + static DateTimeUpDown() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(DateTimeUpDown), new FrameworkPropertyMetadata(typeof(DateTimeUpDown))); + MaximumProperty.OverrideMetadata(typeof(DateTimeUpDown), new FrameworkPropertyMetadata(CultureInfo.CurrentCulture.DateTimeFormat.Calendar.MaxSupportedDateTime)); + MinimumProperty.OverrideMetadata(typeof(DateTimeUpDown), new FrameworkPropertyMetadata(CultureInfo.CurrentCulture.DateTimeFormat.Calendar.MinSupportedDateTime)); + UpdateValueOnEnterKeyProperty.OverrideMetadata(typeof(DateTimeUpDown), new FrameworkPropertyMetadata(true)); + } + + public DateTimeUpDown() + { + this.Loaded += this.DateTimeUpDown_Loaded; + } + + #endregion //Constructors + + #region Base Class Overrides + + public override bool CommitInput() + { + bool isSyncValid = this.SyncTextAndValueProperties(true, Text); + _lastValidDate = this.Value; + return isSyncValid; + } + + protected override void OnCultureInfoChanged(CultureInfo oldValue, CultureInfo newValue) + { + FormatUpdated(); + } + + protected override void OnIncrement() + { + if (this.IsCurrentValueValid()) + { + this.Increment(this.Step); + } + } + + protected override void OnDecrement() + { + if (this.IsCurrentValueValid()) + { + this.Increment(-this.Step); + } + } + + protected override void OnTextChanged(string previousValue, string currentValue) + { + if (!_processTextChanged) + return; + + base.OnTextChanged(previousValue, currentValue); + } + + protected override DateTime? ConvertTextToValue(string text) + { + if (string.IsNullOrEmpty(text)) + return null; + + DateTime result; + this.TryParseDateTime(text, out result); + + //Do not force "unspecified" to a time-zone specific + //parsed text value. This would result in a lost of precision and + //corrupt data. Let the value impose the Kind to the + //DateTimePicker. + if (this.Kind != DateTimeKind.Unspecified) + { + + //Keep the current kind (Local or Utc) + //by imposing it to the parsed text value. + // + //Note: A parsed UTC text value may be + // adjusted with a Local kind and time. + result = this.ConvertToKind(result, this.Kind); + } + + if (this.ClipValueToMinMax) + { + return this.GetClippedMinMaxValue(result); + } + + this.ValidateDefaultMinMax(result); + + return result; + } + + protected override string ConvertValueToText() + { + if (Value == null) + return string.Empty; + + return Value.Value.ToString(GetFormatString(Format), CultureInfo); + } + + protected override void SetValidSpinDirection() + { + ValidSpinDirections validDirections = ValidSpinDirections.None; + + if (!IsReadOnly) + { + if (this.IsLowerThan(this.Value, this.Maximum) || !this.Value.HasValue || !this.Maximum.HasValue) + validDirections = validDirections | ValidSpinDirections.Increase; + + if (this.IsGreaterThan(this.Value, this.Minimum) || !this.Value.HasValue || !this.Minimum.HasValue) + validDirections = validDirections | ValidSpinDirections.Decrease; + } + + if (this.Spinner != null) + this.Spinner.ValidSpinDirection = validDirections; + } + + protected override object OnCoerceValue(object newValue) + { + //Since only changing the "kind" of a date + //Ex. "2001-01-01 12:00 AM, Kind=Utc" to "2001-01-01 12:00 AM Kind=Local" + //by setting the "Value" property won't trigger a property changed, + //but will call this callback (coerce), we update the Kind here. + DateTime? value = (DateTime?)base.OnCoerceValue(newValue); + + //Let the initialized determine the final "kind" value. + if (value != null && this.IsInitialized) + { + //Update kind based on value kind + this.SetKindInternal(value.Value.Kind); + } + + return value; + } + + protected override void OnValueChanged(DateTime? oldValue, DateTime? newValue) + { + DateTimeInfo info = _selectedDateTimeInfo; + + //this only occurs when the user manually type in a value for the Value Property + if (info == null) + info = (this.CurrentDateTimePart != DateTimePart.Other) ? this.GetDateTimeInfo(this.CurrentDateTimePart) : _dateTimeInfoList[0]; + + //whenever the value changes we need to parse out the value into out DateTimeInfo segments so we can keep track of the individual pieces + //but only if it is not null + if (newValue != null) + ParseValueIntoDateTimeInfo(this.Value); + + base.OnValueChanged(oldValue, newValue); + + if (!_isTextChangedFromUI) + { + _lastValidDate = newValue; + } + + if (TextBox != null) + { + //we loose our selection when the Value is set so we need to reselect it without firing the selection changed event + _fireSelectionChangedEvent = false; + TextBox.Select(info.StartPosition, info.Length); + _fireSelectionChangedEvent = true; + } + } + + protected override bool IsCurrentValueValid() + { + DateTime result; + + if (string.IsNullOrEmpty(this.TextBox.Text)) + return true; + + return this.TryParseDateTime(this.TextBox.Text, out result); + } + + protected override void OnInitialized(EventArgs e) + { + base.OnInitialized(e); + if (this.Value != null) + { + DateTimeKind valueKind = this.Value.Value.Kind; + + if (valueKind != this.Kind) + { + //Conflit between "Kind" property and the "Value.Kind" value. + //Priority to the one that is not "Unspecified". + if (this.Kind == DateTimeKind.Unspecified) + { + this.SetKindInternal(valueKind); + } + else + { + this.Value = this.ConvertToKind(this.Value.Value, this.Kind); + } + } + } + } + + protected override void PerformMouseSelection() + { + if (this.UpdateValueOnEnterKey) + { + this.ParseValueIntoDateTimeInfo(this.ConvertTextToValue(this.TextBox.Text)); + } + base.PerformMouseSelection(); + } + + protected internal override void PerformKeyboardSelection(int nextSelectionStart) + { + if (this.UpdateValueOnEnterKey) + { + this.ParseValueIntoDateTimeInfo(this.ConvertTextToValue(this.TextBox.Text)); + } + base.PerformKeyboardSelection(nextSelectionStart); + } + + protected override void InitializeDateTimeInfoList(DateTime? value) + { + _dateTimeInfoList.Clear(); + _selectedDateTimeInfo = null; + + string format = GetFormatString(Format); + + if (string.IsNullOrEmpty(format)) + return; + + while (format.Length > 0) + { + int elementLength = GetElementLengthByFormat(format); + DateTimeInfo info = null; + + switch (format[0]) + { + case '"': + case '\'': + { + int closingQuotePosition = format.IndexOf(format[0], 1); + info = new DateTimeInfo + { + IsReadOnly = true, + Type = DateTimePart.Other, + Length = 1, + Content = format.Substring(1, Math.Max(1, closingQuotePosition - 1)) + }; + elementLength = Math.Max(1, closingQuotePosition + 1); + break; + } + case 'D': + case 'd': + { + string d = format.Substring(0, elementLength); + if (elementLength == 1) + d = "%" + d; + + if (elementLength > 2) + info = new DateTimeInfo + { + IsReadOnly = true, + Type = DateTimePart.DayName, + Length = elementLength, + Format = d + }; + else + info = new DateTimeInfo + { + IsReadOnly = false, + Type = DateTimePart.Day, + Length = elementLength, + Format = d + }; + break; + } + case 'F': + case 'f': + { + string f = format.Substring(0, elementLength); + if (elementLength == 1) + f = "%" + f; + + info = new DateTimeInfo + { + IsReadOnly = false, + Type = DateTimePart.Millisecond, + Length = elementLength, + Format = f + }; + break; + } + case 'h': + { + string h = format.Substring(0, elementLength); + if (elementLength == 1) + h = "%" + h; + + info = new DateTimeInfo + { + IsReadOnly = false, + Type = DateTimePart.Hour12, + Length = elementLength, + Format = h + }; + break; + } + case 'H': + { + string H = format.Substring(0, elementLength); + if (elementLength == 1) + H = "%" + H; + + info = new DateTimeInfo + { + IsReadOnly = false, + Type = DateTimePart.Hour24, + Length = elementLength, + Format = H + }; + break; + } + case 'M': + { + string M = format.Substring(0, elementLength); + if (elementLength == 1) + M = "%" + M; + + if (elementLength >= 3) + info = new DateTimeInfo + { + IsReadOnly = false, + Type = DateTimePart.MonthName, + Length = elementLength, + Format = M + }; + else + info = new DateTimeInfo + { + IsReadOnly = false, + Type = DateTimePart.Month, + Length = elementLength, + Format = M + }; + break; + } + case 'S': + case 's': + { + string s = format.Substring(0, elementLength); + if (elementLength == 1) + s = "%" + s; + + info = new DateTimeInfo + { + IsReadOnly = false, + Type = DateTimePart.Second, + Length = elementLength, + Format = s + }; + break; + } + case 'T': + case 't': + { + string t = format.Substring(0, elementLength); + if (elementLength == 1) + t = "%" + t; + + info = new DateTimeInfo + { + IsReadOnly = false, + Type = DateTimePart.AmPmDesignator, + Length = elementLength, + Format = t + }; + break; + } + case 'Y': + case 'y': + { + string y = format.Substring(0, elementLength); + if (elementLength == 1) + y = "%" + y; + + info = new DateTimeInfo + { + IsReadOnly = false, + Type = DateTimePart.Year, + Length = elementLength, + Format = y + }; + break; + } + case '\\': + { + if (format.Length >= 2) + { + info = new DateTimeInfo + { + IsReadOnly = true, + Content = format.Substring(1, 1), + Length = 1, + Type = DateTimePart.Other + }; + elementLength = 2; + } + break; + } + case 'g': + { + string g = format.Substring(0, elementLength); + if (elementLength == 1) + g = "%" + g; + + info = new DateTimeInfo + { + IsReadOnly = true, + Type = DateTimePart.Period, + Length = elementLength, + Format = format.Substring(0, elementLength) + }; + break; + } + case 'm': + { + string m = format.Substring(0, elementLength); + if (elementLength == 1) + m = "%" + m; + + info = new DateTimeInfo + { + IsReadOnly = false, + Type = DateTimePart.Minute, + Length = elementLength, + Format = m + }; + break; + } + case 'z': + { + string z = format.Substring(0, elementLength); + if (elementLength == 1) + z = "%" + z; + + info = new DateTimeInfo + { + IsReadOnly = true, + Type = DateTimePart.TimeZone, + Length = elementLength, + Format = z + }; + break; + } + default: + { + elementLength = 1; + info = new DateTimeInfo + { + IsReadOnly = true, + Length = 1, + Content = format[0].ToString(), + Type = DateTimePart.Other + }; + break; + } + } + + _dateTimeInfoList.Add(info); + format = format.Substring(elementLength); + } + } + + protected override bool IsLowerThan(DateTime? value1, DateTime? value2) + { + if (value1 == null || value2 == null) + return false; + + return (value1.Value < value2.Value); + } + + protected override bool IsGreaterThan(DateTime? value1, DateTime? value2) + { + if (value1 == null || value2 == null) + return false; + + return (value1.Value > value2.Value); + } + + protected override void OnUpdateValueOnEnterKeyChanged(bool oldValue, bool newValue) + { + throw new NotSupportedException("DateTimeUpDown controls do not support modifying UpdateValueOnEnterKey property."); + } + + protected override void OnKeyDown(KeyEventArgs e) + { + if (e.Key == Key.Escape) + { + this.SyncTextAndValueProperties(false, null); + e.Handled = true; + } + + base.OnKeyDown(e); + } + + + #endregion //Base Class Overrides + + #region Methods + + public void SelectAll() + { + _fireSelectionChangedEvent = false; + TextBox.SelectAll(); + _fireSelectionChangedEvent = true; + } + + private void FormatUpdated() + { + InitializeDateTimeInfoList(this.Value); + if (Value != null) + ParseValueIntoDateTimeInfo(this.Value); + + // Update the Text representation of the value. + _processTextChanged = false; + + this.SyncTextAndValueProperties(false, null); + + _processTextChanged = true; + + } + + private static int GetElementLengthByFormat(string format) + { + for (int i = 1; i < format.Length; i++) + { + if (String.Compare(format[i].ToString(), format[0].ToString(), false) != 0) + { + return i; + } + } + return format.Length; + } + + private void Increment(int step) + { + _fireSelectionChangedEvent = false; + + var currentValue = this.ConvertTextToValue(this.TextBox.Text); + if (currentValue.HasValue) + { + var newValue = this.UpdateDateTime(currentValue, step); + if (newValue == null) + return; + this.TextBox.Text = newValue.Value.ToString(this.GetFormatString(this.Format), this.CultureInfo); + } + else + { + this.TextBox.Text = (this.DefaultValue != null) + ? this.DefaultValue.Value.ToString(this.GetFormatString(this.Format), this.CultureInfo) + : this.ContextNow.ToString(this.GetFormatString(this.Format), this.CultureInfo); + } + + if (this.TextBox != null) + { + DateTimeInfo info = _selectedDateTimeInfo; + //this only occurs when the user manually type in a value for the Value Property + if (info == null) + info = (this.CurrentDateTimePart != DateTimePart.Other) ? this.GetDateTimeInfo(this.CurrentDateTimePart) : _dateTimeInfoList[0]; + + //whenever the value changes we need to parse out the value into out DateTimeInfo segments so we can keep track of the individual pieces + this.ParseValueIntoDateTimeInfo(this.ConvertTextToValue(this.TextBox.Text)); + + //we loose our selection when the Value is set so we need to reselect it without firing the selection changed event + this.TextBox.Select(info.StartPosition, info.Length); + } + _fireSelectionChangedEvent = true; + + this.SyncTextAndValueProperties(true, Text); + } + + private void ParseValueIntoDateTimeInfo(DateTime? newDate) + { + string text = string.Empty; + + _dateTimeInfoList.ForEach(info => + { + if (info.Format == null) + { + info.StartPosition = text.Length; + info.Length = info.Content.Length; + text += info.Content; + } + else if (newDate != null) + { + DateTime date = newDate.Value; + info.StartPosition = text.Length; + info.Content = date.ToString(info.Format, CultureInfo.DateTimeFormat); + info.Length = info.Content.Length; + text += info.Content; + } + }); + } + + internal string GetFormatString(DateTimeFormat dateTimeFormat) + { + switch (dateTimeFormat) + { + case DateTimeFormat.ShortDate: + return CultureInfo.DateTimeFormat.ShortDatePattern; + case DateTimeFormat.LongDate: + return CultureInfo.DateTimeFormat.LongDatePattern; + case DateTimeFormat.ShortTime: + return CultureInfo.DateTimeFormat.ShortTimePattern; + case DateTimeFormat.LongTime: + return CultureInfo.DateTimeFormat.LongTimePattern; + case DateTimeFormat.FullDateTime: + return CultureInfo.DateTimeFormat.FullDateTimePattern; + case DateTimeFormat.MonthDay: + return CultureInfo.DateTimeFormat.MonthDayPattern; + case DateTimeFormat.RFC1123: + return CultureInfo.DateTimeFormat.RFC1123Pattern; + case DateTimeFormat.SortableDateTime: + return CultureInfo.DateTimeFormat.SortableDateTimePattern; + case DateTimeFormat.UniversalSortableDateTime: + return CultureInfo.DateTimeFormat.UniversalSortableDateTimePattern; + case DateTimeFormat.YearMonth: + return CultureInfo.DateTimeFormat.YearMonthPattern; + case DateTimeFormat.Custom: + { + switch (this.FormatString) + { + case "d": + return CultureInfo.DateTimeFormat.ShortDatePattern; + case "t": + return CultureInfo.DateTimeFormat.ShortTimePattern; + case "T": + return CultureInfo.DateTimeFormat.LongTimePattern; + case "D": + return CultureInfo.DateTimeFormat.LongDatePattern; + case "f": + return CultureInfo.DateTimeFormat.LongDatePattern + " " + CultureInfo.DateTimeFormat.ShortTimePattern; + case "F": + return CultureInfo.DateTimeFormat.FullDateTimePattern; + case "g": + return CultureInfo.DateTimeFormat.ShortDatePattern + " " + CultureInfo.DateTimeFormat.ShortTimePattern; + case "G": + return CultureInfo.DateTimeFormat.ShortDatePattern + " " + CultureInfo.DateTimeFormat.LongTimePattern; + case "m": + return CultureInfo.DateTimeFormat.MonthDayPattern; + case "y": + return CultureInfo.DateTimeFormat.YearMonthPattern; + case "r": + return CultureInfo.DateTimeFormat.RFC1123Pattern; + case "s": + return CultureInfo.DateTimeFormat.SortableDateTimePattern; + case "u": + return CultureInfo.DateTimeFormat.UniversalSortableDateTimePattern; + default: + return FormatString; + } + } + default: + throw new ArgumentException("Not a supported format"); + } + } + + private DateTime? UpdateDateTime(DateTime? currentDateTime, int value) + { + DateTimeInfo info = _selectedDateTimeInfo; + + //this only occurs when the user manually type in a value for the Value Property + if (info == null) + info = (this.CurrentDateTimePart != DateTimePart.Other) ? this.GetDateTimeInfo(this.CurrentDateTimePart) : _dateTimeInfoList[0]; + + DateTime? result = null; + + try + { + switch (info.Type) + { + case DateTimePart.Year: + { + result = ((DateTime)currentDateTime).AddYears(value); + break; + } + case DateTimePart.Month: + case DateTimePart.MonthName: + { + result = ((DateTime)currentDateTime).AddMonths(value); + break; + } + case DateTimePart.Day: + case DateTimePart.DayName: + { + result = ((DateTime)currentDateTime).AddDays(value); + break; + } + case DateTimePart.Hour12: + case DateTimePart.Hour24: + { + result = ((DateTime)currentDateTime).AddHours(value); + break; + } + case DateTimePart.Minute: + { + result = ((DateTime)currentDateTime).AddMinutes(value); + break; + } + case DateTimePart.Second: + { + result = ((DateTime)currentDateTime).AddSeconds(value); + break; + } + case DateTimePart.Millisecond: + { + result = ((DateTime)currentDateTime).AddMilliseconds(value); + break; + } + case DateTimePart.AmPmDesignator: + { + result = ((DateTime)currentDateTime).AddHours(value * 12); + break; + } + default: + { + break; + } + } + } + catch + { + //this can occur if the date/time = 1/1/0001 12:00:00 AM which is the smallest date allowed. + //I could write code that would validate the date each and everytime but I think that it would be more + //efficient if I just handle the edge case and allow an exeption to occur and swallow it instead. + } + + return this.CoerceValueMinMax(result); + } + + private bool TryParseDateTime(string text, out DateTime result) + { + bool isValid = false; + result = this.ContextNow; + + DateTime current = this.ContextNow; + try + { + current = (this.Value.HasValue) + ? this.Value.Value + : DateTime.Parse(this.ContextNow.ToString(), this.CultureInfo.DateTimeFormat); + + isValid = DateTimeParser.TryParse(text, this.GetFormatString(Format), current, this.CultureInfo, this.AutoClipTimeParts, out result); + } + catch (FormatException) + { + isValid = false; + } + + if (!isValid) + { + isValid = DateTime.TryParseExact(text, this.GetFormatString(this.Format), this.CultureInfo, DateTimeStyles.None, out result); + } + + if (!isValid) + { + result = (_lastValidDate != null) ? _lastValidDate.Value : current; + } + + return isValid; + } + + private DateTime ConvertToKind(DateTime dateTime, DateTimeKind kind) + { + //Same kind, just return same value. + if (kind == dateTime.Kind) + return dateTime; + + //"ToLocalTime()" from an unspecified will assume + // That the time was originaly Utc and affect the datetime value. + // Just "Force" the "Kind" instead. + if (dateTime.Kind == DateTimeKind.Unspecified + || kind == DateTimeKind.Unspecified) + return DateTime.SpecifyKind(dateTime, kind); + + return (kind == DateTimeKind.Local) + ? dateTime.ToLocalTime() + : dateTime.ToUniversalTime(); + } + + #endregion //Methods + + #region Event Handlers + + private void DateTimeUpDown_Loaded(object sender, RoutedEventArgs e) + { + if ((this.Format == DateTimeFormat.Custom) && (string.IsNullOrEmpty(this.FormatString))) + { + throw new InvalidOperationException("A FormatString is necessary when Format is set to Custom."); + } + } + + #endregion + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimeUpDown/Themes/Aero2.NormalColor.xaml b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimeUpDown/Themes/Aero2.NormalColor.xaml new file mode 100644 index 00000000..fda5f876 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DateTimeUpDown/Themes/Aero2.NormalColor.xaml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DropDownButton/Themes/Generic.xaml b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DropDownButton/Themes/Generic.xaml new file mode 100644 index 00000000..cdd6e7e6 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/DropDownButton/Themes/Generic.xaml @@ -0,0 +1,174 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/IconButton/Implementation/IconButton.Icon.bmp b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/IconButton/Implementation/IconButton.Icon.bmp new file mode 100644 index 00000000..ce76dc5b --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/IconButton/Implementation/IconButton.Icon.bmp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e95d8b086aa0680fa4b987fc38d9701b23c24b9d6334806e6d5a7fa0b3687373 +size 822 diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/IconButton/Implementation/IconButton.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/IconButton/Implementation/IconButton.cs new file mode 100644 index 00000000..5f604c48 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/IconButton/Implementation/IconButton.cs @@ -0,0 +1,185 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System.Windows; +using System.Windows.Controls; +using System.Windows.Media; + +namespace Xceed.Wpf.Toolkit +{ + public class IconButton : Button + { + #region Constructors + + static IconButton() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(IconButton), new FrameworkPropertyMetadata(typeof(IconButton))); + } + + public IconButton() + { + } + + #endregion //Constructors + + #region Properties + + #region Icon + + public static readonly DependencyProperty IconProperty = DependencyProperty.Register("Icon", typeof(Image), typeof(IconButton), new FrameworkPropertyMetadata(null)); + public Image Icon + { + get + { + return (Image)this.GetValue(IconButton.IconProperty); + } + set + { + this.SetValue(IconButton.IconProperty, value); + } + } + + #endregion //Icon + + #region IconLocation + + public static readonly DependencyProperty IconLocationProperty = DependencyProperty.Register("IconLocation", typeof(Location), + typeof(IconButton), new FrameworkPropertyMetadata(Location.Left)); + public Location IconLocation + { + get + { + return (Location)this.GetValue(IconButton.IconLocationProperty); + } + set + { + this.SetValue(IconButton.IconLocationProperty, value); + } + } + + #endregion //IconLocation + + #region MouseOverBackground + + public static readonly DependencyProperty MouseOverBackgroundProperty = DependencyProperty.Register("MouseOverBackground", typeof(Brush), typeof(IconButton), new FrameworkPropertyMetadata(null)); + + public Brush MouseOverBackground + { + get + { + return (Brush)this.GetValue(IconButton.MouseOverBackgroundProperty); + } + set + { + this.SetValue(IconButton.MouseOverBackgroundProperty, value); + } + } + + #endregion //MouseOverBackground + + #region MouseOverBorderBrush + + public static readonly DependencyProperty MouseOverBorderBrushProperty = DependencyProperty.Register("MouseOverBorderBrush", typeof(Brush), typeof(IconButton), new FrameworkPropertyMetadata(null)); + + public Brush MouseOverBorderBrush + { + get + { + return (Brush)this.GetValue(IconButton.MouseOverBorderBrushProperty); + } + set + { + this.SetValue(IconButton.MouseOverBorderBrushProperty, value); + } + } + + #endregion //MouseOverBorderBrush + + #region MouseOverForeground + + public static readonly DependencyProperty MouseOverForegroundProperty = DependencyProperty.Register("MouseOverForeground", typeof(Brush), typeof(IconButton), new FrameworkPropertyMetadata(null)); + + public Brush MouseOverForeground + { + get + { + return (Brush)this.GetValue(IconButton.MouseOverForegroundProperty); + } + set + { + this.SetValue(IconButton.MouseOverForegroundProperty, value); + } + } + + #endregion //MouseOverForeground + + #region MousePressedBackground + + public static readonly DependencyProperty MousePressedBackgroundProperty = DependencyProperty.Register("MousePressedBackground", typeof(Brush), typeof(IconButton), new FrameworkPropertyMetadata(null)); + + public Brush MousePressedBackground + { + get + { + return (Brush)this.GetValue(IconButton.MousePressedBackgroundProperty); + } + set + { + this.SetValue(IconButton.MousePressedBackgroundProperty, value); + } + } + + #endregion //MousePressedBackground + + #region MousePressedBorderBrush + + public static readonly DependencyProperty MousePressedBorderBrushProperty = DependencyProperty.Register("MousePressedBorderBrush", typeof(Brush), typeof(IconButton), new FrameworkPropertyMetadata(null)); + + public Brush MousePressedBorderBrush + { + get + { + return (Brush)this.GetValue(IconButton.MousePressedBorderBrushProperty); + } + set + { + this.SetValue(IconButton.MousePressedBorderBrushProperty, value); + } + } + + #endregion //MousePressedBorderBrush + + #region MousePressedForeground + + public static readonly DependencyProperty MousePressedForegroundProperty = DependencyProperty.Register("MousePressedForeground", typeof(Brush), typeof(IconButton), new FrameworkPropertyMetadata(null)); + + public Brush MousePressedForeground + { + get + { + return (Brush)this.GetValue(IconButton.MousePressedForegroundProperty); + } + set + { + this.SetValue(IconButton.MousePressedForegroundProperty, value); + } + } + + #endregion //MousePressedForeground + + #endregion + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/IconButton/Themes/Aero2.NormalColor.xaml b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/IconButton/Themes/Aero2.NormalColor.xaml new file mode 100644 index 00000000..1450cbc6 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/IconButton/Themes/Aero2.NormalColor.xaml @@ -0,0 +1,166 @@ + + + + + + + + + + + + + diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/IconButton/Themes/Generic.xaml b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/IconButton/Themes/Generic.xaml new file mode 100644 index 00000000..1450cbc6 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/IconButton/Themes/Generic.xaml @@ -0,0 +1,166 @@ + + + + + + + + + + + + + diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Magnifier/Implementation/Converters/RadiusConverter.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Magnifier/Implementation/Converters/RadiusConverter.cs new file mode 100644 index 00000000..2c15a0ee --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Magnifier/Implementation/Converters/RadiusConverter.cs @@ -0,0 +1,38 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Windows.Data; + +namespace Xceed.Wpf.Toolkit.Mag.Converters +{ + public class RadiusConverter : IValueConverter + { + #region IValueConverter Members + + public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + return (double)value * 2; + } + + public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + throw new NotImplementedException(); + } + + #endregion + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Magnifier/Implementation/FrameType.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Magnifier/Implementation/FrameType.cs new file mode 100644 index 00000000..1b799699 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Magnifier/Implementation/FrameType.cs @@ -0,0 +1,24 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +namespace Xceed.Wpf.Toolkit +{ + public enum FrameType + { + Circle, + Rectangle + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Magnifier/Implementation/Magnifier.Icon.bmp b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Magnifier/Implementation/Magnifier.Icon.bmp new file mode 100644 index 00000000..ce76dc5b --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Magnifier/Implementation/Magnifier.Icon.bmp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e95d8b086aa0680fa4b987fc38d9701b23c24b9d6334806e6d5a7fa0b3687373 +size 822 diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Magnifier/Implementation/Magnifier.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Magnifier/Implementation/Magnifier.cs new file mode 100644 index 00000000..1ee09d79 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Magnifier/Implementation/Magnifier.cs @@ -0,0 +1,311 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System.Windows; +using System.Windows.Controls; +using System.Windows.Media; +using Xceed.Wpf.Toolkit.Core.Utilities; + +namespace Xceed.Wpf.Toolkit +{ + [TemplatePart(Name = PART_VisualBrush, Type = typeof(VisualBrush))] + public class Magnifier : Control + { + private const double DEFAULT_SIZE = 100d; + private const string PART_VisualBrush = "PART_VisualBrush"; + + #region Private Members + + private VisualBrush _visualBrush = new VisualBrush(); + + #endregion //Private Members + + #region Properties + + #region FrameType + + public static readonly DependencyProperty FrameTypeProperty = DependencyProperty.Register("FrameType", typeof(FrameType), typeof(Magnifier), new UIPropertyMetadata(FrameType.Circle, OnFrameTypeChanged)); + public FrameType FrameType + { + get + { + return (FrameType)GetValue(FrameTypeProperty); + } + set + { + SetValue(FrameTypeProperty, value); + } + } + + private static void OnFrameTypeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + Magnifier m = (Magnifier)d; + m.OnFrameTypeChanged((FrameType)e.OldValue, (FrameType)e.NewValue); + } + + protected virtual void OnFrameTypeChanged(FrameType oldValue, FrameType newValue) + { + this.UpdateSizeFromRadius(); + } + + #endregion //FrameType + + #region IsUsingZoomOnMouseWheel + + public static readonly DependencyProperty IsUsingZoomOnMouseWheelProperty = DependencyProperty.Register("IsUsingZoomOnMouseWheel", typeof(bool) + , typeof(Magnifier), new UIPropertyMetadata(true)); + public bool IsUsingZoomOnMouseWheel + { + get + { + return (bool)GetValue(IsUsingZoomOnMouseWheelProperty); + } + set + { + SetValue(IsUsingZoomOnMouseWheelProperty, value); + } + } + + #endregion //IsUsingZoomOnMouseWheel + + #region IsFrozen + + public bool IsFrozen + { + get; + private set; + } + + #endregion + + #region Radius + + public static readonly DependencyProperty RadiusProperty = DependencyProperty.Register("Radius", typeof(double), typeof(Magnifier), new FrameworkPropertyMetadata((Magnifier.DEFAULT_SIZE / 2), new PropertyChangedCallback(OnRadiusPropertyChanged))); + public double Radius + { + get + { + return (double)GetValue(RadiusProperty); + } + set + { + SetValue(RadiusProperty, value); + } + } + + private static void OnRadiusPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + Magnifier m = (Magnifier)d; + m.OnRadiusChanged(e); + } + + protected virtual void OnRadiusChanged(DependencyPropertyChangedEventArgs e) + { + this.UpdateSizeFromRadius(); + } + + #endregion + + #region Target + + public static readonly DependencyProperty TargetProperty = DependencyProperty.Register("Target", typeof(UIElement), typeof(Magnifier)); + public UIElement Target + { + get + { + return (UIElement)GetValue(TargetProperty); + } + set + { + SetValue(TargetProperty, value); + } + } + + #endregion //Target + + #region ViewBox + + internal Rect ViewBox + { + get + { + return _visualBrush.Viewbox; + } + set + { + _visualBrush.Viewbox = value; + } + } + + #endregion + + #region ZoomFactor + + public static readonly DependencyProperty ZoomFactorProperty = DependencyProperty.Register("ZoomFactor", typeof(double), typeof(Magnifier), new FrameworkPropertyMetadata(0.5, OnZoomFactorPropertyChanged), OnValidationCallback); + public double ZoomFactor + { + get + { + return (double)GetValue(ZoomFactorProperty); + } + set + { + SetValue(ZoomFactorProperty, value); + } + } + + private static bool OnValidationCallback(object baseValue) + { + double zoomFactor = (double)baseValue; + return (zoomFactor >= 0); + } + + private static void OnZoomFactorPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + Magnifier m = (Magnifier)d; + m.OnZoomFactorChanged(e); + } + + protected virtual void OnZoomFactorChanged(DependencyPropertyChangedEventArgs e) + { + UpdateViewBox(); + } + + #endregion //ZoomFactor + + #region ZoomFactorOnMouseWheel + + public static readonly DependencyProperty ZoomFactorOnMouseWheelProperty = DependencyProperty.Register("ZoomFactorOnMouseWheel", typeof(double) + , typeof(Magnifier), new FrameworkPropertyMetadata(0.1d, OnZoomFactorOnMouseWheelPropertyChanged), OnZoomFactorOnMouseWheelValidationCallback); + public double ZoomFactorOnMouseWheel + { + get + { + return (double)GetValue(ZoomFactorOnMouseWheelProperty); + } + set + { + SetValue(ZoomFactorOnMouseWheelProperty, value); + } + } + + private static bool OnZoomFactorOnMouseWheelValidationCallback(object baseValue) + { + double zoomFactorOnMouseWheel = (double)baseValue; + return (zoomFactorOnMouseWheel >= 0); + } + + private static void OnZoomFactorOnMouseWheelPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + Magnifier m = (Magnifier)d; + m.OnZoomFactorOnMouseWheelChanged(e); + } + + protected virtual void OnZoomFactorOnMouseWheelChanged(DependencyPropertyChangedEventArgs e) + { + } + + #endregion //ZoomFactorOnMouseWheel + + #endregion //Properties + + #region Constructors + + /// + /// Initializes static members of the class. + /// + static Magnifier() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(Magnifier), new FrameworkPropertyMetadata(typeof(Magnifier))); + HeightProperty.OverrideMetadata(typeof(Magnifier), new FrameworkPropertyMetadata(Magnifier.DEFAULT_SIZE)); + WidthProperty.OverrideMetadata(typeof(Magnifier), new FrameworkPropertyMetadata(Magnifier.DEFAULT_SIZE)); + } + + public Magnifier() + { + this.SizeChanged += new SizeChangedEventHandler(OnSizeChangedEvent); + } + + private void OnSizeChangedEvent(object sender, SizeChangedEventArgs e) + { + UpdateViewBox(); + } + + private void UpdateSizeFromRadius() + { + if (this.FrameType == Toolkit.FrameType.Circle) + { + double newSize = Radius * 2; + if (!DoubleHelper.AreVirtuallyEqual(Width, newSize)) + { + Width = newSize; + } + + if (!DoubleHelper.AreVirtuallyEqual(Height, newSize)) + { + Height = newSize; + } + } + } + + #endregion + + #region Base Class Overrides + + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + VisualBrush newBrush = GetTemplateChild(PART_VisualBrush) as VisualBrush; + + // Just create a brush as placeholder even if there is no such brush. + // This avoids having to "if" each access to the _visualBrush member. + // Do not keep the current _visualBrush whatsoever to avoid memory leaks. + if (newBrush == null) + { + newBrush = new VisualBrush(); + } + + newBrush.Viewbox = _visualBrush.Viewbox; + _visualBrush = newBrush; + } + + #endregion // Base Class Overrides + + #region Public Methods + + public void Freeze(bool freeze) + { + this.IsFrozen = freeze; + } + + #endregion + + #region Private Methods + + private void UpdateViewBox() + { + if (!IsInitialized) + return; + + ViewBox = new Rect( + ViewBox.Location, + new Size(ActualWidth * ZoomFactor, ActualHeight * ZoomFactor)); + } + + #endregion //Methods + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Magnifier/Implementation/MagnifierAdorner.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Magnifier/Implementation/MagnifierAdorner.cs new file mode 100644 index 00000000..65030594 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Magnifier/Implementation/MagnifierAdorner.cs @@ -0,0 +1,129 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System.Windows; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; + +namespace Xceed.Wpf.Toolkit +{ + public class MagnifierAdorner : Adorner + { + #region Members + + private Magnifier _magnifier; + private Point _currentMousePosition; + private double _currentZoomFactor; + + #endregion + + #region Constructors + + public MagnifierAdorner(UIElement element, Magnifier magnifier) + : base(element) + { + _magnifier = magnifier; + _currentZoomFactor = _magnifier.ZoomFactor; + UpdateViewBox(); + AddVisualChild(_magnifier); + + Loaded += (s, e) => InputManager.Current.PostProcessInput += OnProcessInput; + Unloaded += (s, e) => InputManager.Current.PostProcessInput -= OnProcessInput; + } + + + #endregion + + #region Private/Internal methods + + private void OnProcessInput(object sender, ProcessInputEventArgs e) + { + Point pt = Mouse.GetPosition(this); + + if ((_currentMousePosition == pt) && (_magnifier.ZoomFactor == _currentZoomFactor)) + return; + + if (_magnifier.IsFrozen) + return; + + _currentMousePosition = pt; + _currentZoomFactor = _magnifier.ZoomFactor; + UpdateViewBox(); + InvalidateArrange(); + } + + internal void UpdateViewBox() + { + var viewBoxLocation = CalculateViewBoxLocation(); + _magnifier.ViewBox = new Rect(viewBoxLocation, _magnifier.ViewBox.Size); + } + + private Point CalculateViewBoxLocation() + { + double offsetX = 0, offsetY = 0; + + Point adorner = Mouse.GetPosition(this); + Point element = Mouse.GetPosition(AdornedElement); + + offsetX = element.X - adorner.X; + offsetY = element.Y - adorner.Y; + + //An element will use the offset from its parent (StackPanel, Grid, etc.) to be rendered. + //When this element is put in a VisualBrush, the element will draw with that offset applied. + //To fix this: we add that parent offset to Magnifier location. + Vector parentOffsetVector = VisualTreeHelper.GetOffset(_magnifier.Target); + Point parentOffset = new Point(parentOffsetVector.X, parentOffsetVector.Y); + + double left = _currentMousePosition.X - ((_magnifier.ViewBox.Width / 2) + offsetX) + parentOffset.X; + double top = _currentMousePosition.Y - ((_magnifier.ViewBox.Height / 2) + offsetY) + parentOffset.Y; + return new Point(left, top); + } + + #endregion + + #region Overrides + + protected override Visual GetVisualChild(int index) + { + return _magnifier; + } + + protected override int VisualChildrenCount + { + get + { + return 1; + } + } + + protected override Size MeasureOverride(Size constraint) + { + _magnifier.Measure(constraint); + return base.MeasureOverride(constraint); + } + + protected override Size ArrangeOverride(Size finalSize) + { + double x = _currentMousePosition.X - (_magnifier.Width / 2); + double y = _currentMousePosition.Y - (_magnifier.Height / 2); + _magnifier.Arrange(new Rect(x, y, _magnifier.Width, _magnifier.Height)); + return base.ArrangeOverride(finalSize); + } + + #endregion + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Magnifier/Implementation/MagnifierManager.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Magnifier/Implementation/MagnifierManager.cs new file mode 100644 index 00000000..e53e1984 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Magnifier/Implementation/MagnifierManager.cs @@ -0,0 +1,146 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Windows; +using System.Windows.Documents; +using System.Windows.Input; + +namespace Xceed.Wpf.Toolkit +{ + public class MagnifierManager : DependencyObject + { + #region Members + + private MagnifierAdorner _adorner; + private UIElement _element; + + #endregion //Members + + #region Properties + + public static readonly DependencyProperty CurrentProperty = DependencyProperty.RegisterAttached("Magnifier", typeof(Magnifier), typeof(UIElement), new FrameworkPropertyMetadata(null, OnMagnifierChanged)); + public static void SetMagnifier(UIElement element, Magnifier value) + { + element.SetValue(CurrentProperty, value); + } + public static Magnifier GetMagnifier(UIElement element) + { + return (Magnifier)element.GetValue(CurrentProperty); + } + + private static void OnMagnifierChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + UIElement target = d as UIElement; + + if (target == null) + throw new ArgumentException("Magnifier can only be attached to a UIElement."); + + MagnifierManager manager = new MagnifierManager(); + manager.AttachToMagnifier(target, e.NewValue as Magnifier); + } + + #endregion //Properties + + #region Event Handlers + + private void Element_MouseLeave(object sender, MouseEventArgs e) + { + var magnifier = MagnifierManager.GetMagnifier(_element) as Magnifier; + if ((magnifier != null) && magnifier.IsFrozen) + return; + + HideAdorner(); + } + + private void Element_MouseEnter(object sender, MouseEventArgs e) + { + ShowAdorner(); + } + + private void Element_MouseWheel(object sender, MouseWheelEventArgs e) + { + var magnifier = MagnifierManager.GetMagnifier(_element) as Magnifier; + if ((magnifier != null) && magnifier.IsUsingZoomOnMouseWheel) + { + if (e.Delta < 0) + { + var newValue = magnifier.ZoomFactor + magnifier.ZoomFactorOnMouseWheel; +#if VS2008 + magnifier.ZoomFactor = newValue; +#else + magnifier.SetCurrentValue(Magnifier.ZoomFactorProperty, newValue); +#endif + } + else if (e.Delta > 0) + { + var newValue = (magnifier.ZoomFactor >= magnifier.ZoomFactorOnMouseWheel) ? magnifier.ZoomFactor - magnifier.ZoomFactorOnMouseWheel : 0d; +#if VS2008 + magnifier.ZoomFactor = newValue; +#else + magnifier.SetCurrentValue(Magnifier.ZoomFactorProperty, newValue); +#endif + } + _adorner.UpdateViewBox(); + } + } + + #endregion //Event Handlers + + #region Methods + + private void AttachToMagnifier(UIElement element, Magnifier magnifier) + { + _element = element; + _element.MouseEnter += this.Element_MouseEnter; + _element.MouseLeave += this.Element_MouseLeave; + _element.MouseWheel += this.Element_MouseWheel; + + magnifier.Target = _element; + + _adorner = new MagnifierAdorner(_element, magnifier); + } + + void ShowAdorner() + { + VerifyAdornerLayer(); + _adorner.Visibility = Visibility.Visible; + } + + bool VerifyAdornerLayer() + { + if (_adorner.Parent != null) + return true; + + AdornerLayer layer = AdornerLayer.GetAdornerLayer(_element); + if (layer == null) + return false; + + layer.Add(_adorner); + return true; + } + + void HideAdorner() + { + if (_adorner.Visibility == Visibility.Visible) + { + _adorner.Visibility = Visibility.Collapsed; + } + } + + #endregion //Methods + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Magnifier/Themes/Generic.xaml b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Magnifier/Themes/Generic.xaml new file mode 100644 index 00000000..4acf5b9d --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/Magnifier/Themes/Generic.xaml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MaskedTextBox/Implementation/AutoCompletingMaskEventArgs.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MaskedTextBox/Implementation/AutoCompletingMaskEventArgs.cs new file mode 100644 index 00000000..027e18f6 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MaskedTextBox/Implementation/AutoCompletingMaskEventArgs.cs @@ -0,0 +1,105 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Text; +using System.ComponentModel; + +namespace Xceed.Wpf.Toolkit +{ + public class AutoCompletingMaskEventArgs : CancelEventArgs + { + public AutoCompletingMaskEventArgs(MaskedTextProvider maskedTextProvider, int startPosition, int selectionLength, string input) + { + m_autoCompleteStartPosition = -1; + + m_maskedTextProvider = maskedTextProvider; + m_startPosition = startPosition; + m_selectionLength = selectionLength; + m_input = input; + } + + #region MaskedTextProvider PROPERTY + + private MaskedTextProvider m_maskedTextProvider; + + public MaskedTextProvider MaskedTextProvider + { + get { return m_maskedTextProvider; } + } + + #endregion MaskedTextProvider PROPERTY + + #region StartPosition PROPERTY + + private int m_startPosition; + + public int StartPosition + { + get { return m_startPosition; } + } + + #endregion StartPosition PROPERTY + + #region SelectionLength PROPERTY + + private int m_selectionLength; + + public int SelectionLength + { + get { return m_selectionLength; } + } + + #endregion SelectionLength PROPERTY + + #region Input PROPERTY + + private string m_input; + + public string Input + { + get { return m_input; } + } + + #endregion Input PROPERTY + + + #region AutoCompleteStartPosition PROPERTY + + private int m_autoCompleteStartPosition; + + public int AutoCompleteStartPosition + { + get { return m_autoCompleteStartPosition; } + set { m_autoCompleteStartPosition = value; } + } + + #endregion AutoCompleteStartPosition PROPERTY + + #region AutoCompleteText PROPERTY + + private string m_autoCompleteText; + + public string AutoCompleteText + { + get { return m_autoCompleteText; } + set { m_autoCompleteText = value; } + } + + #endregion AutoCompleteText PROPERTY + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MaskedTextBox/Implementation/InsertKeyModeEnum.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MaskedTextBox/Implementation/InsertKeyModeEnum.cs new file mode 100644 index 00000000..e4f2daa3 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MaskedTextBox/Implementation/InsertKeyModeEnum.cs @@ -0,0 +1,29 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Xceed.Wpf.Toolkit +{ + public enum InsertKeyMode + { + Default = 0, + Insert = 1, + Overwrite = 2 + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MaskedTextBox/Implementation/MaskFormatEnum.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MaskedTextBox/Implementation/MaskFormatEnum.cs new file mode 100644 index 00000000..fcc5baac --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MaskedTextBox/Implementation/MaskFormatEnum.cs @@ -0,0 +1,30 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Xceed.Wpf.Toolkit +{ + public enum MaskFormat + { + ExcludePromptAndLiterals, + IncludeLiterals, + IncludePrompt, + IncludePromptAndLiterals + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MaskedTextBox/Implementation/MaskedTextBox.Icon.bmp b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MaskedTextBox/Implementation/MaskedTextBox.Icon.bmp new file mode 100644 index 00000000..ce76dc5b --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MaskedTextBox/Implementation/MaskedTextBox.Icon.bmp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e95d8b086aa0680fa4b987fc38d9701b23c24b9d6334806e6d5a7fa0b3687373 +size 822 diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MaskedTextBox/Implementation/MaskedTextBox.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MaskedTextBox/Implementation/MaskedTextBox.cs new file mode 100644 index 00000000..70c60784 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MaskedTextBox/Implementation/MaskedTextBox.cs @@ -0,0 +1,1955 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Controls; +using System.Windows; +using System.Windows.Data; +using System.Collections.Specialized; +using System.ComponentModel; +using System.Windows.Input; +using System.Diagnostics; +using System.Windows.Documents; +using System.Globalization; +using System.Windows.Controls.Primitives; +using System.Reflection; + +using System.Collections; +using System.Security; +using System.Security.Permissions; +using System.Windows.Automation; +using Xceed.Wpf.Toolkit.Primitives; + +namespace Xceed.Wpf.Toolkit +{ + public class MaskedTextBox : ValueRangeTextBox + { + #region STATIC MEMBERS + + private static readonly char[] MaskChars = { '0', '9', '#', 'L', '?', '&', 'C', 'A', 'a', '.', ',', ':', '/', '$', '<', '>', '|', '\\' }; + + private static char DefaultPasswordChar = '\0'; + + private static string NullMaskString = "<>"; + + private static string GetRawText(MaskedTextProvider provider) + { + return provider.ToString(true, false, false, 0, provider.Length); + } + + public static string GetFormatSpecifierFromMask(string mask, IFormatProvider formatProvider) + { + List notUsed; + + return MaskedTextBox.GetFormatSpecifierFromMask( + mask, + MaskedTextBox.MaskChars, + formatProvider, + true, + out notUsed); + } + + private static string GetFormatSpecifierFromMask( + string mask, + char[] maskChars, + IFormatProvider formatProvider, + bool includeNonSeparatorLiteralsInValue, + out List unhandledLiteralsPositions) + { + unhandledLiteralsPositions = new List(); + + NumberFormatInfo numberFormatInfo = NumberFormatInfo.GetInstance(formatProvider); + + StringBuilder formatSpecifierBuilder = new StringBuilder(32); + + // Space will be considered as a separator literals and will be included + // no matter the value of IncludeNonSeparatorLiteralsInValue. + bool lastCharIsLiteralIdentifier = false; + int i = 0; + int j = 0; + + while (i < mask.Length) + { + char currentChar = mask[i]; + + if ((currentChar == '\\') && (!lastCharIsLiteralIdentifier)) + { + lastCharIsLiteralIdentifier = true; + } + else + { + if ((lastCharIsLiteralIdentifier) || (Array.IndexOf(maskChars, currentChar) < 0)) + { + lastCharIsLiteralIdentifier = false; + + // The currentChar was preceeded by a liteal identifier or is not part of the MaskedTextProvider mask chars. + formatSpecifierBuilder.Append('\\'); + formatSpecifierBuilder.Append(currentChar); + + if ((!includeNonSeparatorLiteralsInValue) && (currentChar != ' ')) + unhandledLiteralsPositions.Add(j); + + j++; + } + else + { + // The currentChar is part of the MaskedTextProvider mask chars. + if ((currentChar == '0') || (currentChar == '9') || (currentChar == '#')) + { + formatSpecifierBuilder.Append('0'); + j++; + } + else if (currentChar == '.') + { + formatSpecifierBuilder.Append('.'); + j += numberFormatInfo.NumberDecimalSeparator.Length; + } + else if (currentChar == ',') + { + formatSpecifierBuilder.Append(','); + j += numberFormatInfo.NumberGroupSeparator.Length; + } + else if (currentChar == '$') + { + string currencySymbol = numberFormatInfo.CurrencySymbol; + + formatSpecifierBuilder.Append('"'); + formatSpecifierBuilder.Append(currencySymbol); + formatSpecifierBuilder.Append('"'); + + for (int k = 0; k < currencySymbol.Length; k++) + { + if (!includeNonSeparatorLiteralsInValue) + unhandledLiteralsPositions.Add(j); + + j++; + } + } + else + { + formatSpecifierBuilder.Append(currentChar); + + if ((!includeNonSeparatorLiteralsInValue) && (currentChar != ' ')) + unhandledLiteralsPositions.Add(j); + + j++; + } + } + } + + i++; + } + + return formatSpecifierBuilder.ToString(); + } + + #endregion STATIC MEMBERS + + #region CONSTRUCTORS + + static MaskedTextBox() + { + MaskedTextBox.TextProperty.OverrideMetadata(typeof(MaskedTextBox), + new FrameworkPropertyMetadata( + null, + new CoerceValueCallback(MaskedTextBox.TextCoerceValueCallback))); + } + + public MaskedTextBox() + { + CommandManager.AddPreviewCanExecuteHandler(this, new CanExecuteRoutedEventHandler(this.OnPreviewCanExecuteCommands)); + CommandManager.AddPreviewExecutedHandler(this, new ExecutedRoutedEventHandler(this.OnPreviewExecutedCommands)); + + this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Paste, null, new CanExecuteRoutedEventHandler(this.CanExecutePaste))); + this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Cut, null, new CanExecuteRoutedEventHandler(this.CanExecuteCut))); + this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Copy, null, new CanExecuteRoutedEventHandler(this.CanExecuteCopy))); + this.CommandBindings.Add(new CommandBinding(EditingCommands.ToggleInsert, new ExecutedRoutedEventHandler(this.ToggleInsertExecutedCallback))); + + this.CommandBindings.Add(new CommandBinding(EditingCommands.Delete, null, new CanExecuteRoutedEventHandler(this.CanExecuteDelete))); + this.CommandBindings.Add(new CommandBinding(EditingCommands.DeletePreviousWord, null, new CanExecuteRoutedEventHandler(this.CanExecuteDeletePreviousWord))); + this.CommandBindings.Add(new CommandBinding(EditingCommands.DeleteNextWord, null, new CanExecuteRoutedEventHandler(this.CanExecuteDeleteNextWord))); + + this.CommandBindings.Add(new CommandBinding(EditingCommands.Backspace, null, new CanExecuteRoutedEventHandler(this.CanExecuteBackspace))); + + System.Windows.DragDrop.AddPreviewQueryContinueDragHandler(this, new QueryContinueDragEventHandler(this.PreviewQueryContinueDragCallback)); + this.AllowDrop = false; + } + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1820:TestForEmptyStringsUsingStringLength")] + private void InitializeMaskedTextProvider() + { + string preInitializedText = this.Text; + + string mask = this.Mask; + + if (mask == string.Empty) + { + m_maskedTextProvider = this.CreateMaskedTextProvider(MaskedTextBox.NullMaskString); + m_maskIsNull = true; + } + else + { + m_maskedTextProvider = this.CreateMaskedTextProvider(mask); + m_maskIsNull = false; + } + + if ((!m_maskIsNull) && (preInitializedText != string.Empty)) + { + bool success = m_maskedTextProvider.Add(preInitializedText); + + if ((!success) && (!DesignerProperties.GetIsInDesignMode(this))) + throw new InvalidOperationException("An attempt was made to apply a new mask that cannot be applied to the current text."); + } + } + + #endregion CONSTRUCTORS + + #region ISupportInitialize + + protected override void OnInitialized(EventArgs e) + { + this.InitializeMaskedTextProvider(); + + this.SetIsMaskCompleted(m_maskedTextProvider.MaskCompleted); + this.SetIsMaskFull(m_maskedTextProvider.MaskFull); + + base.OnInitialized(e); + } + + #endregion ISupportInitialize + + #region AllowPromptAsInput Property + + public static readonly DependencyProperty AllowPromptAsInputProperty = + DependencyProperty.Register("AllowPromptAsInput", typeof(bool), typeof(MaskedTextBox), + new UIPropertyMetadata( + true, + new PropertyChangedCallback(MaskedTextBox.AllowPromptAsInputPropertyChangedCallback))); + + public bool AllowPromptAsInput + { + get + { + return (bool)GetValue(AllowPromptAsInputProperty); + } + set + { + SetValue(AllowPromptAsInputProperty, value); + } + } + + private static void AllowPromptAsInputPropertyChangedCallback(object sender, DependencyPropertyChangedEventArgs e) + { + MaskedTextBox maskedTextBox = sender as MaskedTextBox; + + if (!maskedTextBox.IsInitialized) + return; + + if (maskedTextBox.m_maskIsNull) + return; + + maskedTextBox.m_maskedTextProvider = maskedTextBox.CreateMaskedTextProvider(maskedTextBox.Mask); + } + + #endregion AllowPromptAsInput Property + + #region ClipboardMaskFormat Property + + public MaskFormat ClipboardMaskFormat + { + get + { + return (MaskFormat)GetValue(ClipboardMaskFormatProperty); + } + set + { + SetValue(ClipboardMaskFormatProperty, value); + } + } + + public static readonly DependencyProperty ClipboardMaskFormatProperty = + DependencyProperty.Register("ClipboardMaskFormat", typeof(MaskFormat), typeof(MaskedTextBox), + new UIPropertyMetadata(MaskFormat.IncludeLiterals)); + + #endregion ClipboardMaskFormat Property + + #region HidePromptOnLeave Property + + public bool HidePromptOnLeave + { + get + { + return (bool)GetValue(HidePromptOnLeaveProperty); + } + set + { + SetValue(HidePromptOnLeaveProperty, value); + } + } + + public static readonly DependencyProperty HidePromptOnLeaveProperty = + DependencyProperty.Register("HidePromptOnLeave", typeof(bool), typeof(MaskedTextBox), new UIPropertyMetadata(false)); + + #endregion HidePromptOnLeave Property + + #region IncludeLiteralsInValue Property + + public bool IncludeLiteralsInValue + { + get + { + return (bool)GetValue(IncludeLiteralsInValueProperty); + } + set + { + SetValue(IncludeLiteralsInValueProperty, value); + } + } + + public static readonly DependencyProperty IncludeLiteralsInValueProperty = + DependencyProperty.Register("IncludeLiteralsInValue", typeof(bool), typeof(MaskedTextBox), + new UIPropertyMetadata( + true, + new PropertyChangedCallback(MaskedTextBox.InlcudeLiteralsInValuePropertyChangedCallback))); + + private static void InlcudeLiteralsInValuePropertyChangedCallback(object sender, DependencyPropertyChangedEventArgs e) + { + MaskedTextBox maskedTextBox = sender as MaskedTextBox; + + if (!maskedTextBox.IsInitialized) + return; + + maskedTextBox.RefreshConversionHelpers(); + maskedTextBox.RefreshValue(); + } + + #endregion IncludeLiteralsInValue Property + + #region IncludePromptInValue Property + + public bool IncludePromptInValue + { + get + { + return (bool)GetValue(IncludePromptInValueProperty); + } + set + { + SetValue(IncludePromptInValueProperty, value); + } + } + + public static readonly DependencyProperty IncludePromptInValueProperty = + DependencyProperty.Register("IncludePromptInValue", typeof(bool), typeof(MaskedTextBox), + new UIPropertyMetadata( + false, + new PropertyChangedCallback(MaskedTextBox.IncludePromptInValuePropertyChangedCallback))); + + private static void IncludePromptInValuePropertyChangedCallback(object sender, DependencyPropertyChangedEventArgs e) + { + MaskedTextBox maskedTextBox = sender as MaskedTextBox; + + if (!maskedTextBox.IsInitialized) + return; + + maskedTextBox.RefreshValue(); + } + + #endregion IncludePromptInValue Property + + #region InsertKeyMode Property + + public InsertKeyMode InsertKeyMode + { + get + { + return (InsertKeyMode)GetValue(InsertKeyModeProperty); + } + set + { + SetValue(InsertKeyModeProperty, value); + } + } + + public static readonly DependencyProperty InsertKeyModeProperty = + DependencyProperty.Register("InsertKeyMode", typeof(InsertKeyMode), typeof(MaskedTextBox), new UIPropertyMetadata(InsertKeyMode.Default)); + + #endregion InsertKeyMode Property + + #region IsMaskCompleted Read-Only Property + + private static readonly DependencyPropertyKey IsMaskCompletedPropertyKey = + DependencyProperty.RegisterReadOnly("IsMaskCompleted", typeof(bool), typeof(MaskedTextBox), new PropertyMetadata(false)); + + public static readonly DependencyProperty IsMaskCompletedProperty = MaskedTextBox.IsMaskCompletedPropertyKey.DependencyProperty; + + + public bool IsMaskCompleted + { + get + { + return (bool)this.GetValue(MaskedTextBox.IsMaskCompletedProperty); + } + } + + private void SetIsMaskCompleted(bool value) + { + this.SetValue(MaskedTextBox.IsMaskCompletedPropertyKey, value); + } + + #endregion IsMaskCompleted Read-Only Property + + #region IsMaskFull Read-Only Property + + private static readonly DependencyPropertyKey IsMaskFullPropertyKey = + DependencyProperty.RegisterReadOnly("IsMaskFull", typeof(bool), typeof(MaskedTextBox), new PropertyMetadata(false)); + + public static readonly DependencyProperty IsMaskFullProperty = MaskedTextBox.IsMaskFullPropertyKey.DependencyProperty; + + public bool IsMaskFull + { + get + { + return (bool)this.GetValue(MaskedTextBox.IsMaskFullProperty); + } + } + + private void SetIsMaskFull(bool value) + { + this.SetValue(MaskedTextBox.IsMaskFullPropertyKey, value); + } + + #endregion IsMaskFull Read-Only Property + + #region Mask Property + + public static readonly DependencyProperty MaskProperty = + DependencyProperty.Register("Mask", typeof(string), typeof(MaskedTextBox), + new UIPropertyMetadata( + string.Empty, + new PropertyChangedCallback(MaskedTextBox.MaskPropertyChangedCallback), + new CoerceValueCallback(MaskedTextBox.MaskCoerceValueCallback))); + + public string Mask + { + get + { + return (string)this.GetValue(MaskedTextBox.MaskProperty); + } + set + { + this.SetValue(MaskedTextBox.MaskProperty, value); + } + } + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")] + private static object MaskCoerceValueCallback(DependencyObject sender, object value) + { + if (value == null) + value = string.Empty; + + if (value.Equals(string.Empty)) + return value; + + // Validate the text against the would be new Mask. + + MaskedTextBox maskedTextBox = sender as MaskedTextBox; + + if (!maskedTextBox.IsInitialized) + return value; + + bool valid; + + try + { + MaskedTextProvider provider = maskedTextBox.CreateMaskedTextProvider((string)value); + + string rawText = MaskedTextBox.GetRawText(maskedTextBox.m_maskedTextProvider); + + valid = provider.VerifyString(rawText); + } + catch (Exception exception) + { + throw new InvalidOperationException("An error occured while testing the current text against the new mask.", exception); + } + + if (!valid) + throw new ArgumentException("The mask cannot be applied to the current text.", "Mask"); + + return value; + } + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1820:TestForEmptyStringsUsingStringLength")] + private static void MaskPropertyChangedCallback(DependencyObject sender, DependencyPropertyChangedEventArgs e) + { + MaskedTextBox maskedTextBox = sender as MaskedTextBox; + + if (!maskedTextBox.IsInitialized) + return; + + MaskedTextProvider provider = null; + + string mask = (string)e.NewValue; + + if (mask == string.Empty) + { + provider = maskedTextBox.CreateMaskedTextProvider(MaskedTextBox.NullMaskString); + maskedTextBox.m_maskIsNull = true; + maskedTextBox.Text = ""; + } + else + { + provider = maskedTextBox.CreateMaskedTextProvider(mask); + maskedTextBox.m_maskIsNull = false; + } + + maskedTextBox.m_maskedTextProvider = provider; + + maskedTextBox.RefreshConversionHelpers(); + + if (maskedTextBox.ValueDataType != null) + { + string textFromValue = maskedTextBox.GetTextFromValue(maskedTextBox.Value); + maskedTextBox.m_maskedTextProvider.Set(textFromValue); + } + + maskedTextBox.RefreshCurrentText(true); + } + + #endregion Mask Property + + #region MaskedTextProvider Property + + public MaskedTextProvider MaskedTextProvider + { + get + { + if (!m_maskIsNull) + return m_maskedTextProvider.Clone() as MaskedTextProvider; + + return null; + } + } + + #endregion MaskedTextProvider Property + + #region PromptChar Property + + public static readonly DependencyProperty PromptCharProperty = + DependencyProperty.Register("PromptChar", typeof(char), typeof(MaskedTextBox), + new UIPropertyMetadata( + '_', + new PropertyChangedCallback(MaskedTextBox.PromptCharPropertyChangedCallback), + new CoerceValueCallback(MaskedTextBox.PromptCharCoerceValueCallback))); + + public char PromptChar + { + get + { + return (char)this.GetValue(MaskedTextBox.PromptCharProperty); + } + set + { + this.SetValue(MaskedTextBox.PromptCharProperty, value); + } + } + + private static object PromptCharCoerceValueCallback(object sender, object value) + { + MaskedTextBox maskedTextBox = sender as MaskedTextBox; + + if (!maskedTextBox.IsInitialized) + return value; + + MaskedTextProvider provider = maskedTextBox.m_maskedTextProvider.Clone() as MaskedTextProvider; + + try + { + provider.PromptChar = (char)value; + } + catch (Exception exception) + { + throw new ArgumentException("The prompt character is invalid.", exception); + } + + return value; + } + + private static void PromptCharPropertyChangedCallback(object sender, DependencyPropertyChangedEventArgs e) + { + MaskedTextBox maskedTextBox = sender as MaskedTextBox; + + if (!maskedTextBox.IsInitialized) + return; + + if (maskedTextBox.m_maskIsNull) + return; + + maskedTextBox.m_maskedTextProvider.PromptChar = (char)e.NewValue; + + maskedTextBox.RefreshCurrentText(true); + } + + #endregion PromptChar Property + + #region RejectInputOnFirstFailure Property + + public bool RejectInputOnFirstFailure + { + get + { + return (bool)GetValue(RejectInputOnFirstFailureProperty); + } + set + { + SetValue(RejectInputOnFirstFailureProperty, value); + } + } + + public static readonly DependencyProperty RejectInputOnFirstFailureProperty = + DependencyProperty.Register("RejectInputOnFirstFailure", typeof(bool), typeof(MaskedTextBox), new UIPropertyMetadata(true)); + + #endregion RejectInputOnFirstFailure Property + + #region ResetOnPrompt Property + + public bool ResetOnPrompt + { + get + { + return (bool)GetValue(ResetOnPromptProperty); + } + set + { + SetValue(ResetOnPromptProperty, value); + } + } + + public static readonly DependencyProperty ResetOnPromptProperty = + DependencyProperty.Register("ResetOnPrompt", typeof(bool), typeof(MaskedTextBox), + new UIPropertyMetadata( + true, + new PropertyChangedCallback(MaskedTextBox.ResetOnPromptPropertyChangedCallback))); + + private static void ResetOnPromptPropertyChangedCallback(object sender, DependencyPropertyChangedEventArgs e) + { + MaskedTextBox maskedTextBox = sender as MaskedTextBox; + + if (!maskedTextBox.IsInitialized) + return; + + if (maskedTextBox.m_maskIsNull) + return; + + maskedTextBox.m_maskedTextProvider.ResetOnPrompt = (bool)e.NewValue; + } + + #endregion ResetOnPrompt Property + + #region ResetOnSpace Property + + public bool ResetOnSpace + { + get + { + return (bool)GetValue(ResetOnSpaceProperty); + } + set + { + SetValue(ResetOnSpaceProperty, value); + } + } + + public static readonly DependencyProperty ResetOnSpaceProperty = + DependencyProperty.Register("ResetOnSpace", typeof(bool), typeof(MaskedTextBox), + new UIPropertyMetadata( + true, + new PropertyChangedCallback(MaskedTextBox.ResetOnSpacePropertyChangedCallback))); + + private static void ResetOnSpacePropertyChangedCallback(object sender, DependencyPropertyChangedEventArgs e) + { + MaskedTextBox maskedTextBox = sender as MaskedTextBox; + + if (!maskedTextBox.IsInitialized) + return; + + if (maskedTextBox.m_maskIsNull) + return; + + maskedTextBox.m_maskedTextProvider.ResetOnSpace = (bool)e.NewValue; + } + + #endregion ResetOnSpace Property + + #region RestrictToAscii Property + + public bool RestrictToAscii + { + get + { + return (bool)GetValue(RestrictToAsciiProperty); + } + set + { + SetValue(RestrictToAsciiProperty, value); + } + } + + public static readonly DependencyProperty RestrictToAsciiProperty = + DependencyProperty.Register("RestrictToAscii", typeof(bool), typeof(MaskedTextBox), + new UIPropertyMetadata( + false, + new PropertyChangedCallback(MaskedTextBox.RestrictToAsciiPropertyChangedCallback), + new CoerceValueCallback(MaskedTextBox.RestrictToAsciiCoerceValueCallback))); + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")] + private static object RestrictToAsciiCoerceValueCallback(object sender, object value) + { + MaskedTextBox maskedTextBox = sender as MaskedTextBox; + + if (!maskedTextBox.IsInitialized) + return value; + + if (maskedTextBox.m_maskIsNull) + return value; + + bool restrictToAscii = (bool)value; + + if (!restrictToAscii) + return value; + + // Validate the text to make sure that it is only made of Ascii characters. + + MaskedTextProvider provider = maskedTextBox.CreateMaskedTextProvider( + maskedTextBox.Mask, + maskedTextBox.GetCultureInfo(), + maskedTextBox.AllowPromptAsInput, + maskedTextBox.PromptChar, + MaskedTextBox.DefaultPasswordChar, + restrictToAscii); + + if (!provider.VerifyString(maskedTextBox.Text)) + throw new ArgumentException("The current text cannot be restricted to ASCII characters. The RestrictToAscii property is set to true.", "RestrictToAscii"); + + return restrictToAscii; + } + + private static void RestrictToAsciiPropertyChangedCallback(object sender, DependencyPropertyChangedEventArgs e) + { + MaskedTextBox maskedTextBox = sender as MaskedTextBox; + + if (!maskedTextBox.IsInitialized) + return; + + if (maskedTextBox.m_maskIsNull) + return; + + maskedTextBox.m_maskedTextProvider = maskedTextBox.CreateMaskedTextProvider(maskedTextBox.Mask); + + maskedTextBox.RefreshCurrentText(true); + } + + #endregion RestrictToAscii Property + + #region SkipLiterals Property + + public bool SkipLiterals + { + get + { + return (bool)GetValue(SkipLiteralsProperty); + } + set + { + SetValue(SkipLiteralsProperty, value); + } + } + + public static readonly DependencyProperty SkipLiteralsProperty = + DependencyProperty.Register("SkipLiterals", typeof(bool), typeof(MaskedTextBox), + new UIPropertyMetadata( + true, + new PropertyChangedCallback(MaskedTextBox.SkipLiteralsPropertyChangedCallback))); + + private static void SkipLiteralsPropertyChangedCallback(object sender, DependencyPropertyChangedEventArgs e) + { + MaskedTextBox maskedTextBox = sender as MaskedTextBox; + + if (!maskedTextBox.IsInitialized) + return; + + if (maskedTextBox.m_maskIsNull) + return; + + maskedTextBox.m_maskedTextProvider.SkipLiterals = (bool)e.NewValue; + } + + #endregion SkipLiterals Property + + #region Text Property + + private static object TextCoerceValueCallback(DependencyObject sender, object value) + { + MaskedTextBox maskedTextBox = sender as MaskedTextBox; + + if (!maskedTextBox.IsInitialized) + return DependencyProperty.UnsetValue; + + if (maskedTextBox.IsInIMEComposition) + { + // In IME Composition. We must return an uncoerced value or else the IME decorator won't disappear after text input. + return value; + } + + if (value == null) + value = string.Empty; + + if ((maskedTextBox.IsForcingText) || (maskedTextBox.m_maskIsNull)) + return value; + + // Only direct affectation to the Text property or binding of the Text property should + // come through here. All other cases should pre-validate the text and affect it through the ForceText method. + string text = maskedTextBox.ValidateText((string)value); + + return text; + } + + private string ValidateText(string text) + { + string coercedText = text; + + if (this.RejectInputOnFirstFailure) + { + MaskedTextProvider provider = m_maskedTextProvider.Clone() as MaskedTextProvider; + + int notUsed; + MaskedTextResultHint hint; + + //0 – Digit zero to 9[ Required ] + //9 – Digit 0 – 9[ Optional ] + //A – Alpha Numeric. [Required] + //a – Alpha Numeric. [Optional] + //L – Letters a-z, A-Z[ Required ] + //? – Letters a-z, A-Z[ Optional ] + //C – Any non-control character [Optional] + //< - When first, all following characters are in lower case. + //> - When first, all following characters are in upper case. + if (provider.Set(text, out notUsed, out hint) || provider.Mask.StartsWith(">") || provider.Mask.StartsWith("<")) + { + coercedText = this.GetFormattedString(provider, text); + } + else + { + // Coerce the text to remain the same. + coercedText = this.GetFormattedString(m_maskedTextProvider, text); + + // The TextPropertyChangedCallback won't be called. + // Therefore, we must sync the maskedTextProvider. + m_maskedTextProvider.Set(coercedText); + } + } + else + { + MaskedTextProvider provider = (MaskedTextProvider)m_maskedTextProvider.Clone(); + + int caretIndex; + + if (this.CanReplace(provider, text, 0, m_maskedTextProvider.Length, this.RejectInputOnFirstFailure, out caretIndex)) + { + coercedText = this.GetFormattedString(provider, text); + } + else + { + // Coerce the text to remain the same. + coercedText = this.GetFormattedString(m_maskedTextProvider, text); + + // The TextPropertyChangedCallback won't be called. + // Therefore, we must sync the maskedTextProvider. + m_maskedTextProvider.Set(coercedText); + } + } + + return coercedText; + } + + protected override void OnTextChanged(TextChangedEventArgs e) + { + if (!m_maskIsNull) + { + if ((this.IsInValueChanged) || (!this.IsForcingText)) + { + string newText = this.Text; + + if (m_maskIsNull) + { + this.CaretIndex = newText.Length; + } + else + { + m_maskedTextProvider.Set(newText); + + if (m_maskedTextProvider.Mask.StartsWith(">") || m_maskedTextProvider.Mask.StartsWith("<")) + { + this.CaretIndex = newText.Length; + } + else + { + int caretIndex = m_maskedTextProvider.FindUnassignedEditPositionFrom(0, true); + + if (caretIndex == -1) + caretIndex = m_maskedTextProvider.Length; + + this.CaretIndex = caretIndex; + } + } + } + } + + // m_maskedTextProvider can be null in the designer. With WPF 3.5 SP1, sometimes, + // TextChanged will be triggered before OnInitialized is called. + if (m_maskedTextProvider != null) + { + this.SetIsMaskCompleted(m_maskedTextProvider.MaskCompleted); + this.SetIsMaskFull(m_maskedTextProvider.MaskFull); + } + + base.OnTextChanged(e); + } + + #endregion Text Property + + + #region COMMANDS + + private void OnPreviewCanExecuteCommands(object sender, CanExecuteRoutedEventArgs e) + { + if (m_maskIsNull) + return; + + RoutedUICommand routedUICommand = e.Command as RoutedUICommand; + + if ((routedUICommand != null) + && ((routedUICommand.Name == "Space") || (routedUICommand.Name == "ShiftSpace"))) + { + if (this.IsReadOnly) + { + e.CanExecute = false; + } + else + { + MaskedTextProvider provider = (MaskedTextProvider)m_maskedTextProvider.Clone(); + int caretIndex; + e.CanExecute = this.CanReplace(provider, " ", this.SelectionStart, this.SelectionLength, this.RejectInputOnFirstFailure, out caretIndex); + } + + e.Handled = true; + } + else if ((e.Command == ApplicationCommands.Undo) || (e.Command == ApplicationCommands.Redo)) + { + e.CanExecute = false; + e.Handled = true; + } + } + + private void OnPreviewExecutedCommands(object sender, ExecutedRoutedEventArgs e) + { + if (m_maskIsNull) + return; + + if (e.Command == EditingCommands.Delete) + { + e.Handled = true; + this.Delete(this.SelectionStart, this.SelectionLength, true); + } + else if (e.Command == EditingCommands.DeleteNextWord) + { + e.Handled = true; + EditingCommands.SelectRightByWord.Execute(null, this as IInputElement); + this.Delete(this.SelectionStart, this.SelectionLength, true); + } + else if (e.Command == EditingCommands.DeletePreviousWord) + { + e.Handled = true; + EditingCommands.SelectLeftByWord.Execute(null, this as IInputElement); + this.Delete(this.SelectionStart, this.SelectionLength, false); + } + else if (e.Command == EditingCommands.Backspace) + { + e.Handled = true; + this.Delete(this.SelectionStart, this.SelectionLength, false); + } + else if (e.Command == ApplicationCommands.Cut) + { + e.Handled = true; + + if (ApplicationCommands.Copy.CanExecute(null, this as IInputElement)) + ApplicationCommands.Copy.Execute(null, this as IInputElement); + + this.Delete(this.SelectionStart, this.SelectionLength, true); + } + else if (e.Command == ApplicationCommands.Copy) + { + e.Handled = true; + this.ExecuteCopy(); + } + else if (e.Command == ApplicationCommands.Paste) + { + e.Handled = true; + + string clipboardContent = (string)Clipboard.GetDataObject().GetData("System.String"); + this.Replace(clipboardContent, this.SelectionStart, this.SelectionLength); + } + else + { + RoutedUICommand routedUICommand = e.Command as RoutedUICommand; + + if ((routedUICommand != null) + && ((routedUICommand.Name == "Space") || (routedUICommand.Name == "ShiftSpace"))) + { + e.Handled = true; + this.ProcessTextInput(" "); + } + } + } + + private void CanExecuteDelete(object sender, CanExecuteRoutedEventArgs e) + { + if (m_maskIsNull) + return; + + e.CanExecute = this.CanDelete(this.SelectionStart, this.SelectionLength, true, this.MaskedTextProvider.Clone() as MaskedTextProvider); + e.Handled = true; + + if ((!e.CanExecute) && (this.BeepOnError)) + System.Media.SystemSounds.Beep.Play(); + } + + private void CanExecuteDeletePreviousWord(object sender, CanExecuteRoutedEventArgs e) + { + if (m_maskIsNull) + return; + + bool canDeletePreviousWord = (!this.IsReadOnly) && (EditingCommands.SelectLeftByWord.CanExecute(null, this as IInputElement)); + + if (canDeletePreviousWord) + { + int cachedSelectionStart = this.SelectionStart; + int cachedSelectionLength = this.SelectionLength; + + EditingCommands.SelectLeftByWord.Execute(null, this as IInputElement); + + canDeletePreviousWord = this.CanDelete(this.SelectionStart, this.SelectionLength, false, this.MaskedTextProvider.Clone() as MaskedTextProvider); + + if (!canDeletePreviousWord) + { + this.SelectionStart = cachedSelectionStart; + this.SelectionLength = cachedSelectionLength; + } + } + + e.CanExecute = canDeletePreviousWord; + e.Handled = true; + + if ((!e.CanExecute) && (this.BeepOnError)) + System.Media.SystemSounds.Beep.Play(); + } + + private void CanExecuteDeleteNextWord(object sender, CanExecuteRoutedEventArgs e) + { + if (m_maskIsNull) + return; + + bool canDeleteNextWord = (!this.IsReadOnly) && (EditingCommands.SelectRightByWord.CanExecute(null, this as IInputElement)); + + if (canDeleteNextWord) + { + int cachedSelectionStart = this.SelectionStart; + int cachedSelectionLength = this.SelectionLength; + + EditingCommands.SelectRightByWord.Execute(null, this as IInputElement); + + canDeleteNextWord = this.CanDelete(this.SelectionStart, this.SelectionLength, true, this.MaskedTextProvider.Clone() as MaskedTextProvider); + + if (!canDeleteNextWord) + { + this.SelectionStart = cachedSelectionStart; + this.SelectionLength = cachedSelectionLength; + } + } + + e.CanExecute = canDeleteNextWord; + e.Handled = true; + + if ((!e.CanExecute) && (this.BeepOnError)) + System.Media.SystemSounds.Beep.Play(); + } + + private void CanExecuteBackspace(object sender, CanExecuteRoutedEventArgs e) + { + if (m_maskIsNull) + return; + + e.CanExecute = this.CanDelete(this.SelectionStart, this.SelectionLength, false, this.MaskedTextProvider.Clone() as MaskedTextProvider); + e.Handled = true; + + if ((!e.CanExecute) && (this.BeepOnError)) + System.Media.SystemSounds.Beep.Play(); + } + + private void CanExecuteCut(object sender, CanExecuteRoutedEventArgs e) + { + if (m_maskIsNull) + return; + + bool canCut = (!this.IsReadOnly) && (this.SelectionLength > 0); + + if (canCut) + { + int endPosition = (this.SelectionLength > 0) ? ((this.SelectionStart + this.SelectionLength) - 1) : this.SelectionStart; + + MaskedTextProvider provider = m_maskedTextProvider.Clone() as MaskedTextProvider; + + canCut = provider.RemoveAt(this.SelectionStart, endPosition); + } + + e.CanExecute = canCut; + e.Handled = true; + + if ((!canCut) && (this.BeepOnError)) + System.Media.SystemSounds.Beep.Play(); + } + + private void CanExecutePaste(object sender, CanExecuteRoutedEventArgs e) + { + if (m_maskIsNull) + return; + + bool canPaste = false; + + if (!this.IsReadOnly) + { + string clipboardContent = string.Empty; + + try + { + clipboardContent = (string)Clipboard.GetDataObject().GetData("System.String"); + + if (clipboardContent != null) + { + MaskedTextProvider provider = (MaskedTextProvider)m_maskedTextProvider.Clone(); + int caretIndex; + canPaste = this.CanReplace(provider, clipboardContent, this.SelectionStart, this.SelectionLength, this.RejectInputOnFirstFailure, out caretIndex); + } + } + catch + { + } + } + + e.CanExecute = canPaste; + e.Handled = true; + + if ((!e.CanExecute) && (this.BeepOnError)) + System.Media.SystemSounds.Beep.Play(); + } + + private void CanExecuteCopy(object sender, CanExecuteRoutedEventArgs e) + { + if (m_maskIsNull) + return; + + e.CanExecute = !m_maskedTextProvider.IsPassword; + e.Handled = true; + + if ((!e.CanExecute) && (this.BeepOnError)) + System.Media.SystemSounds.Beep.Play(); + } + + private void ExecuteCopy() + { + string selectedText = this.GetSelectedText(); + try + { + new UIPermission(UIPermissionClipboard.AllClipboard).Demand(); + + if (selectedText.Length == 0) + { + Clipboard.Clear(); + } + else + { + Clipboard.SetText(selectedText); + } + } + catch (SecurityException) + { + } + } + + private void ToggleInsertExecutedCallback(object sender, ExecutedRoutedEventArgs e) + { + m_insertToggled = !m_insertToggled; + } + + #endregion COMMANDS + + #region DRAG DROP + + private void PreviewQueryContinueDragCallback(object sender, QueryContinueDragEventArgs e) + { + if (m_maskIsNull) + return; + + e.Action = DragAction.Cancel; + e.Handled = true; + } + + protected override void OnDragEnter(DragEventArgs e) + { + if (!m_maskIsNull) + { + e.Effects = DragDropEffects.None; + e.Handled = true; + } + + base.OnDragEnter(e); + } + + protected override void OnDragOver(DragEventArgs e) + { + if (!m_maskIsNull) + { + e.Effects = DragDropEffects.None; + e.Handled = true; + } + + base.OnDragOver(e); + } + + #endregion DRAG DROP + + + #region VALUE FROM TEXT + + protected override bool QueryValueFromTextCore(string text, out object value) + { + Type valueDataType = this.ValueDataType; + + if (valueDataType != null) + { + if ((m_unhandledLiteralsPositions != null) + && (m_unhandledLiteralsPositions.Count > 0)) + { + text = m_maskedTextProvider.ToString(false, false, true, 0, m_maskedTextProvider.Length); + + for (int i = m_unhandledLiteralsPositions.Count - 1; i >= 0; i--) + { + text = text.Remove(m_unhandledLiteralsPositions[i], 1); + } + } + } + + return base.QueryValueFromTextCore(text, out value); + } + + #endregion VALUE FROM TEXT + + #region TEXT FROM VALUE + + protected override string QueryTextFromValueCore(object value) + { + if ((m_valueToStringMethodInfo != null) && (value != null)) + { + try + { + string text = (string)m_valueToStringMethodInfo.Invoke(value, new object[] { m_formatSpecifier, this.GetActiveFormatProvider() }); + return text; + } + catch + { + } + } + + return base.QueryTextFromValueCore(value); + } + + #endregion TEXT FROM VALUE + + + #region PROTECTED METHODS + + protected virtual char[] GetMaskCharacters() + { + return MaskedTextBox.MaskChars; + } + + private MaskedTextProvider CreateMaskedTextProvider(string mask) + { + return this.CreateMaskedTextProvider( + mask, + this.GetCultureInfo(), + this.AllowPromptAsInput, + this.PromptChar, + MaskedTextBox.DefaultPasswordChar, + this.RestrictToAscii); + } + + protected virtual MaskedTextProvider CreateMaskedTextProvider( + string mask, + CultureInfo cultureInfo, + bool allowPromptAsInput, + char promptChar, + char passwordChar, + bool restrictToAscii) + { + MaskedTextProvider provider = new MaskedTextProvider( + mask, + cultureInfo, + allowPromptAsInput, + promptChar, + passwordChar, + restrictToAscii); + + provider.ResetOnPrompt = this.ResetOnPrompt; + provider.ResetOnSpace = this.ResetOnSpace; + provider.SkipLiterals = this.SkipLiterals; + + provider.IncludeLiterals = true; + provider.IncludePrompt = true; + + provider.IsPassword = false; + + return provider; + } + + internal override void OnIMECompositionEnded(CachedTextInfo cachedTextInfo) + { + // End of IME Composition. Restore the critical infos. + this.ForceText(cachedTextInfo.Text, false); + this.CaretIndex = cachedTextInfo.CaretIndex; + this.SelectionStart = cachedTextInfo.SelectionStart; + this.SelectionLength = cachedTextInfo.SelectionLength; + } + + protected override void OnTextInput(System.Windows.Input.TextCompositionEventArgs e) + { + if (this.IsInIMEComposition) + this.EndIMEComposition(); + + if ((m_maskIsNull) || (m_maskedTextProvider == null) || (this.IsReadOnly)) + { + base.OnTextInput(e); + return; + } + + e.Handled = true; + + if (this.CharacterCasing == CharacterCasing.Upper) + { + this.ProcessTextInput(e.Text.ToUpper()); + } + else if (this.CharacterCasing == CharacterCasing.Lower) + { + this.ProcessTextInput(e.Text.ToLower()); + } + else + { + this.ProcessTextInput(e.Text); + } + + base.OnTextInput(e); + } + + private void ProcessTextInput(string text) + { + if (text.Length == 1) + { + string textOutput = this.MaskedTextOutput; + + int caretIndex; + if (this.PlaceChar(text[0], this.SelectionStart, this.SelectionLength, this.IsOverwriteMode, out caretIndex)) + { + if (this.MaskedTextOutput != textOutput) + this.RefreshCurrentText(false); + + this.SelectionStart = caretIndex + 1; + } + else + { + if (this.BeepOnError) + System.Media.SystemSounds.Beep.Play(); + } + + if (this.SelectionLength > 0) + this.SelectionLength = 0; + } + else + { + this.Replace(text, this.SelectionStart, this.SelectionLength); + } + } + + protected override void ValidateValue(object value) + { + base.ValidateValue(value); + + // Validate if it fits in the mask + if (!m_maskIsNull) + { + string representation = this.GetTextFromValue(value); + + MaskedTextProvider provider = m_maskedTextProvider.Clone() as MaskedTextProvider; + + if (!provider.VerifyString(representation)) + throw new ArgumentException("The value representation '" + representation + "' does not match the mask.", "value"); + } + } + + #endregion PROTECTED METHODS + + + #region INTERNAL PROPERTIES + + internal bool IsForcingMask + { + get + { + return m_forcingMask; + } + } + + internal string FormatSpecifier + { + get + { + return m_formatSpecifier; + } + set + { + m_formatSpecifier = value; + } + } + + internal override bool IsTextReadyToBeParsed + { + get + { + return this.IsMaskCompleted; + } + } + + internal override bool GetIsEditTextEmpty() + { + if (!m_maskIsNull) + return (this.MaskedTextProvider.AssignedEditPositionCount == 0); + return true; + } + + #endregion INTERNAL PROPERTIES + + #region INTERNAL METHODS + + internal override string GetCurrentText() + { + if (m_maskIsNull) + return base.GetCurrentText(); + + string displayText = this.GetFormattedString(m_maskedTextProvider, this.Text); + + return displayText; + } + + internal override string GetParsableText() + { + if (m_maskIsNull) + return base.GetParsableText(); + + bool includePrompt = false; + bool includeLiterals = true; + + if (this.ValueDataType == typeof(string)) + { + includePrompt = this.IncludePromptInValue; + includeLiterals = this.IncludeLiteralsInValue; + } + + return m_maskedTextProvider + .ToString(false, includePrompt, includeLiterals, 0, m_maskedTextProvider.Length); + } + + internal override void OnFormatProviderChanged() + { + MaskedTextProvider provider = new MaskedTextProvider(this.Mask); + + m_maskedTextProvider = provider; + + this.RefreshConversionHelpers(); + this.RefreshCurrentText(true); + + base.OnFormatProviderChanged(); + } + + internal override void RefreshConversionHelpers() + { + Type type = this.ValueDataType; + + if ((type == null) || (!this.IsNumericValueDataType)) + { + m_formatSpecifier = null; + m_valueToStringMethodInfo = null; + m_unhandledLiteralsPositions = null; + return; + } + + m_valueToStringMethodInfo = type.GetMethod("ToString", new Type[] { typeof(string), typeof(IFormatProvider) }); + + string mask = m_maskedTextProvider.Mask; + IFormatProvider activeFormatProvider = this.GetActiveFormatProvider(); + + char[] maskChars = this.GetMaskCharacters(); + + List unhandledLiteralsPositions; + + m_formatSpecifier = MaskedTextBox.GetFormatSpecifierFromMask( + mask, + maskChars, + activeFormatProvider, + this.IncludeLiteralsInValue, + out unhandledLiteralsPositions); + + NumberFormatInfo numberFormatInfo = activeFormatProvider.GetFormat(typeof(NumberFormatInfo)) as NumberFormatInfo; + + if (numberFormatInfo != null) + { + string negativeSign = numberFormatInfo.NegativeSign; + + if (m_formatSpecifier.Contains(negativeSign)) + { + // We must make sure that the value data type is numeric since we are about to + // set the format specifier to its Positive,Negative,Zero format pattern. + // If we do not do this, the negative symbol would double itself when IncludeLiteralsInValue + // is set to True and a negative symbol is added to the mask as a literal. + Debug.Assert(this.IsNumericValueDataType); + + m_formatSpecifier = m_formatSpecifier + ";" + m_formatSpecifier + ";" + m_formatSpecifier; + } + else + { + + } + } + + m_unhandledLiteralsPositions = unhandledLiteralsPositions; + } + + internal void SetValueToStringMethodInfo(MethodInfo valueToStringMethodInfo) + { + m_valueToStringMethodInfo = valueToStringMethodInfo; + } + + internal void ForceMask(string mask) + { + m_forcingMask = true; + + try + { + this.Mask = mask; + } + finally + { + m_forcingMask = false; + } + } + + #endregion INTERNAL METHODS + + #region PRIVATE PROPERTIES + + private bool IsOverwriteMode + { + get + { + if (!m_maskIsNull) + { + switch (this.InsertKeyMode) + { + case InsertKeyMode.Default: + { + return m_insertToggled; + } + + case InsertKeyMode.Insert: + { + return false; + } + + case InsertKeyMode.Overwrite: + { + return true; + } + } + } + + return false; + } + } + + #endregion PRIVATE PROPERTIES + + #region PRIVATE METHODS + + private bool PlaceChar(char ch, int startPosition, int length, bool overwrite, out int caretIndex) + { + return this.PlaceChar(m_maskedTextProvider, ch, startPosition, length, overwrite, out caretIndex); + } + + + private bool PlaceChar(MaskedTextProvider provider, char ch, int startPosition, int length, bool overwrite, out int caretPosition) + { + if (this.ShouldQueryAutoCompleteMask(provider.Clone() as MaskedTextProvider, ch, startPosition)) + { + AutoCompletingMaskEventArgs e = new AutoCompletingMaskEventArgs( + m_maskedTextProvider.Clone() as MaskedTextProvider, + startPosition, + length, + ch.ToString()); + + this.OnAutoCompletingMask(e); + + if ((!e.Cancel) && (e.AutoCompleteStartPosition > -1)) + { + caretPosition = startPosition; + + // AutoComplete the block. + for (int i = 0; i < e.AutoCompleteText.Length; i++) + { + if (!this.PlaceCharCore(provider, e.AutoCompleteText[i], e.AutoCompleteStartPosition + i, 0, true, out caretPosition)) + return false; + } + + caretPosition = e.AutoCompleteStartPosition + e.AutoCompleteText.Length; + return true; + } + } + + return this.PlaceCharCore(provider, ch, startPosition, length, overwrite, out caretPosition); + } + + private bool ShouldQueryAutoCompleteMask(MaskedTextProvider provider, char ch, int startPosition) + { + if (provider.IsEditPosition(startPosition)) + { + int nextSeparatorIndex = provider.FindNonEditPositionFrom(startPosition, true); + + if (nextSeparatorIndex != -1) + { + if (provider[nextSeparatorIndex].Equals(ch)) + { + int previousSeparatorIndex = provider.FindNonEditPositionFrom(startPosition, false); + + if (provider.FindUnassignedEditPositionInRange(previousSeparatorIndex, nextSeparatorIndex, true) != -1) + { + return true; + } + } + } + } + + return false; + } + + protected virtual void OnAutoCompletingMask(AutoCompletingMaskEventArgs e) + { + if (this.AutoCompletingMask != null) + this.AutoCompletingMask(this, e); + } + + public event EventHandler AutoCompletingMask; + + + private bool PlaceCharCore(MaskedTextProvider provider, char ch, int startPosition, int length, bool overwrite, out int caretPosition) + { + caretPosition = startPosition; + + if (startPosition < m_maskedTextProvider.Length) + { + MaskedTextResultHint notUsed; + + if (length > 0) + { + int endPosition = (startPosition + length) - 1; + return provider.Replace(ch, startPosition, endPosition, out caretPosition, out notUsed); + } + + if (overwrite) + return provider.Replace(ch, startPosition, out caretPosition, out notUsed); + + return provider.InsertAt(ch, startPosition, out caretPosition, out notUsed); + } + + return false; + } + + internal void Replace(string text, int startPosition, int selectionLength) + { + MaskedTextProvider provider = (MaskedTextProvider)m_maskedTextProvider.Clone(); + int tentativeCaretIndex; + + if (this.CanReplace(provider, text, startPosition, selectionLength, this.RejectInputOnFirstFailure, out tentativeCaretIndex)) + { + System.Diagnostics.Debug.WriteLine("Replace caret index to: " + tentativeCaretIndex.ToString()); + + bool mustRefreshText = this.MaskedTextOutput != provider.ToString(); + m_maskedTextProvider = provider; + + if (mustRefreshText) + this.RefreshCurrentText(false); + + this.CaretIndex = tentativeCaretIndex + 1; + } + else + { + if (this.BeepOnError) + System.Media.SystemSounds.Beep.Play(); + } + } + + internal virtual bool CanReplace(MaskedTextProvider provider, string text, int startPosition, int selectionLength, bool rejectInputOnFirstFailure, out int tentativeCaretIndex) + { + int endPosition = (startPosition + selectionLength) - 1; + tentativeCaretIndex = -1; + + + bool success = false; + + foreach (char ch in text) + { + if (!m_maskedTextProvider.VerifyEscapeChar(ch, startPosition)) + { + int editPositionFrom = provider.FindEditPositionFrom(startPosition, true); + + if (editPositionFrom == MaskedTextProvider.InvalidIndex) + break; + + startPosition = editPositionFrom; + } + + int length = (endPosition >= startPosition) ? 1 : 0; + bool overwrite = length > 0; + + if (this.PlaceChar(provider, ch, startPosition, length, overwrite, out tentativeCaretIndex)) + { + // Only one successfully inserted character is enough to declare the replace operation successful. + success = true; + + startPosition = tentativeCaretIndex + 1; + } + else if (rejectInputOnFirstFailure) + { + return false; + } + } + + if ((selectionLength > 0) && (startPosition <= endPosition)) + { + + // Erase the remaining of the assigned edit character. + int notUsed; + MaskedTextResultHint notUsedHint; + if (!provider.RemoveAt(startPosition, endPosition, out notUsed, out notUsedHint)) + success = false; + } + + return success; + } + + private bool CanDelete(int startPosition, int selectionLength, bool deleteForward, MaskedTextProvider provider) + { + if (this.IsReadOnly) + return false; + + + if (selectionLength == 0) + { + if (!deleteForward) + { + if (startPosition == 0) + return false; + + startPosition--; + } + else if ((startPosition + selectionLength) == provider.Length) + { + return false; + } + } + + MaskedTextResultHint notUsed; + int tentativeCaretPosition = startPosition; + + int endPosition = (selectionLength > 0) ? ((startPosition + selectionLength) - 1) : startPosition; + + bool success = provider.RemoveAt(startPosition, endPosition, out tentativeCaretPosition, out notUsed); + + return success; + } + + private void Delete(int startPosition, int selectionLength, bool deleteForward) + { + if (this.IsReadOnly) + return; + + + if (selectionLength == 0) + { + if (!deleteForward) + { + if (startPosition == 0) + return; + + startPosition--; + } + else if ((startPosition + selectionLength) == m_maskedTextProvider.Length) + { + return; + } + } + + MaskedTextResultHint hint; + int tentativeCaretPosition = startPosition; + + int endPosition = (selectionLength > 0) ? ((startPosition + selectionLength) - 1) : startPosition; + + string oldTextOutput = this.MaskedTextOutput; + + bool success = m_maskedTextProvider.RemoveAt(startPosition, endPosition, out tentativeCaretPosition, out hint); + + if (!success) + { + if (this.BeepOnError) + System.Media.SystemSounds.Beep.Play(); + + return; + } + + if (this.MaskedTextOutput != oldTextOutput) + { + this.RefreshCurrentText(false); + } + else if (selectionLength > 0) + { + tentativeCaretPosition = startPosition; + } + else if (hint == MaskedTextResultHint.NoEffect) + { + if (deleteForward) + { + tentativeCaretPosition = m_maskedTextProvider.FindEditPositionFrom(startPosition, true); + } + else + { + if (m_maskedTextProvider.FindAssignedEditPositionFrom(startPosition, true) == MaskedTextProvider.InvalidIndex) + { + tentativeCaretPosition = m_maskedTextProvider.FindAssignedEditPositionFrom(startPosition, false); + } + else + { + tentativeCaretPosition = m_maskedTextProvider.FindEditPositionFrom(startPosition, false); + } + + if (tentativeCaretPosition != MaskedTextProvider.InvalidIndex) + tentativeCaretPosition++; + } + + if (tentativeCaretPosition == MaskedTextProvider.InvalidIndex) + tentativeCaretPosition = startPosition; + } + else if (!deleteForward) + { + tentativeCaretPosition = startPosition; + } + + this.CaretIndex = tentativeCaretPosition; + } + + private string MaskedTextOutput + { + get + { + System.Diagnostics.Debug.Assert(m_maskedTextProvider.EditPositionCount > 0); + + return m_maskedTextProvider.ToString(); + } + } + + private string GetRawText() + { + if (m_maskIsNull) + return this.Text; + + return MaskedTextBox.GetRawText(m_maskedTextProvider); + } + + private string GetFormattedString(MaskedTextProvider provider, string text) + { + //System.Diagnostics.Debug.Assert( provider.EditPositionCount > 0 ); + + + bool includePrompt = (this.IsReadOnly) ? false : (!this.HidePromptOnLeave || this.IsFocused); + + string displayString = provider.ToString(false, includePrompt, true, 0, m_maskedTextProvider.Length); + + if (provider.Mask.StartsWith(">")) + return displayString.ToUpper(); + if (provider.Mask.StartsWith("<")) + return displayString.ToLower(); + + return displayString; + } + + private string GetSelectedText() + { + System.Diagnostics.Debug.Assert(!m_maskIsNull); + + int selectionLength = this.SelectionLength; + + if (selectionLength == 0) + return string.Empty; + + bool includePrompt = (this.ClipboardMaskFormat & MaskFormat.IncludePrompt) != MaskFormat.ExcludePromptAndLiterals; + bool includeLiterals = (this.ClipboardMaskFormat & MaskFormat.IncludeLiterals) != MaskFormat.ExcludePromptAndLiterals; + + return m_maskedTextProvider.ToString(true, includePrompt, includeLiterals, this.SelectionStart, selectionLength); + } + + #endregion PRIVATE METHODS + + #region PRIVATE FIELDS + + private MaskedTextProvider m_maskedTextProvider; // = null; + private bool m_insertToggled; // = false; + private bool m_maskIsNull = true; + private bool m_forcingMask; // = false; + + List m_unhandledLiteralsPositions; // = null; + private string m_formatSpecifier; + private MethodInfo m_valueToStringMethodInfo; // = null; + + #endregion PRIVATE FIELDS + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MessageBox/Icons/Error48.png b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MessageBox/Icons/Error48.png new file mode 100644 index 00000000..1fc8cf53 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MessageBox/Icons/Error48.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f2a684102eb03f8dc08aefeff5e1fc77e0618034c36229d1eeb2bce3252842ef +size 4170 diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MessageBox/Icons/Information48.png b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MessageBox/Icons/Information48.png new file mode 100644 index 00000000..cf30b6ae --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MessageBox/Icons/Information48.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:00682201c807e880b987c6089b49d712b7a9aa59db6b86e7b3dc00cc011bf5a1 +size 5101 diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MessageBox/Icons/Question48.png b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MessageBox/Icons/Question48.png new file mode 100644 index 00000000..ca9d8286 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MessageBox/Icons/Question48.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a2a7d13d1a4e4ced89c95c60a0768a9ae98793819f9064be90addfb42f00c63c +size 5492 diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MessageBox/Icons/Warning48.png b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MessageBox/Icons/Warning48.png new file mode 100644 index 00000000..ef6e6282 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MessageBox/Icons/Warning48.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:df14a2b5997e84d7dbfc1f09b2b34724784a23c40501c8b91f589601ae58d012 +size 3281 diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MessageBox/Implementation/MessageBox.Icon.bmp b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MessageBox/Implementation/MessageBox.Icon.bmp new file mode 100644 index 00000000..ce76dc5b --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MessageBox/Implementation/MessageBox.Icon.bmp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e95d8b086aa0680fa4b987fc38d9701b23c24b9d6334806e6d5a7fa0b3687373 +size 822 diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MessageBox/Implementation/MessageBox.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MessageBox/Implementation/MessageBox.cs new file mode 100644 index 00000000..0b9ad645 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MessageBox/Implementation/MessageBox.cs @@ -0,0 +1,1203 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Controls.Primitives; +using System.Windows.Media; +using System.Windows.Input; +using System.Text; +using System.Security.Permissions; +using System.Security; +using Xceed.Wpf.Toolkit.Primitives; +using System.Diagnostics; +using System.Windows.Media.Imaging; +using System.Windows.Threading; +using System.Windows.Interop; + +namespace Xceed.Wpf.Toolkit +{ + [TemplateVisualState(Name = VisualStates.OK, GroupName = VisualStates.MessageBoxButtonsGroup)] + [TemplateVisualState(Name = VisualStates.OKCancel, GroupName = VisualStates.MessageBoxButtonsGroup)] + [TemplateVisualState(Name = VisualStates.YesNo, GroupName = VisualStates.MessageBoxButtonsGroup)] + [TemplateVisualState(Name = VisualStates.YesNoCancel, GroupName = VisualStates.MessageBoxButtonsGroup)] + [TemplatePart(Name = PART_CancelButton, Type = typeof(Button))] + [TemplatePart(Name = PART_NoButton, Type = typeof(Button))] + [TemplatePart(Name = PART_OkButton, Type = typeof(Button))] + [TemplatePart(Name = PART_YesButton, Type = typeof(Button))] + [TemplatePart(Name = PART_WindowControl, Type = typeof(WindowControl))] + public class MessageBox : WindowControl + { + private const string PART_CancelButton = "PART_CancelButton"; + private const string PART_NoButton = "PART_NoButton"; + private const string PART_OkButton = "PART_OkButton"; + private const string PART_YesButton = "PART_YesButton"; + private const string PART_CloseButton = "PART_CloseButton"; + private const string PART_WindowControl = "PART_WindowControl"; + + #region Private Members + + /// + /// Tracks the MessageBoxButon value passed into the InitializeContainer method + /// + private MessageBoxButton _button = MessageBoxButton.OK; + + /// + /// Tracks the MessageBoxResult to set as the default and focused button + /// + private MessageBoxResult _defaultResult = MessageBoxResult.None; + + /// + /// Will contain the result when the messagebox is shown inside a WindowContainer + /// + private MessageBoxResult _dialogResult = MessageBoxResult.None; + + /// + /// Tracks the owner of the MessageBox + /// + private Window _owner; + private IntPtr _ownerHandle; + + private WindowControl _windowControl; + + #endregion //Private Members + + #region Constructors + + static MessageBox() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(MessageBox), new FrameworkPropertyMetadata(typeof(MessageBox))); + } + + public MessageBox() + { + this.Visibility = Visibility.Collapsed; + this.InitHandlers(); + this.IsVisibleChanged += this.MessageBox_IsVisibleChanged; + } + + #endregion //Constructors + + #region Properties + + #region Protected Properties + + protected Window Container + { + get { return (this.Parent as Window); } + } + + #endregion //Protected Properties + + #region Dependency Properties + + #region ButtonRegionBackground + + public static readonly DependencyProperty ButtonRegionBackgroundProperty = DependencyProperty.Register("ButtonRegionBackground", typeof(Brush), typeof(MessageBox), new PropertyMetadata(null)); + public Brush ButtonRegionBackground + { + get + { + return (Brush)GetValue(ButtonRegionBackgroundProperty); + } + set + { + SetValue(ButtonRegionBackgroundProperty, value); + } + } + + #endregion //ButtonRegionBackground + + #region CancelButtonContent + + public static readonly DependencyProperty CancelButtonContentProperty = DependencyProperty.Register("CancelButtonContent", typeof(object), typeof(MessageBox), new UIPropertyMetadata("Cancel")); + public object CancelButtonContent + { + get + { + return (object)GetValue(CancelButtonContentProperty); + } + set + { + SetValue(CancelButtonContentProperty, value); + } + } + + #endregion //CancelButtonContent + + #region CancelButtonStyle + + public static readonly DependencyProperty CancelButtonStyleProperty = DependencyProperty.Register("CancelButtonStyle", typeof(Style), typeof(MessageBox), new PropertyMetadata(null)); + public Style CancelButtonStyle + { + get + { + return (Style)GetValue(CancelButtonStyleProperty); + } + set + { + SetValue(CancelButtonStyleProperty, value); + } + } + + #endregion //CancelButtonStyle + + #region ImageSource + + public static readonly DependencyProperty ImageSourceProperty = DependencyProperty.Register("ImageSource", typeof(ImageSource), typeof(MessageBox), new UIPropertyMetadata(default(ImageSource))); + public ImageSource ImageSource + { + get + { + return (ImageSource)GetValue(ImageSourceProperty); + } + set + { + SetValue(ImageSourceProperty, value); + } + } + + #endregion //ImageSource + + #region OkButtonContent + + public static readonly DependencyProperty OkButtonContentProperty = DependencyProperty.Register("OkButtonContent", typeof(object), typeof(MessageBox), new UIPropertyMetadata("OK")); + public object OkButtonContent + { + get + { + return (object)GetValue(OkButtonContentProperty); + } + set + { + SetValue(OkButtonContentProperty, value); + } + } + + #endregion //OkButtonContent + + #region OkButtonStyle + + public static readonly DependencyProperty OkButtonStyleProperty = DependencyProperty.Register("OkButtonStyle", typeof(Style), typeof(MessageBox), new PropertyMetadata(null)); + public Style OkButtonStyle + { + get + { + return (Style)GetValue(OkButtonStyleProperty); + } + set + { + SetValue(OkButtonStyleProperty, value); + } + } + + #endregion //OkButtonStyle + + #region MessageBoxResult + + /// + /// Gets the MessageBox result, which is set when the "Closed" event is raised. + /// + public MessageBoxResult MessageBoxResult + { + get { return _dialogResult; } + } + + #endregion //MessageBoxResult + + #region NoButtonContent + + public static readonly DependencyProperty NoButtonContentProperty = DependencyProperty.Register("NoButtonContent", typeof(object), typeof(MessageBox), new UIPropertyMetadata("No")); + public object NoButtonContent + { + get + { + return (object)GetValue(NoButtonContentProperty); + } + set + { + SetValue(NoButtonContentProperty, value); + } + } + + #endregion //NoButtonContent + + #region NoButtonStyle + + public static readonly DependencyProperty NoButtonStyleProperty = DependencyProperty.Register("NoButtonStyle", typeof(Style), typeof(MessageBox), new PropertyMetadata(null)); + public Style NoButtonStyle + { + get + { + return (Style)GetValue(NoButtonStyleProperty); + } + set + { + SetValue(NoButtonStyleProperty, value); + } + } + + #endregion //NoButtonStyle + + #region Text + + public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(MessageBox), new UIPropertyMetadata(String.Empty)); + public string Text + { + get + { + return (string)GetValue(TextProperty); + } + set + { + SetValue(TextProperty, value); + } + } + + #endregion //Text + + #region YesButtonContent + + public static readonly DependencyProperty YesButtonContentProperty = DependencyProperty.Register("YesButtonContent", typeof(object), typeof(MessageBox), new UIPropertyMetadata("Yes")); + public object YesButtonContent + { + get + { + return (object)GetValue(YesButtonContentProperty); + } + set + { + SetValue(YesButtonContentProperty, value); + } + } + + #endregion //YesButtonContent + + #region YesButtonStyle + + public static readonly DependencyProperty YesButtonStyleProperty = DependencyProperty.Register("YesButtonStyle", typeof(Style), typeof(MessageBox), new PropertyMetadata(null)); + public Style YesButtonStyle + { + get + { + return (Style)GetValue(YesButtonStyleProperty); + } + set + { + SetValue(YesButtonStyleProperty, value); + } + } + + #endregion //YesButtonStyle + + #endregion //Dependency Properties + + #endregion //Properties + + #region Base Class Overrides + + internal override bool AllowPublicIsActiveChange + { + get { return false; } + } + + /// + /// Overrides the OnApplyTemplate method. + /// + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + if (_windowControl != null) + { + _windowControl.HeaderDragDelta -= (o, e) => this.OnHeaderDragDelta(e); + _windowControl.HeaderIconDoubleClicked -= (o, e) => this.OnHeaderIconDoubleClicked(e); + _windowControl.CloseButtonClicked -= (o, e) => this.OnCloseButtonClicked(e); + } + _windowControl = this.GetTemplateChild(PART_WindowControl) as WindowControl; + if (_windowControl != null) + { + _windowControl.HeaderDragDelta += (o, e) => this.OnHeaderDragDelta(e); + _windowControl.HeaderIconDoubleClicked += (o, e) => this.OnHeaderIconDoubleClicked(e); + _windowControl.CloseButtonClicked += (o, e) => this.OnCloseButtonClicked(e); + } + this.UpdateBlockMouseInputsPanel(); + + ChangeVisualState(_button.ToString(), true); + + Button closeButton = GetMessageBoxButton(PART_CloseButton); + if (closeButton != null) + closeButton.IsEnabled = !object.Equals(_button, MessageBoxButton.YesNo); + + Button okButton = GetMessageBoxButton(PART_OkButton); + if (okButton != null) + okButton.IsCancel = object.Equals(_button, MessageBoxButton.OK); + + SetDefaultResult(); + } + + protected override void OnPreviewKeyDown(KeyEventArgs e) + { + base.OnPreviewKeyDown(e); + + // Prevent MenuItem shortcuts while MessageBox is active. + if (Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt)) + { + e.Handled = true; + } + } + + protected override object OnCoerceCloseButtonVisibility(Visibility newValue) + { + if (newValue != Visibility.Visible) + throw new InvalidOperationException("Close button on MessageBox is always Visible."); + return newValue; + } + + protected override object OnCoerceWindowStyle(WindowStyle newValue) + { + if (newValue != WindowStyle.SingleBorderWindow) + throw new InvalidOperationException("Window style on MessageBox is not available."); + return newValue; + } + + internal override void UpdateBlockMouseInputsPanel() + { + if (_windowControl != null) + { + _windowControl.IsBlockMouseInputsPanelActive = this.IsBlockMouseInputsPanelActive; + } + } + + + + + #endregion //Base Class Overrides + + #region Methods + + #region Public Static + + #region Show with Window as Owner + + + /// + /// Displays a message box that has a message and that returns a result. + /// + /// A System.String that specifies the text to display. + /// A Style that will be applied to the MessageBox instance. + /// A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user. + public static MessageBoxResult Show(string messageText) + { + return Show(messageText, string.Empty, MessageBoxButton.OK, (Style)null); + } + + /// + /// Displays a message box that has a message and that returns a result. + /// + /// A System.Windows.Window that represents the owner of the MessageBox + /// A System.String that specifies the text to display. + /// A Style that will be applied to the MessageBox instance. + /// A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user. + public static MessageBoxResult Show(Window owner, string messageText) + { + return Show(owner, messageText, string.Empty, MessageBoxButton.OK, (Style)null); + } + + /// + /// Displays a message box that has a message and title bar caption; and that returns a result. + /// + /// A System.String that specifies the text to display. + /// A System.String that specifies the title bar caption to display. + /// A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user. + public static MessageBoxResult Show(string messageText, string caption) + { + return Show(messageText, caption, MessageBoxButton.OK, (Style)null); + } + + public static MessageBoxResult Show(Window owner, string messageText, string caption) + { + return Show(owner, messageText, caption, (Style)null); + } + + public static MessageBoxResult Show(Window owner, string messageText, string caption, Style messageBoxStyle) + { + return Show(owner, messageText, caption, MessageBoxButton.OK, messageBoxStyle); + } + + public static MessageBoxResult Show(string messageText, string caption, MessageBoxButton button) + { + return Show(messageText, caption, button, (Style)null); + } + + /// + /// Displays a message box that has a message and that returns a result. + /// + /// A System.String that specifies the text to display. + /// A System.String that specifies the title bar caption to display. + /// A System.Windows.MessageBoxButton value that specifies which button or buttons to display. + /// A Style that will be applied to the MessageBox instance. + /// A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user. + public static MessageBoxResult Show(string messageText, string caption, MessageBoxButton button, Style messageBoxStyle) + { + return ShowCore(null, IntPtr.Zero, messageText, caption, button, MessageBoxImage.None, MessageBoxResult.None, messageBoxStyle); + } + + + public static MessageBoxResult Show(Window owner, string messageText, string caption, MessageBoxButton button) + { + return Show(owner, messageText, caption, button, (Style)null); + } + + public static MessageBoxResult Show(Window owner, string messageText, string caption, MessageBoxButton button, Style messageBoxStyle) + { + return ShowCore(owner, IntPtr.Zero, messageText, caption, button, MessageBoxImage.None, MessageBoxResult.None, messageBoxStyle); + } + + + public static MessageBoxResult Show(string messageText, string caption, MessageBoxButton button, MessageBoxImage icon) + { + return Show(messageText, caption, button, icon, (Style)null); + } + + /// + /// Displays a message box that has a message and that returns a result. + /// + /// A System.String that specifies the text to display. + /// A System.String that specifies the title bar caption to display. + /// A System.Windows.MessageBoxButton value that specifies which button or buttons to display. + /// A System.Windows.MessageBoxImage value that specifies the icon to display. + /// A Style that will be applied to the MessageBox instance. + /// A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user. + public static MessageBoxResult Show(string messageText, string caption, MessageBoxButton button, MessageBoxImage icon, Style messageBoxStyle) + { + return ShowCore(null, IntPtr.Zero, messageText, caption, button, icon, MessageBoxResult.None, messageBoxStyle); + } + + public static MessageBoxResult Show(Window owner, string messageText, string caption, MessageBoxButton button, MessageBoxImage icon) + { + return Show(owner, messageText, caption, button, icon, (Style)null); + } + + public static MessageBoxResult Show(Window owner, string messageText, string caption, MessageBoxButton button, MessageBoxImage icon, Style messageBoxStyle) + { + return ShowCore(owner, IntPtr.Zero, messageText, caption, button, icon, MessageBoxResult.None, messageBoxStyle); + } + + + public static MessageBoxResult Show(string messageText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult) + { + return Show(messageText, caption, button, icon, defaultResult, (Style)null); + } + /// + /// Displays a message box that has a message and that returns a result. + /// + /// A System.String that specifies the text to display. + /// A System.String that specifies the title bar caption to display. + /// A System.Windows.MessageBoxButton value that specifies which button or buttons to display. + /// A System.Windows.MessageBoxImage value that specifies the icon to display. + /// A System.Windows.MessageBoxResult value that specifies the default result of the MessageBox. + /// A Style that will be applied to the MessageBox instance. + /// A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user. + public static MessageBoxResult Show(string messageText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult, Style messageBoxStyle) + { + return ShowCore(null, IntPtr.Zero, messageText, caption, button, icon, defaultResult, messageBoxStyle); + } + + public static MessageBoxResult Show(Window owner, string messageText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult) + { + return Show(owner, messageText, caption, button, icon, defaultResult, (Style)null); + } + + + public static MessageBoxResult Show(Window owner, string messageText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult, Style messageBoxStyle) + { + return ShowCore(owner, IntPtr.Zero, messageText, caption, button, icon, defaultResult, messageBoxStyle); + } + + #endregion //Show with Window as Owner + + #region Show with Window handle as Owner + + public static MessageBoxResult Show(IntPtr ownerWindowHandle, string messageText) + { + return Show(ownerWindowHandle, messageText, string.Empty, MessageBoxButton.OK, (Style)null); + } + + public static MessageBoxResult Show(IntPtr ownerWindowHandle, string messageText, string caption) + { + return Show(ownerWindowHandle, messageText, caption, (Style)null); + } + + public static MessageBoxResult Show(IntPtr ownerWindowHandle, string messageText, string caption, Style messageBoxStyle) + { + return Show(ownerWindowHandle, messageText, caption, MessageBoxButton.OK, messageBoxStyle); + } + + public static MessageBoxResult Show(IntPtr ownerWindowHandle, string messageText, string caption, MessageBoxButton button) + { + return Show(ownerWindowHandle, messageText, caption, button, (Style)null); + } + + public static MessageBoxResult Show(IntPtr ownerWindowHandle, string messageText, string caption, MessageBoxButton button, Style messageBoxStyle) + { + return ShowCore(null, ownerWindowHandle, messageText, caption, button, MessageBoxImage.None, MessageBoxResult.None, messageBoxStyle); + } + + public static MessageBoxResult Show(IntPtr ownerWindowHandle, string messageText, string caption, MessageBoxButton button, MessageBoxImage icon) + { + return Show(ownerWindowHandle, messageText, caption, button, icon, (Style)null); + } + + public static MessageBoxResult Show(IntPtr ownerWindowHandle, string messageText, string caption, MessageBoxButton button, MessageBoxImage icon, Style messageBoxStyle) + { + return ShowCore(null, ownerWindowHandle, messageText, caption, button, icon, MessageBoxResult.None, messageBoxStyle); + } + + public static MessageBoxResult Show(IntPtr ownerWindowHandle, string messageText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult) + { + return Show(ownerWindowHandle, messageText, caption, button, icon, defaultResult, (Style)null); + } + + public static MessageBoxResult Show(IntPtr ownerWindowHandle, string messageText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult, Style messageBoxStyle) + { + return ShowCore(null, ownerWindowHandle, messageText, caption, button, icon, defaultResult, messageBoxStyle); + } + + #endregion //Show with Window handle as Owner + + #endregion //Public Static + + #region Public Methods + /// + /// Displays this message box when embedded in a WindowContainer parent. + /// Note that this call is not blocking and that you must register to the Closed event in order to handle the dialog result, if any. + /// + public void ShowMessageBox() + { + if (this.Container != null || this.Parent == null) + throw new InvalidOperationException( + "This method is not intended to be called while displaying a MessageBox outside of a WindowContainer. Use ShowDialog() instead in that case."); + + if (!(this.Parent is WindowContainer)) + throw new InvalidOperationException( + "The MessageBox instance is not intended to be displayed in a container other than a WindowContainer."); + + _dialogResult = System.Windows.MessageBoxResult.None; + this.Visibility = Visibility.Visible; + } + + /// + /// Displays this message box when embedded in a WindowContainer parent. + /// Note that this call is not blocking and that you must register to the Closed event in order to handle the dialog result, if any. + /// + public void ShowMessageBox(string messageText) + { + this.ShowMessageBoxCore(messageText, string.Empty, MessageBoxButton.OK, MessageBoxImage.None, MessageBoxResult.None); + } + + /// + /// Displays this message box when embedded in a WindowContainer parent. + /// Note that this call is not blocking and that you must register to the Closed event in order to handle the dialog result, if any. + /// + public void ShowMessageBox(string messageText, string caption) + { + this.ShowMessageBoxCore(messageText, caption, MessageBoxButton.OK, MessageBoxImage.None, MessageBoxResult.None); + } + + /// + /// Displays this message box when embedded in a WindowContainer parent. + /// Note that this call is not blocking and that you must register to the Closed event in order to handle the dialog result, if any. + /// + public void ShowMessageBox(string messageText, string caption, MessageBoxButton button) + { + this.ShowMessageBoxCore(messageText, caption, button, MessageBoxImage.None, MessageBoxResult.None); + } + + /// + /// Displays this message box when embedded in a WindowContainer parent. + /// Note that this call is not blocking and that you must register to the Closed event in order to handle the dialog result, if any. + /// + public void ShowMessageBox(string messageText, string caption, MessageBoxButton button, MessageBoxImage icon) + { + this.ShowMessageBoxCore(messageText, caption, button, icon, MessageBoxResult.None); + } + + /// + /// Displays this message box when embedded in a WindowContainer parent. + /// Note that this call is not blocking and that you must register to the Closed event in order to handle the dialog result, if any. + /// + public void ShowMessageBox(string messageText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult) + { + this.ShowMessageBoxCore(messageText, caption, button, icon, defaultResult); + } + + /// + /// Display the MessageBox window and returns only when this MessageBox closes. + /// + public bool? ShowDialog() + { + if (this.Parent != null) + throw new InvalidOperationException( + "This method is not intended to be called while displaying a Message Box inside a WindowContainer. Use 'ShowMessageBox()' instead."); + + _dialogResult = System.Windows.MessageBoxResult.None; + this.Visibility = Visibility.Visible; + this.CreateContainer(); + + return this.Container.ShowDialog(); + } + + #endregion + + #region Protected + /// + /// Initializes the MessageBox. + /// + /// The Window owner. + /// The Window Handle owner. + /// The text. + /// The caption. + /// The button. + /// The image. + /// The MessageBox result as default. + protected void InitializeMessageBox(Window owner, IntPtr ownerHandle, string text, string caption, MessageBoxButton button, MessageBoxImage image, MessageBoxResult defaultResult) + { + Text = text; + Caption = caption; + _button = button; + _defaultResult = defaultResult; + _owner = owner; + _ownerHandle = ownerHandle; + SetImageSource(image); + } + + /// + /// Changes the control's visual state(s). + /// + /// name of the state + /// True if state transitions should be used. + protected void ChangeVisualState(string name, bool useTransitions) + { + VisualStateManager.GoToState(this, name, useTransitions); + } + + #endregion //Protected + + + + + + #region Private + + private bool IsCurrentWindow(object windowtoTest) + { + return object.Equals(_windowControl, windowtoTest); + } + + /// + /// Closes the MessageBox. + /// + private void Close() + { + if (this.Container != null) + { + // The Window.Closed event callback will call "OnClose" + this.Container.Close(); + } + else + { + this.OnClose(); + } + } + + /// + /// Sets the button that represents the _defaultResult to the default button and gives it focus. + /// + private void SetDefaultResult() + { + var defaultButton = GetDefaultButtonFromDefaultResult(); + if (defaultButton != null) + { + defaultButton.IsDefault = true; + defaultButton.Focus(); + } + } + + /// + /// Gets the default button from the _defaultResult. + /// + /// The default button that represents the defaultResult + private Button GetDefaultButtonFromDefaultResult() + { + Button defaultButton = null; + switch (_defaultResult) + { + case MessageBoxResult.Cancel: + defaultButton = GetMessageBoxButton(PART_CancelButton); + break; + case MessageBoxResult.No: + defaultButton = GetMessageBoxButton(PART_NoButton); + break; + case MessageBoxResult.OK: + defaultButton = GetMessageBoxButton(PART_OkButton); + break; + case MessageBoxResult.Yes: + defaultButton = GetMessageBoxButton(PART_YesButton); + break; + case MessageBoxResult.None: + defaultButton = GetDefaultButton(); + break; + } + return defaultButton; + } + + /// + /// Gets the default button. + /// + /// Used when the _defaultResult is set to None + /// The button to use as the default + private Button GetDefaultButton() + { + Button defaultButton = null; + switch (_button) + { + case MessageBoxButton.OK: + case MessageBoxButton.OKCancel: + defaultButton = GetMessageBoxButton(PART_OkButton); + break; + case MessageBoxButton.YesNo: + case MessageBoxButton.YesNoCancel: + defaultButton = GetMessageBoxButton(PART_YesButton); + break; + } + return defaultButton; + } + + /// + /// Gets a message box button. + /// + /// The name of the button to get. + /// The button + private Button GetMessageBoxButton(string name) + { + Button button = GetTemplateChild(name) as Button; + return button; + } + + private void ShowMessageBoxCore(string messageText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult) + { + this.InitializeMessageBox(null, IntPtr.Zero, messageText, caption, button, icon, defaultResult); + this.ShowMessageBox(); + } + + private void InitHandlers() + { + AddHandler(ButtonBase.ClickEvent, new RoutedEventHandler(this.Button_Click)); + + CommandBindings.Add(new CommandBinding(ApplicationCommands.Copy, new ExecutedRoutedEventHandler(ExecuteCopy))); + } + + /// + /// Shows the MessageBox. + /// + /// The message text. + /// The caption. + /// The button. + /// The icon. + /// The default result. + /// + private static MessageBoxResult ShowCore(Window owner, IntPtr ownerHandle, string messageText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult, Style messageBoxStyle) + { + if (System.Windows.Interop.BrowserInteropHelper.IsBrowserHosted) + { + throw new InvalidOperationException("Static methods for MessageBoxes are not available in XBAP. Use the instance ShowMessageBox methods instead."); + } + + if ((owner != null) && (ownerHandle != IntPtr.Zero)) + { + throw new NotSupportedException("The owner of a MessageBox can't be both a Window and a WindowHandle."); + } + + var msgBox = new MessageBox(); + msgBox.InitializeMessageBox(owner, ownerHandle, messageText, caption, button, icon, defaultResult); + + // Setting the style to null will inhibit any implicit styles + if (messageBoxStyle != null) + { + msgBox.Style = messageBoxStyle; + } + + msgBox.ShowDialog(); + return msgBox.MessageBoxResult; + } + + private delegate Window ComputeOwnerWindowCoreDelegate(); + + /// + /// Resolves the owner Window of the MessageBox. + /// + /// the owner Window + private static Window ComputeOwnerWindow() + { + Window result = null; + + if (Application.Current != null) + { + if (Application.Current.Dispatcher.CheckAccess()) + { + result = ComputeOwnerWindowCore(); + } + else + { + Application.Current.Dispatcher.BeginInvoke(new Action(() => + { + result = ComputeOwnerWindowCore(); + } + )); + } + } + + return result; + } + + private static Window ComputeOwnerWindowCore() + { + Window owner = null; + + if (Application.Current != null) + { + foreach (Window w in Application.Current.Windows) + { + if (w.IsActive) + { + owner = w; + break; + } + } + } + + return owner; + } + + /// + /// Sets the message image source. + /// + /// The image to show. + private void SetImageSource(MessageBoxImage image) + { + String iconName = String.Empty; + + switch (image) + { + case MessageBoxImage.Error: + { + iconName = "Error48.png"; + break; + } + case MessageBoxImage.Information: + { + iconName = "Information48.png"; + break; + } + case MessageBoxImage.Question: + { + iconName = "Question48.png"; + break; + } + case MessageBoxImage.Warning: + { + iconName = "Warning48.png"; + break; + } + case MessageBoxImage.None: + default: + { + return; + } + } + + // Use this syntax for other themes to get the icons + this.ImageSource = new BitmapImage(new Uri(String.Format("/Xceed.Wpf.Toolkit;component/MessageBox/Icons/{0}", iconName), UriKind.RelativeOrAbsolute)); + } + + /// + /// Creates the container which will host the MessageBox control. + /// + /// + private Window CreateContainer() + { + var newWindow = new Window(); + newWindow.AllowsTransparency = true; + newWindow.Background = Brushes.Transparent; + newWindow.Content = this; + + if (_ownerHandle != IntPtr.Zero) + { + var windowHelper = new WindowInteropHelper(newWindow) { Owner = _ownerHandle }; + newWindow.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterOwner; + } + else + { + newWindow.Owner = _owner ?? ComputeOwnerWindow(); + if (newWindow.Owner != null) + newWindow.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterOwner; + else + newWindow.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen; + } + + newWindow.ShowInTaskbar = false; + newWindow.SizeToContent = System.Windows.SizeToContent.WidthAndHeight; + newWindow.ResizeMode = System.Windows.ResizeMode.NoResize; + newWindow.WindowStyle = System.Windows.WindowStyle.None; + newWindow.Closed += new EventHandler(OnContainerClosed); + return newWindow; + } + + #endregion //Private + + #endregion //Methods + + #region Event Handlers + + /// + /// Processes the move of a drag operation on the header. + /// + /// The instance containing the event data. + protected virtual void OnHeaderDragDelta(DragDeltaEventArgs e) + { + if (!this.IsCurrentWindow(e.OriginalSource)) + return; + + e.Handled = true; + + DragDeltaEventArgs args = new DragDeltaEventArgs(e.HorizontalChange, e.VerticalChange); + args.RoutedEvent = HeaderDragDeltaEvent; + args.Source = this; + this.RaiseEvent(args); + + if (!args.Handled) + { + if (this.Container == null) + { + double left = 0.0; + + if (this.FlowDirection == System.Windows.FlowDirection.RightToLeft) + left = this.Left - e.HorizontalChange; + else + left = this.Left + e.HorizontalChange; + + this.Left = left; + this.Top += e.VerticalChange; + } + else + { + double left = 0.0; + + if (this.FlowDirection == System.Windows.FlowDirection.RightToLeft) + left = Container.Left - e.HorizontalChange; + else + left = Container.Left + e.HorizontalChange; + + Container.Left = left; + Container.Top += e.VerticalChange; + } + } + } + + /// + /// Processes the double-click on the header. + /// + /// The instance containing the event data. + protected virtual void OnHeaderIconDoubleClicked(MouseButtonEventArgs e) + { + if (!this.IsCurrentWindow(e.OriginalSource)) + return; + + e.Handled = true; + + MouseButtonEventArgs args = new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, MouseButton.Left); + args.RoutedEvent = HeaderIconDoubleClickedEvent; + args.Source = this; + this.RaiseEvent(args); + + if (!args.Handled) + { + this.Close(); + } + } + + /// + /// Processes the close button click. + /// + /// The instance containing the event data. + protected virtual void OnCloseButtonClicked(RoutedEventArgs e) + { + if (!this.IsCurrentWindow(e.OriginalSource)) + return; + + e.Handled = true; + + _dialogResult = object.Equals(_button, MessageBoxButton.OK) + ? MessageBoxResult.OK + : MessageBoxResult.Cancel; + + RoutedEventArgs args = new RoutedEventArgs(CloseButtonClickedEvent, this); + this.RaiseEvent(args); + + if (!args.Handled) + { + this.Close(); + } + } + + /// + /// Sets the MessageBoxResult according to the button pressed and then closes the MessageBox. + /// + /// The source of the event. + /// The instance containing the event data. + private void Button_Click(object sender, RoutedEventArgs e) + { + Button button = e.OriginalSource as Button; + + if (button == null) + return; + + switch (button.Name) + { + case PART_NoButton: + _dialogResult = MessageBoxResult.No; + this.Close(); + break; + case PART_YesButton: + _dialogResult = MessageBoxResult.Yes; + this.Close(); + break; + case PART_CancelButton: + _dialogResult = MessageBoxResult.Cancel; + this.Close(); + break; + case PART_OkButton: + _dialogResult = MessageBoxResult.OK; + this.Close(); + break; + } + + e.Handled = true; + } + + /// + /// Callack to the Container.Closed event + /// + /// + /// + private void OnContainerClosed(object sender, EventArgs e) + { + this.Container.Closed -= this.OnContainerClosed; + this.Container.Content = null; + Debug.Assert(this.Container == null); + this.OnClose(); + } + + private void OnClose() + { + this.Visibility = Visibility.Collapsed; + this.OnClosed(EventArgs.Empty); + } + + private void MessageBox_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) + { + if ((bool)e.NewValue) + { + Action action = () => + { + //Focus first Focusable Child element of MessageBox to prevent Tab outside MessageBox. + var defaultButton = this.GetDefaultButtonFromDefaultResult(); + if (defaultButton != null) + { + defaultButton.Focus(); + } + }; + + Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, action); + } + } + + #endregion //Event Handlers + + #region Events + + /// + /// Occurs when the MessageBox is closed. + /// + public event EventHandler Closed; + protected virtual void OnClosed(EventArgs e) + { + if (Closed != null) + Closed(this, e); + } + + + #endregion + + #region COMMANDS + + private void ExecuteCopy(object sender, ExecutedRoutedEventArgs e) + { + StringBuilder sb = new StringBuilder(); + sb.Append("---------------------------"); + sb.AppendLine(); + sb.Append(Caption); + sb.AppendLine(); + sb.Append("---------------------------"); + sb.AppendLine(); + sb.Append(Text); + sb.AppendLine(); + sb.Append("---------------------------"); + sb.AppendLine(); + switch (_button) + { + case MessageBoxButton.OK: + sb.Append(OkButtonContent.ToString()); + break; + case MessageBoxButton.OKCancel: + sb.Append(OkButtonContent + " " + CancelButtonContent); + break; + case MessageBoxButton.YesNo: + sb.Append(YesButtonContent + " " + NoButtonContent); + break; + case MessageBoxButton.YesNoCancel: + sb.Append(YesButtonContent + " " + NoButtonContent + " " + CancelButtonContent); + break; + } + sb.AppendLine(); + sb.Append("---------------------------"); + + try + { + new UIPermission(UIPermissionClipboard.AllClipboard).Demand(); + Clipboard.SetText(sb.ToString()); + } + catch (SecurityException) + { + throw new SecurityException(); + } + } + + #endregion COMMANDS + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MessageBox/Implementation/VisualStates.MessageBox.cs b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MessageBox/Implementation/VisualStates.MessageBox.cs new file mode 100644 index 00000000..11dba62b --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MessageBox/Implementation/VisualStates.MessageBox.cs @@ -0,0 +1,27 @@ +/************************************************************************************* + + Toolkit for WPF + + Copyright (C) 2007-2018 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +namespace Xceed.Wpf.Toolkit +{ + internal static partial class VisualStates + { + public const string MessageBoxButtonsGroup = "MessageBoxButtonsGroup"; + public const string OK = "OK"; + public const string OKCancel = "OKCancel"; + public const string YesNo = "YesNo"; + public const string YesNoCancel = "YesNoCancel"; + } +} diff --git a/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MessageBox/Themes/Aero2.NormalColor.xaml b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MessageBox/Themes/Aero2.NormalColor.xaml new file mode 100644 index 00000000..c0a3ddb1 --- /dev/null +++ b/third_party/ExtendedWPFToolkit/Xceed.Wpf.Toolkit/MessageBox/Themes/Aero2.NormalColor.xaml @@ -0,0 +1,238 @@ + + + + + + + + + + + + + + + + + + + + + + + Visible + + + + + + + + + + + Visible + + + + + + + Visible + + + + + + + + + + + Visible + + + + + + + Visible + + + + + + + + + + + Visible + + + + + + + Visible + + + + + + + Visible + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +