Recent

Author Topic: TStatusBar contents not drawn  (Read 7703 times)

LRS

  • New member
  • *
  • Posts: 7
TStatusBar contents not drawn
« on: December 27, 2012, 12:39:19 pm »
Hi,

In compiling a project for Carbon that I've developed on Linux (GTK2 and Qt), and successfully also compiled for Windows, I've discovered that the TStatusBar that works fine in all those other widgetsets doesn't have its contents drawn on Carbon. To create a small project that demonstrates this, create a new application with as per default a single form, to which add a TStatusBar, to which add a single panel with width of 50 and Style of psOwnerDraw, and a single TButton, then add to the "var" section of Unit1 the Integer variable "n", initialised to 0, and then set the following OnDrawPanel event for the TStatusBar and OnClick event for the TButton:

Code: [Select]
procedure TForm1.StatusBar1DrawPanel(StatusBar: TStatusBar;
  Panel: TStatusPanel; const Rect: TRect);
begin
  Inc(n);
  Form1.Text := '[' + IntToStr(n) + '] Entered StatusBar1DrawPanel';
  StatusBar.Canvas.Brush.Color := clGreen;
  StatusBar.Canvas.FillRect(Rect);
end;

procedure TForm1.Button1Click(Sender: TObject);
var rect: TRect;
begin
  rect.Left := 1;
  rect.Right := StatusBar1.Panels[0].Width - 2;
  rect.Top := 1;
  rect.Bottom := StatusBar1.Height - 2;
  StatusBar1.Canvas.Brush.Color := clRed;
  StatusBar1.Canvas.FillRect(Rect);
end;

When I run this on all widgetsets other than Carbon, the status bar is immediately filled in red and the form's title bar is set to '[<some small integer>] Entered StatusBar1DrawPanel', and clicking on the button fills in the leftmost area of the status bar in green. When I run it on Carbon, though, none of this happens: the form's title remains "Form1", the statusbar appears but it is coloured the default grey, and clicking on the button has no visible effect.

(If I add to the status bar another panel with Style set to psText and with Text set to "Test", it *does* show up as expected, with the expected text visible)

Is this expected/known behaviour and/or a known bug? If not, can anyone else reproduce it? I'm using Lazarus 1.0.4 on OSX; earlier versions for other platforms.

Thanks for your time.

Ocye

  • Hero Member
  • *****
  • Posts: 518
    • Scrabble3D
Re: TStatusBar contents not drawn
« Reply #1 on: December 27, 2012, 02:28:14 pm »
Carbon allows drawing only at OnPaint-events. It is not possible to user draw status bar's panels (and most other controls). But you may use Qt widgetset to have almost the same behaviour.
Lazarus 1.7 (SVN) FPC 3.0.0

LRS

  • New member
  • *
  • Posts: 7
Re: TStatusBar contents not drawn
« Reply #2 on: December 27, 2012, 05:47:29 pm »
Thanks for the definitive answer, Ocye. If I were to use the Qt widgetset, would I then need to distribute the Qt library with the OSX version of application, or is it (or can it be) statically linked in? I haven't even thought to question this on Linux because for that platform I provide both Qt and GTK2 versions of my application, and regardless of whether or not those libraries are linked in statically (judging by my application size, they're very probably not), any given Linux user is bound to have at least one of the two installed for dynamic linking.

Also, I just tried to build for the Cocoa widgetset, but if I so much as add an empty TStatusBar to an empty project, running the project results in an "Access violation" dialogue. Is this known/expected behaviour, and/or a known bug?

Thanks again.

Ocye

  • Hero Member
  • *****
  • Posts: 518
    • Scrabble3D
Re: TStatusBar contents not drawn
« Reply #3 on: December 27, 2012, 10:35:10 pm »
You can "statical add" the Qt framework to your app. But the resulting compressed disc image (dmg) is rather big [1]. I decided for the same reason as you to make the MacOS based on Qt only and provide both Gtk2 and Qt for Linux. BTW: Keep in mind that Qt framework needs libqtpas even on Linux which might not be part of the distribution.

