Wielki problem ogólny

0

Programuję już od jakiegoś czasu w Delphi. Może nie jestem jakiś super-zaawansowany, ale radze sobie jako-tako. Napisałem trochę
programów i jestem w trakcie pisania kilku kolejnych. Jednym z nich jest program mający służyć pomocą chemikom (jak większość moich
programów). Jego zadaniem będzie pomoc w tworzeniu wzorów kropkowych różnych zwązków chemicznych.
Na czym polega problem?
Więc praktycznie na wszystkim. Ten program <ort>przyspożył </ort>mi już tylu problemów, że sam zwątpiłem w moje umiejętności. Przedstawię <ort>po
krótce</ort> jak miałby wyglądać ten programik.

W menu ToolBar użytkonik wybiera pierwiastek np. O i klika na przeznaczonej do tego celu częćsi formy, np. Panel1, albo coś innego. W
miejscu kliknięcia pojawia się kolejny Panel2 z Caption:='O'. Panel2 może być przemieszczany za pomocą Drag&Drop w obrębie Panel1.

  • do tego miejsca sobie radzę, ale dalej hmmm...

W około napisu 'O' rozmieszczone są kropki, np. w Image1, Image2 ... Image12. Rozmieszczone na planie kwadratu po trzy na każdym
boku. Niektóre są widoczne, a inne nie. Jeszcze inne tworzą linie (pary kropek). Dla O:

  -
. O .
  -

Rzecz polega na tym, że Panel2 posiada swój PopUp i tam są inne pierwiastki. Po kilknięciu na inny symbol Caption zmienia się na
właśnie wybrany, ale zmienia się też układ kropek (jak go zmienić skoro nie znam nazw tych obrazków - atomów może przecież być
więcej). Myślałem o napisaniu stosownego komponentu, ale to zupełnie mi nie wychodzi.
Np. zmienia się wszystko na:

  .
| N .
  .

Dalszą rzeczą jest to, że elektrony można przeciągać w <ort>obrembie </ort>atomu. Np. z poprzedniego układu zrobić za pomocą myszy coś takiego:

  -
  O :
  -

Albo można przeciągać elektrony na inne atomy w wolne miejsca, czyli z:

         -
 Na.   . Cl |
         -

zrobić za pomocą myszy coś takiego:

         -
 Na    : Cl |
         -

Ale to nie wszystko, bo muszą się teraz pokazać ładunki na tych atomach:

   (+)   - (-)
 Na    : Cl |
         -

Kolejną rzeczą jest to, że gdy elektron zostanie przeciąnięty na inny elektron to zostaną one połączone linią prostą w taki sposób,
że z:

       -
 H . . Cl |
       -

uzyskamy:

       -
 H ._. Cl |
       -

albo z:

  -     -
| O : : O |

w:

  -     -
| O :=: O |

Pamiętając przy tym, że atomy mogą zmieniać położenie.
Ostatnią rzeczą jest przeciągnięcie całej pary w wolną przestrzeń, np z tego:

-

|O:

-   -
S:=:O
-   -

zrobić to:

-

|O:
^
- -
S:=:O
- -

Przy czym ^ ocznacza strzałkę...

Oh! To wszystko mnie przerasta. Zapewne poradziłbym sobie, gdybym tylko wpadł na to jak zacząć. Byłoby naprawdę super, gdyby taki program powstał.

0

Lepiej zrób wszystko za pomocą canvasa. Zrób sobie jakiś typ danych, przechowujący symbol pierwiastka oraz ilość kropek, po czym rysuj na canvasie symbol, a wokół niego odpowiednią liczbę kropek. Gdy będziesz chciał zmienić pierwiastek, czyścisz canvas, zmieniasz dane w recordzie i rysujesz na nowo. Proste?

// Dopisane
Sprecyzuj dokładniej, co masz na myśli, mówiąc przeciąganie. Może było wyzej, ale nie chciało mi się czytać całego postu. Niezależnie jednak od tego, na canvasie da się to zrobić, zapewne dużo łatwiej, niż ci się zdaje. Nie najlepszym pomysłem natomiast, wydaje mi się używanie dynamicznych komponentów. Tu dopiero będzie bałagan, nie mówiąc już o szybkości działania takiego programu, szczególnie, jak zaczniesz tworzyć panele, potem na nich image, itd, itd. Ale rób, jak wydaje ci się prościej.

