Newsgroup: it.comp.lang.delphi
Titolo: Aggiunta colori in TColorComboBox in Firemonkey

 
 
Salve a tutti,
 
sono un insegnante che si diletta a realizzare talora piccoli
programmini un po' piu' completi dei soliti esempi elementari
dei libri.
Preferenzialmente per scrivere codice uso sw Borland
(ora Embarcadero) o Lazarus.
Ultimamente ho avuto un problema che mi sta' facendo perdere un
sacco di tempo.  Volevo realizzare un semplice convertitore
che partendo dal codice a colori di una resistenza elettrica
rendesse il suo valore in ohm.
Ho iniziato percio' a considerare il controllo TColorComboBox
sotto Firemonkey (volevo che questa applicazione fosse riadattabile
anche ai tablet o cellulari Android), ossia la combo che permette
di associare il nome del colore ad una indicazione visiva
del colore stesso.
Purtroppo non ho assolutamente capito come fare ad aggiungere
nuovi colori nella lista della combo.
Sono riuscito a svuotare la combo, ma non ad aggiungere elementi
colore nuovi, ma solo scritte (ma a questo punto e' inutile
utilizzare una TColorComboBox).
Specifico che con il controllo analogo sotto VCL (TColorBox)
non ho avuto problemi a fare tutte le necessarie operazioni:
(aggiunta custom di colori):
 
    ColorBox1.Clear();
    ColorBox1.Items.AddObject('Rosso',TObject(clRed));
    ColorBox1.Items.AddObject('Giallo',TObject(clYellow));
    ....
purtroppo con VCL non posso creare Apps.
 
Qualcuno un po' esperto di Firemonkey e delle ultime versioni
di Delphi mi puo' scrivere un esempio, possibilmente semplice,
che mostri come aggiungere nuovi colori ad una TColorComboBox vuota ?
Specifico che sto' utilizzando RAD Studio XE7.
 
Ringrazio molto per l'aiuto
 
                             Alberto Veneziani
 
 

Ciao,
 
Potresti partire da qui
 
http://torry.net/pages.php?id=135
 
 
Sono componenti un po datati, pero' uno e' molto interessante e potrebbe 
fare al caso tuo (nel senso che potresti modificarlo e oltre a mettere il 
nome del colore puoi anche mettere il valore della resistenza. In questo 
caso potresti fare una combo dove al posto del colore metti il valore della 
resistenza da cui poi recuperi il colore per lo schema).
 
Buon lavoro
 
Daniele 
 


Ciao Daniele,
 
ti ringrazio molto per la tua risposta.
Dare una mano nei gruppi di discussione penso sia
una attivita' benemerita e che necessita anche di
una certa pazienza.
Sono andato a vedere la pagina che mi hai indicato
e ho osservato, seppur superficialmente, le caratteristiche
dei componenti (interessanti, fosse solo per il fatto
che sono freeware e hanno abbinati i sorgenti) che mi hai
indicato.
Quello su cui sto' lavorando e' infatti un componente
di quel tipo, ma purtroppo sotto Firemonkey in quanto
voglio creare una App da utilizzare su tablet
e/o telefoni Android.
Non posso (almeno credo) utilizzare componenti di
vecchie versioni di Delphi per sviluppare multipiattaforma.
Il componente che avevo programmato di utilizzare e'
standard e gia' accluso a XE7, sotto la tab Colors quando
si opera con Firemonkey ed e' documentato on line,
sul sito Embarcadero, qui:
 
http://docwiki.embarcadero.com/Libraries/XE7/en/FMX.Colors.TColorComboBox
 
 
Si tratta solo di farlo "funzionare" a dovere, cosa
che non so' fare.  Il mio problema resta quello,
dopo averlo svuotato, di aggiungere colori custom,
e semmai, all'occorrenza, rimuoverli.
Sotto VCL sono riuscito ad ottenere il pochi minuti
le due operazioni e devo dire che li' mi sembrano piu' intuitive.
Spero che qualcuno sappia come fare per ottenere
questo risultato anche in Firemonkey.
Ciao, ed ancora grazie
 
                         Alberto
 
 
 
 
 

 
 
 
Ciao a tutti,
 
dopo diversi giorni di lavoro serrato, test e ricerche su Internet
e grazie anche al fatto delle vacanze di Natale, ho potuto dare
soluzione al problema che avevo precedentemente posto nel thread
utilizzando Firemonkey e C++ Builder XE7.
Per prima cosa ho determinato ad un certo punto che anche le
combobox comuni in Firemonkey possono operare come la meno nota
ColorComboBox.
Per cui ad un certo punto ho deciso di praticare questa strada,
partendo appunto da una combo vuota in cui aggiungere elementi
dinamicamente.
In pratica risulta che per aggiungere un oggetto TListBoxItem ad una
combobox (dovrebbe essere analogo anche per la listbox) basta
inizialmente operare sul gruppo degli Items della Combo, aggiungendo
una voce come stringa.
Successivamente si recupera l'item ormai creato e vi si opera sopra,
indicando che deve avere stile colorlistboxitemstyle.
Questo ha come effetto che nell'item cosi' settato appare
in automatico anche una piccola box per indicare il colore.
Importante: Perche' cio' accada la proprieta' DropDownKind
della combo deve essere posta a Custom.
Successivamente si opera per variare il colore.
Non sono riuscito finora a capire come effettuare
questa operazione tramite l'IDE a design-time.
Ragion per cui mi sono documentato per operare via programma;
(le box colore della combo inizialmente avevano colori a caso
e persino varianti a seconda dei momenti !).
Pare che queste variazioni possano essere un bug del componente,
in quanto una volta impostato o presente un colore non c'e' alcun
senso che esso vari a caso.
Questi ultimi passi decisivi gli ho recuperati da un sito tedesco
(per fortuna che i tedeschi non hanno abbandonato Delphi !
e secondo me fanno bene):
 
