Drawings SDK Developer Guide > Working with .dwg Files > Working with Colors > Example of Entering and Displaying Color Objects
Example of Entering and Displaying Color Objects

The example demonstrates working with the color object, including the display and modification of its properties. This example uses a console menu for the following operations: getting and setting the color index [I], red component value [R], green component value [G], blue component value [B], color name with color book [N], un-naming a color [L], selecting the color method [M], and displaying the color properties [P].

The AboutColor() function displays information about the specified color value. The function requires one argument — a color value as the OdCmColor instance — and returns information about the passed value as an OdString value. The function gets the color definition method and uses the switch statement to select whether the method defines the color (byLayer, byBlock, byColor, byACI, byPen, Foreground, byDgnIndex, or None). The function inserts the color method name in the resulting string. When the method is byColor, the function gets the red, green, and blue color component values using the red(), green(), blue() methods and inserts them in the resulting string. When the method is byACI or byDgnIndex, the function gets the color index using the colorIndex() method and inserts it in the resulting string. If the index is less than 7, the function gets the predefined color name using the colorNameForDisplay() method and inserts it in the resulting string. If the color method is undefined, the function inserts the hexadecimal color value in the resulting string.

The AboutColor() function has the following implementation:


OdString AboutColor(OdCmColor color)
{
  OdString sAbout;
  switch(color.colorMethod())
  {
    case OdCmEntityColor::kByLayer:
      sAbout = L"[byLayer]";
      break;

    case OdCmEntityColor::kByBlock:
      sAbout = L"[byBlock]";
      break;

    case OdCmEntityColor::kByColor:
      sAbout.format(L"[byRGB(%d,%d,%d)]", color.red(), color.green(), color.blue());
      break;

    case OdCmEntityColor::kByACI:
      if(color.colorIndex() == 7)
        sAbout = L"[Foreground]";
      else if(color.colorIndex() < 7)
        sAbout.format(L"[byACI=%d(%s)]", color.colorIndex(), color.colorNameForDisplay().c_str());
      else
        sAbout.format(L"[byACI=%d]", color.colorIndex());
      break;

    case OdCmEntityColor::kByPen:
      sAbout = L"[byPen]";
      break;

    case OdCmEntityColor::kForeground:
      sAbout = L"[Foreground]";
      break;

    case OdCmEntityColor::kByDgnIndex:
      sAbout.format(L"[byDgnIndex=%d]", color.colorIndex());
      break;

    case OdCmEntityColor::kNone:
      sAbout = L"[Color:None]";
      break;

    default:
      sAbout.format(L"[Color:%X]", color.color());
  }
  return sAbout;
}

The PrintColorProperties() function displays the listed properties of the passed color instance and does not return a value. This function uses the color() method to display the hexadecimal color value, colorMethod() method to display the color definition method, colorIndex() method to display the color index, red(), green(), and blue() methods to display the color component values, getDictionaryKey() method to display the color dictionary key, bookName() method to display the color book name, colorName() method to display the color name in the color book, colorNameForDisplay() method to display the color display name, and the isByColor(), isByACI(), isByLayer(), isByBlock(), isForeground(), isByDgnIndex(), and isNone() functions to display the specific method name.

The PrintColorProperties() function has the following implementation:


void PrintColorProperties(OdCmColor color)
{
  wcout << L"\n  Value = [" << hex << color.entityColor().color() << dec << L"]"
        << L"\n  Method = " << (color.colorMethod() & 0x0F)
                            << ((color.isByColor()) ? L", byRGB" : L"")
                            << ((color.isByACI()) ? L", byACI" : L"")
                            << ((color.isByLayer()) ? L", byLayer" : L"")
                            << ((color.isByBlock()) ? L", byBlock" : L"")
                            << ((color.isForeground()) ? L", Foreground" : L"")
                            << ((color.isByDgnIndex()) ? L", byDgnIndex" : L"")
                            << ((color.isNone()) ? L", None" : L"")
        << L"\n  Index = " << color.colorIndex()
        << L"\n  Red = " << color.red() << L", Green = " << color.green() << L", Blue = " << color.blue() 
        << L"\n  Key = " << color.getDictionaryKey()
        << L"\n  Name = \"" << color.colorName() << "\""
        << L" in Book = \"" << color.bookName() << "\""
        << L"\n  Display Name = \"" << color.colorNameForDisplay() << L"\"";
}