0

Canvas? Hmmm, wg mnie to kiepskie rozwiązanie, jak widzisz w tym przeciąganie? Ja bym do tego celu użył klas i dynamicznego tworzenia komponentów... Na pierwszy rzut oka problem wydaje się ogromny, ale jeśli dłużej na to popatrzeć - wydaje się nie takie straszne, a nawet: ciekawe :P

0

Wiec zrob to dynamicznie (zn te kropki) poten przy creowaniu zapisz je sobie w TStringList. Jak chces cos zmienic to odwolanie do itemow w TStringList i masz swoj TImage, na przyklad (Lista.Objects[2] as TImage).Top ....

0

Hmmm... Canvas nie jest głupi, ale Drag&Drop w tym momencie odpada, bo raczej siężko byłoby przeciągać obiekt którego nie ma :-) .

Pomyślę nad dynamicznym tworzeniem komponentów, ale nie radze sobie z odwoływaniem się do konkretnych elementów. Wolverine pisał, ale jeszce nie udało mi się tego wprowadzić w życie.

W każdym razie dzięki, jak ktoś wpadnie na jakiś (konkretny) pomysł, to słucham.

0

Hmmm... Canvas nie jest głupi, ale Drag&Drop w tym momencie odpada, bo raczej siężko byłoby przeciągać obiekt którego nie ma :-) .

Da się :)
Moja propozycja (częściowo jest to połączenie wcześniejszych pomysłów).
Utwórz sobie klasy typu jądro, elektron i atom. Atom będzie zawierał wewnątrz siebie jądro i tablicę eleketronów (ew. jakoś inaczej je wkomponować). Zmiany konfiguracji będziesz mógł swobodnie dokonać za pomocą odpowiednich funkcji "przenoszących" elektrony. Ew. jaką jeszcze klasę typu cząsteczka, jeżeli mają być uwspólnione elektrony dwóch atomów itp.
A teraz to starszne przeciąganie :)
Wszystkie te obiekty trzymasz np. w jakiejś tablicy. Każdy z nich ma jakieś współrzędne, więc bez problemu wyrysujesz je na TCanvas. Jeżeli zechcesz przeciągnąć, to po prostu obsłużysz OnMouseDown, OnMouseUp i OnMouseMove dla TCanvas i odpowiednio na podstawie współrzędnych wyszukasz obiekty z tablicy. Dla klasy nadrzędnej dla pozostałych możesz utworzyć funkcję sprawdzającą, czy dane współrzędne "należą" do obiektu.
Bardzo ładny przyklad programu wykorzystującego obiektowość... Hmm może podsunę taki pomysł na projekt :)

0

Sam nie wiem czy wyszukiwanie obiektu po wpółżędnych to dobry pomyśł. Poza tym nie tylko same atomy, ale także elektrony wokoło atomu mogą zmieniać pozycje, np:

 -
.S.
 -

zmienić myszką na:

 -
:S
 -

Inną sprawą jest to, jak zrobić takie zależności jednych obiektów (elektrony) od innych (atomy)? Byłbym wdzięczny, gdyby ktoś napisał mi chociaż krótki przykład.

0

Może bardziej zgrabny przykład:

z:

.S.

na:

:S

0

A więc tak. Jeśli chodzi o położenie tych atomów, to ja bym zrobił coś takiego:
Jest sobie (Jak wcześniej było napisane) tablica obiektów TAtom. Teraz TAtom wyglądałby w sposób następujący:

Type TAtom = object
  Symbol: String; //Niektóre atomy mają dwuliterowe symbole, więc Char nie wystarczy.
  PosX, PosY: Word; //Współrzędne atomu
  Elektrony: Array of TElektron; //Możesz podać zakres od 1 do 8 albo od 0 do 7 - jak ci wygodniej, i tak więcej elektronów walencyjnych nie będzie, a konkretna tablica jest prostsza w obsłudze niż dynamiczna
  end;
{Natomiast TElektron}
Type TElektron = object
  PosX, PosY: ShortInt; //Tutaj podajesz pozycję WZGLĘDEM POZYCJI JĄDRA, co pozwala na uproszczenie - podczas "poruszania" całym atomem, nie musisz modyfikować tych współrzędnych, elektrony pozostają na swoim miejscu względem jądra.
  end;

