Что нового

Размещение контролов в зависимости от входных данных

tecae

Новичок
Сообщения
5
Репутация
0
Версия AutoIt: 3.3.14.1

Описание:
Доброго времени суток.
Есть массив вида Пример = [0,1,1,1,2,4,1,4,2,4,4,1,1,2,2,4,1,1,2,1,2,0]

В зависимости от каждого флага разместить элемент управления

Попытка решения 8)
Из кода изъяты строки не относящиеся к алгоритму

Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

; Флаги расположения
Global const $NEW_CLMN           = 1  ; новая колонка сдвиг в право обнуление высоты
Global const $NEW_STR             = 2  ; новая строка сдвиг вниз
Global const $NEW_CLMN_STR  = 4  ; новая колонка сдвиг в право в той же строке без обнуления высоты
    ;===========================================================================
    ; Входные данные 

    Local $pos_k[22] = [0,1,1,1,2,4,1,4,2,4,4,1,1,2,2,4,1,1,2,1,2,0] ; масив флагов  может быть любым набором 4 знаков 0,..[124].,0

    
    Local  $Start_w = 100 , $Start_h = 20 , $Start_l = $Start_w *-1 , $Start_t = 0 , $K = 1  ; стартовые размеры контролов и отступ

    ;=========================================================================== 
    ;Реализация
    Local $m_str_h = 3 ; 
    Local $result[21] = [21] 
   
    
    
    Local  $old_w = 100
    Local  $old_h = 20 
    Local  $pos  = 1
    GUICreate("Мой GUI", 1024, 768, -1, -1, $WS_OVERLAPPEDWINDOW + $WS_POPUP) ; Создаёт окно в центре экрана
    GUISetState(@SW_SHOW) ; показывает созданное окно

    For $i = 1 To 20 Step 1  
      $pos = $pos_k[$i]   
           Switch $pos
               Case $NEW_CLMN 
                   $Start_l = $Start_l+$Start_w+$K
                   $Start_t = 0 
                   $Start_w = 100 
                   If $pos_k[$i+1] = $NEW_CLMN Then     ; дальше новая колонка
                     $Start_h = 20 * $m_str_h
                   ElseIF $pos_k[$i+1] = $NEW_STR Then  ; дальше строка 
                     $Start_h = 20
                   ElseIF $pos_k[$i+1] = $NEW_CLMN_STR Then  ; дальше строка  
                     $Start_h = 20
                     ; $Start_w =  100 / 2
                   EndIf
               Case $NEW_STR 
                   ;$Start_l = 0 ; не трогаем
                   $Start_t = $Start_t + $Start_h + $K
                   $Start_w = 100
                   $Start_h = 20
                   If $pos_k[$i+1] = $NEW_CLMN Then     ; дальше новая колонка
                     ;$Start_h = 20 * $m_str_h
                   ElseIF $pos_k[$i+1] = $NEW_STR Then  ; дальше строка 
                     ;l$Start_h = 20
                   ElseIF $pos_k[$i+1] = $NEW_CLMN_STR Then  ; дальше строка  
                      $Start_w =  100 / 2
                   EndIf 
                   If $pos_k[$i-1] = $NEW_CLMN_STR Then 
                      $Start_l = $Start_l-$Start_w ; не трогаем
                   Endif
                   
               Case $NEW_CLMN_STR 
                   $Start_l = $Start_l+$Start_w+$K
                   ;$Start_t = 0 ; не трогаем 
                   ;$Start_w = 100
                   $Start_h = 20
                                  
               Case Else
                   
           EndSwitch
           

           

       $result[$i] = GUICtrlCreateLabel("F"&$pos&' = I'&$i , $Start_l, $Start_t, $Start_w, $Start_h, $SS_CENTER + $WS_BORDER) 

    Next
     
    Do
        $msg = GUIGetMsg()

    Until $msg = $GUI_EVENT_CLOSE


Предполагаемый результат для данного случая
Контролы I4 I5 I8 I9 I10 I18 I20 = высота * 2
Контролы I8 I9 I10 ширина = (I6 ширина + I7 ширина )/3


