PageRenderTime 33ms CodeModel.GetById 26ms app.highlight 3ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/CChoiceControl.ahk

http://github.com/Skiouros/Macro
AutoHotKey | 433 lines | 278 code | 1 blank | 154 comment | 74 complexity | 1b2ba9e153d7cd0413bb29992a06f6b0 MD5 | raw file
  1/*
  2Class: CChoiceControl
  3This class implements DropDownList, ComboBox and ListBox controls.
  4
  5This control extends <CControl>. All basic properties and functions are implemented and documented in this class.
  6*/
  7Class CChoiceControl Extends CControl ;This class is a ComboBox, ListBox and DropDownList
  8{
  9	__New(Name, Options, Text, GUINum, Type)
 10	{
 11		Base.__New(Name, Options, Text, GUINum)
 12		this.Type := Type
 13		if(Type = "Combobox")
 14			this._.Insert("ControlStyles", {LowerCase : 0x400, Uppercase : 0x2000, Sort : 0x100, Simple : 0x1})
 15		else if(Type = "DropDownList")
 16			this._.Insert("ControlStyles", {LowerCase : 0x400, Uppercase : 0x2000, Sort : 0x100})
 17		else if(Type = "ListBox")
 18			this._.Insert("ControlStyles", {Multi : 0x800, ReadOnly : 0x4000, Sort : 0x2, ToggleSelection : 0x8})
 19		this._.Insert("Events", ["SelectionChanged"])
 20		if(Type = "ListBox")
 21			this._.Insert("Messages", {5 : "KillFocus", 4 : "SetFocus" }) ;Used for automatically registering message callbacks
 22		else if(Type = "ComboBox" || Type = "DropDownList")
 23			this._.Insert("Messages", {4 : "KillFocus", 3 : "SetFocus" }) ;Used for automatically registering message callbacks
 24	}
 25	PostCreate()
 26	{
 27		Base.PostCreate()
 28		this._.Items := new this.CItems(this.GUINum, this.hwnd)
 29		Content := this.Content
 30		Loop, Parse, Content, |
 31			this._.Items.Insert(new this.CItems.CItem(A_Index, this.GUINum, this.hwnd))
 32		this._.PreviouslySelectedItem := this.SelectedItem
 33	}
 34	/*
 35	Variable: SelectedItem
 36	The text of the selected item.
 37
 38	Variable: SelectedIndex
 39	The index of the selected item.
 40
 41	Variable: Items
 42	An array containing all items. See <CChoiceControl.CItems>.
 43	*/
 44	__Get(Name, Params*)
 45    {
 46		;~ global CGUI
 47		if(Name != "GUINum" && !CGUI.GUIList[this.GUINum].IsDestroyed)
 48		{
 49			DetectHidden := A_DetectHiddenWindows
 50			DetectHiddenWindows, On
 51			if(Name = "SelectedItem")
 52				ControlGet, Value, Choice,,, % "ahk_id " . this.hwnd
 53			else if(Name = "Text")
 54				ControlGet, Value, Choice,,,% "ahk_id " this.hwnd
 55			else if(Name = "SelectedIndex")
 56			{
 57				SendMessage, 0x147, 0, 0,,% "ahk_id " this.hwnd
 58				Value := ErrorLevel + 1
 59			}
 60			else if(Name = "Items")
 61				Value := this._.Items
 62			else if(Name = "PreviouslySelectedItem")
 63				Value := this._.PreviouslySelectedItem
 64			;~ else if(Name = "Items")
 65			;~ {
 66				;~ ControlGet, List, List,,, % " ahk_id " this.hwnd
 67				;~ Value := Array()
 68				;~ Loop, Parse, List, `n
 69					;~ Value.Insert(A_LoopField)
 70			;~ }
 71			Loop % Params.MaxIndex()
 72				if(IsObject(Value)) ;Fix unlucky multi parameter __GET
 73					Value := Value[Params[A_Index]]
 74			if(!DetectHidden)
 75				DetectHiddenWindows, Off
 76			if(Value != "")
 77				return Value
 78		}
 79	}
 80	__Set(Name, Params*)
 81	{
 82		;~ global CGUI
 83		if(!CGUI.GUIList[this.GUINum].IsDestroyed)
 84		{
 85			Value := Params[Params.MaxIndex()]
 86			Params.Remove(Params.MaxIndex())
 87			DetectHidden := A_DetectHiddenWindows
 88			DetectHiddenWindows, On
 89			Handled := true
 90			if(Name = "SelectedItem")
 91			{
 92				Loop % this.Items.MaxIndex()
 93					if(this.Items[A_Index] = Value)
 94					{
 95						GuiControl, % this.GUINum ":Choose", % this.ClassNN, % A_Index
 96						this.ProcessSubControlState(this._.PreviouslySelectedItem, this.SelectedItem)
 97						this._.PreviouslySelectedItem := this.SelectedItem
 98					}
 99			}
100			else if(Name = "SelectedIndex" && Value >= 1 && Value <= this.Items.MaxIndex())
101			{
102				GuiControl, % this.GUINum ":Choose", % this.ClassNN, % Value
103				this.ProcessSubControlState(this._.PreviouslySelectedItem, this.SelectedItem)
104				this._.PreviouslySelectedItem := this.SelectedItem
105			}
106			;~ else if(Name = "Items" && !Params[1])
107			;~ {
108				;~ if(!IsObject(Value))
109				;~ {
110					;~ if(InStr(Value, "|") = 1) ;Overwrite current items
111					;~ {
112						;~ ;Hide overwritten controls for now (until they can be removed properly).
113						;~ for index, item in this.Items
114							;~ for index2, control in item.Controls
115								;~ control.hide()
116						;~ this.Items := new this.CItems(this.GUINum, this.Name)
117					;~ }
118					;~ Loop, Parse, Value,|
119						;~ if(A_LoopField)
120							;~ this.Items.Insert(this.Items.MaxIndex() + 1, new this.CItems.CItem(this.Items.MaxIndex() + 1, this.GUINum, this.Name))
121				;~ }
122				;~ else
123				;~ {
124					;~ ;Hide overwritten controls for now (until they can be removed properly).
125					;~ for index, item in this.Items
126						;~ for index2, control in item.Controls
127							;~ control.hide()
128					;~ this.Items := new this.CItems(this.GUINum, this.Name)
129					;~ Loop % Value.MaxIndex()
130						;~ this.Items.Insert(A_Index, new this.CItems.CItem(A_Index, this.GUINum, this.Name))
131				;~ }
132				;~ ItemsString := ""
133				;~ Loop % this.Items.MaxIndex()
134					;~ ItemsString .= "|" Items[A_Index]
135				;~ GuiControl, % this.GUINum ":", % this.ClassNN, %ItemsString%
136				;~ if(!IsObject(Value) && InStr(Value, "||"))
137				;~ {
138					;~ if(RegExMatch(Value, "(?:^|\|)(..*?)\|\|", SelectedItem))
139						;~ Control, ChooseString, %SelectedItem1%,,% "ahk_id " this.hwnd
140				;~ }
141				;~ for index, item in Items
142					;~ this.Items._.Insert(new this.CItems.CItem(A_Index, this.GUINum, this.Name))
143			;~ }
144			;~ else if(Name = "Items" && Params[1] > 0)
145			;~ {
146				;~ this._.Items[Params[1]] := Value
147				;~ msgbox should not be here
148				;~ Items := this.Items
149				;~ Items[Params[1]] := Value
150				;~ ItemsString := ""
151				;~ Loop % Items.MaxIndex()
152					;~ ItemsString .= "|" Items[A_Index]
153				;~ SelectedIndex := this.SelectedIndex
154				;~ GuiControl, % this.GUINum ":", % this.ClassNN, %ItemsString%
155				;~ GuiControl, % this.GUINum ":Choose", % this.ClassNN, %SelectedIndex%
156			;~ }
157			else if(Name = "Text")
158			{
159				found := false
160				Loop % this.Items.MaxIndex()
161					if(this.Items[A_Index].Text = Value)
162					{
163						GuiControl, % this.GUINum ":Choose", % this.ClassNN, % A_Index
164						this.ProcessSubControlState(this._.PreviouslySelectedItem, this.SelectedItem)
165						this._.PreviouslySelectedItem := this.SelectedItem
166						found := true
167					}
168				if(!found && this.type = "ComboBox")
169					ControlSetText, , %Value%, % "ahk_id " this.hwnd
170				;~ {
171					;~ GuiControl, % this.GUINum ":ChooseString", % this.ClassNN, % Value
172					;~ this.ProcessSubControlState(this._.PreviouslySelectedItem, this.SelectedItem)
173					;~ this._.PreviouslySelectedItem := this.SelectedItem
174				;~ }
175			}
176			else
177				Handled := false
178			if(!DetectHidden)
179				DetectHiddenWindows, Off
180			if(Handled)
181				return Value
182		}
183	}
184	/*
185	Event: Introduction
186	To handle control events you need to create a function with this naming scheme in your window class: ControlName_EventName(params)
187	The parameters depend on the event and there may not be params at all in some cases.
188	Additionally it is required to create a label with this naming scheme: GUIName_ControlName
189	GUIName is the name of the window class that extends CGUI. The label simply needs to call CGUI.HandleEvent().
190	For better readability labels may be chained since they all execute the same code.
191	Instead of using ControlName_EventName() you may also call <CControl.RegisterEvent> on a control instance to register a different event function name.
192
193	Event: SelectionChanged(SelectedItem)
194	Invoked when the selection was changed.
195	*/
196	HandleEvent(Event)
197	{
198		this.ProcessSubControlState(this._.PreviouslySelectedItem, this.SelectedItem)
199		this._.PreviouslySelectedItem := this.SelectedItem
200		this.CallEvent("SelectionChanged", this.SelectedItem)
201	}
202	/*
203	Class: CChoiceControl.CItems
204	An array containing all items of the control.
205	*/
206	Class CItems
207	{
208		__New(GUINum, hwnd)
209		{
210			this.Insert("_", {})
211			this._.GUINum := GUINum
212			this._.hwnd := hwnd
213		}
214
215		/*
216		Variable: 1,2,3,4,...
217		Individual items can be accessed by their index.
218
219		Variable: Count
220		The number of items in this control.
221		*/
222		__Get(Name)
223		{
224			;~ global CGUI
225			if(this._.HasKey(Name))
226				return this._[Name]
227			else if(Name = "Count")
228				return this.MaxIndex()
229		}
230		__Set(Name, Value)
231		{
232			;~ global CGUI
233			if Name is Integer
234				return
235		}
236		/*
237		Function: Add
238		Adds an item to the list of choices.
239
240		Parameters:
241			Text - The text of the new item.
242			Position - The position at which the item will be inserted. Items with indices >= this value will be appended.
243		*/
244		Add(Text, Position = -1)
245		{
246			;~ global CGUI
247			GUI := CGUI.GUIList[this._.GUINum]
248			Control := GUI.Controls[this._.hwnd]
249			Selected := Control.SelectedIndex
250			ItemsString := ""
251			Pos := 1
252			Loop % this.MaxIndex()
253			{
254				ItemsString .= "|" (Position = A_Index ? Text : this[pos].Text)
255				if(Position = A_Index)
256					pos--
257				pos++
258			}
259			if(Position = -1)
260				ItemsString .= "|" Text
261			GuiControl, % this._.GUINum ":", % Control.ClassNN, %ItemsString%
262			this._.Insert(Position = -1 ? this.MaxIndex() + 1 : Position, new this.CItems.CItem(Position, this._.GUINum, this.Name)) ;Insert new item object
263			for index, item in this ;Move existing indices
264				item._.Index := index
265			GuiControl, % this._.GUINum ":Choose", % Control.ClassNN, % (Position != -1 && Selected < Position ? Selected : Selected + 1)
266		}
267		/*
268		Function: Remove
269		Removes an item to the list of choices.
270
271		Parameters:
272			IndexTextOrItem - The item which should be removed. This can either be an index, the text of the item or the item object stored in the Items array.
273		*/
274		Remove(IndexTextOrItem)
275		{
276			;~ global CGUI
277			GUI := CGUI.GUIList[this._.GUINum]
278			Control := GUI.Controls[this.hwnd]
279			if(IsObject(IndexTextOrItem))
280			{
281				Loop % this.MaxIndex()
282					if(this[A_Index] = IndexTextOrItem)
283						IndexTextOrItem := A_Index
284			}
285			else if IndexTextOrItem is not Integer
286			{
287				Loop % this.MaxIndex()
288					if(this[A_Index].Text = IndexTextOrItem)
289						IndexTextOrItem := A_Index
290			}
291			if IndexTextOrItem is Number
292			{
293				if(IndexTextOrItem > 0 && IndexTextOrItem <= this.MaxIndex())
294				{
295					Selected := Control.SelectedIndex
296					this._.Remove(IndexTextOrItem)
297					ItemsString := ""
298					Loop % this.MaxIndex()
299						if(A_Index != IndexTextOrItem)
300							ItemsString .= "|" this[A_Index]
301					GuiControl, % this.GUINum ":Choose", % Control.ClassNN, % (Selected <= IndexTextOrItem ? Selected : Selected - 1)
302					for index, item in this
303						item._.Index := index
304				}
305			}
306		}
307		/*
308		Function: MaxIndex
309		Returns the number of items in this control.
310		*/
311		MaxIndex()
312		{
313			;~ global CGUI
314			DetectHidden := A_DetectHiddenWindows
315			DetectHiddenWindows, On
316			GUI := CGUI.GUIList[this._.GUINum]
317			ControlGet, List, List,,, % " ahk_id " this._.hwnd
318			count := 0
319			Loop, Parse, List, `n
320				count++
321			if(!DetectHidden)
322				DetectHiddenWindows, Off
323			return count
324		}
325		_NewEnum()
326		{
327			;~ global CEnumerator
328			return new CEnumerator(this)
329		}
330		/*
331		Class: CChoiceControl.CItems.CItem
332		A single item of this control.
333		*/
334		Class CItem
335		{
336			__New(Index, GUINum, hwnd)
337			{
338				this.Insert("_", {})
339				this._.Insert("GUINum", GUINum)
340				this._.Insert("hwnd", hwnd)
341				this._.Insert("Index", Index)
342				this._.Insert("Controls", {})
343			}
344			/*
345			Function: AddControl
346			Adds a control to this item that will be visible only when this item is selected. The parameters correspond to the Add() function of CGUI.
347
348			Parameters:
349				Type - The type of the control.
350				Name - The name of the control.
351				Options - Options used for creating the control.
352				Text - The text of the control.
353				UseEnabledState - If true, the control will be enabled/disabled instead of visible/hidden.
354			*/
355			AddControl(type, Name, Options, Text, UseEnabledState = 0)
356			{
357				;~ global CGUI
358				GUI := CGUI.GUIList[this._.GUINum]
359				if(!this.Selected)
360					Options .= UseEnabledState ? " Disabled" : " Hidden"
361				Control := GUI.AddControl(type, Name, Options, Text, this._.Controls)
362				Control._.UseEnabledState := UseEnabledState
363				Control.hParentControl := this._.hwnd
364				return Control
365			}
366			/*
367			Variable: Selected
368			If true, the item is selected.
369
370			Variable: Text
371			The text of the list item.
372			*/
373			__Get(Name, Params*)
374			{
375				;~ global CGUI
376				DetectHidden := A_DetectHiddenWindows
377				DetectHiddenWindows, On
378				if(Name = "Text")
379				{
380					GUI := CGUI.GUIList[this._.GUINum]
381					Control := GUI.Controls[this._.hwnd]
382					ControlGet, List, List,,, % " ahk_id " Control.hwnd
383					Loop, Parse, List, `n
384						if(A_Index = this._.Index)
385						{
386							Value := A_LoopField
387							break
388						}
389				}
390				else if(Name = "Selected")
391				{
392					GUI := CGUI.GUIList[this._.GUINum]
393					Control := GUI.Controls[this._.hwnd]
394					SendMessage, 0x147, 0, 0,,% "ahk_id " Control.hwnd
395					Value := (this._.Index = ErrorLevel + 1)
396				}
397				else if(Name = "Controls")
398					Value := this._.Controls
399				Loop % Params.MaxIndex()
400					if(IsObject(Value)) ;Fix unlucky multi parameter __GET
401						Value := Value[Params[A_Index]]
402				if(!DetectHidden)
403					DetectHiddenWindows, Off
404				return Value
405			}
406			__Set(Name, Value)
407			{
408				;~ global CGUI
409				if(Name = "Text")
410				{
411					GUI := CGUI.GUIList[this._.GUINum]
412					Control := GUI.Controls[this._.hwnd]
413					ItemsString := ""
414					SelectedIndex := Control.SelectedIndex
415					for index, item in Control.Items
416						ItemsString .= "|" (index = this._.Index ? Value : item.text)
417					GuiControl, % this._.GUINum ":", % Control.ClassNN, %ItemsString%
418					GuiControl, % this._.GUINum ":Choose", % Control.ClassNN, %SelectedIndex%
419					return Value
420				}
421				else if(Name = "Selected" && Value = 1)
422				{
423					GUI := CGUI.GUIList[this._.GUINum]
424					Control := GUI.Controls[this._.hwnd]
425					GuiControl, % this._.GUINum ":Choose", % Control.ClassNN, % this._.Index
426					this.ProcessSubControlState(this._.PreviouslySelectedItem, this.SelectedItem)
427					Control._.PreviouslySelectedItem := Control.SelectedItem
428					return Value
429				}
430			}
431		}
432	}
433}