Oczywiście w w/w obiektach trzeba dodać metody pozwalające na dowolną modyfikację odpowiednich właściwości, a obiekt TAtom musi mieć metodę rysującą... To takie wskazówki - mam nadzieję, że pomogą.
Pozdrawiam.

0
{Natomiast TElektron}
Type TElektron = object
  PosX, PosY: ShortInt; //Tutaj podajesz pozycję WZGLĘDEM POZYCJI JĄDRA, co pozwala na uproszczenie - podczas "poruszania" całym atomem, nie musisz modyfikować tych współrzędnych, elektrony pozostają na swoim miejscu względem jądra.
  end;

Ja bym to zrobił na takich współrzędnych :

Type TElektron = object
    Promien : real;
    Kat : real;
end;

Ułatwiłoby to późniejszą ewentualną animację elektronów krążących wokół jądra.

0

Sam nie wiem czy wyszukiwanie obiektu po wpółżędnych to dobry pomyśł. Poza tym nie tylko same atomy, ale także elektrony wokoło atomu mogą zmieniać pozycje

Przecież elektrony to także obiekty, więc i one będą miały współrzędne :)
Co do kompozycji, to o ile pamiętam to atom może mieć maksymalnie 8 elektronów walencyjnych (ale nie ma to akurat większego znaczenia, można zwiększyć).
Wszyskie obiekty niech pochodzą od klasy TCzastka z polami współrzędne, masa i co tam jeszcze jest dla wszystkich wspólne i potrzebne. Dodatkowo niech posiadają metodę JestWOtoczeniu(x, y) zwracającą wartość Boolean zależnie czy współrzędne obiektu są w pobliżu danych współrzędnych (jakąś rozsądna granicę trzeba ustalić). Przydałyby się też metody Rysuj(x, y) (najlepiej wirtualna) oraz Przesun(Wektor) (być może także powinna być wirtualna, by można było przesuwać całke zbiory elementów).
To umożliwi nam sprawdzenie, czy w aktualnym miejscu jest obiekt, przesuwać go oraz wyrysować.
Teraz tworzymy obiekty pochodzne od TCzastka: TElektron i TAtom. W atomie tworzymy np. tablicę klas TElektron, która będzie przechowywać obiekty typu TElektron (albo dokładniej rzecz ujmując wskaźniki). Oczywiście TAtom zawiera informację na termat rodzaju pierwiastka (czyli jaka jest np. liczba protonów oraz aktualna wartosciowosc). Przydadzą nam się metody DodajElektron(e: TElektron), UsunElektron itp. Teraz przeciągając elektron na atom wywołujemy metodę DodajElektron, która zapamiętuje nam w tablicy nowo dodany elektron, modyfikuje wartościowość itp. Analogicznie "odciągniecie" elektronu jest usunięciem jego.
Jeżeli chcemy stworzyć np. wiązanie jonowe możemy np. zrobić tak, że przeciągamy elektron z jednego atomu na drugi (czyli usuwamy z jednego i dodajemy do drugiego) a powiązanie pomiędzy atomami albo wyliczamy (zależnie od położenia względem siebie atomów wiązania z jednymi mogą być silniejsze od innych) albo tworzymy klasę opakowanie TCzasteczka, która przechowuje nam inne czastki (m. in. powiązane atomy). Jako że jest też klasy TCzastka to również można ją przesuwać (ma większy zakres działania metody JestWOtoczeniu i/lub przesuwa się jej wew. elementy, jak Ctrl jest wciśnięty, albo się ją tak kasuje).
Teraz wiązania kowalencyjne. Przeciągnijmy elektron na elektron zamiast na atom i już mamy sparowane elektrony (można znowu utworzyć obiekt opakowujący, który będzie odrysowywał linię pomiędzy nimi lub w TElektron dać wskaźnik na drugi elektron i odrysowywać linię tylko wtedy, gdy sąsiad <> nil).
Sądzę, że możnaby to napisać bez wielkiego nakładu pracy, a byłoby to całkiem elastyczne (jakby zaszła potrzeba dodania jakiś właściwości to nie trzeba wiele modyfikować). Oczywiście przyjąć możesz sobie dowolny inny układ. Może gdzieś wykorzystujesz inne informacje (np. o własnościach pierwiastków) to mógłbyś połaczyć je z konkretnymi atomami. Może chcesz mieć możliwość ingerencji w jądro to rozbijesz TAtom tak, by jako jedno z pól było typu TJadro itp. itd.

