Jump to content

Problem with TUniImage on a Custom Component


eelias
 Share

Recommended Posts

This is been a big problem for me. Unigui 0.93

 

I have tried may different ways and I dont know what to do anymore.

 

I have an infraestructure that is hard to share a test case. I wonder if someone could point what is the problem.

 

This component is a kind of button, but based on the TUniImage. 

 

I have 2 images, one black other white.

 

According with the background color on my theme (not extjs theme) it calculates the highcontrast color and select the proper image to display.

 

I have tried to use ONE TUniImage and load the PNG property, from black or white when needed. BUT IT DOES NOT WORK in webmode. It causes an exception of 'nnn' file extension not recognized.

 

So I decided to use TUniPanel as the inherited class and create 2 TUniImages. One black and other white. THen I turn visible the one that I need.

 

I have tried so many things that code is looking weird. However it ALWAYS work on VCL mode.

 

In the WEB mode only the white picture shows up. The other one does not work. 

 

Above is the complete code of this component. It relies in other components and classes, but everything works, the only problem is when the TUniImage with the black image needs to show up.

unit NaharWebFlatButton;

interface

uses
  Nahar.Theme,
  NaharWebFrame,
  NaharWebThemeController, Vcl.ExtCtrls, Vcl.StdCtrls, pngimage,
  System.SysUtils, System.Classes, Vcl.Controls, uniGUIBaseClasses, PngFunctions,
  uniGUIClasses, uniImage, UniPanel, Vcl.Graphics, UniGuiTypes, uniLabel;

type
  TNaharWebFlatButton = class(TUniPanel)
  private
    FThemeColor : TNaharPalleteColor;
    FCaption: string;
    FPictureBlack: TPicture;
    FPictureWhite: TPicture;
    FShowCaption: boolean;
    FOnClick: TNotifyEvent;
    FThemeFont: TNaharPalleteFont;
    procedure   OnObserver(Sender: TObject; AParam, AValue: Variant);
    procedure   UpdateColor;
    procedure   SetThemeColor(const Value: TNaharPalleteColor);
    function    GetThemeManager: TNaharThemeManager;
    procedure   SetCaption(const Value: string);
    procedure   SetShowCaption(const Value: boolean);
    procedure   OnPictureClick(Sender: TObject);
    procedure   SetOnClick(const Value: TNotifyEvent);
    procedure   SetPictureBlack(const Value: TPicture);
    procedure   SetPictureWhite(const Value: TPicture);
    procedure   SetThemeFont(const Value: TNaharPalleteFont);
  protected
    FThemeController: TNaharThemeController;
    FImageWhite: TUniImage;
    FImageBlack: TUniImage;
    FLabel: TUnilabel;
    procedure   Loaded; override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor  Destroy; override;
    property    ThemeManager: TNaharThemeManager read GetThemeManager;
  published
    property    ThemeColor: TNaharPalleteColor read FThemeColor write SetThemeColor default npcMainColor;
    property    ThemeFont: TNaharPalleteFont read FThemeFont write SetThemeFont default npfBody;
    property    PictureWhite: TPicture read FPictureWhite write SetPictureWhite;
    property    PictureBlack: TPicture read FPictureBlack write SetPictureBlack;
    property    Caption: string read FCaption write SetCaption;
    property    ShowCaption: boolean read FShowCaption write SetShowCaption;
    property    Width default 25;
    property    Height default 25;
    property    OnClick: TNotifyEvent read FOnClick write SetOnClick;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('NaharWeb Standard', [TNaharWebFlatButton]);
end;

{ TNaharWebFlatButton }

constructor TNaharWebFlatButton.Create(AOwner: TComponent);
begin
  inherited;

  FPictureBlack         := TPicture.Create;
  FPictureWhite         := TPicture.Create;
  Width                 := 25;
  Height                := 25;
  BorderStyle           := ubsNone;

  FImageWhite                := TUniImage.Create(self);
  FImageWhite.Parent         := self;
  FImageWhite.Align          := alNone;
  FImageWhite.Center         := true;
  FImageWhite.Proportional   := true;
  FImageWhite.Transparent    := true;
  FImageWhite.Stretch        := true;
  FImageWhite.OnClick        := OnPictureClick;
  FImageWhite.Tag            := -1;

  FImageBlack                := TUniImage.Create(self);
  FImageBlack.Parent         := self;
  FImageBlack.Align          := alNone;
  FImageBlack.Center         := true;
  FImageBlack.Proportional   := true;
  FImageBlack.Transparent    := true;
  FImageBlack.Stretch        := true;
  FImageBlack.OnClick        := OnPictureClick;
  FImageBlack.Tag            := -1;

  FLabel                := TUniLabel.Create(Self);
  FLabel.Parent         := Self;
  FLabel.Visible        := false;
  FLabel.Align          := alBottom;
  FLabel.Alignment      := taCenter;
  FLabel.Text           := '';
  Caption               := '';