Примечания:
Помогите построить универсальный алгоритм для любого случая удовлетворяющего $pos_k = "0[124]*?0"

Недостаток выше указанного кода - для его расширения и адаптации нужно применять циклы с проверкой назад и в перед что в последствии замедляет перерисовку формы
 

Вложения

  • Результат.jpg
    Результат.jpg
    31.4 КБ · Просмотры: 26
Автор
tecae

tecae

Новичок
Сообщения
5
Репутация
0
Сам критик сам и режиссёр
Сам сценарист сам и актер


Доброго времени суток.
Искренни благодарю за столь увлекательную дискуссию на открытую тему 8).

И так результатом многократного биения о стену является нижеследующий участок кода (функция)

Это часть проекта и копировать вставить работать не будет но сам алгоритм размещения отследить можно.
Если кому интересно ....

Код:
Func _lw_table_display_string($oSelf, $column, $left, $top, $func_display_control, $type = $STRING_TYPRE, $stringNum = 0)
	;Local $result = 0
	Local $num_str_heder = 1
	Local $num_colmn_in_column = 1

	Local $add_widht_index = 33
	Local $t_arr = $column;$oSelf.a_column
	Local $Start_l = $left
	Local $Start_t = $top
	Local $Start_w = $oSelf.widht_column
	Local $Start_h = $oSelf.hight_row
	Local $border = $oSelf.border
	;===== получаем масив колонок
	Local $t_arr_colmn = AssocArrayKeys($t_arr)
	_ArraySort($t_arr_colmn)
	Local $Ubound_t_arr_colmn = UBound($t_arr_colmn)
	Local $arr_pos[$Ubound_t_arr_colmn]
	; собрать данные
	Local $temp_n_s = 1
	Local $temp_val_wight = 0
	;===== разбираем положение каждой колонки формируем представление
	If $type = $HADER_TYPRE or $type = $TOTAL_TYPRE Then ;==============================================>

		For $i = 0 To $Ubound_t_arr_colmn - 1 Step 1
			Local $key_info = $t_arr_colmn[$i]
			Local $obj_column_info = AssocArrayGet($t_arr, $key_info)
			Local $post__info = $obj_column_info.position
			$arr_pos[$i] = $post__info
			; посчитать количество строк
			If $post__info = $NEW_CLMN Then
				If $temp_n_s > $num_str_heder Then
					$num_str_heder = $temp_n_s
				EndIF
				$temp_n_s = 1
			ElseIF $post__info = $NEW_STR Then
				$temp_n_s = $temp_n_s + 1
			EndIF
			;====>
		Next ; последнее не подтягивает прдублировано
		If $temp_n_s > $num_str_heder Then
			$num_str_heder = $temp_n_s
		EndIF

		If $type = $TOTAL_TYPRE Then
			; отобразим итоги в самом низу
			$Start_t = $oSelf.hight - ($Start_h * $num_str_heder) + (($num_str_heder - 1) * $border)
		EndIF
		$temp_val_wight = $oSelf.widht - $oSelf.widht_all_column

		If $temp_val_wight > 0 Then
			$add_widht_index = Floor($temp_val_wight / $oSelf.n_column_on)
		EndIF

		;===== разбираем представление по колонке
		Local $string_pos = _ArrayToString($arr_pos, "")
		Local $arr_colmn = StringSplit($string_pos, "1", 2)
		_ArrayDelete($arr_colmn, 0)

		;===== подготовить переменную возврата
		
		;===== переменные в не интерации
		Local $old_top = $Start_t
		Local $old_hight = $Start_h
		Local $lest_wight_clmn = 0
		Local $arr_strklmn
		Local $index_clmn = -1 ; индекс колонки
		Local $index_str = 0 ; индекс строки для колонки

		Local $oldStr = 0
		;Local $hTimer = TimerInit ( )
		;===== основной перебор колонок
	EndIF ;==============================================>

	Local $result[$Ubound_t_arr_colmn] = [$Ubound_t_arr_colmn - 1]
	Local $flag_klmn = 0


	For $i = 0 To $Ubound_t_arr_colmn - 1 Step 1
		Local $temp = $oSelf.hwnd
		Local $key = $t_arr_colmn[$i]
		Local $obj_column = AssocArrayGet($t_arr, $key)
		GUISwitch($temp)
		;===== Установка значений для текущего контрола
		Local $post_t = $obj_column.position

		If $type = $HADER_TYPRE or $type = $TOTAL_TYPRE Then ;==============================================>
			If $post_t = $NEW_CLMN Then ; рисуем колонку
				$index_clmn = $index_clmn + 1
				$index_str = 0
				; ;$dmsg("---------------------["&$arr_colmn[$index_clmn]&"]")
				If($arr_colmn[$index_clmn] = "") or(StringIsSpace($arr_colmn[$index_clmn]) = 1) Then
					; ширина остается
					$Start_h = ($old_hight * $num_str_heder) + (($num_str_heder - 1) * $border)

					$oSelf.index_app = $Start_h
					$oSelf.hight_string = $Start_h
					If $i > 1 Then
						$Start_w = $obj_column.widht
					ElseIf $i = 1 Then
						$Start_w = $obj_column.widht + $add_widht_index
					Else
						$Start_w = $obj_column.widht
					EndIF
					$lest_wight_clmn = $Start_w
				Else
					$arr_strklmn = StringSplit($arr_colmn[$index_clmn], "2", 2) ; строки
					$Start_h = $old_hight
					$Start_w = $obj_column.widht
					$lest_wight_clmn = $Start_w
				EndIF
			ElseIF $post_t = $NEW_STR Then ; рисуем строку
				$index_str = $index_str + 1
				$oldStr = $index_str
				Local $str_len = StringLen($arr_strklmn[$oldStr])
				$str_len = ($str_len = 0) ? 1 : $str_len
				local $is_border = $str_len * $border
				$Start_w = ($lest_wight_clmn - $is_border) / ($str_len + 1)

				If $arr_strklmn[$oldStr] = "" Then
					$Start_w = $lest_wight_clmn
				EndIF
			ElseIF $post_t = $NEW_CLMN_STR Then ; рисуем колонку в строке или колонке
				If $oldStr = $index_str Then
					; колонка в строке
					Local $str_len = StringLen($arr_strklmn[$oldStr])
					$str_len = ($str_len = 0) ? 1 : $str_len
					local $is_border = $str_len * $border
					$Start_w = ($lest_wight_clmn - $is_border) / ($str_len + 1)
				Else ; колонка в колонке
					$Start_w = $obj_column.widht
					$lest_wight_clmn = $lest_wight_clmn + $Start_w + $border
				EndIF
			EndIF
			;=====
		ElseIf $type = $STRING_TYPRE Then ;========================================>
			$Start_l = $obj_column.left
			$Start_t = $obj_column.top + $oSelf.hight_string * $stringNum
			$Start_w = $obj_column.widht
			$Start_h = $obj_column.hight
			Local $temp_ob = $obj_column.ctrl_clmn_id
			Local $tRect_wind = _WinAPI_GetWindowRect(HWND($temp))
			Local $tRect = _WinAPI_GetWindowRect(GUICtrlGetHandle($temp_ob))

			$Start_l = DllStructGetData($tRect, "Left") - DllStructGetData($tRect_wind, "Left")
			$Start_t = $obj_column.top + $oSelf.hight_string * $stringNum
			$Start_w = DllStructGetData($tRect, "Right") - DllStructGetData($tRect, "Left")
			$Start_h = DllStructGetData($tRect, "Bottom") - DllStructGetData($tRect, "Top")
			if $post_t = $NEW_CLMN or($post_t = $NEW_CLMN_STR and $flag_klmn = 1) Then
				$flag_klmn = 1
				$oSelf.widht_all_column = DllStructGetData($tRect, "Right") - DllStructGetData($tRect, "Left") + $border
			Else
				$flag_klmn = 0
			EndIF

		EndIF ;==============================================>
		;==============> сама отрисовка каждого контрола
		
		If isFunc($func_display_control) = 1 Then
			$result[$i] = $func_display_control($obj_column.caption, $Start_l, $Start_t, $Start_w, $Start_h, $SS_CENTER)

			If $type = $TOTAL_TYPRE Then
				GUICtrlSetResizing($result[$i], $GUI_DOCKSTATEBAR); + $GUI_DOCKWIDTH + $GUI_DOCKLEFT)
			ElseIF $type = $HADER_TYPRE Then
				$obj_column.left = $Start_l
				$obj_column.top = $Start_t
				$obj_column.widht = $Start_w
				$obj_column.hight = $Start_h
				$obj_column.ctrl_clmn_id = $result[$i]
				GUICtrlSetResizing($result[$i], $GUI_DOCKMENUBAR); + $GUI_DOCKWIDTH + $GUI_DOCKLEFT)
			ElseIF $type = $STRING_TYPRE Then
				GUICtrlSetResizing($result[$i], $GUI_DOCKMENUBAR); + $GUI_DOCKWIDTH + $GUI_DOCKLEFT)
			EndIF
		EndIF
		
		If $type = $HADER_TYPRE or $type = $TOTAL_TYPRE Then ;==============================================>
			;==============>
			;===== Установка значений для следующего контрола
			If $i + 1 > $Ubound_t_arr_colmn - 1 Then
			Else
				Local $key_next_after = $t_arr_colmn[$i + 1]
				Local $obj_column_next_after = AssocArrayGet($t_arr, $key_next_after)
				Local $post_after = $obj_column_next_after.position

				Switch $post_after
					Case $NEW_CLMN
						$Start_l = $Start_l + $Start_w + $border
						$Start_t = $old_top
					Case $NEW_STR
						If $post_t = $NEW_CLMN_STR Then
							$Start_l = $Start_l - $Start_w - $border
							$Start_t = $Start_t + $Start_h + $border
						ElseIF $post_t = $NEW_CLMN Then
							$Start_t = $Start_t + $Start_h + $border
						EndIF
					Case $NEW_CLMN_STR
						If $post_t = $NEW_CLMN Then
							$Start_l = $Start_l + $Start_w + $border
						ElseIf $post_t = $NEW_STR Then
							$Start_l = $Start_l + $Start_w + $border
						EndIF
					Case $NEW_STR_CLMN
						; $Start_l = $Start_l + $Start_w + $border
					Case Else
				EndSwitch
			EndIf
		EndIF ;==============================================>
	Next
	$oSelf.hight_all_row = $Start_t + $Start_h + $border
	$oSelf.widht_all_column = $Start_l + $Start_w + $border

	Return $result