A... i jeszcze coś. Najlepiej gdzieś te wszystkie elementy przetrzymywać (np. w tablicy) by móc je odrysować za pomocą jednej iteracji po nich i wywołaniu odpowiednich metod (albo np. wyszukaniu przeciąganych elementów).

0

Elektrony można przesuwać względem jądra, ale tylko w określone pozycje - trzy miejsca po prawej, trzy polewej, trzy u góry i trzy na dole. Po przesunięciu atomu jego elektrony muszą iść razem z nim, ale nie krążą wokł niego po żadnych orbitach - są statyczne (nie animowane) ale można ręcznie zmienić ich pozycję).

Jest jeszcze inna rzecz. Po przeciągnięciu elektronu na inny symbol - ten elektron zmienia "właściciela" na tamtego i ustawia się w "stosowwnej" pozycji (wolne miejsce).

Przyznaję, że coraz bardziej zaczynam to widzieć...

0

Teraz przyszła pora na omówienie niedomówień:

  1. Atom bloku s może mieć do dwóch elektronów walencyjnych, atom bloku p do 8 elektronów walencyjnych, atom bloku d może mnieć nawet 12 elektronów walencyjnych (np. Zn), ale to nie jest tak ważne, do w modelu po trzy elektronu u góry, na dole, po prawej i po lewej daje razem 12!

  2. Cząsteczka będzie tylko jedna (tak mi się wydaje), bo program ma służyć do tworzenia tzw. struktur Lewisa, czyli wzorów kropkowych (ang. electron dot diagram).

  3. Nie trzeba zapamiętywać ani masy, ani wartościowości - jedynie wyjściowe rozmieszczenie elektronów wokół symbolu pierwiastka.

  4. Pokazuję przykład, jak mogłoby to wyglądać:

user image

górny rysunek pokazuje wszystkie elementy, następny to przykład - ditlenek siarki SO2.

0

Nie wiem, czemu obrazek sie nie pokazjue - jest pod adresem http://www.chemmix.prv.pl/lewiswww1.gif. Dalej pokażę jak wygląda tworzenie takiego wzoru na rysunkach "z painta".

PS. Oczywiście nie są z painta ;p

korzystam z metody z TAtom i TElektron, bo wydaje się najlepsza, tylko jak mam teraz tworzyć ten atom. Prosze o wsparcie kawałkiem kodu.

0

Wystarczy zerknąć do artykułu na temat obiektów - jest jeden taki na 4p...

var
  Atom: TAtom;
begin
  Atom:=TAtom.Create;
  //.....
end;

PS. Nazwa "ditlenek siarki" to stara nomenklatura, teraz to jest "tlenek siarki (IV)" :)

0

Co do tlenku czy ditlenku to bym się kłócił, bo obie nazwy są poprawne. Mógłbym nawet powiedzieć tlenek siarki(+4), ale co to za różnica skoro i tak nie ma ładu w nomenklaturze chemicznej. Heh zresztą odsyłam do artykułu Nomen omen mojego autorstwa gdzie prezentuję swój pogląd na ten temat.

Jakkolwiek nazwa zmieniałaby się na przestrzeni wieków, tak wzór substancji pozostaje niezmienny (strukturalny, bo pomysły co do wzorów sumarycznych też są różne), dlatego też pisze ten program.

Siak czy owak – udało się!

Oto co ostatecznie zrobiłem:


unit Lewis;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, ToolWin, Menus, XPMan, TB97Ctls, TB97,
  TB97Tlbr, ExtCtrls, ShellApi, Math;

const crAtom = 2;
const crBond = 3;
const crKoor = 4;
const crJony = 5;
const crNorm = 6;
const crEmov = 7;

const WE = 4;
const OdlOdAt = 5;

type TElektron = class(TShape)

end;

