|
AutoCAD... AutoLISP... VisualLISP... |
|
[17] popup_list i kolory |
|
Pisząc programy lispowe często zachodzi potrzeba przypisania koloru obiektom AutoCAD-a. Jeśli jest to program wykorzystujący DCL i ma posiadać możliwość wyboru kolorów przez użytkownika w oknie dialogowym, musimy zdecydować w jaki sposób zrealizujemy to zadanie. Projektując okno dialogowe programu mamy do wyboru albo wykorzystanie zwykłego przycisku, który po naciśnięciu uruchamia standardowe okno wyboru kolorów (funkcja AutoLISP acad_colordlg), lub skonstruowanie własnych procedur. Ze względu na funkcjonalność i szybkość wyboru, wybrałem tę drugą możliwość i napisałem procedury wyboru kolorów z listy rozwijalnej - podobnie jak to ma miejsce w pasku narzędzi AutoCAD-a. Oczywiście ze wzgledu na ograniczenia języka DCL, nie jest możliwe utworzenie takiej listy, aby były wyświetlane kolory. Lista musi być tekstowa, co przy 9 nazwanych kolorach AutoCAD-a zapewnia odpowiednią przejrzystość. Oprócz listy zastosowałem wycinek image który odpowiada za graficzną reprezentację wybranego koloru. Elementy okna dialogowego wyglądają mniej więcej tak:
|
|
|
Lista kolorów ma standardowo 10 pozycji. Są to kolory: JakWarstwa, JakBlok, siedem podstawowych kolorów AutoCAD-a, oraz dodatkowo pozycję "inny".
Na końcu listy pojawia się wtedy kolejna pozycja. Jest to numer wybranego koloru (jeżeli jest inny niż znajdujące sie na liście). Kolejna zmiana koloru powoduje usunięcie ostatnio wybranego koloru.
O ile zdefiniowanie wycinków (popup_list i image) w DCL nie powinno sprawiać żadnych problemów, to napisanie programu do ich obsługi jest nieco bardziej skomplikowane.
Główne problemy jakie napotkamy to:
Numery kolorów AutoCAD-a nie odpowiadają numerom pozycji wyświetlanych pozycji, zatem program musi cały czas "tłumaczyć" numer pozycji na kolor AutoCAD-a (i odwrotnie). Jest to potrzebne do aktualizacji image i samej listy. Ponadto musimy pamietać o tym że kolory AutoCAD-a to liczby całkowite, pozycje listy zaś, to łańcuchy tekstowe reprezentujace liczby całkowite.
Poniżej przedstawiam dwie procedury służące do obsługi listy kolorów AutoCAD-a, dwie inne (również tutaj potrzebne), są bardziej uniwersalne. Pierwsza funkcja służy do sformatowania listy kolorów i jej wyświetlenia. Będzie ona wykorzystywana również do zmiany zawartości popup_list po wybraniu innego koloru. Wywołuje ona też procedurę wypełnienia "image" wybranym kolorem. Poniżej kod funkcji, komentarze wewnątrz pozwolą zruzumieć zasadę działania: : |
;;; -------------------------------------------------- ;;; ;;; Procedura wyswietla liste kolorow. ;;; ;;; Argumenty: ;;; ;;; Key - nazwa wycinka (Str) ;;; ;;; ActCol - aktualny kolor (Str) ;;; ;;; ;;; (defun jk:DLG_FillColorList (Key ActCol / ListCol) (setq ListCol ; lista do wyswietlenia (list "JakWarstwa" ; z podstawowymi "JakBlok" ; kolorami "1 - Czerwony" "2 - Żółty" "3 - Zielony" "4 - Błekitny" "5 - Niebieski" "6 - Fioletowy" "7 - biały" "Inny..." ) ) (cond ; jezeli ((= ActCol "256")(setq ActCol "0")) ; JakWar => poz 0 ((= ActCol "0")(setq ActCol "1")) ; lub JakBl => poz 1 (t (setq ActCol ; w kazdym innym (itoa (1+ (atoi ActCol))) ; przypadku: ) ; poz = 1 + Nr koloru ) ) (if ; jezeli kolor (and ; z przedzialu od 9 (> (atoi ActCol) 8) ; do 255 (< (atoi ActCol) 256) ; utworz liste kolorow ) ; skladajaca z kolorow (setq ListCol ; podstawowych (append ; i nowego koloru ListCol (list (itoa (1- (atoi ActCol))) ) ) ; oraz ustaw pozycje ActCol "10" ; "kolor aktualny" ) ; na poz 10 ) (jk:DLG_List Key ListCol ActCol) ; wyswietl liste ) |
|
Druga funkcja to reakcja na wybranie elementu listy. Wywoływana jest jako argument funkcji "action_tile" w programie obsługi okna dialogowego:
|
;;; -------------------------------------------------------;;; ;;; Procedura wyboru koloru z listy kolorow. Umozliwia ;;; ;;; wybranie koloru z listy lub z okna wyboru standardowych;;; ;;; kolorow AutoCAD-a. Aktualizuje liste i wycinek ;;; ;;; typu "image". Zwraca nowy kolor ;;; ;;; Argumenty: ;;; ;;; Val - aktual. wybrana pozycja listy (Str);;; ;;; OldCol - numer poprzedniego koloru (Int) ;;; ;;; ;;; (defun jk:DLG_ChangeColorList (Val OldCol / NewCol CDlg TmpCol) (setq TmpCol (itoa OldCol)) ; zapamietaj "stary" kolor (cond ((= Val "0")(setq NewCol "256")); jesli 0 => kolor JakWar ((= Val "1")(setq NewCol "0")) ; jesli 1 => kolor jakBlok ((= Val "9") ; jesli 9 (setq CDlg ; wyswietl (acad_colordlg ; okno wyboru kolorow (atoi TmpCol) ; domyslny kolor to ) ; ostatni wybrany kolor ) (if CDlg ; jesli wybrany nowy kolor (setq NewCol (itoa CDlg) ; zamien go na string TmpCol (itoa Cdlg) ; zapamietaj jako ostatni ) ; jesli bylo Cancel (setq NewCol TmpCol) ; to nowy kolor = stary ) ) ; jesli poz 10 (stary) ((= Val "10") nil) ; nic nie rob, w kazdym (t (setq NewCol ; innym przypadku od (itoa (1- (atoi Val)))) ; wybranej poz odejmij 1 ) ; (wynik = string) ) (jk:DLG_FillColorList ; ponownie wypelnij liste "kolor" ; z nowym wybranym NewCol ; kolorem ) (jk:DLG_FillImageColor ; wypelnij image "sldkolor" ; z nowym wybranym (atoi NewCol) ; kolorem ) (atoi NewCol) ; zwroc wynik jako Int ) |
| Na koniec jeszcze dwie funkcje pomocnicze - ich prosta składnia nie wymaga komentarza: |
;;; ---------------------------------------------------- ;;; ;;; Procedura wypelnienia wycinka "image" kolorem ;;; ;;; Argumenty: ;;; ;;; ImageKey - nazwa wycinka (Str) ;;; ;;; FillColor - kolor do wypelnienia (Int) ;;; ;;; ;;; (defun jk:DLG_FillImageColor (ImageKey FillColor / X Y) (Setq X (Dimx_tile ImageKey) Y (Dimy_tile ImageKey) ) (Start_image ImageKey) (Fill_image 0 0 X Y FillColor) (End_image) ) ;;; ---------------------------------------------------- ;;; ;;; Procedura wypelnia wycinek typu "list_box" ;;; ;;; i "popup_list" Argumenty: ;;; ;;; ListKey - nazwa wycinka (Str) ;;; ;;; FillList - lista do wyswietlenia (List) ;;; ;;; APosition - pozycja "aktualna" ;;; ;;; (Str reprezent Int)lub Nil ;;; ;;; ;;; (defun jk:DLG_List (ListKey FillList APosition) (start_list ListKey) (mapcar 'add_list FillList) (end_list) (if APosition (set_tile ListKey APosition)) ) |
|
Prezentowane powyżej rozwiązanie z powodzeniem stosuję w wielu programach. Część z nich jest również dostępna na tych stronach.
|
|
|
|