The EntryColorValue() function edits the color value using a console menu and requires two arguments — a reference to a color value as the OdCmColor instance being used as a default value for editing and the definition status as a Boolean value, which is True when any color method can be used for the color definition or False when only the byColor or byACI methods can be used for the color definition. The function returns True when the color value is modified by the user, or False when the user cancels the entry. The first argument is mandatory; the second argument is optional and is True by default. The function passes the modified color value through the first argument. The function organizes a loop that inquires about the operation code and uses the switch statement to select whether the case must be performed. The function processes user actions in the loop until the user selects [Q] operation. The function displays the current color value in each iteration of the loop using the color() method the returns the color value as a hexadecimal number and the AboutColor() function that returns the string about the color definition.

The EntryColorValue() function uses the auxiliary static function, named EntryComponentValue(), that requires two arguments — a color component name as a non-empty OdString value and a reference to the variable in which the function must save the entered color component value. The function returns True when the value is entered successfully or False when the value is incorrect. The function inquires about the component value as a positive integer value in the range 0 to 255. If an entered value is incorrect or out of the range, the function displays an error message and returns False. If an entered value is correct, the function saves it in the variable specified by the second argument and returns True.

When the user selects [R], [G], or [B], the function calls the EntryComponentValue() function and passes to it the "RED", "GREEN", or "BLUE" name as a first argument and the variable for the color component value as a second argument. If the EntryComponentValue() function returns True, the entered color component value is correct and the EntryColorValue() function sets this value for the color instance using the setRed(), setGreen(), or setBlue() method appropriately. If the current color method is not byColor, the EntryColorValue() function sets the color method to byColor using setColorMethod() method.

When the user selects [I], the function inquires about the color index as a positive integer value in the range 1 to 255. If an entered value is incorrect or out of the range, the function displays an error message and breaks to the console menu. If an entered value is correct, the function calls the setColorIndex() method and passes to it the entered index. If the current color method is not byACI, the EntryColorValue() function sets the color method to byACI using setColorMethod() method.

When the user selects [M], the function inquires about the color method as a positive integer value defined by the values: 0–byLayer, 1–byBlock, 2–byColor, 3–byACI, 4–byPen, 5–Foreground, 7–byDgnIndex, 8–None. If an entered value is incorrect, the function displays an error message and breaks to the console menu. If an entered value is correct, the function calls the setColorMethod() method and passes it the entered value converted to the OdCmEntityColor::ColorMethod enumerator. If the second argument is set to False, the function ignores the [M] operation.

When the user selects [N], the function inquires about the color name and book name as a non-empty string value in the format book$color. The function calls the setNamesFromDictionaryKey() method and passes to it the entered string. The setNamesFromDictionaryKey() method sets the color name and the book name. When a user selects [L], the function calls the setNames() method and passes it empty strings as arguments. Then the EntryColorValue() function displays the color name using the colorName() method and the book name using the bookName() method. If the second argument is set to False, the function ignores the [N] and [L] operations.

When the user selects [P], the function displays the color properties using the PrintColorProperties() function. When the user selects [S], the function breaks the loop, passes the modified color value to the calling function using the first argument, and returns True as a result. When the user selects [Q], the function breaks the loop, remains current color value without changes for the calling function, and returns False as a result.

The EntryColorValue() function has the following implementation:


#include "OdaCommon.h"
#include "CmColor.h"
#include <iostream>
using namespace std;