type TAtom = class(TLabel)
 private
   Elektrony: array [1..12] of TElektron;
 public
   procedure DodajEl(e: TElektron);
   procedure UsunEl(e: TElektron);
end;

type TCzastka = class(TPanel)
 private
   Atomy: array of TAtom;
end;


type
  TForm1 = class(TForm)
    StatusBar1: TStatusBar;
    MainMenu1: TMainMenu;
    Plik1: TMenuItem;
    Zakocz1: TMenuItem;
    Zapiszjako1: TMenuItem;
    Edycja1: TMenuItem;
    Kopiuj1: TMenuItem;
    Pomoc1: TMenuItem;
    Pomoc2: TMenuItem;
    Aktualnawersja1: TMenuItem;
    Oprogramie1: TMenuItem;
    XPManifest1: TXPManifest;
    Dock971: TDock97;
    Dock972: TDock97;
    Toolbar971: TToolbar97;
    bH: TToolbarButton97;
    bNa: TToolbarButton97;
    bO: TToolbarButton97;
    bN: TToolbarButton97;
    bC: TToolbarButton97;
    bCl: TToolbarButton97;
    bP: TToolbarButton97;
    bS: TToolbarButton97;
    Toolbar973: TToolbar97;
    ToolbarButton974: TToolbarButton97;
    ObszarB: TPanel;
    Obszar: TImage;
    Widok1: TMenuItem;
    Pokasiatk1: TMenuItem;
    PopupMenu1: TPopupMenu;
    H1: TMenuItem;
    B1: TMenuItem;
    C1: TMenuItem;
    N1: TMenuItem;
    O1: TMenuItem;
    F1: TMenuItem;
    Na1: TMenuItem;
    Mg1: TMenuItem;
    Al1: TMenuItem;
    Si1: TMenuItem;
    P1: TMenuItem;
    S1: TMenuItem;
    Cl1: TMenuItem;
    K1: TMenuItem;
    Ca1: TMenuItem;
    Mn1: TMenuItem;
    Fe1: TMenuItem;
    Co1: TMenuItem;
    Ni1: TMenuItem;
    Cu1: TMenuItem;
    Zn1: TMenuItem;
    Br1: TMenuItem;
    Ag1: TMenuItem;
    Au1: TMenuItem;
    Hg1: TMenuItem;
    Pb1: TMenuItem;
    grid: TEdit97;
    ToolbarButton975: TToolbarButton97;
    procedure bHClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure ToolbarButton974Click(Sender: TObject);
    procedure ObszarMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure bCClick(Sender: TObject);
    procedure bOClick(Sender: TObject);
    procedure bNClick(Sender: TObject);
    procedure bClClick(Sender: TObject);
    procedure bSClick(Sender: TObject);
    procedure bPClick(Sender: TObject);
    procedure bNaClick(Sender: TObject);
    procedure ObszarDragOver(Sender, Source: TObject; X, Y: Integer;
      State: TDragState; var Accept: Boolean);
    procedure ObszarDragDrop(Sender, Source: TObject; X, Y: Integer);
    procedure WiazDragOver(Sender, Source: TObject; X, Y: Integer;
      State: TDragState; var Accept: Boolean);
    procedure WiazDragDrop(Sender, Source: TObject; X, Y: Integer);
    procedure Zakocz1Click(Sender: TObject);
    procedure Pomoc2Click(Sender: TObject);
    procedure Aktualnawersja1Click(Sender: TObject);
    procedure Oprogramie1Click(Sender: TObject);
    procedure MitClick(Sender: TObject);
    procedure AtomContextPopup(Sender: TObject; MousePos: TPoint;
      var Handled: Boolean);
    procedure ToolbarButton975Click(Sender: TObject);
    procedure Rozmiesc(e: TAtom);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  rysuj:boolean;
  typ:string;
  Atom:TAtom;
  Elektron:TElektron;
  n, I:integer;
  ktory : TObject;
implementation

uses aktualizacja, OProg;

{$R *.dfm}

{$R ZASOBY.RES}


procedure TForm1.bHClick(Sender: TObject);
begin
bH.Color:=clGradientActiveCaption;
bC.Color:=clBtnFace;
bO.Color:=clBtnFace;
bN.Color:=clBtnFace;
bCl.Color:=clBtnFace;
bS.Color:=clBtnFace;
bP.Color:=clBtnFace;
bNa.Color:=clBtnFace;
Obszar.Cursor := crAtom;
typ:='H';
end;

