Page 1 of 2

temporarily ignoring styles

Posted: Tue Apr 24, 2007 7:18 am
by dave novo
Hi Sergey,

We have created a LabelItem descendent with some capabilities to dynamically update its text depending on the state of our program. However, we would also like to change the Style depending on that state of the program.

For instance, for a given label item

if somevalue>x then label item color is red
else if somevalue>y then label item is blue
otherwise label item is color specified by textStyleNo

We could just change the style, but then we would lose what the "user selected style" number is. So if the user selects the label item, and changes the color, the styleNo should change, even though the label item may be being displayed in the red color becuase somevalue > x.

I guess we need something like onGetStyleNo which allows us to override the style number that the label item is returning.

Posted: Tue Apr 24, 2007 8:01 am
by Sergey Tkachenko
You can create your own item type inherited from TRVLabelItemInfo, with overriden DoPaint method.

You'll also need to assign new StyleNo to this item (please do not use values in range -201..-205, as they are reserved for new item types that will be included in the new version of TRichView), override constructors (Create and CreateEx) to assign this StyleNo, and call RegisterRichViewItemClass in the initialization section.

Posted: Tue Apr 24, 2007 2:10 pm
by dave novo
Hi Sergey,

We have already done what you describe, with the exception of overriding the doPaint method.

Will we have to duplicate all the code you have written to paint the label item, except in our own styleNo? That is not very maintainable when you come out with new versions.

It may be useful to have an event like onGetStyleNo that is fired just before the styles are applied in

Code: Select all

  RVStyle.ApplyStyle(Canvas, TextStyleNo, rvbdUnspecified, rvidsCanUseCustomPPI in State);
  RVStyle.ApplyStyleColor(Canvas, TextStyleNo, TextDrawState, false, ColorMode);
that allows the user to supply a different style no to the item. If this could be done for all items, this could be useful to other people as well I think.

For instance:

Code: Select all

useStyleNo:=TextStyleNo
if assigned(onGetStyle) then
  onGetStyle(useStyle);
  RVStyle.ApplyStyle(Canvas, useStyleNo, rvbdUnspecified, rvidsCanUseCustomPPI in State);
  RVStyle.ApplyStyleColor(Canvas, useStyleNo, TextDrawState, false, ColorMode);
Where onGetStyle is a TGetStyleEvent=procedure (var styleNo:integer) of object.

Posted: Tue Apr 24, 2007 6:41 pm
by Sergey Tkachenko
May be you can simply change TextStyleNo property when Text changes?

Posted: Tue Apr 24, 2007 6:56 pm
by dave novo
If we change the textStyleNo when the text changes, we will lose what the original one was.

For instance, if the user selects the label item and chooses BOLD, we want to update the TextStyleNo to be the new bold style, as usual. However, sometimes we want to ignore the user selected TextStyleNo (which they set by doing the usual formatting stuff) and be able to apply our own custom one, without losing what the original one should have been. Of course if we completely copy the DoPaint method, we could do what you suggest such as

Code: Select all

oldStyleNo:=TextStyleNo;
if needToUseSpecialStyle then
  TextStyleNo:=specialStyleNo;
RVStyle.ApplyStyle(Canvas, useStyleNo, rvbdUnspecified, rvidsCanUseCustomPPI in State);
  RVStyle.ApplyStyleColor(Canvas, useStyleNo, TextDrawState, false, ColorMode); 
TextStyleNo:=oldStyleNo;
However, that requires us duplicating your doPaint and making updates problematic. An onGetStyleNo Event should provide the same flexibility and would be relatively safe.

Ideally, you could implement TextStyleNo as a property with a getter that either returned FTextStyleNo or a StyleNo provided by an event.

Code: Select all

function getStyleNo:integer
begin
  result:=FStyleNo;
  if assigned(FOnGetStyleNo) then
    FOnGetStyleNo(result);
end;
Of course, you would have to stream only the FTextStyleNo and not the property, using defineProperties, so that may be a bit more work. An event just before the painting should do the trick for most people.

Posted: Wed Apr 25, 2007 4:07 am
by Sergey Tkachenko
Ok, I got the point.
But the user must provide TextStyleNo having all the same properties, but different colors.
May be it makes more sense to add Color and BackColor properties allowing to override the style's colors?

Posted: Wed Apr 25, 2007 4:43 am
by dave novo
Hi Sergey,

Why would only the color have to change? Why not any part of the style.

for instance, the text in our labels updates according to statistical values. As the statistics of the analysis change, so do the values. When the statistic is within a normal range, they just want normal font (i.e. whatever the textStyleNo is). However, if its out of normal range, they want it 20 pt font, bold and red. Could I not just have the onGetStyleNo event (or whatever) fire and then if the stat is in normal range leave the styleNo alone, but if its out of normal range apply the other style no, with the bigger font?

Posted: Wed Apr 25, 2007 5:01 am
by Sergey Tkachenko
Because all other changes (except for under/over/middle lines) changes text width and/or height.

Posted: Wed Apr 25, 2007 5:07 am
by dave novo
Hi Sergey,

I had presumed that I would have to be able to provide the custom style no every time it was needed, not just printing, but width/height measurement and everywhere else. Would this be very difficult?

Posted: Wed Apr 25, 2007 10:02 am
by Sergey Tkachenko
Ok, a special style can be used for text measuring too. It would be ok providing that you return the same style for measuring and for drawing.
But which style to use for editing operations?

Posted: Wed Apr 25, 2007 3:17 pm
by dave novo
Hi Sergey,

That would be up to me to be consistent. I would probably provide the custom style for editing as well. So for instance, if the statistic was out of range, I would use the 20 pt font style. However, if they selected the label, and chose BOLD and courier, it would update the regular TextStyleNo to be bold and courier, but I would not display it as such. I would use my custom text style no until the value went into normal range, then use the regular TextStyleNo which would now be Bold and Courier.

Of course, if I change the value of the label, and hence the style no, I would have to call .Format (which is what I have to do anyhow if I simply change the text, so the whole document can reformat to accomodate the new text).

You are correct, if the user is implementing this onGetStyleNo event, they must be consistent about providing it in all places its needed i.e. painting, measuring, editing etc. Or more appropriately, the TRichview and TRichviewEdit would have to fire the event when needed.

Posted: Wed Apr 25, 2007 10:30 pm
by dave novo
Hi Sergey,

Please consider this a low priority item. We are not going to get around to implementing this for a while. I just wanted to get the idea out there in case

a) someone else was interested
b) you said it was totally impossible and we had to figure out something else

Posted: Sun Apr 29, 2007 7:40 am
by Sergey Tkachenko
Ok.
But I still think that maintainging several TextStyleNos for one item may be too difficult (to implement consistently).
Probably, an event (or virtual method) called after applying style to canvas would be better. In this event, you can modify canvas properties according to your needs, for example increase font size or change font color.

Posted: Mon Apr 30, 2007 5:34 pm
by dave novo
Hi Sergey,

If we modify the canvas after the font was applied, will the measurement, word wrapping and everything else still work? If so, then I have no complaint with this approach, as long as we get the item ID of the item that the style was being applied to, so we can only do things for our custom label items.

Posted: Tue May 01, 2007 8:42 am
by Sergey Tkachenko
Yes, all measurement and drawing procedures will work.