Przezroczystość w StringGrid

Przezroczystość w StringGrid
KA
  • Rejestracja:prawie 21 lat
  • Ostatnio:około miesiąc
  • Postów:700
0

Cześć,
od paru dni walczę z dostosowanie StringGrida do swoich oczekiwań :) Idzie mi to strasznie ciężko ale zrobiłem małe postępy.

Chciałbym aby po kliknięciu w wybraną komórkę cały wiersz został zaznaczony przezroczystym kolorem. Udało mi się to osiągnąć poprzez wczytanie obrazka z przezroczystością i wypełnieniem nim komórki.

Najbardziej zależy mi na tle StringGrida. Udało mi się wczytać do tła obrazek:

Kopiuj
procedure TForm1.StringGrid1DrawCell(Sender: TObject; aCol, aRow: Integer;
  aRect: TRect; aState: TGridDrawState);
begin

  StringGrid1.Canvas.Draw(0,0, Image1.Picture.Graphic);

end;

I jest ok ale nie do końca wygląda to tak jak chciałem.
Chciałbym aby ten wybrany obrazek wypełnił całą powierzchnię StringGrida a nie tylko miejsce gdzie są komórki.
Oprócz tego pojawił się u mnie pomysł aby całkowicie zlikwidować tło StringGrida.

Czy jest możliwe aby StringGrid nie miał żadnego tła (pomijając celowo pokolorowane komórki) i widoczne przez niego były elementy/kolory/tła komponentów, formy leżącej pod nim? Jak można osiągnąć taki efekt? Jest w ogóle to możliwe?

Dodatkowo pojawił się problem z opóźnieniem przy 'kolorowaniu' całego wiersza obrazem z przezroczystością. Kliknięta komórka koloruje się od razu jednak reszta dopiero po chwili.

Kolorowanie w ten sposób całego wiersza rozwiązałem poprzez zapisanie w zmiennej numeru klikniętego wiersza a potem w procedurze DrawCell sprawdzeniu czy aktualnie rysowana komórka leży w zaznaczonym wierszu.

Kopiuj
procedure TForm1.StringGrid1Click(Sender: TObject);
begin
     PRow:=StringGrid1.Row;
end;


procedure TForm1.StringGrid1DrawCell(Sender: TObject; aCol, aRow: Integer;
  aRect: TRect; aState: TGridDrawState);
begin

  stringgrid1.Canvas.Draw(0,0, Image1.Picture.Graphic);

      if (aCol = 0) or (aRow = 0) then
    begin
      stringgrid1.Canvas.Pen.Color := $00DCE8ED;
      stringgrid1.Canvas.Brush.Color := $00DCE8ED;
      stringgrid1.Canvas.Font.Style := [fsBold];
      stringgrid1.Canvas.Rectangle(aRect);
    end;

    if ((gdSelected in aState) or (PRow=aRow))  then
      begin
        stringgrid1.canvas.StretchDraw(aRect, img.Picture.Graphic);
      end;

end;

Może trochę chaotycznie ale proszę o pomoc:)

  • sg.png (73 KB) - ściągnięć: 236

Kto nigdy nie zrobił var dupa niech pierwszy rzuci kamień.
edytowany 1x, ostatnio: karpov
flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około godziny
  • Lokalizacja:Tuchów
  • Postów:12175
1

Jak chcesz, aby wszystkie komórki w poziomie były zaznaczane po kliknięciu to ustaw wartość goRowSelect na True we właściwości Options; Dzięki temu, po kliknięciu w daną komórkę, wszystkie w danym wierszu zostaną przemalowane, co możesz oprogramować w zdarzeniu OnDrawCell;

Natomiast żadne zdarzenie nie umożliwia oprogramowania malowania pustej przestrzeni kontrolki.


Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
KA
  • Rejestracja:prawie 21 lat
  • Ostatnio:około miesiąc
  • Postów:700
0

Dzięki!