procedure TForm1.FormCreate(Sender: TObject);
begin

Screen.Cursors[crAtom] := LoadCursor (HInstance, 'ATOM');
Screen.Cursors[crBond] := LoadCursor (HInstance, 'BOND');
Screen.Cursors[crNorm] := LoadCursor (HInstance, 'NORM');
Screen.Cursors[crEmov] := LoadCursor (HInstance, 'EMOV');
Screen.Cursors[crKoor] := LoadCursor (HInstance, 'KOOR');
Screen.Cursors[crJony] := LoadCursor (HInstance, 'JONY');

Obszar.Cursor := crNorm;
Obszar.Canvas.Brush.Color:=clWhite;
Obszar.Canvas.Pen.Color:=clWhite;
Obszar.Canvas.Rectangle(0,0,Obszar.Width,Obszar.Height);
n:=0;

end;

procedure TForm1.ToolbarButton974Click(Sender: TObject);
begin
Obszar.Cursor := crNorm;
typ:='';
bH.Color:=clBtnFace;
bC.Color:=clBtnFace;
bO.Color:=clBtnFace;
bN.Color:=clBtnFace;
bCl.Color:=clBtnFace;
bS.Color:=clBtnFace;
bP.Color:=clBtnFace;
bNa.Color:=clBtnFace;
end;

procedure TForm1.ObszarMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
 IF typ <> '' THEN
 BEGIN
  Atom:=TAtom.Create(Form1);


  with Atom do
  begin
   for I := 1 to 12 do Elektrony[I]:=TElektron.Create(Atom);
   Left:=Round(X/StrToInt(Form1.grid.Text))*StrToInt(Form1.grid.Text);
   Top:=Round(Y/StrToInt(Form1.grid.Text))*StrToInt(Form1.grid.Text);
   DragMode:=dmAutomatic;
   Caption:=typ;
   Parent:=Form1.ObszarB;
   Font.Name:='Courier New';
   Font.Size:=14;
   DragCursor:=crNorm;
   PopupMenu:=PopupMenu1;
   OnContextPopup:=AtomContextPopup;
   for I := 1 to 12 do
   begin
    WITH Elektrony[I] DO
    BEGIN
     Shape:=stCircle;
     Brush.Color:=clBlack;
     Width:=WE;
     Height:=WE;
     Parent:=ObszarB;
     OnDragDrop:=WiazDragDrop;
     OnDragOver:=WiazDragOver;
     DragMode:=dmAutomatic;
    END;
   end;
   Rozmiesc(Atom);
  end;
 END;
ToolbarButton974Click(Form1);
end;

procedure TForm1.bCClick(Sender: TObject);
begin
bC.Color:=clGradientActiveCaption;
bH.Color:=clBtnFace;
bO.Color:=clBtnFace;
bN.Color:=clBtnFace;
bCl.Color:=clBtnFace;
bS.Color:=clBtnFace;
bP.Color:=clBtnFace;
bNa.Color:=clBtnFace;
Obszar.Cursor := crAtom;
typ:='C';
end;

procedure TForm1.bOClick(Sender: TObject);
begin
bO.Color:=clGradientActiveCaption;
bC.Color:=clBtnFace;
bH.Color:=clBtnFace;
bN.Color:=clBtnFace;
bCl.Color:=clBtnFace;
bS.Color:=clBtnFace;
bP.Color:=clBtnFace;
bNa.Color:=clBtnFace;
Obszar.Cursor := crAtom;
typ:='O';
end;

procedure TForm1.bNClick(Sender: TObject);
begin
bN.Color:=clGradientActiveCaption;
bC.Color:=clBtnFace;
bO.Color:=clBtnFace;
bH.Color:=clBtnFace;
bCl.Color:=clBtnFace;
bS.Color:=clBtnFace;
bP.Color:=clBtnFace;
bNa.Color:=clBtnFace;
Obszar.Cursor := crAtom;
typ:='N';
end;