//  FImage.Picture.RegisterFileFormat('nnn', '', TPngImage);

  FThemeColor := npcMainColor;
  FThemeFont  := npfBody;

  FThemeController := LocateThemeController(AOwner);

  ThemeManager.AddObserver(OnObserver);

  UpdateColor;
end;

destructor TNaharWebFlatButton.Destroy;
begin
  ThemeManager.RemoveObserver(OnObserver);

  FPictureBlack.Free;
  FPictureWhite.Free;
  FImageWhite.Free;
  FImageBlack.Free;
  FLabel.Free;

  inherited;
end;

function TNaharWebFlatButton.GetThemeManager: TNaharThemeManager;
begin
  if Assigned(FThemeController) then
    result := FThemeController.ThemeManager
  else
    result := NaharThemeManager;
end;

procedure TNaharWebFlatButton.Loaded;
begin
  inherited;

  if not PictureBlack.Graphic.Empty then
    FImageBlack.Picture.Assign(PictureBlack);

  if not PictureWhite.Graphic.Empty then
    FImageWhite.Picture.Assign(PictureWhite);

  UpdateColor;
end;

procedure TNaharWebFlatButton.OnObserver(Sender: TObject; AParam, AValue: Variant);
begin
  if AParam = 'currentpalletechanged' then
    UpdateColor;

end;

procedure TNaharWebFlatButton.OnPictureClick(Sender: TObject);
begin
  if Assigned(FOnClick) then
    FOnClick(Self);
end;

procedure TNaharWebFlatButton.SetCaption(const Value: string);
begin
  FCaption := Value;

  UpdateColor;
end;

procedure TNaharWebFlatButton.SetOnClick(const Value: TNotifyEvent);
begin
  FOnClick := Value;
end;

procedure TNaharWebFlatButton.SetPictureBlack(const Value: TPicture);
begin
  if Assigned(Value) then
  begin
    FPictureBlack.Assign(Value);
    FImageBlack.Picture.Assign(PictureBlack);
  end;

  UpdateColor;
end;

procedure TNaharWebFlatButton.SetPictureWhite(const Value: TPicture);
begin
  if Assigned(Value) then
  begin
    FPictureWhite.Assign(Value);
    FImageWhite.Picture.Assign(PictureWhite);
  end;

  UpdateColor;
end;

procedure TNaharWebFlatButton.SetShowCaption(const Value: boolean);
begin
  FShowCaption := Value;

  UpdateColor;
end;

procedure TNaharWebFlatButton.SetThemeColor(const Value: TNaharPalleteColor);
begin
  FThemeColor := Value;

  UpdateColor;
end;

procedure TNaharWebFlatButton.SetThemeFont(const Value: TNaharPalleteFont);
begin
  FThemeFont := Value;

  UpdateColor;
end;

procedure TNaharWebFlatButton.UpdateColor;
var
  HCColor : TColor;

begin
  if ShowCaption then
  begin
    FLabel.Visible    := true;
    FLabel.Align      := alBottom;
    FLabel.Text       := FCaption;
    FLabel.Alignment  := taCenter;
    FLabel.Font.Size  := Self.Font.Size;
    FLabel.Font.Name  := Self.Font.Name;
    FLabel.Font.Style := Self.Font.Style;
    FLabel.Font.Color := Self.Font.Color;
  end
  else
  begin
    FLabel.Visible    := false;
    FLabel.Text       := '';
    FLabel.Align      := alNone;
  end;

  if (FThemeColor = npcNone) or (FThemeColor = npcUnknown) then
    HCColor := ThemeManager.CurrentPallete.HighContrastColor(Color)
  else
    HCColor := ThemeManager.CurrentPallete.HighContrast(FThemeColor);

  if HCColor = clWhite then
  begin
    FImageWhite.Align   := alClient;
    FImageWhite.Visible := true;
    FImageWhite.BringToFront;

    FImageBlack.Align   := alNone;
    FImageBlack.Visible := false;
  end;

  if HCColor = clBlack then
  begin
    FImageWhite.Align   := alNone;
    FImageWhite.Visible := false;

    FImageBlack.Visible := true;
    FImageBlack.Align   := alClient;
    FImageBlack.BringToFront;
  end;

  if (FThemeColor = npcNone) or (FThemeColor = npcUnknown) then
    exit;

  Color       := ThemeManager.CurrentPallete.Color[FThemeColor];

  Font.Color  := ThemeManager.CurrentPallete.HighContrast(FThemeColor);

  Font.Name   := ThemeManager.CurrentPallete.Font[FThemeFont].FontName;
  Font.Size   := ThemeManager.CurrentPallete.Font[FThemeFont].Size;

  if ShowCaption then
  begin
    FLabel.Font.Name  := Self.Font.Name;
    FLabel.Font.Color := Self.Font.Color;
    FLabel.Font.Size  := Self.Font.Size;
  end;
