comp.lang.idl-pvwave archive
Messages from Usenet group comp.lang.idl-pvwave, compiled by Paulo Penteado

Home » Public Forums » archive » droplist widget for long lists with Unix/X
Show: Today's Messages :: Show Polls :: Message Navigator
E-mail to friend 
Return to the default flat view Create a new topic Submit Reply
droplist widget for long lists with Unix/X [message #7561] Sun, 08 December 1996 00:00
Hans-Martin v.Stockha is currently offline  Hans-Martin v.Stockha
Messages: 4
Registered: June 1996
Junior Member
Hi folks,

I do some programming with IDL 4.0.1 (Solaris 2.5). Recently i found out
that
the height of the screen is some kind of natural limitation to the
number of
selectable elements in droplists, i.e. you can have arbitrarily long
droplists,
but you can only select from those elements that fit on the screen.
In the MacOS version of IDL the droplists becomes scrollable in this
case...

From the hotline i got a small piece of code which i turned into fully
functional
compound widget that can be used as a replacement for WIDGET_DROPLIST
under unix/X
if the list is too long.
The widget consists of a BASE, an optional LABEL, and a BUTTON which
shows the
current selection. If you press the button a new window pops up which
holds a
WIDGET_LIST with a scrollbar and a CANCEL button.

Since i only have access to two different platforms running IDL (MacOS
and unix/X),
i do not know how the others handle droplists larger than the screen
height...
BTW, for the MacOS CW_DROPLIST is just a wrapper for WIDGET_DROPLIST.

Maybe others came across the large list problem too and find the code
useful,

Hans-Martin von Stockhausen
(stockh@pet.mpin-koeln.mpg.de)

PS.: Use the code on your own risk.

--------------------- CUT HERE -----------------------------

; $Id: cw_droplist.pro,v 1.0 1996/11/29 16:09:51 $
;+
; NAME:
; CW_DROPLIST
;
; PURPOSE:
; This widget emulates a droplist with a button and a pop-up window.
; It was developed for Motif where droplists must fit on the screen
; in order to be able to access all elements...
; On the MAC this widget is only a wrapper for the original
WIDGET_DROPLIST.
;
; CATEGORY:
; Compound widgets.
;
; CALLING SEQUENCE:
; Result = CW_DROPLIST(Parent)
;
; INPUTS:
; Parent: The widget ID of the widget to be the droplist's parent.
;
; KEYWORD PARAMETERS:
; TITLE: An optional string containing the text to be used as the label
; for the droplist.
;
; VALUE: The list to be displayed.
;
; XSIZE: An explicit horizontal size in pixels of the button showing the
; current selection.
;
; FONT: A string containing the name of the X Windows font to use
; for the TITLE, the BUTTON, and the LIST.
;
; All other keyword parameters will be given to the base of the
; compound widget via the _EXTRA mechanism.
;
; OUTPUTS:
; This function returns the widget ID of the button which hides the
list.
;
; COMMON BLOCKS:
; None.
;
; PROCEDURE:
; Create the widgets, set up the appropriate event handlers, and return
; the widget ID of the button that hides the list.
;
; To modify the state of the widget (selection or list) use:
;
; CW_DROPLIST_SET, id, list=list, set_list_select=set_list_select
;
; To query the state of the widget (selection or list) use:
;
; CW_DROPLIST_INFO, id, get_list_select=get_list_select,
get_list_number=get_list_number
;
; EXAMPLE:
; The code below creates a main base with a simple droplist in it:
;
; base = WIDGET_BASE()
; dl = CW_DROPLIST(base, VALUE=['a','b','c'], /FRAME)
; WIDGET_CONTROL, base, /REALIZE
;
; MODIFICATION HISTORY:
; Written by: H.-M. von Stockhausen November 1996
;-


PRO CW_DL_SELECT_event, event
;
; select event: store position in list, set new button value
;
WIDGET_CONTROL, event.top, GET_UVALUE=info, /NO_COPY
info.Select = event.index ; current selection in list
item = info.Empty & STRPUT, item, info.List(info.Select), 0
WIDGET_CONTROL, info.Button, SET_VALUE=' '+item

WIDGET_CONTROL, WIDGET_INFO(info.Button, /PARENT), /NO_COPY, $
SEND_EVENT={Id:LONG(info.Button), Top:LONG(info.Top),
Handler:LONG(info.Button), Index:event.index}

WIDGET_CONTROL, info.Button, SET_UVALUE=info, /NO_COPY

WIDGET_CONTROL, event.top, /DESTROY
END


PRO CW_DL_CANCEL_event, event
;
; cancel event -> close list window
;
WIDGET_CONTROL, event.top, GET_UVALUE=info, /NO_COPY
WIDGET_CONTROL, info.Button, SET_UVALUE=info, /NO_COPY
WIDGET_CONTROL, event.top, /DESTROY
END


FUNCTION GetScrOffset, id
;
; get the screen coordinates of the upper left corner of a widget
;
offs = [0,0]
WHILE (id NE 0) DO BEGIN
geom = WIDGET_INFO(id, /GEOMETRY) ; get offset from parent
offs = offs + [geom.xoffset, geom.yoffset]
id = WIDGET_INFO(id, /PARENT)
END

RETURN, offs
END


PRO CW_DL_DROP_event, event
;
; create list in an extra window to select from
;
WIDGET_CONTROL, event.id, GET_UVALUE=info, /NO_COPY
info.Top = event.Top
count = info.Count

base = WIDGET_BASE(/COLUMN, TITLE=' ', /TLB_FRAME_ATTR)
drop_list = WIDGET_LIST(base, VALUE=info.List, YSIZE=(count < 30),
EVENT_PRO='CW_DL_SELECT_event', FONT=info.Font)
cancel = WIDGET_BUTTON(base, VALUE='cancel', /ALIGN_CENTER,
EVENT_PRO='CW_DL_CANCEL_event')

; position list window
DEVICE, GET_SCREEN_SIZE=screen_size
WIDGET_CONTROL, info.Top, TLB_GET_OFFSET=FramePos ; position of frame
hosting the group
geom_base = WIDGET_INFO(base, /GEOMETRY) ; size / position of
list top base
geom_but = WIDGET_INFO(event.id, /GEOMETRY) ; size / position of
DROPLIST-button

offs = GetScrOffset(event.id)
xoff = (offs(0) + geom_but.xsize) > 0
base_xsize = geom_base.xsize + 2 * geom_base.margin
IF ((xoff + base_xsize) GE screen_size(0)) THEN xoff = (offs(0) -
base_xsize) > 0
base_ysize = geom_base.ysize + 2 * geom_base.margin + 30 ; extra for
window frame
yoff = ((offs(1) + (geom_but.ysize / 2) - (base_ysize / 2)) > 0)
ydiff = (yoff + base_ysize - screen_size(1) > 0)

WIDGET_CONTROL, base, TLB_SET_XOFFSET=xoff
WIDGET_CONTROL, base, TLB_SET_YOFFSET=yoff - ydiff

WIDGET_CONTROL, base, /REALIZE
WIDGET_CONTROL, drop_list, SET_LIST_SELECT=info.Select
WIDGET_CONTROL, base, SET_UVALUE=info, /NO_COPY

XMANAGER, 'drop_list', base, /MODAL
end


FUNCTION CW_DROPLIST_INFO, id, get_list_select=get_list_select,
get_list_number=get_list_number
;
; create list in an extra window to select from
;
IF (!version.os EQ 'MacOS') THEN BEGIN
IF KEYWORD_SET(get_list_select) THEN RETURN, WIDGET_INFO(id,
/DROPLIST_SELECT)
IF KEYWORD_SET(get_list_number) THEN RETURN, WIDGET_INFO(id,
/DROPLIST_NUMBER)
RETURN, 0
ENDIF

WIDGET_CONTROL, id, GET_UVALUE=info

IF KEYWORD_SET(get_list_select) THEN RETURN, info.Select
IF KEYWORD_SET(get_list_number) THEN RETURN, info.Count

RETURN, 0
end


PRO CW_DROPLIST_SET, id, list=list, set_list_select=set_list_select
;
; create list in an extra window to select from
;

IF (!version.os EQ 'MacOS') THEN BEGIN
IF (N_ELEMENTS(list) NE 0) THEN WIDGET_CONTROL, id, SET_VALUE=list
IF (N_ELEMENTS(set_list_select) NE 0) THEN WIDGET_CONTROL, id,
SET_DROPLIST_SELECT=set_list_select
RETURN
ENDIF

WIDGET_CONTROL, id, GET_UVALUE=info, /NO_COPY

IF (N_ELEMENTS(list) NE 0) THEN BEGIN
IF (list(0) EQ '') THEN BEGIN
count = 0
width = 10
END ELSE BEGIN
count = N_ELEMENTS(list)
width = MAX(STRLEN(list))
END
IF (count NE info.Count) THEN $ ; rebuild complete structure
info = {Button:Info.Button, Top:info.Top, Width:width,
Empty:STRING(REPLICATE(32B, width)), $
Select:Info.Select, Count:count, Font:info.Font,
List:list} $
ELSE $
info.List = list ; just replace list
ENDIF
IF N_ELEMENTS(set_list_select) THEN info.Select = set_list_select
info.Select = ((info.Select < (info.Count - 1)) > 0)

item = info.Empty & STRPUT, item, info.List(info.Select), 0
WIDGET_CONTROL, info.Button, SET_VALUE=' '+item
WIDGET_CONTROL, info.Button, SENSITIVE=(info.Count GT 0)

WIDGET_CONTROL, id, SET_UVALUE=info, /NO_COPY
end


FUNCTION CW_DROPLIST, parent, VALUE=list, TITLE=title, XSIZE=xsize,
FONT=font, _EXTRA=extra
;

IF NOT KEYWORD_SET(FONT) THEN font = ''
IF NOT KEYWORD_SET(xsize) THEN xsize = 0
IF (N_ELEMENTS(title) EQ 0) THEN title = ''

count = N_ELEMENTS(list)
IF (count NE 0) THEN BEGIN
width = MAX(STRLEN(list)) ; add always one blank left to the item
END ELSE BEGIN
width = 10 ; arbitrary width of empty string
list = ''
END

IF (!version.os EQ 'MacOS') THEN $
RETURN, WIDGET_DROPLIST(parent, VALUE=list, TITLE=title,
XSIZE=xsize, FONT=font, _EXTRA=extra)

; create scrollabel droplist for NON-MacOS
base = WIDGET_BASE(parent, /ROW, /BASE_ALIGN_CENTER, _EXTRA=extra)

info = {Button:0L, Top:0L, Width:width, Empty:STRING(REPLICATE(32B,
width)), $
Select:0, Count:count, Font:font, List:list}

IF (N_ELEMENTS(title) NE 0) THEN text = WIDGET_LABEL(base,
VALUE=STRING(title), FONT=font)
button = WIDGET_BUTTON(base, VALUE=info.Empty, XSIZE=xsize,
EVENT_PRO='CW_DL_DROP_event', $
/ALIGN_LEFT, /DYNAMIC_RESIZE, FONT=font)

info.Button = button
item = info.Empty & STRPUT, item, list(info.Select), 0
WIDGET_CONTROL, button, SET_VALUE=' '+item
WIDGET_CONTROL, button, SENSITIVE=(info.Count GT 0)
WIDGET_CONTROL, button, SET_UVALUE=info, /NO_COPY

RETURN, button
END


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;

; ========== a larger example =============

;PRO MAIN13_Event, Event
;
;common a, cw_dl

; WIDGET_CONTROL,Event.Id,GET_UVALUE=Ev

; CASE Ev OF

; 'list' : print, 'Item: ', event.index

; 'but2' : CW_DROPLIST_SET, cw_dl,
list=['111','22','333333333','444','5555','666666','77777']
; 'but3' : CW_DROPLIST_SET, cw_dl, set_list_select=4
; 'but4' : CW_DROPLIST_SET, cw_dl, list=''
; 'but5' : PRINT,'item: ', CW_DROPLIST_INFO(cw_dl, /get_list_select)

; 'BUTTON2': BEGIN
; Print, 'Event for Ende'
; widget_control, event.top, /destroy
; END
; else:

; ENDCASE
;END


;PRO CW_DL_TEST, GROUP=Group, title=title, frame=frame, font=font

;common a, cw_dl

; IF N_ELEMENTS(Group) EQ 0 THEN GROUP=0

; MAIN13 = WIDGET_BASE(GROUP_LEADER=Group, ROW=1, MAP=1,
TITLE='DROP-WIDGET Test')

; ; This is my large string array, which represent my data.
;
list=["bbb","ccc","ddd","eee","fff","ggg","hhh", "iii","jjj","kkk","lll",
$
;
"aaa","bbb","ccc","ddd","eee","fff","ggg","hhh ","iii","jjj","kkk","lll",
$
;
"aaa","bbb","ccc","ddd","eee","fff","ggg","hhh ","iii","jjj","kkk","lll",
$
;
"aaa","bbb","ccc","ddd","eee","fff","ggg","hhh ","iii","jjj","kkk","lll"]

; cw_dl = CW_DROPLIST(MAIN13, VALUE=list, TITLE=title, FRAME=frame,
/row, uvalue='list', xsize=100, font='5x8')

; button = WIDGET_BUTTON( MAIN13, UVALUE='but2', VALUE=' new ')
; button = WIDGET_BUTTON( MAIN13, UVALUE='but3', VALUE=' select 4 ')
; button = WIDGET_BUTTON( MAIN13, UVALUE='but4', VALUE=' empty ')
; button = WIDGET_BUTTON( MAIN13, UVALUE='but5', VALUE=' query ')
; BUTTON2 = WIDGET_BUTTON( MAIN13, UVALUE='BUTTON2', VALUE='Ende')

; WIDGET_CONTROL, MAIN13, /REALIZE

; XMANAGER, 'MAIN13', MAIN13
;END
[Message index]
 
Read Message
Previous Topic: IDL for Windows NT
Next Topic: error handling child process

-=] Back to Top [=-
[ Syndicate this forum (XML) ] [ RSS ] [ PDF ]

Current Time: Thu Oct 09 23:38:41 PDT 2025

Total time taken to generate the page: 0.40049 seconds