procedure TForm1.bClClick(Sender: TObject);
begin
bCl.Color:=clGradientActiveCaption;
bC.Color:=clBtnFace;
bO.Color:=clBtnFace;
bN.Color:=clBtnFace;
bH.Color:=clBtnFace;
bS.Color:=clBtnFace;
bP.Color:=clBtnFace;
bNa.Color:=clBtnFace;
Obszar.Cursor := crAtom;
typ:='Cl';
end;

procedure TForm1.bSClick(Sender: TObject);
begin
bS.Color:=clGradientActiveCaption;
bC.Color:=clBtnFace;
bO.Color:=clBtnFace;
bN.Color:=clBtnFace;
bCl.Color:=clBtnFace;
bH.Color:=clBtnFace;
bP.Color:=clBtnFace;
bNa.Color:=clBtnFace;
Obszar.Cursor := crAtom;
typ:='S';
end;

procedure TForm1.bPClick(Sender: TObject);
begin
bP.Color:=clGradientActiveCaption;
bC.Color:=clBtnFace;
bO.Color:=clBtnFace;
bN.Color:=clBtnFace;
bCl.Color:=clBtnFace;
bS.Color:=clBtnFace;
bH.Color:=clBtnFace;
bNa.Color:=clBtnFace;
Obszar.Cursor := crAtom;
typ:='P';
end;

procedure TForm1.bNaClick(Sender: TObject);
begin
bNa.Color:=clGradientActiveCaption;
bC.Color:=clBtnFace;
bO.Color:=clBtnFace;
bN.Color:=clBtnFace;
bCl.Color:=clBtnFace;
bS.Color:=clBtnFace;
bP.Color:=clBtnFace;
bH.Color:=clBtnFace;
Obszar.Cursor := crAtom;
typ:='Na';
end;

procedure TForm1.ObszarDragOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
begin
IF (Source is TAtom) THEN Accept:=True ELSE Accept:=False;
TLabel(Source).DragCursor:=crEmov;
end;

procedure TForm1.ObszarDragDrop(Sender, Source: TObject; X, Y: Integer);
begin

 TAtom(Source).Left:=Round(X/StrToInt(Form1.grid.Text))*StrToInt(Form1.grid.Text);
 TAtom(Source).Top:=Round(Y/StrToInt(Form1.grid.Text))*StrToInt(Form1.grid.Text);
 Rozmiesc(TAtom(Source));

end;


procedure TForm1.WiazDragOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
begin
IF ((Sender<>Source) AND (Sender is TElektron) AND (Source is TElektron) AND (TAtom(Sender)<>TAtom(Source))) THEN Accept:=True ELSE Accept:=False;
TElektron(Source).DragCursor:=crBond;
end;

procedure TForm1.WiazDragDrop(Sender, Source: TObject; X, Y: Integer);
begin
Obszar.Canvas.Pen.Color:=clBlack;

 Obszar.Canvas.MoveTo(TElektron(Source).Left+Round(TElektron(Source).Width/2),TElektron(Source).Top+Round(TElektron(Source).Height/2));
 Obszar.Canvas.LineTo(TElektron(Sender).Left+Round(TElektron(Sender).Width/2),TElektron(Sender).Top+Round(TElektron(Sender).Height/2));

end;

procedure TForm1.Zakocz1Click(Sender: TObject);
begin
Close;
end;

procedure TForm1.Pomoc2Click(Sender: TObject);
begin
   ShellExecute(Handle, 'open', 'Pomoc - Lewis.pdf', nil, nil, SW_SHOWNORMAL);
end;

procedure TForm1.Aktualnawersja1Click(Sender: TObject);
begin
Form3.ShowModal;
end;

procedure TForm1.Oprogramie1Click(Sender: TObject);
begin
Form4.ShowModal;
end;

procedure TForm1.MitClick(Sender: TObject);
begin
TLabel(ktory).Caption:=TMenuItem(sender).Caption;
end;

procedure TForm1.AtomContextPopup(Sender: TObject; MousePos: TPoint;
  var Handled: Boolean);
begin
ktory:=sender;
end;

procedure TForm1.ToolbarButton975Click(Sender: TObject);
begin
Obszar.Canvas.Brush.Color:=clWhite;
Obszar.Canvas.Pen.Color:=clWhite;
Obszar.Canvas.Rectangle(0,0,Obszar.Width,Obszar.Height);
end;

