Powoli zbliżam się do końca implementacji Richtrisa w wersji 2.0 (spoko, napiszę o tym na blogu). Główne jego okno jest pozbawione obramowania, a przez to również systemowych przycisków do minimalizacji, przywracania i zamykania okna.
Pomyślałem więc, że sobie takie przyciski zaprogramuję, czyli napiszę odpowiednie klasy (w formie ~komponentu) oraz w konstruktorze klasy formularza stworzę je dynamicznie. Wszystko dlatego, że nie chciało mi się babrać z pakietami i reinstalacją środowiska, żeby mieć je na palecie komponentów i w designerze). Łącznie z pięć — minimalizacja, zamknięcie oraz trzy do innych potrzebnych funkcji, całość w formie fajnego paska narzędzi. Przyciski te są bardzo proste — trzy główne stany (normalny, ”gorący” i wciśnięty) można uprościć do trzech obrazków, podmienianych w odpowiednich zdarzeniach. Roboty na pół godziny.
Ale… Naszło mnie, aby zaimplementować animowany efekt przejścia, wykonywany po najechaniu i zdjęciu kursora — taki sam jak ma np. okno eksploratora. Do łączenia obrazów na potrzeby przejścia, wykorzystałem kod z projektu testowego, którego źródła jakiś czas temu tutaj wrzucałem — https://4programmers.net/Forum/Delphi_Pascal/332442-laczenie_dwoch_obrazow_w_jeden_na_podstawie_zadanego_poziomu. No i te animacje wcale nie były tak trywialne do zaprogramowania, jak mi się na początku wydawało — miałem niemałą zagwozdkę… ;)
Było trochę zabawy z timerem i liczeniem klatek, tak aby w trakcie animacji klasa potrafiła wstrzymać trwające przejście, odwrócić jego kierunek i wznowić, ale koniec końców dało się zrobić. Dawno temu próbowałem coś takiego zrobić, ale zarzuciłem prace, bo mnie te przejścia denerwowały — zawsze się coś zacinało i tak wisiało. A tu się okazało, że trzeba sporo kodu naklepać, dla z pozoru tak prostego bajeru. W dodatku żeby miało to prawo działać, trzeba było użyć pięciu bitmap — jednej instancji do dynamicznego malowania i czterech referencji — i odpowiednio nimi żonglować. oczywiście przejście wykonywane jest jedynie w CMMouseEnter
i CMMouseLeave
— animacje podczas klikania nie są wykorzystywane, zgodnie z zachowaniem systemowych kontrolek.
W każdym razie z efektu końcowego jestem zadowolony — wyszło idealnie. Kody źródłowe kontrolki oraz aplikacji testowej (oraz plik wykonywalny do zabawy dla nie-pascalowców) są w załącznikach. Demówka pokazuje dwa okna, jedno z imitacją czarnego motywu oraz drugie z imitacją jasnego. Grafiki przycisków identyczne jak w systemie. W razie gdyby ktoś chciał mieć tę kontrolkę na palecie, to trzeba kilka rzeczy przenieść do sekcji published
, dodać co nieco dla designera i sprawdzić jak w designerze to działa. Sam nie używam w Richtrisie komponentów wizualnych, więc tworzenie tych przycisków z poziomu kodu mi w zupełności wystarczy.
No, kod do dowolnego użytku, więc częstujcie się i miłej zabawy. Dotacje mile widziane.
PS: Przyciski nie mają przypisanej żadnej akcji po kliknięciu, więc aby zamknąć program, należy zamknąć czarną formę za pomocą Alt+F4
. Nie programowałem klikania tych przycisków, aby móc testować poprawność ich działania. I wy też możecie śmiało klikać — demówka ani się nie zamknie, ani nie zminimalizuje.
PPS: W razie gdyby ktoś chciał sprawdzić w zwolnionym tempie i podrażnić się nieco najeżdżając i zabierając kursor, to zmieńcie sobie wartość prywatnej stałej TWindowButtonFade.FADE_FRAMES
np. na 100
. Animacja wykonywać się będzie bardzo długo, więc będzie czas na zabawę.
PPPS: Przy bardzo szybkim ruszaniu kursorem, zdarza się, że CMMouseLeave
nie jest wywoływany. Nie jest to wina kodu komponentu, a LCL — zgłaszałem ten problem lata temu i nadal nic się w tym temacie nie zmieniło. Ludzie nie potrafili nawet tego zreprodukować, i chyba przez to olano sprawę. Ja to mam szczęście… :D
- buttons.png (2 KB) - ściągnięć: 12
- TWindowButton — demo executable.zip (930 KB) - ściągnięć: 8
- TWindowButton — demo source.zip (71 KB) - ściągnięć: 7
Alt+PrtSc
robi zrzut aktywnego okna? Zapamiętaj, nie będziesz musiał ręcznie wycinać okna z pulpitu. ;)