static bool EntryComponentValue(OdString name, OdInt16& value)
{
  wcout << L"\nEntry the " << name << L" component value [0...255]:>" ;
  wcin >> value;
  if(!wcin.fail() && wcin.peek() == 10)
    if(value >= 0 && value <= 255)
      return true;
    else wcout << L"Error: " << name << L" component value is outside the scope 0...255\n";
  else { wcin.clear();  wcin.sync();  wcout << L"Error: Invalid entered value\n"; }
  return false;
}


bool EntryColorValue(OdCmColor& refColor, bool isAnyMethod = true)
{
  wchar_t keyword[64], ch = L'\0';
  OdCmColor color = refColor;
  OdInt16 value;

  wcout << L"\nStart modifying of the color properties";    
  do {
    switch(ch)
    {
      case L'P':          // Print the specific properties
      case L'p':
        PrintColorProperties(color);
        wcout << L"\n";
        break;


      case L'R':          // Entry the RED color component
      case L'r':
        if(EntryComponentValue(L"RED", value))
        {
          if(!color.isByColor()) color.setColorMethod(OdCmEntityColor::kByColor);
          color.setRed((OdUInt8)value);
        }
        break;


      case L'G':          // Entry the GREEN color component
      case L'g':
        if(EntryComponentValue(L"GREEN", value))
        {
          if(!color.isByColor()) color.setColorMethod(OdCmEntityColor::kByColor);
          color.setGreen((OdUInt8)value);
        }
        break;


      case L'B':          // Entry the BLUE color component
      case L'b':
        if(EntryComponentValue(L"BLUE", value))
        {
          if(!color.isByColor()) color.setColorMethod(OdCmEntityColor::kByColor);
          color.setBlue((OdUInt8)value);
        }
        break;


      case L'I':          // Entry the color INDEX
      case L'i':
        wcout << L"\nEntry an index [1...255]:>" ;
        wcin >> value;
        
        if(!wcin.fail() && wcin.peek() == 10)
          if(value >= 1 && value <= 255)
          {
            if(!color.isByACI()) color.setColorMethod(OdCmEntityColor::kByACI);
            color.setColorIndex(value);
          }
          else wcout << L"Error: Index is outside the scope 1...255\n";
        else { wcin.clear();  wcout << L"Error: Invalid entered index\n";  wcin.sync(); }
        break;


      case L'M':          // Set the color method
      case L'm':
        if(!isAnyMethod) break;
        wcout << L"\nMethod: 0-ByLayer, 1-ByBlock, 2-ByRGB, 3-ByACI,"
              << L"\n        4-ByPen, 5-Foreground, 7-ByDgnIndex, 8-None:>" ;
        wcin >> value;

        if(!wcin.fail() && wcin.peek() == 10)
          if(value == 0 || value == 1 || value == 2 || value == 3 ||
             value == 4 || value == 5 || value == 7 || value == 8)
          {
             color.setColorMethod((OdCmEntityColor::ColorMethod)(0xC0 | value));
          }
          else wcout << L"Error: Undefined color method\n";
        else { wcin.clear();  wcout << L"Error: Invalid entered method number\n";  wcin.sync(); }
        break;


      case L'N':          // Set the color name and book name
      case L'n':
        if(!isAnyMethod) break;
        wcout << L"\nEntry a color and book name [book$name]:>" ;
        wcin.sync();
        wcin.getline(keyword, 64, 10);

        color.setNamesFromDictionaryKey(keyword);
				
        wcout << L"Name = " << color.colorName() << L", Book = " << color.bookName() << L"\n";
        break;


      case L'L':          // Clear the color names
      case L'l':
        if(!isAnyMethod) break;
        color.setNames(L"", L"");
        wcout << L"Name = " << color.colorName() << L", Book = " << color.bookName() << L"\n";
        break;


      case L'S':          // Save and Exit
      case L's':
        refColor = color;
        return true;


      case L'\0':         // Skip an action
        break;

      default:
        wcout << L"Error: Incorrect operation\n";
    }
    wcout << L"\nCurrent color value: [" << hex << color.color() << dec << L"] = " << AboutColor(color);

    if(isAnyMethod)
    {
      wcout << L"\nM. Set the color method";
      wcout << L"\nN. Set the color and book names";
      wcout << L"\nL. Clear the color names";
    }
    wcout << L"\nR. Entry the RED color component";
    wcout << L"\nG. Entry the GREEN color component";
    wcout << L"\nB. Entry the BLUE color component";
    wcout << L"\nI. Entry the color INDEX";
    wcout << L"\nP. Print the specific properties";
    wcout << L"\nQ. Quit without saving";
    wcout << L"\nS. Save and Exit";
    wcout << L"\nSelect operation:>";
    wcin >> ch;
  }
  while(ch != L'Q' && ch != L'q');

  wcout << L"Stop modifying of the color properties\n";
  return color;
}