Cocoa: Never tried. And actually I don't have a Mac  8).

[1] http://www.lazarus.freepascal.org/index.php/topic,17123.msg94131.html
Lazarus 1.7 (SVN) FPC 3.0.0

LRS

  • New member
  • *
  • Posts: 7
Re: TStatusBar contents not drawn
« Reply #4 on: December 29, 2012, 11:18:21 am »
You can "statical add" the Qt framework to your app. But the resulting compressed disc image (dmg) is rather big

I'd rather avoid that. I've found a preferable solution: it seems that certain components can be drawn on outside of the OnPaint event, including TImages (in fact I already knew this because my application is graphical and it already draws to a primary TImage; somehow this fact didn't enter my mind when I read your response). So, I'll simply shift my TStatusBar a little to the right and insert a TImage where the leftmost panel of the TStatusBar used to be, a TImage upon which I can draw as and when required.

BTW: Keep in mind that Qt framework needs libqtpas even on Linux which might not be part of the distribution.

Huh. So it does. I hadn't realised that until now; I'd assumed it was statically linked in. Is there a way to statically link it in? I also notice that ldd reports its path as /usr/local/lib/libQt4Pas.so.5, and my application refuses to run when I move this library file to an alternative location, such as to /usr/lib or the current directory (and yes, I've taken account of the fact that this particular file is a symbolic link to the actual library file). So, are users of my application going to require write access to /usr/local/lib to install this library? I'd prefer them not to have to; ideally, as I said, it would be statically linked, saving that, I'd like to be able to simply package it in the same directory as my application and have it linked from there.

The  only information Google turns up on this is this[1] post, an apparently untested suggestion. It seems plausible, except I'm not sure how you would also direct Lazarus to refrain from trying to dynamically link the library in, which, it seems to me, would cause symbol (function/procedure/variable) conflicts.

[1] http://lists.freepascal.org/lists/fpc-pascal/2012-January/032113.html

kamischi

  • Full Member
  • ***
  • Posts: 177
Re: TStatusBar contents not drawn
« Reply #5 on: February 06, 2013, 05:35:49 pm »
Hi

From a user's perspective, it is best to have all dynamic libs (except the default ones from Apple) inside the application folder and not somewhere on the system. Then the user can move around the application bundle as he likes, even to different machines. That is expected behaviour! As you might expect after this, installing in /usr/local/lib or /usr/local or whereever violates the User Interface Guidelines of Apple.

One way to achieve this is to copy the libs into the .app/Content/MacOS directory of the application and tweak the libs and the executable with install_name_tool. You will have to read the man page of install_name_tool. There is an example in the makefile of UltraStar Deluxe. It is done in the target macosx-standalone-app (https://sourceforge.net/p/ultrastardx/svn/2938/tree/trunk/Makefile.in) for about 40 dylibs, including some nested dependencies. The dylibs for USDX are from fink, but that makes no major difference. It may sound difficult at first, but once it is setup, you are basically done.

Hope this helps - Michael
fpc 2.6.4, lazarus 1.4.0, Mac OS X, fink

LRS

  • New member
  • *
  • Posts: 7
Re: TStatusBar contents not drawn
« Reply #6 on: February 06, 2013, 07:18:33 pm »
Just what I needed to know, thanks, Michael. And I've now with some googling found a comparable tool for Linux, PatchELF[1].  Problem solved.

[1] http://nixos.org/patchelf.html

User137

  • Hero Member
  • *****
  • Posts: 1791
    • Nxpascal home
Re: TStatusBar contents not drawn
« Reply #7 on: February 06, 2013, 07:44:40 pm »
Now that it's mentioned, there does seem to be some interference with TStatusBar. I was originally going to use it with my OpenGL tool, but it caused TOpenGLContext to draw only a white screen. Remove TStatusBar and replace it with bottom aligned TPanel fixed it for me. Sadly i was unable to reproduce it on new project.
« Last Edit: February 06, 2013, 07:46:12 pm by User137 »