Czyli nie da się po prostu tego oprogramować?
Dalej powalcze jednak troche z przezroczystością tła całego komponentu. Niby jest opcja ParentColor ale wtedy StringGrid przybiera tylko jednolity kolor, jeżeli wrzuce na Canvas formy jakiś obraz to oczywiście StringGrid tego nie widzi.


Kto nigdy nie zrobił var dupa niech pierwszy rzuci kamień.
edytowany 1x, ostatnio: karpov
flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około godziny
  • Lokalizacja:Tuchów
  • Postów:12175
1

Czyli nie da się po prostu tego oprogramować?

Da się, ale nie będzie to takie proste; Trzeba będzie ręcznie obsłużyć odpowiednie komunikaty i metody odpowiedzialne za wypełnianie tła komponentu; Oczywiście w taki sposób, aby nie zepsuć pozostałych mechanizmów; Z reguły jest to trudne zadanie i aby uzyskać zawsze działający prawidłowo kod, trzeba mieć dużą wiedzę i postępować z głową;

Niby jest opcja ParentColor ale wtedy StringGrid przybiera tylko jednolity kolor [...]

Efekt prawie taki, jaki Cię interesuje; Ustaw sobie ParentColor na True (dzięki temu kolor tła będzie z automatu taki sam jak rodzica), a następnie oprogramuj zdarzenie OnDrawCell, w którym zdefiniuj malowanie komórek;

Dzięki temu podczas działania programu, wszystkie komórki będą malowane dokładnie tak jak tego chcesz; A wyglądem komponentu w designerze się nie przejmuj - w tym czasie kod własnego zdarzenia nie działa, więc nie ma wtedy podglądu;

Przykładowy kod testowy (komponent nie posiada komórek tytułowych):

Kopiuj
procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; ARect: TRect; AState: TGridDrawState);
var
  LGrid: TStringGrid absolute Sender;
begin
  LGrid.Canvas.Brush.Color := clWhite;
  LGrid.Canvas.FillRect(ARect);
end;

Efekt podczas działania programu:

grid.png

Aby poprawnie rozróżnić tym komórki i jej styl, musisz skorzystać z dostarczonych w zdarzeniu argumentów; Typ komórki (tytułowa lub zwykła) określa się na podstawie współrzędnych malowanej komórki, czyli argumentów ACol i ARow; Aby sprawdzić, czy komórka jest tytułową, wartości tych parametrów należy porównać z wartościami właściwości FixedCols i FixedRows;

Kopiuj
var
  LFixed: Boolean;
begin
  LFixed := (ACol < LGrid.FixedCols) or (ARow < LGrid.FixedRows);

Do sprawdzenia stanu podświetlenia komórki, należy sprawdzić, czy w argumencie AState znajduje się enum gdSelected; Analogicznie z fokusem - jeśli malowana komórka trzyma fokusa to parametr AState zawiera wartość gdFocused; Sprawdzenie istnienia wartości wyliczeniowej w zbiorze dokonuje się za pomocą operatora In:

Kopiuj
var
  LSelected: Boolean;
  LFocused: Boolean;
begin
  LSelected := gdSelected in AState;
  LFocused := gdFocused in AState;

Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
edytowany 1x, ostatnio: flowCRANE
KA
  • Rejestracja:prawie 21 lat
  • Ostatnio:około miesiąc
  • Postów:700
0

Dzieki Panowie za pomoc,
poniosła mnie trochę fantazja i chciałem osiągnąć efekt jak na załączonym screenie ale widzę, że za krótki na razie jestem na takie bajery więc pokombinuje inaczej:)

Chciałem pokombinować z parent color wrzucając w tło formy jakiś obrazek (docelowo jakiś wzorek etc) tylko, że to i tak nie traktowane będzie przez formę jako 'color' a co za tym idzie StringGrid nie wyświetli tego jako ParentColor.


Kto nigdy nie zrobił var dupa niech pierwszy rzuci kamień.
flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około godziny
  • Lokalizacja:Tuchów
  • Postów:12175