http://www.delphipraxis.net/177676-colorlistboxitemstyle-bei-listboxitems-fehler-bei-mir-oder-fmx.html
 
 
questa pagina mi ha dato le ultime informazioni necessarie
per risolvere il problema.  Intanto l'accesso al dato
relativo al colore (della cui tecnica non avevo idea)
ed in secondo luogo l'informazione che pare ci sia
un problema di refresh sul componente, per cui il colore
pur correttamente settato all'inizio dopo poco "sballa"
a caso di nuovo.
Questa ultima cosa (di tedesco ne capisco poco), a quanto
ho capito dovrebbe essere un bug anche secondo gli utenti
esperti che rispondo sul forum e quindi la soluzione
proposta in realta' e', in parte, anche una patch a questo
problema.
Per risolvere si abbina una routine di refresh del colore
corretto all'evento OnPainting dell'oggetto ListItem
appena creato dinamicamente.
Insomma i passaggi sono stati tanti e piuttosto complessi
e nascosti, tra l'altro ci si e' messo anche il
probabile bug sopracitato a complicare un po' le cose.
Una soluzione che sarebbe stata piu' semplice
e che mi era venuta in mente era eliminare in base
al nome del colore da una colorcombobox (che e' gia'
carica di diversi e numerosi colori - pare 140 ed oltre),
tutti quelli che non servivano (se ricordo bene avevo operato
con una forma del tipo Combo->Items->Delete(<indice dell' elemento>),
e aveva funzionato, risparmiandomi tutto questo giro,
ma poi ho deciso che volevo risolvere questo problema
anche per via diretta.
Purtroppo anche qui c'erano dei problemi legati ai
bug della piattaforma.  Fate un drag and drop di
una ColorComboBox su una form.   Dovrebbe risultarvi
che tra i colori presenti ne vengono ripetuti alcuni,
ad esempio a me risultava ripetuto il Fuchsia e l' Aqua.
A parte che la stessa cosa avviene anche nella box
di selezione dei colori sull'object inspector,
quindi deve essere un problema proprio di qualche file
di configurazione o routine piu' generale...
Riporto qui sotto il codice che ho appena scritto
su un C++ Builder XE7 se qualcuno ne avesse bisogno
o non avesse del tutto capito la spiegazione a parole.
Ho parlato di C++ Builder perche' io il programmino lo sto'
scrivendo con quel linguaggio ma ovviamente le problematiche
su Firemonkey e su questi componenti sono del tutto analoghe
anche per Delphi e tradurre questo sorgente, come al solito,
non dovrebbe essere un grosso problema.
 
Auguro a tutti un sereno e proficuo 2017
 
               Alberto Veneziani
 
 
//---------------------------------------------------------------------------
 
#include <fmx.h>
#pragma hdrstop
 
#include "resistenze_android.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.fmx"
 
struct colori
{
	TAlphaColor colore;
	UnicodeString nome_colore;
};
 
TForm1 *Form1;
 
colori cf[10] = { {claBlack, "Nero"} , {claBrown, "Marrone"}, {claRed, 
"Rosso"},
				   {claOrange, "Arancione"}, {claYellow, "Giallo"}, {claGreen, "Verde"},
				   {claBlue, "Blu"}, {claViolet, "Viola"}, {claGray, "Grigio"},
				   {claWhite, "Bianco"} };
 
void __fastcall TForm1::SetListboxItembarColor(TObject *Sender, TCanvas 
*Canvas, const TRectF &ARect)
{
	TListBoxItem *Lbi;
 
	Lbi = (TListBoxItem*) Sender;
	((TRectangle*) Lbi->FindStyleResource("color"))->Fill->Color = Lbi->Tag;
}
 
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
 
 
 
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
	int idx;
	TListBoxItem *Lbi;
 
	for (idx = 0; idx < 10; idx++)
	{
	   cmbCifra1->Items->Add(cf[idx].nome_colore);
	   Lbi = cmbCifra1->ListItems[cmbCifra1->Items->Count - 1];
	   Lbi->StyleLookup = "colorlistboxitemstyle";
        Lbi->Tag = cf[idx].colore;
	   Lbi->OnPainting = SetListboxItembarColor;
	}
}
//---------------------------------------------------------------------------
 
 
//---------------------------------------------------------------------------
 
#ifndef resistenze_androidH
#define resistenze_androidH
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <FMX.Controls.hpp>
#include <FMX.Forms.hpp>
#include <FMX.ListBox.hpp>
#include <FMX.StdCtrls.hpp>
#include <FMX.Types.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:	// IDE-managed Components
	TLabel *Label1;
	TLabel *Label2;
	TLabel *Label3;
	TLabel *Label4;
	TComboBox *cmbCifra1;
	TComboBox *cmbCifra2;
	TComboBox *cmbMolt;
	TComboBox *cmbPrec;
	TLabel *Label5;
	TLabel *Label6;
	TLabel *Label7;
	TLabel *Label8;
	TButton *btnVediDati;
	void __fastcall FormCreate(TObject *Sender);
private:	// User declarations
public:		// User declarations
	__fastcall TForm1(TComponent* Owner);
     void __fastcall TForm1::SetListboxItembarColor(TObject *Sender, 
TCanvas *Canvas, const TRectF &ARect);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif