I have been styling FireMonkey controls, but there is one issue that I have been having some real issues with, and that is how to incorporate bitmaps into FireMonkey styles using the FireMonkey Style Designer (and specifically not the Bitmap Style Designer). Certain styled objects (TButtonStyleObject, for example), have BitmapLink properties, but I cannot see how they are working in the new custom styles that are generated for a FireMonkey control.
Let me try to make the problem as transparent as possible. I add a StyleBook and set its Resource to the MetropolisUIGreen.Style in Delphi's Style directory (in XE7 this is located in C:\Users\Public\Documents\Embarcadero\Studio\16.0\Styles). I then open the FireMonkey Style Designer and locate the buttonstyle style, which consists of a TButtonStyleObject and a TButtonStyleTextObject, both parented to a TLayout. The TButtonStyleObject has a SourceLookup property value of MetroGreenstyle.png, which is a StyleName assoiated with a TImage into which the MetropolisUIGreen.png image has been loaded.
With the TButtonStyleObject (whose StyleName is background) selected, I examine the NormalLink property, which is a collection of TBitmapLinks. It is my understanding that the one BitmapLink that I see defined in NormalLink contains information about the bitmap that should be used for the button, including the coordinates (SourceRect) corresponding to a rectangular region of the MetroGreenstyle.png file.
My assumptions appear to be wrong, because when I examine MetroGreenstyle.png using a graphics program, there is nothing interesting at these coordinates. I have examined the BitmapLinks of many other styles, and there too I find that the SourceRect coordinates do not seem to actually define a meaningful region of the stylelookup png file.
I obviously have this wrong. How does the SourceRect coordinates of a BitmapLink define the bitmap that FireMonkey should use when rendering a control.
-- Edit I actually asked four question. I have updated this question to include just one question. I will include the other questions in another post. --
I think there is a difference between the bitmap embedded in the .style file (embedded as a resource) and the one stored in the file (C:\Users\Public\Documents\Embarcadero\Studio\15.0\Styles\MetropolisUIGreen.png, that is 519x760).
The embedded bitmap seems to be different in size than the external file (you can check that by looking in the Style Editor, selecting the metrogreenstyle.png node, opening the property editor for MultiResBitmap and looking at the image size provided for Scale 1.00: 750x850.
This explains why coordinates seems all wrong. I don't know if it is the external file to be out of date or the opposite.
HTH!
Update: I managed to extract the bitmap stored in the .style file and I can confirm the coordinates are relative to that bitmap!
Update(2):
.Style files and .fmx file are very similar so you can do:
1) open MetropolisUIGreen.Style with a text editor and locate the embedded bitmap (line 18), you can see:
object TImage
StyleName = 'MetroGreenstyle.png'
MultiResBitmap = <
item
Width = 0
Height = 0
PNG = {...}
2) create a new FMX application, add a TImage on the form and load a bitmap (any picture you want)
3) copy the PNG value from the .Style file into the XFM file. Beware to also fix the Width and Height properties:
MultiResBitmap = <
item
Width = 750
Height = 850
PNG = {...}
4) you should be able to see the picture at design time;
5) add a button with Image1.Bitmap.SaveToFile('C:\temp\new_file.png');
run the program and save the file to your disk. :-)
I'd like to verify Andreas solution. This is what I did.
Exported the .png as Andrea described
Opened the .png in Photoshop and changed some of the various objects
Saved the .png from Photoshop
Loaded it into the temp project TImage I used to export it in step 1.
Alt+F12 and copied the png content into the clipboard
Pasted it directly into my .style file (with Ultraedit)
Loaded the .style file in the style editor in Delphi
All the color changes was emediatly reflected in my design. Possibly there is a simpler way, but I don't know it. I did this in XE10 Seattle.
Related
I wrote a gimp python plugin to create an image, add a text layer, and write some text into it. Similar to this one.
I want to apply a different formatting to a portion of this text but I can't find the function to do it when I browse Filters > Script-Fu > Console > Browser.
This gif illustrates what I want. It was done manually:
Very complicated. You can get the info in the "parasite" attached to the text layer:
data=layer.parasite_find('gimp-text-layer').data
So for instance, for an image like this:
Data looks like this:
(markup "<markup>SO<span font=\"URW Bookman L Bold\">ME</span> <span size=\"15728\">TE</span>XT</markup>")
(font "Bungee")
(font-size 80)
(font-size-unit pixels)
(antialias yes)
(language "en")
(base-direction ltr)
(color (color-rgb 0 0 0))
(justify fill)
(box-mode dynamic)
(box-unit pixels)
(hinting yes)
Markup is possibly related to Cairo (which is the library used by Gimp to draw text and curves). However,
The parasite is only available once the image has been saved to disk
I have never checked what happens if you update the parasite.
Edited:
It seems creating or updating the parasite doesn't work and Gimp seems to ignored the parasite. It only considers it when loading the file, and when the file is saved, it generates a new parasite from the actual layer contents.
It may be easier for you to format several individual text layers side-by-side. To align them to the same baseline: if you use pdb.gimp_text_get_extents_fontname() with a character that has a flat bottom (I typically use "X") the "ascent" is the distance of the baseline from the top of the layer (round character such as "O" can extent slightly under the baseline).
I use c++ Builder 2009 but I tagged this for Delphi as well since I expect the exact same issue to exist there as well.
I use TImageList (16x16) and associate it to TListView (SmallImages) and TTreeView.
I was adding new icons via the IDE (design time) and imported some 16x16 True color + alpha channel icons. In the IDE they looked fine:
During run time, they do not look fine at all:
Notice the edges especially. The top icon is icon 5 and the bottom icon is icon 7. See how they are supposed to look in above picture.
When I convert the icons to 8 bit (256 colors) icons and import them via the IDE, they look fine during run time ! So that is certainly a solution for me. But the icons obviously lose information and though probably hardly noticeable in 16x16 icons, it sort of bugs me that I cannot find why this happens ?
The ImageList is created at design time and has its default properties.
I also tried: DrawingStyle = dsTransparent and ColorDepth = cd32Bit after which I had to import the icons again via the IDE.
The result is the same. I wonder if I need to set a particular BlendColor ?
Do I need to do something special for it to support true color icons ?
Or is the issue with TTreeView and TListView ?
Is this a VCL limitation or Windows or ..
Thoughts, suggestions ?
- Additional information - after having read David's comment.
I added a new TImageList to my project and added the 32bit icons with alpha channel. Next I 'hacked' my code to always use that ImageList and it worked beautifully.
What I do in the code is, because I have a set of icons that I use for all OS (very application related) and because I also use icons that are OS specific, such as folder icons, CD icons etc. I have an ImageList that contains all icons (OS and app specific) and on program start and OS check, I copy the OS icons that I need from one list to the list that I use.
Like so:
TIcon *Icon = new TIcon() ;
for (int x = 0 ; x < OS_Specific_count ; x++)
{
OS_xx_ImageList->GetIcon(x, Icon) ;
Use_ImageList->ReplaceIcon(x, Icon) ;
}
delete Icon ;
I fear the issue is in this part of the code !
- Additional information - after having done more testing
If I rewrite the code to something like:
TBitmap *Bitmap= new TBitmap () ;
for (int x = 0 ; x < OS_Specific_count ; x++)
{
OS_xx_ImageList->GetBitmap(x, Bitmap) ;
Use_ImageList->Replace(x, Bitmap, NULL) ;
}
delete Bitmap;
I have similar problems, yet not exactly the same. The transparency seems to get lost !
I have also noticed that:
Use_ImageList->AddImage(OS_xx_ImageList, x) ;
starting from an empty Use_ImageList seems to preserve all alpha channel data properly !
Maybe I should rewrite the code to always copy the lot this way ...
I am using C++ Builder XE2.
I wish to use a RTF file to load a template into a rich edit file so I can change marked strings eg $DATE$.
I have tried both TRichEdit and TJvRichEdit and can do the string replace no problem.
TJvRichEdit also load bmp and JPG which is what I want.
However when I load an RTF file generated in word or wordpad which has cell background colour I get the formatting but not the background colour.
I had a look at the RichView componet (WHich is quite expensive for a single component ($330US).
This loads the background colour but loses the font sizing (Seems to apply its own paragraph style rather than keeping the RTF paragraph file.
Does anyone know of a decent RichText component which will load from rtf file and keep both text formatting as well as the table background and also allow image loading.
Would prefer a free componet or at least reasonable price component < $100 US.
I have a control derived from TImage32:
TChromaDisplay = class(TImage32)
Everything is fine except that when I drop my TChromaDisplay on the form, the resulted DFM file is huge (300KB instead of <1KB) because I have garbage data (it is just a gray image) saved in the Bitmap.Data field. The Bitmap image is created and filled with gray color every time I drop my control on a form. I don't want to save the content of the image (garbage) to the DFM file since it makes the EXE larger but I don't know how.
Probably I need to write somewhere in TChromaDisplay.Create that I don't have any image data saved/stored in my TChromaDisplay. But I don't know where/how to do it.
object Display: TChromaDisplay
Left = 0
Top = 0
Width = 1465
Height = 246
Bitmap.Data = {
C0000000C0000000EBEBEBFFEBEBEBFFEBEBEBFFEBEBEBFFEBEBEBFFEBEBEBFF
EBEBEBFFEBEBEBFFEBEBEBFFEBEBEBFFEBEBEBFFEBEBEBFFEBEBEBFFEBEBEBFF
EBEBEBFFEBEBEBFFEBEBEBFFEBEBEBFFEBEBEBFFEBEBEBFFEBEBEBFFEBEBEBFF
etc
etc
etc
I have tried this in Create but won't help:
Bitmap.Width := 1;
Bitmap.Height:= 1;
Update:
Looking at design time image dialog GR32_Dsgn_Bitmap.pas for TImage32.Bitmap property, the Clear button there uses the Bitmap.Delete procedure what just sets the bitmap size to 0x0. So you can try to call it to clear the bitmap before the form stream is saved:
type
TChromaDisplay = class(TImage32)
protected
procedure WriteState(Writer: TWriter); override;
end;
implementation
procedure TChromaDisplay.WriteState(Writer: TWriter);
begin
Bitmap.Delete;
inherited;
end;
But it still doesn't explain why you have a bitmap data when you put a control on the form. You can also call the Bitmap.Delete in your control constructor after inherited part is done (when the Bitmap is already instantiated).
Still untested, since I can't simulate your problem.
This is not "garbage". It's an image (whether it's one you assigned or one that the control creates in it's constructor). It's a bitmap located at position 0, 0 with a width and height of 1465, 246.
The BitmapData is the data in the bitmap (the pixels, etc.), encoded as a hex string so it will go in the text dfm.
The solution is to figure out how the bitmap is being assigned. It's either:
In the component's constructor (a default image?)
On your form (you've assigned an image in the IDE)
It's not being removed from the DFM from a previous time it was assigned.
The first one requires that you closely examine the source code of the component to figure out where it's being assigned. You can check to see what the bitmap property is called internally (for instance, FBitmap or FImage), and then search for places it gets an image assigned (LoadFromFile, LoadFromStream, LoadFromResource, Assign, and so forth).
The second and third: Backup your dfm just in case. Delete the component from your form. Comment out any code related to it, so your unit will compile. Right-click it, and choose View as Text. Search for TChromaDisplay (or just TChroma), and delete everything you find in the dfm related to it. Right-click and chhose View as Form, and then build your project. Go back into the dfm and make sure all traces of TChroma are still gone.
I'm adding a new entry to the main menu of the Delphi IDE (Delphi 2007) and a bmp image to the image list associated to the menu (without passing a mask as parameter)
IDEMainMenu.Images.Add(Image,nil);
but the image added is not shown with a transparent color , i tried using a 8 and 24 bits bmp and using fucsia as the background color but the ide always display the icon with the background. so the question is which is the color depth of the bmp images which i must use and the color of the backgrpund to make appear the image transparent in the delphi ide menu? or i need pass a mask bmp to the Images.Add function?
try using the icon format (.ico) instead, size 16x16 and 256 colors.
this is the code which I use, the MainMenu is the instance to the IDE menu item.
Image:=TIcon.Create;
try
Image.Handle := LoadIcon(hInstance, sLogo16);
ExplorerItem.ImageIndex:=MainMenu.Images.AddIcon(Image);
finally
Image.Free;
end;