1

poniosła mnie trochę fantazja i chciałem osiągnąć efekt jak na załączonym screenie ale widzę, że za krótki na razie jestem na takie bajery więc pokombinuje inaczej:)

Nie zauważyłem, że w pierwszym poście jest załącznik... :]

Nie widzę problemu, aby taki efekt osiągnąć; O ile nie przeszkadza Ci brak kontroli pustego obszaru to te cuda z komórkami jak najbardziej można uzyskać, i to w dość prosty sposób; Trzeba jednak pamiętać, że jeśli komponent będzie posiadał więcej kolumn/wierszy niż na raz pomieści, to trzeba będzie do obliczeń wziąć pod uwagę indeks pierwszej wyświetlonej kolumny/wiersza; Dzięki temu bez względu na widok (przewinięcie), obraz w komórkach będzie sprawiał wrażenie statycznego (stojącego w miejscu);

Czyli rozwiązanie - malować najpierw obliczony fragment obrazu, a następnie malować półprzezroczysty prostokąt (jeśli komórka jest zaznaczona).


Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
edytowany 1x, ostatnio: flowCRANE
KA
  • Rejestracja:prawie 21 lat
  • Ostatnio:około miesiąc
  • Postów:700
0

No właśnie troche mi nie pasuje brak kontroli nad tłem komponentu ale na razie zostawie ten temat. Zajmę się tym trochę później.

Załącznik w pierwszym poście to jest moje dzieło i efekt tego co udało mi się osiągnąć :)
Załącznik w poście nad Twoim ostatnim to efekt jaki chciałbym ostatecznie osiągnąć.

Dzięki za rady, postaram się powalczyć jeszcze z tematem i dam znać jak wyszło.


Kto nigdy nie zrobił var dupa niech pierwszy rzuci kamień.
flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około godziny
  • Lokalizacja:Tuchów
  • Postów:12175
0

Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
edytowany 1x, ostatnio: flowCRANE
KA
  • Rejestracja:prawie 21 lat
  • Ostatnio:około miesiąc
  • Postów:700
1

Powalczyłem trochę z tematem i udało mi się osiągnąć efekt, który w miarę mnie zadowala :)

grid.png

Jak widać mam jeszcze 2 problemy.

Pierwszy pewnie jest banalny ale nie wiem jak sobie z nim poradzić.
Chodzi o to żeby zlikwidować czerwoną ramkę przy zaznaczonym wierszu. Albo jestem już zmęczony albo StringGrid serio nie posiada nic takiego jak FocusRect=false?

Drugim problemem są ScrollBary. Specjalnie dodałem na screenie jeden żeby pokazać jak pięknie się wyróżnia.
Jest możliwe zmienienie koloru takiego scrollbara?

Cały czas googluje ale nie moge znaleźć nic konkretnego:)


Kto nigdy nie zrobił var dupa niech pierwszy rzuci kamień.
flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około godziny
  • Lokalizacja:Tuchów
  • Postów:12175
0

Chodzi o to żeby zlikwidować czerwoną ramkę przy zaznaczonym wierszu. Albo jestem już zmęczony albo StringGrid serio nie posiada nic takiego jak FocusRect=false?

Ustaw DefaultDrawing na False - będziesz mógł w pełni kontrolować malowanie komórek;

Drugim problemem są ScrollBary. Specjalnie dodałem na screenie jeden żeby pokazać jak pięknie się wyróżnia. Jest możliwe zmienienie koloru takiego scrollbara?

I tak, i nie - domyślnie nie ma takiej możliwości, więc trzeba by pokombinować z WinAPI, łapać odpowiednie komunikaty i oprogramować własne malowanie jego elementów; Albo skorzystać z jakiegoś mechanizmu skinowania (w tej paczce nie ma kontrolki StringGrid).


Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
edytowany 3x, ostatnio: flowCRANE

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.