procedure TAtom.DodajEl(e: TElektron);
begin
 Application.MessageBox('a','a');
end;

procedure TAtom.UsunEl(e: TElektron);
begin
 Application.MessageBox('a','a');
end;

procedure TForm1.Rozmiesc(e: TAtom);
begin
 with TAtom(e) do
 begin
  Elektrony[1].Left:=Left+Round((Width-5*(OdlOdAt-1))/2);
  Elektrony[1].Top:=Top-OdlOdAt;
  Elektrony[2].Left:=Left+Round((Width-5*(OdlOdAt-1))/2)+2*(OdlOdAt-1);
  Elektrony[2].Top:=Top-OdlOdAt;
  Elektrony[3].Left:=Left+Round((Width-5*(OdlOdAt-1))/2)+4*(OdlOdAt-1);
  Elektrony[3].Top:=Top-OdlOdAt;
  Elektrony[4].Left:=Left+Width+(OdlOdAt-1);
  Elektrony[4].Top:=Top+Round((Height-3*WE-2*(OdlOdAt-1))/2);
  Elektrony[5].Left:=Left+Width+(OdlOdAt-1);
  Elektrony[5].Top:=Top+Round((Height-3*WE-2*(OdlOdAt-1))/2)+2*(OdlOdAt-1);
  Elektrony[6].Left:=Left+Width+(OdlOdAt-1);
  Elektrony[6].Top:=Top+Round((Height-3*WE-2*(OdlOdAt-1))/2)+4*(OdlOdAt-1);
  Elektrony[7].Left:=Left+Round((Width-5*(OdlOdAt-1))/2)+4*(OdlOdAt-1);
  Elektrony[7].Top:=Top+Height;
  Elektrony[8].Left:=Left+Round((Width-5*(OdlOdAt-1))/2)+2*(OdlOdAt-1);
  Elektrony[8].Top:=Top+Height;
  Elektrony[9].Left:=Left+Round((Width-5*(OdlOdAt-1))/2);
  Elektrony[9].Top:=Top+Height;
  Elektrony[10].Left:=Left-OdlOdAt-2;
  Elektrony[10].Top:=Top+Round((Height-3*WE-2*(OdlOdAt-1))/2)+4*(OdlOdAt-1);
  Elektrony[11].Left:=Left-OdlOdAt-2;
  Elektrony[11].Top:=Top+Round((Height-3*WE-2*(OdlOdAt-1))/2)+2*(OdlOdAt-1);
  Elektrony[12].Left:=Left-OdlOdAt-2;
  Elektrony[12].Top:=Top+Round((Height-3*WE-2*(OdlOdAt-1))/2);
 end;
end;

end.

Jak widać TElektron dziedziczy class(TShape), a TAtom dziedziczy class(TLabel) i dzięki temu nie musze ich potem wyrysowywać tylko są Od razu.

Troche tego jest, a to nie koniec przecież... ale działa. Musze jeszcze poprawić funkcję Rozmiesc, utworzyć funkcje DodajEl i UsunEl i przy wstawianiu automatycznie usuwac stosowne elektrony. Infrormacje o ich rozmieszczeniu zapisze sobie w pliku ini. I wszystko powinno być ok.

Aha... nie wiem jeszcze jak robić linie pomiędzy tymi elektronami, bo moje rozwiązanie ma swoje wady, bo po przesunięciu atomu wiązanie zostaje: zupełnie to zmienić, czy próbować coś z tym - prosze o rade.

0

Mało obiektowo :P
Co do problemu, to po prostu wzbogać klasę TElektron o pole drugiego elektronu i jeżeli nie jest puste to dorysujesz linię (albo na Canvas, albo jakiego TShape użyjesz, skoro tak lubisz :) )

0

To prawda - jest proste, ale takie miało być. Działa a to najważniejsze. Moze jeszcze kiedyś napisze go od nowa...

0

To prawda - jest proste, ale takie miało być.

Oczywiście, każdy projekt powinien być tak prosty jak się da. Chodziło mi o coś innego, ale to było tylko takie sobie czepianie się ideologiczne :P Program jest spoko.

1 użytkowników online, w tym zalogowanych: 0, gości: 1