Shordi   04-05-2023, 12:03
#1
He necesitado para un proyecto un selector de colores al estilo del que el IDE muestra cuando necesita seleccionar un color, por ejemplo, al pulsar sobre el botón de la propiedad Background.
Su aspecto es éste:

[Imagen: MM1vFa3.png]

Como veis, prácticamente igual que el del IDE, salvo por el orden de los colores. Hasta donde lo he probado funciona bien... peeeero, después de tres días de pelearme con las classes del sistema para obtener los colores por defecto,  me he rendido y he acabando haciendo esto:
Código:
  $aColors.Add([Color.Background, "Background"])
  $aColors.Add([Color.Black, "Black"])
  $aColors.Add([Color.Blue, "Blue"])
  $aColors.Add([Color.ButtonBackground, "ButtonBackground"])
  $aColors.Add([Color.ButtonForeground, "ButtonForeground"])
  $aColors.Add([Color.Cyan, "Cyan"])
  $aColors.Add([Color.DarkBlue, "DarkBlue"])
  $aColors.Add([Color.DarkCyan, "DarkCyan"])
  $aColors.Add([Color.DarkGray, "DarkGray"])
  $aColors.Add([Color.DarkGreen, "DarkGreen"])
  $aColors.Add([Color.DarkMagenta, "DarkMagenta"])
  $aColors.Add([Color.DarkOrange, "DarkOrange"])
  $aColors.Add([Color.DarkPurple, "DarkPurple"])
  $aColors.Add([Color.DarkRed, "DarkRed"])
  $aColors.Add([Color.DarkRoyal, "DarkRoyal"])
  $aColors.Add([Color.DarkViolet, "DarkViolet"])
  $aColors.Add([Color.DarkYellow, "DarkYellow"])
  $aColors.Add([Color.Default, "Default"])
  $aColors.Add([Color.Foreground, "Foreground"])
  $aColors.Add([Color.Gray, "Gray"])
...
...
'etc,etc
donde $aColors es un Variant[] del que se obtiene el gridview de colores.
¿Alguien conoce una manera más elegante de crear ese Variant[], es decir, obtener las constantes y los valores de la clase Color, sin tener que ponerlos a pedal?

Es que así queda como un poco cutre...

Saludos
Archivos adjuntos
.gz
SelectColor-0.0.1.tar.gz (Tamaño: 13.57 KB Descargas: 4)
Última modificación: 04-05-2023, 12:33 por Shordi.

No podemos regresar
tincho   04-05-2023, 23:02
#2
(04-05-2023, 12:03)Shordi escribió: ¿Alguien conoce una manera más elegante de crear ese Variant[], es decir, obtener las constantes y los valores de la clase Color, sin tener que ponerlos a pedal?

Se me ocurre esta forma:
Código:
Dim myClass As Class = Classes["Color"]
Dim sSymbol As String

  For Each sSymbol In myClass.Symbols
    If myClass[sSymbol].Kind = Class.Constant Then
      $aColors.Add([myClass[sSymbol].Value, sSymbol])
    Endif
  Next

1 Saludo.
Shordi   05-05-2023, 08:46
#3
¡Joder, qué simple! Pues ya te digo que estuve dos días enteros atrapado en eso como un pasmarote. Pa que veas el nivel...

Gracias, tron, es justo lo que buscaba.


Saludos

Ah... no vale.  Con eso obtienes sólo las constantes, es decir los colores puros, pero, y son más interesantes aún, no obtienes los colores del sistema. Si modificas el código más o menos así:

Código:
  For Each sSymbol In myClass.Symbols
    If myClass[sSymbol].Kind = Class.Property Or If myClass[sSymbol].Kind = Class.Constant Then
      $aColors.Add([myClass[sSymbol].Value, sSymbol])
    Endif
  Next
Esto genera el Array $aColors tal como lo queremos... pero con el valor de las propiedades (los colores del sistema son propiedades) a Null. El problema es cómo acceder al valor a partir de la cadena del nombre.
algo así como

Código:
dim ncolor as integer
dim colorname as string
colorname = "Background"
ncolor = color.(colorname) 'pongo los paréntesis por poner algo...

Se puede hacer un enfoque mixto donde los colores "simples" se obtengan con tu bucle y los del sistema con mi aproximación chapucera... pero sigue siendo poco elegante.

Gracias por tu interés

Saludos
Última modificación: 05-05-2023, 09:34 por Shordi.

No podemos regresar
tincho   05-05-2023, 11:26
#4
(05-05-2023, 08:46)Shordi escribió: Se puede hacer un enfoque mixto donde los colores "simples" se obtengan con tu bucle y los del sistema con mi aproximación chapucera... pero sigue siendo poco elegante.

