How to test if a TImage has a graphic assigned to it? - delphi

There's a TImage component on a form in my program.
In some situation, the program must test:
If "there is an image assigned to the picture property of the TImage component" then ...
How can I do this?

if Image1.Picture.Graphic = NIL
then ShowMessage("There is no image.")
else ShowMessage("Image found.");
If working with bitmaps, you can also do this:
if Image.Picture.Bitmap.Empty then ShowMessage("There is no spoon");

Better late than never!
The right way is:
if Assigned(Image1.Picture.Graphic) then ...

You don't say, but I'll assume you're talking about Delphi.
You can check whether there's a bitmap in the TImage control by testing:
if Image.Picture.Bitmap.Width > 0 then
// do whatever

Related

How to Clear a Bitmap in VCL

How to clear a bitmap that was declared in the .cpp as follows:
Graphics::TBitmap * Bitmap1 = new Graphics::TBitmap;
All the examples I find are for Firemonkey and there it seems quite simple
MyBitmap = new TBitmap(0,0);
...
MyBitmap->Clear(claWhite);
or
MyBitmap->ClearRect(MyRect);
But Clear() and ClearRect() are not members of TBitmap in VCL
I expect I should delete Bitmap1; in order to clear it, but then how to re-declare it, so that it is still global to all methods in the form?
Thanks in advance.
You don't need to delete and recreate the TBitmap. Simply draw a new image over top of it, for instance by using its Canvas->FillRect() method (that is essentially what the FMX examples are doing), eg:
Bitmap1->Brush->Color = clWhite;
Bitmap1->Canvas->FillRect(Rect(0, 0, Bitmap1->Width, Bitmap1->Height));

Pharo Smalltalk: How to create an input field using TextMorph and then get the data off the input field?

I am completely new to Pharo, Smalltalk. I'm developing a small app that will convert temperature from Fahrenheit to Celsius. Can anyone give me any idea on how to create an input field using TextMorph and display it on a window as shown in the screen shot. In addition, being able to get the data back from the input field when the button is clicked. The below code is what I have done so far.
Screenshot
The class TemperatureMorph
BorderedMorph subclass: #TemperatureMorph
instanceVariableNames: 'tempInputField counter'
classVariableNames: ''
package: 'Assignment'
The initialize method: Contains a label, textbox and a button.
initialize
| headingLabel converterButton|
super initialize.
self bounds: (0#0 corner:300#300).
self color: Color gray.
headingLabel := StringMorph contents: 'Converter'.
headingLabel position: 130#20.
self addMorph: headingLabel.
tempInputField := TextMorph new.
tempInputField position: 50#50.
self addMorph: tempInputField.
Thanks
On a side not, if you're doing UI stuff in Pharo for anything other than learning (It looks like OP /is/ learning, so this probably doesn't apply). You should be looking at either Glamour or Spec. Both of which have really easy text input and control systems.
Spec
Glamour
You can already see the necessary code in your screenshot, you only have to replace the construction of a StringMorph with that of a TextMorph. I suggest you take a look at the Pharo by Example book. It has a chapter on Morphic, which is the UI framework in Pharo.
yourTextMorph := TextMorph new.
yourTextMorph contents: 'initial text'.
ownerMorph addMorph: yourTextMorph.
I guess you will also want to read the contents back out of the TextMorph. You can use yourTextMorph contents to achieve that. See also Pharo Smalltalk: Reading from TextMorph

TListView DynamicAppearance with TImageObjectAppearance will not view image when using LiveBindingsDesigner with TFDMemTable

