Obrazek jako tło Form - proporcje

Obrazek jako tło Form - proporcje
DA
  • Rejestracja:ponad 6 lat
  • Ostatnio:około 2 lata
  • Postów:37
0

Witam.
Próbuję (na razie "wyklikać") coś takiego:

  • na Tform jest Tpicture z właściwością align=alclient i proportional, stretch=true. Po to, żeby obrazek rozciągał się wraz z formą (jako tło), ale zachowywał proporcje.

I obrazek ładnie zmienia swoją wielkość podczas skalowania okna, pozostając we właściwych proporcjach, ale wolną przestrzeń na Form w pionie lub poziomie (zależy jak zmieni się kształt okna) wypełnia pusta przestrzeń. Niby naturalne, skoro chce się zachować proporcje, ale ja chciałbym inaczej. Chciałbym, żeby obrazek wyrównywany był do dłuższego boku okna a drugi wymiar obrazka był obcinany i pojawiał się suwak.

Nie wiem, czy jasno to napisałem, w każdym razie nie wiem jak to ugryźć, choć próbuję na różne sposoby. Czy to, co napisałem jest w ogóle zrozumiałe? Czy nie da się bez ilustracji?

edytowany 2x, ostatnio: flowCRANE
flowCRANE
Lazarus czy Delphi?
DA
Próbowałem i tu i tu. Działało tak samo, czyli nie tak jak chcę. Mam oba, ale chętniej zrobiłbym to w Lazarus.
flowCRANE
Pytam, bo w tagach nie podałeś języka/technologii. Edytuj wątek i popraw te tagi, żeby było wiadomo o które środowisko chodzi.
DA
Ale akurat bez różnicy. Mam oba i w obu powinno to działaś tak samo. Tak przynajmniej zakładam.
flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 5 godzin
  • Lokalizacja:Tuchów
  • Postów:12163
0

Samym TImage tego nie zrobisz, bo ten nie daje takiej możliwości i z racji bycia kontrolką graficzną, nie obsługuje pasków przesuwania. Te natomiast obsługiwane mogą być przez formularz, gdy jego zawartość nie mieści się w obszarze klienta. Aby tak było, trzeba ustawić AutoScroll oraz HorzScrollBar.Visible i/lub VertScrollBar.Visible na True.

Do tego trzeba ręcznie ustalać rozmiar komponentu. Ustaw Align na wartość domyślną i w zdarzeniu OnResize lub metodzie ChangeBounds formularza sam obliczaj rozmiar kontrolki na podstawie rozmiaru obrazka (odczytuj ją z TImage.Picture). Natomiast rozmiar obszaru klienta pobierz z właściwości ClientWidth i ClientHeight – te właściwości zawierają rozmiar obszaru bez scrollbarów.


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 7x, ostatnio: flowCRANE
DA
  • Rejestracja:ponad 6 lat
  • Ostatnio:około 2 lata
  • Postów:37
0
furious programming napisał(a):

Samym TImage tego nie zrobisz, bo ten nie daje takiej możliwości i z racji bycia kontrolką graficzną, nie obsługuje pasków przesuwania. Te natomiast obsługiwane mogą być przez formularz, gdy jego zawartość nie mieści się w obszarze klienta. Aby tak było, trzeba ustawić AutoScroll oraz HorzScrollBar.Visible i/lub VertScrollBar.Visible na True.

Tak, to jasne. BTW: nie mogę edytować posta na którego ktoś już odpisał? (bo rzeczywiście chodzi o TImage a nie TPicture).

Do tego trzeba ręcznie ustalać rozmiar komponentu. Ustaw Align na wartość domyślną i w zdarzeniu OnResize lub metodzie ChangeBounds formularza sam obliczaj rozmiar kontrolki na podstawie rozmiaru obrazka (odczytuj ją z TImage.Picture). Natomiast rozmiar obszaru klienta pobierz z właściwości ClientWidth i ClientHeight – te właściwości zawierają rozmiar obszaru bez scrollbarów.

Tak, masz rację, to do tego zmierza. Myślałem, że da się to skonfigurować. Zacząłem już tak próbować, ale przy zdarzeniu OnPaint...

flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 5 godzin
  • Lokalizacja:Tuchów
  • Postów:12163
0

Jeśli bardzo chcesz to możesz skorzystać z OnPaint i malować obrazek za pomocą Canvas.StretchDraw na płótnie okna. Jednak w takim przypadku trzeba będzie ręcznie obliczać proporcje i wymiary obrazu względem obszaru klienta i ręcznie pokazywać, ukrywać i konfigurować paski przewijania.

Rozwiązanie z TImage jest prostsze i wymaga mniejszej ilości kodu do naklepania.


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 4x, ostatnio: flowCRANE
DA
  • Rejestracja:ponad 6 lat
  • Ostatnio:około 2 lata
  • Postów:37
0

Dokładnie tak zacząłem kombinować. Czy mógłbyś mi wyjaśnić, tak bardziej łopatologicznie, w czym by ta Twoja propozycja była lepsza/prostsza? Bo może jest właściwsza a nie kumam różnicy. Bez ręcznego wyliczania proporcji.