end;

end.

Please, if someone could point me what is the problem, why only one show up.

 

Eduardo

Link to comment
Share on other sites

  • Administrators

I don't have time to review your code but at first glance I can say that it is not compatible with uniGUI.

ThemeManager.AddObserver(OnObserver);

ThemeManager will not work in web mode.

ThemeManager

is not Thread safe.

FImageWhite.BringToFront;

BringToFront in web mode is not same as VCL!

 

 

I think you are trying to achieve a simple visual affect by writing very complex code. Web programming needs to think simple and code in a simple way.

 

Keep in mind that webmode is very different than VCL and calling Windows API functions has no meaning in web mode.

Link to comment
Share on other sites

I don't have time to review your code but at first glance I can say that it is not compatible with uniGUI.

ThemeManager.AddObserver(OnObserver);

ThemeManager will not work in web mode.

ThemeManager

is not Thread safe.

FImageWhite.BringToFront;

BringToFront in web mode is not same as VCL!

 

 

I think you are trying to achieve a simple visual affect by writing very complex code. Web programming needs to think simple and code in a simple way.

 

Keep in mind that webmode is very different than VCL and calling Windows API functions has no meaning in web mode.

 

Thanks on replying,

 

"Keep in mind that webmode is very different than VCL and calling Windows API functions has no meaning in web mode."

 

I am aware of that. And I understand the overall concept, that you use VCL components as an adapter to extpascal. However I can only experiment with no documentation. :)

 

ThemeManager is a class (actually a component) of my infraestructure. It gives me the colors, font sizes etc. that my components based on UniGui uses to apply these properties. It is thread safe and besides the name there is no correlation with any other delphi or 3rd party vendor.

 

It copies from the current theme the color, font, size, etc. Then all the panels, labels, buttons, etc, follow the same style. It is not the same as the ExTJS where themes are not only colors but rendering.

 

THis is not the problem.

 

The problem is that I have 2 TUniImage components that are created on the fly on tha TUniPanel. One shows up, other doesnt.

 

The both TUniImage are of the same size. I use alignment to client. Then it follows the same size of the TUniPanel. It is a compound component.

 

I used bringtofront and many other things trying to make one TUniImage disappear and the other shows up. I am trying to switch between then. 

 

If the background is black I need the TUniImage with the white image. And vice versa.

 

All that logic works for me. However I dont know how to make the UniGUI understand that I need to switch between the TUniImages.

 

Could you tell me how?

 

 

Eduardo

Link to comment
Share on other sites

I don't have time to review your code but at first glance I can say that it is not compatible with uniGUI.

ThemeManager.AddObserver(OnObserver);

ThemeManager will not work in web mode.

ThemeManager

is not Thread safe.

FImageWhite.BringToFront;

BringToFront in web mode is not same as VCL!

 

 

I think you are trying to achieve a simple visual affect by writing very complex code. Web programming needs to think simple and code in a simple way.

 

Keep in mind that webmode is very different than VCL and calling Windows API functions has no meaning in web mode.

 

Farshad,

 

After hundreds of tests I could find a potential problem on uniGUI.

 

My component (above) is fully working. I have instead loaded a BLACK image, used something else. It it worked.

 

The problem is that somehow BLACK images are not showing up. I have tried gray image and it shows, but difficult to see.

 

I have tried every possible combination, with our without transparency, etc.

 

It seems the problem is when I assign the PNG.

 

HOWEVER if I open the Load Image dialog box, for my PictureBlack property, I see the black image is there, as a PNG image. Then I click COPY, CLEAR and PASTE. 

 

Since this dialog only copies to clipboard as BITMAP, it transformed my image to bitmap.

 

Then it WORKS !

 

But this is not nice. Why is TUniImage accepting only images that are no black? THe image file is not corrupt, since in VCL mode it shows up on design time.

 

The framework is set to work with PNG images.

 

I am loaging a lot of other images to TUniImages. It only does not work if you use UniImage.Graphich.Assign(sourceimage)

 

Any Ideas?

 

Eduardo

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...