Author Topic: Colour Combobox for AutoCAD  (Read 2783 times)

0 Members and 1 Guest are viewing this topic.

mcarson

  • Guest
Colour Combobox for AutoCAD
« on: September 14, 2009, 04:08:38 AM »
Hi guys; still unemployed but all the spare time gives me time to play with the AutoCAD API.

I have coded a custom control that inherits from the standard .NET combo box and attempts to replicate
the AutoCAD Select Color combo box. I intend to use this in multiple add-ons I am writing for AutoCAD.

My target is AutoCAD 2010 and I am using Visual Studio 2008 (should have waited for VS2010, I've heard)

All the code is in VB (sorry, I know most of you use c#)

Code: [Select]
Namespace CCSDotNetArx

  ''' <summary>
  ''' Custom control that mirrors the legacy AutoCAD select colour combo box
  ''' </summary>
  Public Class ColourComboBox
    Inherits ComboBox

    ''' <summary>
    ''' New colours collection that determines the list in the combo box
    ''' </summary>
    Private Colours As New List(Of String)

    Private mSelectedColour As AcadCo.Color

    Public Property SelectedColour() As AcadCo.Color
      Get
        If Not IsNothing(mSelectedColour) Then
          Return mSelectedColour
        Else
          Return Nothing
        End If
      End Get
      Set(ByVal value As AcadCo.Color)
        mSelectedColour = value
      End Set
    End Property

    ''' <summary>
    ''' Default ctor
    ''' </summary>
    Public Sub New()
      Me.DrawMode = Windows.Forms.DrawMode.OwnerDrawFixed
      Me.DropDownStyle = ComboBoxStyle.DropDownList
      InitialiseDefaultColours()
      RefreshMe()
    End Sub

    Public Shadows Sub Dispose()
      If Not IsNothing(Colours) Then Colours = Nothing
    End Sub

    ''' <summary>
    ''' Refresh the custom combo box and reload all colours
    ''' </summary>
    Private Sub RefreshMe()
      Me.Items.Clear()
      For i As Integer = 0 To Colours.Count - 1
        Me.Items.Add(Colours(i))
      Next
      If Me.Items.Contains("Select...") Then
        Me.Items.Remove("Select...")
      End If
      Me.Items.Add("Select...")
    End Sub

    ''' <summary>
    ''' Add the default colours to the colours collection
    ''' </summary>
    Private Sub InitialiseDefaultColours()
      Colours.Add("1")
      Colours.Add("2")
      Colours.Add("3")
      Colours.Add("4")
      Colours.Add("5")
      Colours.Add("6")
      Colours.Add("7")
    End Sub

    ''' <summary>
    ''' Add a new item to the colours collection
    ''' </summary>
    ''' <param name="item">Input for the new item</param>
    Private Sub AddNewItem(ByVal item As String)
      Colours.Add(item)
    End Sub

    ''' <summary>
    ''' Determine when the "Select..." item is clicked and display the select colour dialog box
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub SelectColour(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.SelectedValueChanged
      'Get the value of the combo box and continue if valid
      Dim TextValue As String = Me.Text : If TextValue = "" Then Exit Sub
      'Ignore all values except the custom select item at the bottom of the list
      If Not TextValue = "Select..." Then
        SelectedColour = AcadCo.Color.FromColorIndex(AcadCo.ColorMethod.ByAci, TextValue)
        Exit Sub
      End If

      'Load the AutoCAD Select Colour dialog to prompt the user for a new colour
      Dim clr As New AcadWd.ColorDialog : clr.IncludeByBlockByLayer = False : clr.SetDialogTabs(1)
      If clr.ShowDialog <> DialogResult.OK Then
        RefreshMe()
        Me.Text = "1"
      Else
        'Check the colours list to see if the colour has already been added
        If Colours.Contains(clr.Color.ColorIndex) Then
          RefreshMe()
          Me.Text = clr.Color.ColorIndex
        Else
          AddNewItem(clr.Color.ColorIndex)
          RefreshMe()
          Me.Text = clr.Color.ColorIndex
        End If
      End If
    End Sub

    ''' <summary>
    ''' Perform all the painting of the items in the combo box replicating the AutoCAD legacy colour combo box
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub CustomDraw(ByVal sender As Object, ByVal e As DrawItemEventArgs) Handles Me.DrawItem
      If e.Index = -1 Then Exit Sub

      'Get the text value of the combo box item
      Dim TextString As String = Me.Items(e.Index)

      'Create a rectangle for custom drawing the colour box
      Dim ColourBoxRect As New Rectangle(e.Bounds.X + 1, e.Bounds.Y + 1, 18, e.Bounds.Height - 3)
      'Create a rectangle for custom drawing the text string
      Dim TextBoxRect As New Rectangle(e.Bounds.X + ColourBoxRect.Width + 4, e.Bounds.Y + 1, e.Bounds.Width - 1, e.Bounds.Height - 1)
      'Create a new brush for the background of the item
      Dim BackColourBrush As New SolidBrush(e.BackColor)
      'Create a new brush for the colour box
      Dim ColourBoxBrush As SolidBrush = Nothing

      'Create an AutoCAD colour for looking up the RGB values of the intended colour
      Dim AutoCADColour As AcadCo.Color = Nothing
      'Create a colour for the colour box
      Dim ColourBoxColour As Drawing.Color = Nothing

      'We do not need a colour box if the text is Select... as this executes a call to select a
      'new colour
      If Not TextString = "Select..." Then
        'Add a Try/Catch to prevent the forms designer from crashing when attempting to load the AutoCAD libraries
        Try
          'Get the AutoCAD colour object from the value of the item
          AutoCADColour = AcadCo.Color.FromColorIndex(AcadCo.ColorMethod.ByAci, TextString)
          'Get the RGB values of the AutoCAD colour to create a system colour for the colour box
          ColourBoxColour = Drawing.Color.FromArgb(AutoCADColour.ColorValue.R, AutoCADColour.ColorValue.G, AutoCADColour.ColorValue.B)
          'Set the colour box brush to the required colour
          ColourBoxBrush = New SolidBrush(ColourBoxColour)
        Catch ex As Exception
          Exit Sub
        End Try

        'Draw the background of the cell
        e.Graphics.FillRectangle(BackColourBrush, e.Bounds)
        'Fill the Colour Box with the new colour
        e.Graphics.FillRectangle(ColourBoxBrush, ColourBoxRect)
        'Draw the rectangle for the colour box
        e.Graphics.DrawRectangle(Pens.Black, ColourBoxRect)
        'Custom draw the text
        e.Graphics.DrawString(TextString, Me.Font, Brushes.Black, TextBoxRect)
      Else
        'Draw the background of the cell
        e.Graphics.FillRectangle(BackColourBrush, e.Bounds)
        'Custom draw the text
        e.Graphics.DrawString(TextString, Me.Font, Brushes.Black, TextBoxRect)
      End If

      If Not IsNothing(BackColourBrush) Then BackColourBrush.Dispose()
      If Not IsNothing(ColourBoxBrush) Then ColourBoxBrush.Dispose()
    End Sub

  End Class
End Namespace

The above code seems to work quite well, however, is there any suggestions to 'clean-up' the code. I have 'a hunch'
that something isn't quite right?

Also, any pointers how it could be modified to support True Color and Color Books - with the ability to persist the
'SelectedValue'?

mcarson

  • Guest
Re: Colour Combobox for AutoCAD
« Reply #1 on: September 16, 2009, 05:39:31 AM »
nobody interested in helping out?