I am welcoming Embarcaderos efforts to make TListView more dynamically, and was exited to see Sarina Duponts post here where you could just link the imageindex to the TListView properties in LiveBindings Designer, and even the image property to a datafield (integer) when using DynamicAppearance and TImageObjectAppearance.
But... I tried, and did almost succeed.
In my challenge I have an application where I use TFDMemTable with TREST* function to populate the TFDMemTable. All works well if I don't use the DynamicAppearance and use i.e. ImageListItem and links the datafield I want to use to the imageindex property in TListView using LiveBindings Designer.
With DynamicApperance though, there are no imageindex property to link to, but Sarina Dupont says in here post that you could link the integer field directly to the image property (and IDE/compiler will figure it out).
Well... I figured following out: My data fields (semicreated from TREST* and TFDMemTable) are not neccesserely what they seems to be. Since I am using REST/JSON, the fieldtypes are "anonymized" to WideString, actually the FieldDefs->'dataitem'->DataType is set to "ftWideString". I tried to change this value to ftInteger in hope that this would help, but I did just get this errormessage: "FDMemtTable1: Type mismatch in field for 'datafield', exepecting: WideString actual: Integer".
So... I was nearly there, and I really want to use DynamicAppearance and view several images and textfields for each TListViewItem...
...or is it easier to make a ListViewItem 'Template' dynamically and populate it with data instead, and what is the best way to do that ?
I usually try to avoid LiveBindings. The fastest, most stable and easiest way is to add items using code.
ListView1->BeginUpdate();
try {
for (int i = 0; i < arrayOfThings->item.Length; i++) {
TListViewItem* item = ListView1->Items->Add();
item->Text = arrayOfThings->item[i]->item_name;
item->Data["itemName"] = TValue::From<UnicodeString>( arrayOfThings->item[i]->item_name);
item->Data["itemId"] = TValue::From<UnicodeString>( IntToStr( arrayOfThings->item[i]->id ));
item->Data["itemDate"] = TValue::From<UnicodeString>(arrayOfThings->item[i]->item_date);
// adding the image - imgClock is name of the image field [TImageObjectAppearance ] added to items in ItemAppearance in the TListView object that uses DynamicAppereance
const UnicodeString imgClock = L"imgClock";
dynamic_cast<TListItemImage*>(item->Objects->FindDrawable(imgClock))->Bitmap = //bitmap source;
}
} catch (...) {
}
ListView1->EndUpdate();

How to create a Chat callout in delphi

I would like to create a chat ballon just like messengers does via FireMonkey TCalloutPanel , so how could I do that by giving it a text as a parameter then get the callout resized according to the text given ^^
Thanks in advance
I wrote this up quickly. Can use this as an example to work from to meet your specific needs/wants. Also, I would highly suggest going to the custom styling route as this way, adding TControls to the TListBoxItem ( although works ) makes the TListbox scrolling horrible.
procedure TForm1.LoadMessage(SelfSent:Boolean;msg:String;var LItem:TListBoxItem);
var
panel:Tcalloutpanel;
memo:TMemo;
begin
panel:=TCalloutPanel.Create(LItem);
panel.Parent:=LItem;
panel.Align:=TAlignLayout.Client;
panel.Margins.Left:=5;
panel.Margins.Right:=5;
panel.Margins.Top:=5;
panel.Margins.Bottom:=5;
if selfSent=true then
panel.CalloutPosition:=TCalloutPosition.right
else
panel.CalloutPosition:=TCalloutPosition.Left;
panel.CalloutOffset:=10;
memo:=TMemo.Create(panel);
memo.Parent:=panel;
memo.Align:=TAlignLayout.Contents;
memo.Margins.Left:=15;
memo.Margins.Right:=15;
memo.Margins.Top:=5;
memo.Margins.Bottom:=5;
memo.HitTest:=false;
memo.Text:=msg;
LItem.Height:=memo.ContentBounds.Height+30;
if LItem.Height<60 then
LItem.Height:=70;
end;

How to check if listbox is empty?

I want to do a check on a ListBox if it is empty, like:
if {Listbox.Items is empty} then
begin
Listbox.Items.Add('Item');
end else
begin
//do somthing else
end;
The part of the check if Listbox.Items or if Listbox are/is empty is a little hard for me. I tried to figure out a way how to do it, but I failed as I am still a beginner with Delphi. How can I implement that in Delphi XE5?
if listbox.items.count = 0 then
// it's empty
In Access VBA there is no ".items.count" property on a Listbox
I tried Me.ListBox.ListCount and .ListIndex to see if the List was empty.
ListCount was always 1 and ListIndex always -1 whether the list was empty or not (in my case).
To overcome that I used:
If Me.ListBox.ItemData(0) = "" then
Do Something
End If
This worked for me - hope this helps someone
I would reverse your if statement.
Personally I like the most code in the true part of my statement and the shorter code in the false part. For some reason it makes more sense to me.
So the code would look like:
If Listbox.items.count > 0
begin
//Do something else
end
else
Listbox.items.add('item');
Also if your true, or false, part only contains 1 line of code you don't need a begin..end. It's not wrong to have them but in my opinion it makes code easier to read if they aren't there ;)

Resources