1 /*--License:
2 	Kyra Sprite Engine
3 	Copyright Lee Thomason (Grinning Lizard Software) 2001-2005
4 	www.grinninglizard.com/kyra
5 	www.sourceforge.net/projects/kyra
6 
7 	Kyra is provided under the LGPL.
8 
9 	I kindly request you display a splash screen (provided in the HTML documentation)
10 	to promote Kyra and acknowledge the software and everyone who has contributed to it,
11 	but it is not required by the license.
12 
13 --- LGPL License --
14 
15     This library is free software; you can redistribute it and/or
16     modify it under the terms of the GNU Lesser General Public
17     License as published by the Free Software Foundation; either
18     version 2.1 of the License, or (at your option) any later version.
19 
20     This library is distributed in the hope that it will be useful,
21     but WITHOUT ANY WARRANTY; without even the implied warranty of
22     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23     Lesser General Public License for more details.
24 
25     You should have received a copy of the GNU Lesser General Public
26     License along with this library; if not, write to the Free Software
27     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28 
29 	The full text of the license can be found in lgpl.txt
30 */
31 
32 #include "textwidget.h"
33 #include "listbox.h"
34 #include "../engine/fontresource.h"
35 
36 using namespace grinliz;
37 
KrListBox(int _width,int _height,const KrScheme & s,bool drawBorder)38 KrListBox::KrListBox(	int _width, int _height,
39 						const KrScheme& s,
40 						bool drawBorder ) : KrWidget( s )
41 {
42 	width = _width;
43 	height = _height;
44 	firstItem = 0;
45 	selectedItem = 0;
46 
47 	unsigned numVisibleItems = ( height - 2 ) / scheme.font->FontHeight();
48 	textWidgets.resize( numVisibleItems );
49 
50 	height = numVisibleItems * scheme.font->FontHeight() + 2;
51 
52 	outerBevel = 0;
53 	if ( drawBorder )
54 		outerBevel = new KrBevelElement( width, height, scheme );
55 }
56 
~KrListBox()57 KrListBox::~KrListBox()
58 {
59 	delete outerBevel;
60 }
61 
AddedtoTree()62 void KrListBox::AddedtoTree()
63 {
64 	if ( outerBevel )
65 	{
66 		outerBevel->AddToTree( Engine(), this );
67 		outerBevel->DrawIn();
68 	}
69 
70 	for( unsigned i=0; i<textWidgets.size(); ++i )
71 	{
72 		textWidgets[i] = new KrTextWidget( width /*- scrollWidth*/ - 2, scheme.font->FontHeight(),
73 										   false, true, false, scheme );
74 		textWidgets[i]->SetPos( 1, i * scheme.font->FontHeight() + 1 );
75 		Engine()->Tree()->AddNode( this, textWidgets[i] );
76 		//textWidgets[i]->AddListener( this );
77 		//textWidgets[i]->SelectedSignal1.connect( this, &KrListBox::ItemSelected );
78 		//textWidgets[i]->widgetPublish.AddListener( this );
79 		textWidgets[i]->widgetPublish.AddListener( this );
80 	}
81 	DrawText();
82 }
83 
84 
HandleWidgetEvent(KrWidget * source,const KrWidgetEvent & event)85 bool KrListBox::HandleWidgetEvent(	KrWidget* source, const KrWidgetEvent& event )
86 {
87 	if ( event.type == KrWidgetEvent::SELECTION )
88 	{
89 		ItemSelected( source );
90 		return true;
91 	}
92 	return false;
93 }
94 
ItemSelected(KrWidget * source)95 void KrListBox::ItemSelected( KrWidget* source )
96 {
97 	unsigned i;
98 	KrColorTransform normal;
99 	KrColorTransform selected = scheme.CalcHiPrimary();
100 
101 	for( i=0; i<textWidgets.size(); ++i )
102 	{
103 		if ( textWidgets[i] == source  )
104 		{
105 			int indexToString = i + firstItem;
106 			if ( InRange( indexToString, 0, (int) textStrings.size()-1 ) )
107 			{
108 				selectedItem = indexToString;
109 
110 				KrWidgetEvent event;
111 				event.type = KrWidgetEvent::SELECTION;
112 				event.selection.index = indexToString;
113 				event.selection.text = textStrings[selectedItem].c_str();
114 
115 				//PublishEvent( SELECTION, indexToString, 0, 0, 0 );
116 				//ItemSelectedSignal0.emit();
117 				//ItemSelectedSignal1.emit( textStrings[selectedItem] );
118 				for(	Publisher< IKrWidgetListener >::const_iterator it = widgetPublish.begin();
119 						it != widgetPublish.end();
120 						++it )
121 				{
122 					(*it)->HandleWidgetEvent( this, event );
123 				}
124 				break;
125 			}
126 		}
127 	}
128 
129 	for( i=0; i<textWidgets.size(); ++i )
130 	{
131 		if ( i == (unsigned) ( selectedItem - firstItem ) )
132 			textWidgets[i]->SetColor( selected );
133 		else
134 			textWidgets[i]->SetColor( normal );
135 	}
136 }
137 
138 
AddTextChar(const std::string & text)139 int KrListBox::AddTextChar( const std::string& text )
140 {
141 	textStrings.push_back( text );
142 	DrawText();
143 	return textStrings.size() - 1;
144 }
145 
146 
GetTextChar(int id,std::string * text)147 void KrListBox::GetTextChar( int id, std::string* text )
148 {
149 	*text = "";
150 	if ( id < (int) textStrings.size() )
151 		*text = textStrings[ id ];
152 }
153 
154 
MoveSelection(int delta)155 void KrListBox::MoveSelection( int delta )
156 {
157 	if (    delta != 0
158 	     && InRange( selectedItem+delta, 0, (int) textStrings.size()-1 ) )
159 	{
160 		selectedItem += delta;
161 		if ( selectedItem < firstItem )
162 			firstItem = selectedItem;
163 		else if ( selectedItem >= firstItem + (int) textWidgets.size() )
164 			firstItem = selectedItem - textWidgets.size() + 1;
165 
166 		//PublishEvent( SELECTION, selectedItem, 0, 0, 0 );
167 		//ItemSelectedSignal0.emit();
168 		//ItemSelectedSignal1.emit( textStrings[selectedItem] );
169 		KrWidgetEvent event;
170 		event.type = KrWidgetEvent::SELECTION;
171 		event.selection.index = selectedItem;
172 		event.selection.text = textStrings[selectedItem].c_str();
173 
174 		for(	Publisher< IKrWidgetListener >::const_iterator it = widgetPublish.begin();
175 				it != widgetPublish.end();
176 				++it )
177 		{
178 			(*it)->HandleWidgetEvent( this, event );
179 		}
180 
181 		DrawText();
182 	}
183 }
184 
185 
DrawText()186 void KrListBox::DrawText()
187 {
188 	for( int i=0; i<(int)textWidgets.size(); ++i )
189 	{
190 		KrColorTransform normal;
191 		KrColorTransform selected = scheme.CalcHiPrimary();
192 
193 		int index = i + firstItem;
194 		textWidgets[i]->SetColor( normal );
195 
196 		if ( InRange( index, 0, (int) textStrings.size()-1 ) )
197 		{
198 			textWidgets[i]->SetTextChar( textStrings[ index ] );
199 
200 			if ( selectedItem == index )
201 			{
202 				textWidgets[i]->SetColor( selected );
203 			}
204 		}
205 	}
206 }
207