1 #include <lib/gui/listbox.h>
2 #include <lib/gui/eprogress.h>
3 #include <lib/gui/numberactions.h>
4 #include <lib/system/econfig.h>
5 #include <lib/gdi/font.h>
7 gFont
eListBoxEntryText::font
;
8 gFont
eListBoxEntryTextStream::font
;
10 eListBoxBase::eListBoxBase(eWidget
* parent
, const eWidget
* descr
, int takefocus
, int item_height
, const char *deco
)
11 : eDecoWidget(parent
, takefocus
, deco
),
12 removed_height_pixel(0), descr(descr
),
16 colorActiveB(eSkin::getActive()->queryScheme("listbox.selected.background")),
17 colorActiveF(eSkin::getActive()->queryScheme("listbox.selected.foreground")),
18 movemode(0), MaxEntries(0), flags(0), item_height(item_height
),
19 columns(1), in_atomic(0), entries(0), currentPos(-1), top(childs
.end()), bottom(childs
.end()), current(childs
.end())
21 scrollbar
= new eProgress(this);
22 scrollbar
->setDirection(1);
23 childs
.setAutoDelete(false); // machen wir selber
24 addActionMap(&i_cursorActions
->map
);
25 addActionMap(&i_listActions
->map
);
27 colorActiveB
=eSkin::getActive()->queryScheme("global.selected.background");
29 colorActiveF
=eSkin::getActive()->queryScheme("global.selected.foreground");
31 gColor col
= eSkin::getActive()->queryScheme("listbox.normal.background");
36 gColor col
= eSkin::getActive()->queryScheme("listbox.normal.foreground");
42 eListBoxBase::~eListBoxBase()
44 ePtrList
<eListBoxEntry
>::iterator
it(childs
.begin());
45 while (it
!= childs
.end())
53 void eListBoxBase::setFlags(int _flags
)
56 if (_flags
== flagHasShortcuts
)
57 addActionMap(&i_shortcutActions
->map
);
60 void eListBoxBase::removeFlags(int _flags
)
63 if (_flags
== flagHasShortcuts
)
64 removeActionMap(&i_shortcutActions
->map
);
67 void eListBoxBase::recalcMaxEntries()
69 // MaxEntries is PER COLUMN
71 if (deco_selected
&& have_focus
)
73 MaxEntries
= crect_selected
.height();
74 decoheight
= height() - crect_selected
.height();
78 MaxEntries
= crect
.height();
79 decoheight
= height() - crect
.height();
82 MaxEntries
= height();
84 MaxEntries
/= item_height
;
85 /* eDebug("height = %d, MaxEntries = %d, item height = %d",
86 tmp, MaxEntries, item_height);*/
87 // das ist echt mal komischer code hier.. aber funktioniert :)
88 // damit werden listboxen automatisch auf die höhe resized,
89 // die benötigt wird damit alle entrys genau sichtbar sind..
90 // und kein Rand bleibt..
91 if ( tmp
- ( MaxEntries
*item_height
) > 0 )
93 if ( !removed_height_pixel
)
95 removed_height_pixel
= height() - ((MaxEntries
*item_height
) + decoheight
);
96 resize( eSize( size
.width(), height()-removed_height_pixel
) );
100 int newMax
= (tmp
+ removed_height_pixel
) / item_height
;
101 if ( newMax
> MaxEntries
)
103 removed_height_pixel
-= (newMax
*item_height
) - tmp
;
104 resize( eSize( size
.width(), newMax
*item_height
+decoheight
) );
108 int tmp
= height() - ((MaxEntries
*item_height
) + decoheight
);
109 resize( eSize( size
.width(), height() - tmp
) );
110 removed_height_pixel
+= tmp
;
115 eDebug("is ok .. do nothing");*/
118 eRect
eListBoxBase::getEntryRect(int pos
)
121 ( entries
> (unsigned int)(MaxEntries
*columns
) && MaxEntries
*columns
> 1 );
124 // in case we show partial last lines (which only works in single-column),
125 // we increase MaxEntries by one since we don't want the last line
126 // one the next (invisible) column
127 if ( (columns
== 1) && (flags
& flagShowPartial
))
129 if ( deco_selected
&& have_focus
)
130 return eRect( ePoint( deco_selected
.borderLeft
+ ( ( pos
/ lme
) * ( crect_selected
.width() / columns
) ) , deco_selected
.borderTop
+ ( pos
% lme
) * item_height
), eSize( (crect_selected
.width() / columns
) - (sbar
?scrollbar
->width()+5:columns
>1?5:0), item_height
) );
132 return eRect( ePoint( deco
.borderLeft
+ ( ( pos
/ lme
) * ( crect
.width() / columns
) ) , deco
.borderTop
+ ( pos
% lme
) * item_height
), eSize( (crect
.width() / columns
) - (sbar
?scrollbar
->width()+5:columns
>1?5:0), item_height
) );
133 else if ( deco_selected
)
134 return eRect( ePoint( deco_selected
.borderLeft
+ ( ( pos
/ lme
) * ( crect_selected
.width() / columns
) ) , deco_selected
.borderTop
+ ( pos
% lme
) * item_height
), eSize( (crect_selected
.width() / columns
) - (sbar
?scrollbar
->width()+5:columns
>1?5:0), item_height
) );
136 return eRect( ePoint( ( ( pos
/ lme
) * ( size
.width() / columns
) ) , ( pos
% lme
) * item_height
), eSize( (size
.width() / columns
) - (sbar
?scrollbar
->width()+5:columns
>1?5:0), item_height
) );
139 void eListBoxBase::setColumns(int col
)
145 int eListBoxBase::setProperty(const eString
&prop
, const eString
&value
)
147 if (prop
== "noPageMovement")
150 flags
&= ~flagNoPageMovement
;
152 flags
|= flagNoPageMovement
;
154 else if (prop
== "noUpDownMovement")
157 flags
&= ~flagNoUpDownMovement
;
159 flags
|= flagNoUpDownMovement
;
161 else if (prop
=="activeForegroundColor")
162 colorActiveF
=eSkin::getActive()->queryScheme(value
);
163 else if (prop
=="activeBackgroundColor")
164 colorActiveB
=eSkin::getActive()->queryScheme(value
);
165 else if (prop
=="showEntryHelp")
166 setFlags( flagShowEntryHelp
);
167 else if (prop
=="columns")
168 setColumns( value
?atoi(value
.c_str()):1 );
170 return eDecoWidget::setProperty(prop
, value
);
175 void eListBoxBase::recalcScrollBar()
177 int scrollbarwidth
=0;
179 if ( have_focus
&& deco_selected
)
185 scrollbarwidth
=rc
.width()/16;
186 if ( scrollbarwidth
< 18 )
188 if ( scrollbarwidth
> 22 )
190 scrollbar
->move( ePoint(rc
.right() - scrollbarwidth
, rc
.top()) );
191 scrollbar
->resize( eSize( scrollbarwidth
, (MaxEntries
*item_height
) ) );
195 void eListBoxBase::recalcClientRect()
199 crect
.setLeft( deco
.borderLeft
);
200 crect
.setTop( deco
.borderTop
);
201 crect
.setRight( width() - deco
.borderRight
);
202 crect
.setBottom( height() - deco
.borderBottom
);
206 crect_selected
.setLeft( deco_selected
.borderLeft
);
207 crect_selected
.setTop( deco_selected
.borderTop
);
208 crect_selected
.setRight( width() - deco_selected
.borderRight
);
209 crect_selected
.setBottom( height() - deco_selected
.borderBottom
);
211 eWidget::recalcClientRect();
214 int eListBoxBase::eventHandler(const eWidgetEvent
&event
)
218 case eWidgetEvent::changedSize
:
219 eWidget::eventHandler(event
);
225 case eWidgetEvent::evtAction
:
226 if ((flags
& flagHasShortcuts
) && eventHandlerShortcuts(event
))
228 else if ((event
.action
== &i_listActions
->pageup
) && !(flags
& flagNoPageMovement
))
229 moveSelection(dirPageUp
);
230 else if ((event
.action
== &i_listActions
->pagedown
) && !(flags
& flagNoPageMovement
))
231 moveSelection(dirPageDown
);
232 else if ( entries
&& current
->eventHandler(event
) )
234 else if ((event
.action
== &i_cursorActions
->up
) && !(flags
& flagNoUpDownMovement
) && !(flags
&flagLostFocusOnFirst
&& current
== childs
.begin()) )
235 moveSelection(dirUp
);
236 else if ((event
.action
== &i_cursorActions
->down
) && !(flags
& flagNoUpDownMovement
) && !(flags
&flagLostFocusOnLast
&& current
== --childs
.end()) )
237 moveSelection(dirDown
);
238 else if (event
.action
== &i_cursorActions
->ok
)
240 if ( current
== childs
.end() )
241 /*emit*/ SendSelected(0);
243 /*emit*/ SendSelected(*current
);
245 else if (event
.action
== &i_cursorActions
->cancel
&& MaxEntries
> 1 )
246 /*emit*/ SendSelected(0);
253 return eWidget::eventHandler(event
);
256 void eListBoxBase::invalidateContent()
258 if ( have_focus
&& deco_selected
)
259 invalidate( crect_selected
);
266 int eListBoxBase::newFocus()
268 if (deco
&& deco_selected
)
281 int eListBoxBase::setCurrent(const eListBoxEntry
*c
, bool sendSelected
)
283 /* if (childs.empty() || ((current != childs.end()) && (*current == c))) // no entries or current is equal the entry to search
284 return E_ALLREADY_SELECTED; // do nothing*/
287 return E_COULDNT_FIND
;
289 ePtrList
<eListBoxEntry
>::iterator
item(childs
.begin()), it(childs
.begin());
292 for ( ; item
!= childs
.end(); ++item
, ++cnt
)
296 if ( item
== childs
.end() ) // entry not in listbox... do nothing
297 return E_COULDNT_FIND
;
303 ePtrList
<eListBoxEntry
>::iterator
oldCur(current
);
307 for (it
=top
; it
!= bottom
; ++it
, ++i
) // check if entry to set between bottom and top
318 if (newCurPos
!= -1) // found on current screen, so redraw only old and new
324 if (atomic_redraw
== arNothing
)
326 atomic_redraw
= arCurrentOld
;
327 atomic_old
= oldCurPos
;
329 if (atomic_redraw
== arCurrentOld
)
330 atomic_new
= newCurPos
;
333 invalidateEntry(newCurPos
);
335 invalidateEntry(oldCurPos
);
338 } else // then we start to search from begin
340 bottom
= childs
.begin();
342 while (newCurPos
== -1 && MaxEntries
) // MaxEntries is already checked above...
344 if ( bottom
!= childs
.end() )
345 top
= bottom
; // nächster Durchlauf
347 for (i
= 0; (i
< (MaxEntries
*columns
) ) && (bottom
!= childs
.end()); ++bottom
, ++i
)
351 current
= bottom
; // we have found
359 invalidateContent(); // Draw all
367 /*emit*/ SendSelChanged(*current
);
369 /*emit*/ SendSelected(*current
);
380 void eListBoxBase::append(eListBoxEntry
* entry
, bool holdCurrent
, bool front
)
382 eListBoxEntry
* cur
= 0;
387 childs
.push_front(entry
);
389 childs
.push_back(entry
);
397 void eListBoxBase::take(eListBoxEntry
* entry
, bool holdCurrent
)
399 eListBoxEntry
*cur
= 0;
401 if (holdCurrent
&& current
!= entry
)
405 if ( entries
!= childs
.size() )
415 void eListBoxBase::clearList()
417 ePtrList
<eListBoxEntry
>::iterator
it(childs
.begin());
425 current
= top
= bottom
= childs
.end();
428 /*emit*/ SendSelChanged(0);
441 eListBoxEntry
*eListBoxBase::goNext()
443 moveSelection(dirDown
);
444 return current
!=childs
.end() ? *current
: 0;
447 eListBoxEntry
* eListBoxBase::goPrev()
449 moveSelection(dirUp
);
450 return current
!=childs
.end() ? *current
: 0;
453 void eListBoxBase::redrawWidget(gPainter
*target
, const eRect
&where
)
455 // redraw scrollbar only...
456 if ( where
.size() == scrollbar
->getSize() &&
457 where
.topLeft() == scrollbar
->getPosition() )
462 if (deco_selected
&& have_focus
)
464 deco_selected
.drawDecoration(target
, ePoint(width(), height()));
469 deco
.drawDecoration(target
, ePoint(width(), height()));
475 if ( currentPos
== -1 )
478 ePtrList
<eListBoxEntry
>::iterator it
= childs
.begin();
479 for (; it
!= childs
.end() ;++it
, ++currentPos
)
484 if ( entries
> (unsigned int)(MaxEntries
*columns
) && MaxEntries
*columns
> 1 )
486 int pages
= entries
/ (MaxEntries
*columns
);
487 if ( (unsigned int)(pages
*MaxEntries
*columns
) < entries
)
489 int start
=(currentPos
/(MaxEntries
*columns
)*MaxEntries
*columns
*100)/(pages
*MaxEntries
*columns
);
490 int vis
=MaxEntries
*columns
*100/(pages
*MaxEntries
*columns
);
493 scrollbar
->setParams(start
,vis
);
500 for (ePtrList
<eListBoxEntry
>::iterator
entry(top
); ((flags
& flagShowPartial
) || (entry
!= bottom
)) && (entry
!= childs
.end()); ++entry
)
502 eRect rect
= getEntryRect(i
);
503 if ( rc
.intersects(rect
) )
505 target
->clip(rect
& rc
);
506 if ( entry
== current
)
509 if ( LCDTmp
) // LCDTmp is only valid, when we have the focus
510 LCDTmp
->setText( entry
->redraw(target
, rect
, colorActiveB
, colorActiveF
, getBackgroundColor(), getForegroundColor(), 1 ) );
511 else if ( parent
->LCDElement
&& have_focus
)
512 parent
->LCDElement
->setText( entry
->redraw(target
, rect
, colorActiveB
, colorActiveF
, getBackgroundColor(), getForegroundColor(), 1 ) );
515 entry
->redraw(target
, rect
, colorActiveB
, colorActiveF
, getBackgroundColor(), getForegroundColor(), ( have_focus
? 1 : ( MaxEntries
> 1 ? 2 : 0 ) ) );
518 entry
->redraw(target
, rect
, colorActiveB
, colorActiveF
, getBackgroundColor(), getForegroundColor(), 0 /*( have_focus ? 0 : ( MaxEntries > 1 ? 2 : 0 ) )*/ );
521 // special case for "showPartial": as bottom is set to the
522 // last, half visible entry we want to redraw this, too.
523 if (flags
& flagShowPartial
)
531 void eListBoxBase::gotFocus()
534 if (parent
&& parent
->LCDElement
) // detect if LCD Avail
537 parent
->LCDElement
->setText("");
538 LCDTmp
= new eLabel(parent
->LCDElement
);
540 eSize s
= parent
->LCDElement
->getSize();
541 LCDTmp
->move(ePoint(0,s
.height()/2));
542 LCDTmp
->resize(eSize(s
.width(), s
.height()/2));
544 tmpDescr
= new eLabel(parent
->LCDElement
);
546 tmpDescr
->move(ePoint(0,0));
547 tmpDescr
->resize(eSize(s
.width(), s
.height()/2));
548 tmpDescr
->setText( descr
->getText() );
555 if ( newFocus() ) // recalced ?
557 ePtrList
<eListBoxEntry
>::iterator it
= current
;
561 else if ( isVisible() )
564 for (ePtrList
<eListBoxEntry
>::iterator
entry(top
); entry
!= bottom
; ++i
, ++entry
)
565 if (entry
== current
)
569 if (flags
& flagShowEntryHelp
)
570 setHelpText( current
!= childs
.end() ? current
->getHelpText(): eString(" ")); // eString(_("no description available")));
573 void eListBoxBase::lostFocus()
586 if ( newFocus() ) //recalced ?
588 ePtrList
<eListBoxEntry
>::iterator it
= current
;
592 else if ( isVisible() )
595 for (ePtrList
<eListBoxEntry
>::iterator
entry(top
); entry
!= bottom
; ++i
, ++entry
)
596 if (entry
== current
)
600 if (parent
&& parent
->LCDElement
)
601 parent
->LCDElement
->setText("");
605 void eListBoxBase::invalidateCurrent()
608 for (ePtrList
<eListBoxEntry
>::iterator
i(top
); i
!= bottom
; ++i
, ++n
)
610 invalidate(getEntryRect(n
));
613 void eListBoxBase::init()
615 currentPos
=entries
?0:-1;
616 current
= top
= bottom
= childs
.begin();
617 for (int i
= 0; i
< (MaxEntries
*columns
); ++i
, ++bottom
)
618 if (bottom
== childs
.end() )
621 /* when the first item isn't a selectable item, keep scrolling down till we find one */
622 while ( !current
->isSelectable() && current
!= --childs
.end())
638 int eListBoxBase::moveSelection(int dir
, bool sendSelected
)
640 int direction
=0, forceredraw
=0;
645 ePtrList
<eListBoxEntry
>::iterator oldptr
=current
, oldtop
=top
;
651 for (int i
= 0; i
< MaxEntries
; ++i
)
654 if (++current
== bottom
) // unten (rechts) angekommen? page down
656 if (bottom
== childs
.end()) // einzige ausnahme: unten (rechts) angekommen
662 for (int i
= 0; i
< MaxEntries
* columns
; ++i
)
664 if (bottom
!= childs
.end())
666 if (top
!= childs
.end())
671 /* when we didn't find a selectable item, keep scrolling down till we find one */
672 while ( !current
->isSelectable() && current
!= --childs
.end())
677 /* when we couldn't find a selectable item below, find the nearest one above */
678 while ( !current
->isSelectable() && current
!= childs
.begin())
687 for (int i
= 0; i
< MaxEntries
; ++i
)
689 if (current
== childs
.begin())
692 if (current
-- == top
/* && current != childs.begin()*/ ) // oben (links) angekommen? page up
694 for (int i
= 0; i
< MaxEntries
* columns
; ++i
)
696 if (--top
== childs
.begin()) // einzige ausnahme: oben (links) angekommen
700 // und einmal bottom neuberechnen :)
702 for (int i
= 0; i
< MaxEntries
*columns
; ++i
)
703 if (bottom
!= childs
.end())
707 /* when we didn't find a selectable item, keep scrolling up till we find one */
708 while ( !current
->isSelectable() && current
!= childs
.begin())
713 /* when we couldn't find a selectable item above, find the nearest one below */
714 while ( !current
->isSelectable() && current
!= --childs
.end())
724 while (first
|| !current
->isSelectable() )
727 if ( current
== childs
.begin() ) // wrap around?
730 top
= bottom
= current
= childs
.end();
732 currentPos
=entries
-1;
733 int cnt
= entries
%(MaxEntries
*columns
);
734 for (int i
= 0; i
< (cnt
?cnt
:MaxEntries
*columns
); ++i
, --top
)
735 if (top
== childs
.begin())
742 if (current
-- == top
) // new top must set
744 for (int i
= 0; i
< MaxEntries
*columns
; ++i
, --top
)
745 if (top
== childs
.begin())
748 for (int i
= 0; i
< MaxEntries
*columns
; ++i
, ++bottom
)
749 if (bottom
== childs
.end())
760 while (first
|| !current
->isSelectable() )
763 if ( current
== --ePtrList
<eListBoxEntry
>::iterator(childs
.end()) ) // wrap around?
767 top
= current
= bottom
= childs
.begin(); // goto first
768 for (int i
= 0; i
< MaxEntries
* columns
; ++i
, ++bottom
)
769 if ( bottom
== childs
.end() )
776 if (++current
== bottom
) // ++current ??
778 for (int i
= 0; i
<MaxEntries
* columns
; ++i
)
780 if (bottom
!= childs
.end() )
782 if (top
!= childs
.end() )
793 top
= current
= bottom
= childs
.begin(); // goto first;
794 for (int i
= 0; i
< MaxEntries
* columns
; ++i
, ++bottom
)
795 if ( bottom
== childs
.end() )
797 /* when the first item isn't a selectable item, keep scrolling down till we find one */
798 while ( !current
->isSelectable() && current
!= --childs
.end())
807 top
= bottom
= current
= childs
.end();
809 currentPos
=entries
-1;
810 int cnt
= entries
%(MaxEntries
*columns
);
811 for (int i
= 0; i
< (cnt
?cnt
:MaxEntries
*columns
); ++i
, --top
)
812 if (top
== childs
.begin())
814 /* when the last item isn't a selectable item, keep scrolling up till we find one */
815 while ( !current
->isSelectable() && current
!= childs
.begin())
826 if (current
!= oldptr
) // current has changed
830 // feel free to rewrite using stl::copy[_backward], but i didn't succeed.
831 std::list
<eListBoxEntry
*>::iterator o
=oldptr
,
837 eListBoxEntry
* old
=*o
;
864 if (flags
& flagShowEntryHelp
)
865 setHelpText( current
!= childs
.end() ? current
->getHelpText():eString(_("no description available")));
869 /*emit*/ SendSelChanged(*current
);
871 /*emit*/ SendSelected(*current
);
882 if ((oldtop
!= top
) || forceredraw
)
888 } else if ( current
!= oldptr
)
893 for (ePtrList
<eListBoxEntry
>::iterator
entry(top
); entry
!= bottom
; ++i
, ++entry
)
894 if ( entry
== oldptr
)
896 else if ( entry
== current
)
901 if (atomic_redraw
== arNothing
)
904 atomic_redraw
= arCurrentOld
;
906 if (atomic_redraw
== arCurrentOld
)
911 invalidateEntry(old
);
913 invalidateEntry(cur
);
920 void eListBoxBase::setActiveColor(gColor back
, gColor front
)
927 if ((back
|| front
) && current
!= childs
.end())
930 for (ePtrList
<eListBoxEntry
>::iterator
it(top
); it
!= bottom
; ++i
, ++it
)
941 void eListBoxBase::beginAtomic()
945 atomic_redraw
=arNothing
;
952 void eListBoxBase::endAtomic()
956 if (atomic_redraw
== arAll
)
958 else if (atomic_redraw
== arCurrentOld
)
960 if (atomic_new
!= -1)
961 invalidateEntry(atomic_new
);
962 if (atomic_old
!= -1)
963 invalidateEntry(atomic_old
);
965 if (atomic_selchanged
)
967 /*emit*/ SendSelChanged(0);
969 /*emit*/ SendSelChanged(*current
);
973 /*emit*/ SendSelected(0);
975 /*emit*/ SendSelected(*current
);
979 void eListBoxBase::sort()
981 eListBoxEntry
* cur
= current
;
990 int eListBoxBase::getShortcut(eListBoxEntry
* e
)
993 for (ePtrList
<eListBoxEntry
>::iterator
it(childs
.begin());
994 it
!= childs
.end(); ++it
)
996 if ( it
->isSelectable()&2)
1006 int eListBoxBase::eventHandlerShortcuts(const eWidgetEvent
&event
)
1009 int ColorShortcutsFirst
= (getFlags() & flagColorShortcutsFirst
? 1 : 0);
1013 case eWidgetEvent::evtAction
:
1014 if (event
.action
== &i_shortcutActions
->number0
)
1015 num
=9 + ColorShortcutsFirst
*4;
1016 else if (event
.action
== &i_shortcutActions
->number1
)
1017 num
=0 + ColorShortcutsFirst
*4;
1018 else if (event
.action
== &i_shortcutActions
->number2
)
1019 num
=1 + ColorShortcutsFirst
*4;
1020 else if (event
.action
== &i_shortcutActions
->number3
)
1021 num
=2 + ColorShortcutsFirst
*4;
1022 else if (event
.action
== &i_shortcutActions
->number4
)
1023 num
=3 + ColorShortcutsFirst
*4;
1024 else if (event
.action
== &i_shortcutActions
->number5
)
1025 num
=4 + ColorShortcutsFirst
*4;
1026 else if (event
.action
== &i_shortcutActions
->number6
)
1027 num
=5 + ColorShortcutsFirst
*4;
1028 else if (event
.action
== &i_shortcutActions
->number7
)
1029 num
=6 + ColorShortcutsFirst
*4;
1030 else if (event
.action
== &i_shortcutActions
->number8
)
1031 num
=7 + ColorShortcutsFirst
*4;
1032 else if (event
.action
== &i_shortcutActions
->number9
)
1033 num
=8 + ColorShortcutsFirst
*4;
1034 else if (event
.action
== &i_shortcutActions
->red
)
1035 num
=10 - ColorShortcutsFirst
*10;
1036 else if (event
.action
== &i_shortcutActions
->green
)
1037 num
=11 - ColorShortcutsFirst
*10;
1038 else if (event
.action
== &i_shortcutActions
->yellow
)
1039 num
=12 - ColorShortcutsFirst
*10;
1040 else if (event
.action
== &i_shortcutActions
->blue
)
1041 num
=13 - ColorShortcutsFirst
*10;
1046 for (ePtrList
<eListBoxEntry
>::iterator
i(childs
.begin()); i
!=childs
.end(); ++i
)
1047 if (i
->isSelectable()&2 && !num
--)
1059 eListBoxBaseExt::eListBoxBaseExt(eWidget
* parent
, const eWidget
* descr
, int takefocus
, int item_height
, const char *deco
)
1060 :eListBoxBase(parent
, descr
, takefocus
, item_height
, deco
), browseTimer(eApp
)
1062 CONNECT(browseTimer
.timeout
, eListBoxBaseExt::browseTimeout
);
1063 addActionMap(&i_numberActions
->map
);
1066 void eListBoxBaseExt::gotFocus()
1068 eListBoxBase::gotFocus();
1069 eRCInput::getInstance()->setKeyboardMode(eRCInput::kmAscii
);
1072 int eListBoxBaseExt::eventHandler(const eWidgetEvent
&event
)
1076 case eWidgetEvent::evtAction
:
1077 if (event
.action
== &i_cursorActions
->ok
)
1080 browseHistory
.clear();
1081 return eListBoxBase::eventHandler(event
);
1083 else if (event
.action
== &i_numberActions
->keyBackspace
)
1086 browseText
.erase(browseText
.length()-1,1);
1087 if ( browseHistory
.size() )
1089 setCurrent(browseHistory
.front(),false);
1090 browseHistory
.pop_front();
1092 browseTimer
.start(2*1000,true);
1094 else if (event
.action
== &i_cursorActions
->down
&& browseTimer
.isActive())
1096 const char *browseBuf
= browseText
.c_str();
1097 int len
= browseText
.length();
1098 ePtrList
<eListBoxEntry
>::iterator
it(current
);
1100 for (;it
!= childs
.end(); ++it
)
1102 if ( !strncasecmp(it
->getText().c_str(), browseBuf
, len
) )
1104 if ( it
!= current
)
1106 setCurrent(*it
,false);
1107 browseTimer
.start(2*1000,true);
1113 for (;it
!= childs
.end(); ++it
)
1115 if ( !strncasecmp(it
->getText().c_str(), browseBuf
, len
) )
1117 if ( it
!= current
)
1119 setCurrent(*it
,false);
1120 browseTimer
.start(2*1000,true);
1126 else if (event
.action
== &i_cursorActions
->up
&& browseTimer
.isActive() )
1128 const char *browseBuf
= browseText
.c_str();
1129 int len
= browseText
.length();
1130 ePtrList
<eListBoxEntry
>::reverse_iterator
it((ePtrList
<eListBoxEntry
>::reverse_iterator
&)current
);
1131 for (;it
!= childs
.rend(); ++it
)
1133 if ( !strncasecmp(it
->getText().c_str(), browseBuf
, len
) )
1135 if ( it
!= current
)
1137 setCurrent(*it
,false);
1138 browseTimer
.start(2*1000,true);
1144 for (;it
!= childs
.rend(); ++it
)
1146 if ( !strncasecmp(it
->getText().c_str(), browseBuf
, len
) )
1148 if ( it
!= current
)
1150 setCurrent(*it
,false);
1151 browseTimer
.start(2*1000,true);
1163 return eListBoxBase::eventHandler(event
);
1166 int eListBoxBaseExt::keyDown(int key
)
1168 if (key
>= KEY_ASCII
)
1170 browseTimer
.start(2*1000,true);
1171 // TODO convert browseText to utf8 !!
1172 browseText
+=(char)key
;
1173 const char *browseBuf
= browseText
.c_str();
1174 int len
= browseText
.length();
1175 for (ePtrList
<eListBoxEntry
>::iterator
it(childs
.begin());
1176 it
!= childs
.end(); ++it
)
1178 if ( !strncasecmp(it
->getText().c_str(), browseBuf
, len
) )
1180 if ( it
!= current
)
1182 browseHistory
.push_front(current
);
1183 setCurrent(*it
,false);
1188 browseText
.erase(len
-1,1);
1193 void eListBoxBaseExt::clearList()
1195 eListBoxBase::clearList();
1196 browseHistory
.clear();
1199 void eListBoxBaseExt::lostFocus()
1201 eListBoxBase::lostFocus();
1202 eRCInput::getInstance()->setKeyboardMode(eRCInput::kmNone
);
1204 browseHistory
.clear();
1207 void eListBoxEntry::drawEntryBorder(gPainter
*rc
, const eRect
& rect
, gColor coActiveB
, gColor coActiveF
, gColor coNormalB
, gColor coNormalF
)
1209 rc
->setForegroundColor(coActiveB
);
1210 rc
->line( ePoint(rect
.left(), rect
.bottom()-1), ePoint(rect
.right()-1, rect
.bottom()-1) );
1211 rc
->line( ePoint(rect
.left(), rect
.top()), ePoint(rect
.right()-1, rect
.top()) );
1212 rc
->line( ePoint(rect
.left(), rect
.top()), ePoint(rect
.left(), rect
.bottom()-1) );
1213 rc
->line( ePoint(rect
.right()-1, rect
.top()), ePoint(rect
.right()-1, rect
.bottom()-1) );
1214 rc
->line( ePoint(rect
.left()+1, rect
.bottom()-2), ePoint(rect
.right()-2, rect
.bottom()-2) );
1215 rc
->line( ePoint(rect
.left()+1, rect
.top()+1), ePoint(rect
.right()-2, rect
.top()+1) );
1216 rc
->line( ePoint(rect
.left()+1, rect
.top()+2), ePoint(rect
.left()+1, rect
.bottom()-3) );
1217 rc
->line( ePoint(rect
.right()-2, rect
.top()+2), ePoint(rect
.right()-2, rect
.bottom()-3) );
1218 rc
->line( ePoint(rect
.left()+2, rect
.bottom()-3), ePoint(rect
.right()-3, rect
.bottom()-3) );
1219 rc
->line( ePoint(rect
.left()+2, rect
.top()+2), ePoint(rect
.right()-3, rect
.top()+2) );
1220 rc
->line( ePoint(rect
.left()+2, rect
.top()+3), ePoint(rect
.left()+2, rect
.bottom()-4) );
1221 rc
->line( ePoint(rect
.right()-3, rect
.top()+3), ePoint(rect
.right()-3, rect
.bottom()-4) );
1224 void eListBoxEntry::drawEntryRect(gPainter
*rc
, const eRect
& rect
, gColor coActiveB
, gColor coActiveF
, gColor coNormalB
, gColor coNormalF
, int state
)
1226 if ( (coNormalB
!= -1 && !state
) || (state
&& coActiveB
!= -1) )
1228 rc
->setForegroundColor(state
?coActiveB
:coNormalB
);
1230 rc
->setBackgroundColor(state
?coActiveB
:coNormalB
);
1234 eWidget
*w
=listbox
->getNonTransparentBackground();
1235 rc
->setForegroundColor(w
->getBackgroundColor());
1237 rc
->setBackgroundColor(w
->getBackgroundColor());
1239 rc
->setForegroundColor(state
?coActiveF
:coNormalF
);
1242 eListBoxEntryText::~eListBoxEntryText()
1251 int eListBoxEntryText::getEntryHeight()
1253 if ( !font
.pointSize
)
1254 font
= eSkin::getActive()->queryFont("eListBox.EntryText.normal");
1256 return calcFontHeight( font
) + 4;
1259 int eListBoxEntryTextStream::getEntryHeight()
1261 if ( !font
.pointSize
)
1262 font
= eSkin::getActive()->queryFont("eListBox.EntryText.normal");
1264 return calcFontHeight( font
) + 4;
1267 int calcFontHeight( const gFont
& font
)
1270 test
= new eTextPara( eRect(0,0,100,50) );
1271 test
->setFont( font
);
1272 test
->renderString("Mjdyl");
1273 int i
= test
->getBoundBox().height();
1278 const eString
& eListBoxEntryText::redraw(gPainter
*rc
, const eRect
& rect
, gColor coActiveB
, gColor coActiveF
, gColor coNormalB
, gColor coNormalF
, int state
)
1282 if ( (b
= (state
== 2)) )
1285 drawEntryRect( rc
, rect
, coActiveB
, coActiveF
, coNormalB
, coNormalF
, state
);
1287 int lft
= rect
.left();
1288 if (listbox
->getFlags() & eListBoxBase::flagHasShortcuts
)
1290 int hideshortcuts
=0;
1291 eConfig::getInstance()->getKey("/ezap/osd/hideshortcuts", hideshortcuts
);
1294 int shortcut
= listbox
->getShortcut(this);
1295 if (listbox
->getFlags() & eListBoxBase::flagColorShortcutsFirst
)
1299 else if (shortcut
< 15)
1303 eString strShortcut
;
1306 case 10: shortcut
= 0;
1316 strShortcut
= eString().sprintf("shortcut.%d",shortcut
);
1319 strShortcut
= eString().sprintf("shortcut.red");
1322 strShortcut
= eString().sprintf("shortcut.green");
1325 strShortcut
= eString().sprintf("shortcut.yellow");
1328 strShortcut
= eString().sprintf("shortcut.blue");
1336 gPixmap
* pm
= eSkin::getActive()->queryImage(strShortcut
);
1339 left
.setRight( lft
);
1340 left
.setLeft(rect
.left()+5);
1343 eSize psize
= pm
->getSize(),
1344 esize
= rect
.size();
1346 int yOffs
= rect
.top()+((esize
.height() - psize
.height()) / 2);
1348 rc
->blit(*pm
, ePoint(left
.left(), yOffs
), left
, gPixmap::blitAlphaTest
);
1356 para
= new eTextPara( eRect( 0, 0, rect
.width()-lft
, rect
.height() ) );
1357 para
->setFont( font
);
1358 para
->renderString(text
);
1359 para
->realign(align
);
1360 // yOffs = ((rect.height() - para->getBoundBox().height()) / 2 + 0) - para->getBoundBox().top() ;
1363 rc
->renderPara(*para
, ePoint( lft
, rect
.top()+yOffs
) );
1366 drawEntryBorder( rc
, rect
, coActiveB
, coActiveF
, coNormalB
, coNormalF
);
1371 const eString
&eListBoxEntryTextStream::redraw(gPainter
*rc
, const eRect
& rect
, gColor coActiveB
, gColor coActiveF
, gColor coNormalB
, gColor coNormalF
, int state
)
1373 rc
->setFont( font
);
1375 drawEntryRect( rc
, rect
, coActiveB
, coActiveF
, coNormalB
, coNormalF
, state
);
1377 rc
->setForegroundColor(state
?coActiveF
:coNormalF
);
1378 rc
->renderText(rect
, text
.str());
1381 return ret
= text
.str();
1384 void eListBoxEntryText::SetText(const eString
& txt
)
1393 const eString
& eListBoxSeparator::redraw(gPainter
*rc
, const eRect
& rect
, gColor coActiveB
, gColor coActiveF
, gColor coNormalB
, gColor coNormalF
, int state
)
1399 eSize psize
= pm
->getSize(),
1400 esize
= rect
.size();
1401 int yOffs
= rect
.top()+((esize
.height() - psize
.height()) / 2);
1404 rc
->blit(*pm
, ePoint(x
, yOffs
), eRect(x
, yOffs
, psize
.width(), psize
.height()), alphatest
?gPixmap::blitAlphaTest
:0 );
1408 while (x
<esize
.width());
1411 static eString ret
="separator";
1416 const eString
& eListBoxEntrySeparator::redraw(gPainter
*rc
, const eRect
& rect
, gColor coActiveB
, gColor coActiveF
, gColor coNormalB
, gColor coNormalF
, int state
)
1422 eSize psize
= pm
->getSize(),
1423 esize
= rect
.size();
1424 int yOffs
= rect
.top()+((esize
.height() - psize
.height()) / 2);
1427 rc
->blit(*pm
, ePoint(x
, yOffs
), eRect(x
, yOffs
, psize
.width(), psize
.height()), alphatest
?gPixmap::blitAlphaTest
:0 );
1431 while (x
<esize
.width());
1434 static eString ret
="separator";
1438 eListBoxEntryCheck::eListBoxEntryCheck( eListBox
<eListBoxEntryMenu
> *lb
, const char* text
, const char* regkey
, const eString
& hlptxt
)
1439 :eListBoxEntryMenu(lb
, text
, hlptxt
, 0 )
1440 ,pm(eSkin::getActive()->queryImage("eListBoxEntryCheck"))
1441 ,regKey(regkey
), checked(0)
1446 if ( eConfig::getInstance()->getKey( regKey
.c_str(), checked
) )
1447 eConfig::getInstance()->setKey( regKey
.c_str(), checked
);
1451 void eListBoxEntryCheck::LBSelected(eListBoxEntry
* t
)
1456 eConfig::getInstance()->setKey( regKey
.c_str(), checked
);
1457 listbox
->invalidateCurrent();
1458 /* emit */ selected((bool)checked
);
1462 const eString
& eListBoxEntryCheck::redraw(gPainter
*rc
, const eRect
& rect
, gColor coActiveB
, gColor coActiveF
, gColor coNormalB
, gColor coNormalF
, int state
)
1466 if ( (b
= (state
== 2)) )
1469 eListBoxEntryText::redraw( rc
, rect
, coActiveB
, coActiveF
, coNormalB
, coNormalF
, state
);
1471 if ( pm
&& checked
)
1474 right
.setLeft( rect
.right() - (pm
->x
+ 10) );
1477 eSize psize
= pm
->getSize(),
1478 esize
= rect
.size();
1480 int yOffs
= rect
.top()+((esize
.height() - psize
.height()) / 2);
1482 rc
->blit(*pm
, ePoint(right
.left(), yOffs
), right
, gPixmap::blitAlphaTest
);
1490 eListBoxEntryMulti::eListBoxEntryMulti( eListBox
<eListBoxEntryMenu
> *lb
, const char *hlptext
)
1491 :eListBoxEntryMenu( lb
, NULL
, hlptext
, (int)eTextPara::dirCenter
),
1497 void eListBoxEntryMulti::add( const char *text
, int key
)
1499 entrys
.push_back( std::pair
< int, eString
>(key
,text
) );
1502 void eListBoxEntryMulti::add( const eString
&text
, int key
)
1504 entrys
.push_back( std::pair
< int, eString
>(key
,text
) );
1507 void eListBoxEntryMulti::setCurrent(int key
)
1509 for ( std::list
< std::pair
< int, eString
> >::iterator
it(entrys
.begin())
1510 ;it
!= entrys
.end(); ++it
)
1512 if ( it
->first
== key
)
1516 this->key
= (void*) cur
->first
;
1522 listbox
->invalidateCurrent();
1523 listbox
->selchanged(this);
1529 int eListBoxEntryMulti::eventHandler( const eWidgetEvent
&e
)
1533 case eWidgetEvent::evtAction
:
1534 if ( e
.action
== &i_listActions
->pageup
)
1536 std::list
< std::pair
< int, eString
> >::iterator
it(cur
);
1538 if ( it
!= entrys
.end() )
1542 key
= (void*) cur
->first
;
1547 listbox
->invalidateCurrent();
1548 listbox
->selchanged(this);
1553 else if ( e
.action
== &i_listActions
->pagedown
)
1555 std::list
< std::pair
< int, eString
> >::iterator
it(cur
);
1557 if ( it
!= entrys
.end() )
1561 key
= (void*) cur
->first
;
1566 listbox
->invalidateCurrent();
1567 listbox
->selchanged(this);