edytowany 1x, ostatnio: darekdarek
flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 5 godzin
  • Lokalizacja:Tuchów
  • Postów:12163
0

IMO bez obliczania proporcji się nie obejdzie, skoro potrzebujesz pokazywać albo dolny pasek przewijania, albo boczny. Ale nie ma się co martwić – wyznaczenie proporcji to podzielenie szerokości obrazka przez jego wysokość – i tyle.


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.
DA
  • Rejestracja:ponad 6 lat
  • Ostatnio:około 2 lata
  • Postów:37
0

Tu nie chodzi o matematykę ;) Dlaczego napisałeś, że ręcznie trzeba będzie pokazywać/ukrywać paski przewijania? Auto-scroll nie zadziała?

flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 5 godzin
  • Lokalizacja:Tuchów
  • Postów:12163
0
darekdarek napisał(a):

Dlaczego napisałeś, że ręcznie trzeba będzie pokazywać/ukrywać paski przewijania? Auto-scroll nie zadziała?

Jeśli chcesz samemu malować obraz na płótnie formularza, to samemu musisz te paski pokazywać. W końcu one pojawiają się wtedy, kiedy zawartość się nie mieści (a tą zawartością są komponenty).


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.
DA
  • Rejestracja:ponad 6 lat
  • Ostatnio:około 2 lata
  • Postów:37
0

Próbujesz mi powiedzieć, że Canvas formsa nie będzie nigdy miało rozmiarów z zapasem (większych niż form)?

edytowany 2x, ostatnio: darekdarek
flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 5 godzin
  • Lokalizacja:Tuchów
  • Postów:12163
0

No oczywiście – a niby dlaczego miałby być większy?


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.
DA
  • Rejestracja:ponad 6 lat
  • Ostatnio:około 2 lata
  • Postów:37
0

Nie twierdzę, że ma być. Rozumiem. Tylko to komplikuje całą zabawę (konkretnie z metodą Canvas.StretchDraw). Dzięki. Męczę się z tym, dobrze, że już przynajmniej wiem, że raczej tego nie wyklikam na obiektach.

Bo kombinowałem jakoś jeszcze tak: żeby na TForm położyć TPanel, który ma Canvas i może "wystawać" poza TForm (a na to Panel dopiero Image). I tu chciałem to skonfigurować właściwościami w ObjectInspectorze. No i poległem, póki co.

edytowany 2x, ostatnio: darekdarek
flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 5 godzin
  • Lokalizacja:Tuchów
  • Postów:12163
0
darekdarek napisał(a):

Męczę się z tym, dobrze, że już przynajmniej wiem, że raczej tego nie wyklikam na obiektach.

Właśnie w tym rzecz, że jeśli chcesz skorzystać z automatycznego dostosowywania pasków przewijania, to musisz mieć komponent (bo tylko wtedy te paski będą pokazywane przy AutoScroll).

Bo kombinowałem jakoś jeszcze tak: żeby na TForm położyć TPanel, który ma Canvas i może "wystawać" poza TForm (a na to Panel dopiero Image).

To samo możesz uzyskać ze zwykłym TImage i włączonym AutoScroll i to przecież Ci cały czas sugeruję. Jedyne co musisz zrobić to dostosować rozmiar komponentu podczas rozciągania formularza w taki sposób, aby komponent z obrazkiem nie mieścił się w obszarze klienta, aby formularz mógł pokazać/ukryć scrollbar(y).


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
DA
  • Rejestracja:ponad 6 lat
  • Ostatnio:około 2 lata
  • Postów:37
0

To i tak nie działa, nie wiem czemu.
Formuła typu image1.width:=form1.width; nie robi nic ani wewnątrz OnResize, ani wewn. ChangeBounds. Tak jakby rozmiary okna były jeszcze niedostępne w momencie ich wywoływania (tylko chwilę potem, już po narysowaniu wszystkiego) Nie wiem...

flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 5 godzin
  • Lokalizacja:Tuchów
  • Postów:12163
0
darekdarek napisał(a):

Formuła typu image1.width:=form1.width; nie robi nic ani wewnątrz OnResize […]

Pisałem o ClientWidth i ClientHeight. Poza tym to działa:

Kopiuj
procedure TMainForm.FormResize(Sender: TObject);
begin
  Image.Width := ClientWidth;
  Image.Height := ClientHeight;
end;

U mnie śmiga bez problemu.

[…] ani wewn. ChangeBounds. Tak jakby rozmiary okna były jeszcze niedostępne w momencie ich wywoływania (tylko chwilę potem, już po narysowaniu wszystkiego) Nie wiem...

Nowe wymiary okna są dostępne zarówno w zdarzeniu OnResize, jak i w metodzie ChangeBounds. W przypadku tego drugiego, jeśli już nadpisujemy tę metodę, to bieżące wymiary są dostępne przed wywołaniem wersji bazowej (za pomocą inherited), a nowe tuż po tym wywołaniu:

Kopiuj
procedure TMainForm.ChangeBounds(ALeft, ATop, AWidth, AHeight: Integer; AKeepBase: Boolean);
begin
  // tu jeszcze masz dostęp do starych rozmiarów

  inherited ChangeBounds(ALeft, ATop, AWidth, AHeight, AKeepBase);

  // a tutaj już do nowych
end;

Problem jednak jest taki, że ta metoda może być wywoływana wielokrotnie zanim obiekt komponentu zostanie utworzony w pamięci, dlatego trzeba to najpierw sprawdzić, zanim zacznie się korzystać z referencji kontrolki.

Drugi problem jest taki, że komponent z obrazkiem nie zostanie dopasowany do rozmiarów okna po pokazaniu okna na ekranie. Formularz się otworzy, ale kontrolka nadal będzie posiadać domyślne wymiary (te z designera) i dopiero wtedy podczas rozciągania okna zacznie ona się zachowywać tak jak chcemy (czyli dopasowywać swój rozmiar do klienta).

Wszystko dlatego, że metoda ChangeBounds okna jest wywoływana podczas ładowania danych formularza (wtedy jeszcze Image nie istnieje), ale nie jest wołana podczas wczytywania danych komponentu Image. Aby to zabezpieczyć, wystarczy nadpisać jeszcze jedną metodę – Loaded – która wywoływana jest tuż po załadowaniu i skonfigurowaniu formularza, i w niej wywołać ChangeBounds, przekazując bieżące wymiary.

Cały kod niżej, a w załączniku masz projekt do przetestowania lokalnie:

Kopiuj
type
  TMainForm = class(TForm)
    Image: TImage;
  protected
    procedure Loaded(); override;
    procedure ChangeBounds(ALeft, ATop, AWidth, AHeight: Integer; AKeepBase: Boolean); override;
  end;

{..}

procedure TMainForm.Loaded();
begin
  inherited Loaded();
  ChangeBounds(Left, Top, Width, Height, True);
end;

procedure TMainForm.ChangeBounds(ALeft, ATop, AWidth, AHeight: Integer; AKeepBase: Boolean);
begin
  inherited ChangeBounds(ALeft, ATop, AWidth, AHeight, AKeepBase);

  if Assigned(Image) then
    Image.BoundsRect := Self.ClientRect;
end;

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 5x, ostatnio: flowCRANE
DA
  • Rejestracja:ponad 6 lat
  • Ostatnio:około 2 lata
  • Postów:37
0

Dzięki za trud. Odpiszę jak przeanalizuję i przetestuję.

flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 5 godzin
  • Lokalizacja:Tuchów
  • Postów:12163
0

To co pokazałem wyżej sprawia, że rozmiar komponentu będzie zgodny z rozmiarem obszaru klienta. Podałem ten przykład dlatego, że sam nie poradziłeś sobie z obsługą OnResize i ChangeBounds.

Jak opanujesz działanie tych przykładów, to powinieneś się zabrać najpierw za wymyślenie sposobu dopasowywania według proporcji i dopiero wtedy za pisanie kodu. Przy czym łatwiejsze będzie wykorzystanie OnResize.


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
DA
  • Rejestracja:ponad 6 lat
  • Ostatnio:około 2 lata
  • Postów:37
0
furious programming napisał(a):

Podałem ten przykład dlatego, że sam nie poradziłeś sobie z obsługą OnResize i ChangeBounds.

Z ChangeBounds nie poradziłbym sobie, bo poległbym na inherited. Nie znalazłbym tego problemu.
Ale czemu OnResize u mnie po prostu nie działa, to nie wiem.

Inna sprawa - czy te dwa przykłady działają w zasadzie identycznie? Czy OnResize zadziała dopiero po puszczeniu LPM? Pytam, bo nie działa mi ani tak, ani tak.

Jak opanujesz działanie tych przykładów, to powinieneś się zabrać najpierw za wymyślenie sposobu dopasowywania według proporcji i dopiero wtedy za pisanie kodu.

Tak, po kolei.

edytowany 2x, ostatnio: flowCRANE
flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 5 godzin
  • Lokalizacja:Tuchów
  • Postów:12163
0
darekdarek napisał(a):

Z ChangeBounds nie poradziłbym sobie, bo poległbym na inherited. Nie znalazłbym tego problemu.

inherited to nie jest problem – to podstawowa własność programowania obiektowego. Musisz się podszkolić z obiektówki, jeśli chcesz sprawnie tworzyć aplikacje okienkowe.

Ale czemu OnResize u mnie po prostu nie działa, to nie wiem.

No ja też nie wiem, bo nie widziałem Twojego kodu.

Inna sprawa - czy te dwa przykłady działają w zasadzie identycznie?

Oba przykłady działają identycznie, zmieniając rozmiar komponentu w trakcie rozciągania okna – na żywo, nie po puszczeniu LPM. Dodaj do załączników projekt który Ci nie działa to go sprawdzę i napiszę co jest w nim nie tak.

We wcześniejszym poście dodałem projekt do załączników – pobierz sobie i przetestuj.


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 4x, ostatnio: flowCRANE
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)