Si, yo estuve rompiéndome el coco un rato pero no encontré la manera de obtener esos colores Null creo que el interprete los carga de alguna manera al inicio del programa.
Encontré las siguientes clases que mencionan un método llamado defaultBackground() pero todos en el componente gb.gtk
Código:
$ find . -type f -exec grep -H 'defaultBackground' {} \;
./gb.gtk/src/gcontrol.cpp:gColor gControl::defaultBackground() const
./gb.gtk/src/gcontrol.cpp:    return defaultBackground();
./gb.gtk/src/gcontrol.cpp:        return no_default ? defaultBackground() : COLOR_DEFAULT;
./gb.gtk/src/gtextbox.h:    virtual gColor defaultBackground() const;
./gb.gtk/src/gtextbox.cpp:gColor gTextBox::defaultBackground() const
./gb.gtk/src/gbutton.h:    gColor defaultBackground() const;
./gb.gtk/src/gbutton.cpp:gColor gButton::defaultBackground() const
./gb.gtk/src/gbutton.cpp:        return gControl::defaultBackground();
./gb.gtk/src/gcontrol.h:    virtual gColor defaultBackground() const;
./gb.gtk/src/gtextarea.h:    virtual gColor defaultBackground() const;
./gb.gtk/src/gtextarea.cpp:gColor gTextArea::defaultBackground() const
Pero no se me ocurre como acceder a ese método para "preguntarle" el color "BackGround"
Nota: Envié un email a la lista internacional preguntando por el asunto, a ver que sale de ahí.
Última modificación: 05-05-2023, 11:28 por tincho.

1 Saludo.
Shordi   05-05-2023, 13:03
#5
Genial. Han respondido en la lista y esto se queda así tras la respuesta de Bruce Steers

Código:
  Dim sSymbol As String

  For Each sSymbol In myClass.Symbols
    If myClass[sSymbol].Kind = Class.Constant Then
      $aColors.Add([myClass[sSymbol].Value, sSymbol])
    Else If myClass[sSymbol].Kind = Class.Property
      $aColors.Add([Object.GetProperty(Color, sSymbol), sSymbol])
    Endif
  Next

Gracias!!

Saludos

Lo que me fastidia es que esas clases (object, classec, etc.) las he usado cientos de veces y aún así me lío con ellas que te cagas.

Viejuno estoy, oiga...


Saludos
Última modificación: 05-05-2023, 13:04 por Shordi.

No podemos regresar
tincho   05-05-2023, 13:26
#6
(05-05-2023, 13:03)Shordi escribió: Genial. Han respondido en la lista y esto se queda así tras la respuesta de Bruce Steers

Perfecto. Hice unos cambios para usar una collection en vez de un Variant[]. Alguien una vez me convenció de usar colecciones Big Grin
Saludos.
Archivos adjuntos
.gz
SelectColor-0.0.2.tar.gz (Tamaño: 13.35 KB Descargas: 3)

1 Saludo.
tincho   05-05-2023, 19:22
#7
Shordi ¿Viste la version minimalista del la lista inernacional?

Código:
 For Each sSymbol As String In Classes["Color"].Symbols
   If Classes["Color"][sSymbol].Kind = Class.Constant Or If Classes["Color"][sSymbol].Kind = Class.Property Then $Colors[sSymbol] = Object.GetProperty(Color, sSymbol)
 Next

1 Saludo.
Shordi   05-05-2023, 20:44
#8
Sí, mola. El problema de ese tipo de sentencias es que con el tiempo, cuando tienes que releer el código se hacen farragosas... "Código ofuscado" creo que lo llaman. yo lo he dejado así en mi programa

Código:
.Symbols
  aSymbols.sort
  For Each sSymbol As String In Classes["Color"].Symbols
    If Classes["Color"][sSymbol].Kind = Class.Constant Or If Classes["Color"][sSymbol].Kind = Class.Property Then
      $aColors.Add([Object.GetProperty(Color, sSymbol), sSymbol])
    Endif
  Next
Es lo mismo y me parece más legible.
La duda que me queda es si separar en la lista según tipo, como hace el IDE o dejarla alfabética. No sé qué es más apropiado.

También resaltar lo que ya he dicho otras veces: Te rompes el coco, haces cien pruebas escribes decenas de líneas de código y al final, cuando lo solucionas, todo se reduce a unas muy pocas líneas. A veces una sola. Ser simple es lo más difícil, lo juro.

Saludos
Última modificación: 05-05-2023, 20:48 por Shordi.

No podemos regresar
tincho   06-05-2023, 10:19
#9
(05-05-2023, 20:44)Shordi escribió: Es lo mismo y me parece más legible.

si, estoy de acuerdo, ademas no me gusta cuando las variables están declaradas sobre la marcha y no todas al comienzo del método, pero bueno es otra manera de hacerlo en menos lineas.

1 Saludo.
Shordi   14-05-2023, 19:22
#10
Al final he modificado el formulario ColorSelector para que ofrezca los colores de la lista como hace el IDE: por categorías. Es decir, primero el transparente, luegos los colores del tema del escritorio y luego los colores estándar.
Lo he modificado simplemente porque acostumbrado al del IDE me perdía buscando en la lista alfabética...

Lo podéis encontrar en https://gitlab.com/shordi/ColorSelector

También he subido un vídeo al Youtube presentándolo.


Espero que os guste.

Saludos

No podemos regresar
  
Usuarios navegando en este tema: 3 invitado(s)
Powered By MyBB, © 2002-2024 MyBB Group.
Made with by Curves UI.