EndFunc   ;==>_lw_table_display_string
 

Вложения

  • result.jpg
    result.jpg
    127.9 КБ · Просмотры: 17

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
tecae [?]
Искренни благодарю за столь увлекательную дискуссию на открытую тему
tecae, ну и молодцА!
сам добился. значит очень нужно было. и знаний и опыта прибавилось у тебя. а так, дали бы готовый ответ и до сих пор не понимал бы как что работает.
 
Автор
tecae

tecae

Новичок
Сообщения
5
Репутация
0
joiner сказал(а):
tecae, ну и молодцА!
сам добился. значит очень нужно было. и знаний и опыта прибавилось у тебя. а так, дали бы готовый ответ и до сих пор не понимал бы как что работает.

Спасибо...
В этом и есть наша проблема. Каждый из нас вынужден получать опыт и тратя драгоценное время изобретая все то же колесо... Хотя совместными усилиями уже катались бы на мотоцикле или летали на самолете....
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
не проблема, а момент обучения или самообучения. ты сочиняешь проект и это только твой проект.если бы ты искал партнеров по разработке, то, возможно, было бы совсем по-другому.
OffTopic:
насчет мотоцикла и самолета, то "блага" цивилизации весьма сомнительная штука и не делают жизнь человека счастливой
 
Верх