Hi,
Could anyone tell me, or point me at an example of how you add an image to a column in a ListView. I know it has something to do with ImageMangers and Images, but its not clear to me how you get a bitmap into an instance of an Image - it looks like you have to use a resource file. Is this correct? I've looked at the code for MethodBrowser to see how that did it but got totally thrown when I saw the getImageBlock aspect for one of the ListViewColumns refer to IconicListAbstract. How does this work? Thanks very much. Regards Barry Carr Ixian Software Components Ltd Blairgowrie Perthshire |
Barry,
> I know it has something to do with ImageMangers and Images, but its not > clear to me how you get a bitmap into an instance of an Image - it looks > like you have to use a resource file. Is this correct? I don't pretend to understand image lists (fortunately I don't have to<g>), but they seem to work in terms of indexes returned by #imageIndex. > I've looked at the code for MethodBrowser to see how that did it but got > totally thrown when I saw the getImageBlock aspect for one of the > ListViewColumns refer to IconicListAbstract. How does this work? This is a common (and clever) "trick". In various places that view resources would be tempted to hang onto a block, you will instead find a class. If you look at the class (class vs. instance tab in the CHB), you will find #value, #value:, #value:value: as appropriate. The resulting view resources are smaller because they don't have to hold a block, only an STB proxy for the class. Have a good one, Bill -- Wilhelm K. Schwab, Ph.D. [hidden email] |
In reply to this post by Barry Carr-4
Barry,
> I know it has something to do with ImageMangers and Images, but its not > clear to me how you get a bitmap into an instance of an Image - it looks > like you have to use a resource file. Is this correct? For a ListView I think you have to use icons rather than bitmaps (but could easily be wrong). Try the following in a workspace [1] "When you add an icon to the image manager it answers an Integer, a unique value for the icon *in the current image*" index1 := IconImageManager current addImage: (Icon fromFile: 'c:\x.ico'). index2 := IconImageManager current addImage: (Icon fromFile: 'c:\y.ico'). "You can then use this index as the value answered by the #getImageBlock:." lp := ListPresenter show: 'Enhanced list view'. lp view getImageBlock: [:o | (o includes: $e) ifTrue: [index1] ifFalse: [index2]]. lp list: #('one' 'two' 'three') In actual use I would expect the #getImageBlock: argument to be an instance of a class and to interrogate that for the imageIndex to use. Something like [2] ... lp view getImageBlock: [:myObject | myObject imageIndex] then... MyObjectClass>>imageIndex self useImage1 ifTrue: [self imageIndex1] ifFalse: [self imageIndex2] MyObjectClass>>imageIndex1 ^cachedIndexForImage1 ifNil: [cachedIndexForImage1 := Icon fromFile: 'blah'] ifNotNil: [:arg | arg] You get the idea :-) You can also interrogate the IconImageManager for an index ... (Icon fromFile: 'c:\x.ico') imageIndex or IconImageManager current indexOfImage: (Icon fromFile: 'c:\x.ico'). ... but I've usually found it easier to remember it for myself. Ian [1] I think the following is normally equivalent to the above but it might be preferable in some circumstances (???) lp := ListPresenter show: 'Enhanced list view'. index1 := lp view imageManager addImage: (Icon fromFile: 'c:\x.ico'). index2 := lp view imageManager addImage: (Icon fromFile: 'c:\y.ico'). lp view getImageBlock: [:o | (o includes: $e) ifTrue: [index1] ifFalse: [index2]]. lp list: #('one' 'two' 'three') [2] I'd probably use a Message rather than a block but that would just complicate things here. |
"Ian Bartholomew" <[hidden email]> wrote in message
news:O0Dh9.8402$J47.644995@stones... > Barry, > > > I know it has something to do with ImageMangers and Images, but its not > > clear to me how you get a bitmap into an instance of an Image - it looks > > like you have to use a resource file. Is this correct? > > For a ListView I think you have to use icons rather than bitmaps (but could > easily be wrong). .... It is generally easier to use Icons than Bitmaps, and the results will probably be more satisfactory, but it is not essential. The issue is how to create the "mask" for the transparent background areas of the image. ImageManagers have a way to do this for bitmaps which involves choosing a colour to be treated as transparent. The addition of images to the image manage is double-dispatched, so it does not matter whether you add bitmaps or icons. An example of the use of bitmaps with a list view can be seen in the Active-X Control Browser's "New Control" dialog, which displays the toolbox bitmaps registered for each control alongside its description. The code that sets this up can be seen in AXControlSite class>>chooseControl: Regards Blair |
In reply to this post by Barry Carr-4
Gentlemen,
My aplogies for not responding sooner. Thank you for your help with my ListView porblem. I've got it sorted now and have a deeper understanding of what going on, always useful. However, I do have another question. On ListViewColumn how are the following aspects used? getContentBlock - obviously, this returns the underlying object that is used in column, but when would you need it? customDrawBlock - does this allow you to implement an "owner-draw" listview (as Delphi programmers would call it)? If so, could someone point me at an example please. Thanks once again for your help. Regards Barry Carr Ixian Software Components Ltd Blairgowrie Perthshire |
Barry,
> However, I do have another question. On > ListViewColumn how are the following aspects used? > > getContentBlock - obviously, this returns the underlying object that > is used in column, but when would you need it? Displaying an object as an item in a ListView is a two stage operation - 1) The #getContentsBlock: is evaluated with the object in the appropriate position in the ListModel as the block's argument. 2) The object answered by this block evaluation is then used as the argument for #getTextBlock:, #getImageBlock: etc. The main reason to use it is to make the creation of the ListView easier. It enables you to avoid having to write specific handlers for #getTextBlock: and the others if the default blocks will suffice. For example - you have a ListView displaying MyObjects and the first column in this ListView shows the result of sending #first to each of the MyObjects. You might end up with getTextBlock := [:o | o first displayString] getImageBlock := [:o | o first icon] sortBlock := [:a :b | a first <= b first] As these three block all perform the default operations (see IconicListAbstract class>>value, BasicListAbstract class>>value and SortedCollection class>>value:value:) you could leave all the above as defaults and just use ... getContentsBlock := [:o | o first] ... as the object passed to the default equivalent of all of the previous blocks will then be the one answered by the #getContentsBlock. > customDrawBlock - does this allow you to implement an "owner-draw" > listview (as Delphi programmers would call it)? If > so, could someone point me at an example please. Pass. Steve Waring did some work on this, there is a thread from early 2000 in the archive, but I'm not sure about the current state. Regards Ian |
Hi Ian,
Thanks very much - I truly have learnt something there. I've just been using getTextBlock Cheers Barry |
In reply to this post by Barry Carr-4
On Mon, 23 Sep 2002 09:49:15 +0000 (UTC),
Barry Carr <[hidden email]> wrote: > > customDrawBlock - does this allow you to implement an "owner-draw" > listview (as Delphi programmers would call it)? If > so, could someone point me at an example please. ho hum ... I don't know what "owner-draw" in Delphi does, but here is what I did in a MultipleSelectionListView with 13 ListViewColumns in its columnsList. The respective customDrawBlocks are 1. nil 2. nil 3. [ :item | item backcolor: (RGB red: 255 green: 230 blue: 230) ] 4. nil 5. [ :item | item backcolor: (RGB red: 230 green: 255 blue: 230) ] 6. nil 7. nil 8. [ :item | item backcolor: (RGB red: 255 green: 255 blue: 230) ] 9. nil 10. nil 11. [ :item | item backcolor: (RGB red: 230 green: 230 blue: 255) ] 12. nil 13. nil The columns have the following background colors: 1. white 2. white 3. red 4. red 5. green 6. green 7. green 8. yellow 9. yellow 10. yellow 11. blue 12. blue 13. blue I don't know whether that's the right way to do it, but at least it works. HTH s. |
> ho hum ... I don't know what "owner-draw" in Delphi does, but here
> is what I did in a MultipleSelectionListView with 13 ListViewColumns > in its columnsList. The respective customDrawBlocks are > > 1. nil > 2. nil > 3. [ :item | item backcolor: (RGB red: 255 green: 230 blue: 230) ] > 4. nil > 5. [ :item | item backcolor: (RGB red: 230 green: 255 blue: 230) ] > 6. nil > 7. nil > 8. [ :item | item backcolor: (RGB red: 255 green: 255 blue: 230) ] > 9. nil > 10. nil > 11. [ :item | item backcolor: (RGB red: 230 green: 230 blue: 255) ] > 12. nil > 13. nil > > The columns have the following background colors: > > 1. white > 2. white > 3. red > 4. red > 5. green > 6. green > 7. green > 8. yellow > 9. yellow > 10. yellow > 11. blue > 12. blue > 13. blue > > I don't know whether that's the right way to do it, but at least > it works. > > HTH > s. Hi Stefan, Thanks for the tip. It does seem similar to Delphi's owner draw controls. Cheers Barry |
Free forum by Nabble | Edit this page |