Testing gives the following results:


Start modifying of the color properties

Current color value: [c0000000] = [byLayer]
M. Set the color method
N. Set the color and book names
L. Clear the color names
R. Entry the RED color component
G. Entry the GREEN color component
B. Entry the BLUE color component
I. Entry the color INDEX
P. Print the specific properties
Q. Quit without saving
S. Save and Exit
Select operation:>

When the operation is P-"Print the specific properties":


Value = [c0000000]
Method = 0, byLayer
Index = 256
Red = 0, Green = 0, Blue = 0
Key =
Name = "" in Book = ""
Display Name = "BYLAYER"

When the operation is M-"Set the color method":


Method: 0-ByLayer, 1-ByBlock, 2-ByRGB, 3-ByACI,
        4-ByPen, 5-Foreground, 7-ByDgnIndex, 8-None:>1

Current color value: [c1000000] = [byBlock]

When the operation is I-"Enter the color INDEX":


Entry an index [1...255]:>5
Current color value: [c3000005] = [byACI=5(blue)]

When the operation is N-"Set the color and book names":


Entry a color and book name [book$name]:>colorbook$blue
Name = blue, Book = colorbook

When the operation is P-"Print the specific properties":


Value = [c3000005]
Method = 3, byACI
Index = 5
Red = 0, Green = 0, Blue = 255
Key = colorbook$blue
Name = "magenta" in Book = "colorbook"
Display Name = "blue"

When the operation is L-"Clear the color names":


Name = , Book =
Current color value: [c3000005] = [byACI=5(blue)]

When the operation is I-"Enter the color INDEX" and then P-"Print the specific properties":


Entry an index [1...255]:>35

Value = [c3000023]
Method = 3, byACI
Index = 35
Red = 153, Green = 114, Blue = 76
Key =
Name = "" in Book = ""
Display Name = "35"

When the operation is R-"Enter the RED color component":


Entry the RED component value [0...255]:>12
Current color value: [c20c0000] = [byRGB(12,0,0)]

When the operation is G-"Enter the GREEN color component":


Entry the GREEN component value [0...255]:>34
Current color value: [c20c2200] = [byRGB(12,34,0)]

When the operation is B-"Enter the BLUE color component":


Entry the BLUE component value [0...255]:>56
Current color value: [c20c2238] = [byRGB(12,34,56)]

When the operation is P-"Print the specific properties":


Value = [c20c2238]
Method = 2, byRGB
Index = 158
Red = 12, Green = 34, Blue = 56
Key =
Name = "" in Book = ""
Display Name = "12,34,56"

Use the Q-"Quit" operation to exit:


Stop modifying of the color properties

The AboutColor(), PrintColorProperties(), and EntryColorValue() functions are used in the documented examples that require display and entry of a color value.

See Also

Working with Colors and Transparencies

Methods of the Color Definition

Copyright © 2002 – 2020. Open Design Alliance. All rights reserved.