]> matita.cs.unibo.it Git - logicplayer.git/blobdiff - mainActivity/src/com/example/furt/myapplication/Node.java
New version (to be tested).
[logicplayer.git] / mainActivity / src / com / example / furt / myapplication / Node.java
index 9b724ffb4068b38de5d493a4e24f68bd1991d03d..0a39fdf635fb59653cd434ce6b15ff7b52015a53 100755 (executable)
@@ -29,16 +29,17 @@ public class Node implements Tree {
     List<Hypothesis> NodeHP = new ArrayList<Hypothesis>(); //ipotesi associate
     Node Father; //puntatore al padre
     View.OnClickListener handler; //touchHandler per far comparire il pop-up delle regole
+    View.OnLongClickListener longHandler; //touchHandler per far comparire il menu con tutte le regole
     boolean hasFocus; //indica se questo nodo è quello selezionato
     int status; //stato del nodo (chiuso, aperto,fake...)
     RelativeLayout global; //layout in cui si trova l'albero
     BorderedTextView view; //view contenente questo oggetto
     TextView ruleView; //view contenente l'intestazione della regola
 
-    float baseLine;
-    float leftOffset;
-    float rightOffset;
-    float maxWidth;
+    float baseLine; //baseLine del Node: corrisponde alla lunghezza dell'overline
+    float leftOffset; //leftOffset: corrisponde alla larghezza della porzione di albero a sinistra del nodo
+    float rightOffset; //rightOffset: porzione di albero a destra del nodo
+    float maxWidth; //larghezza del sottoalbero di questo nodo (comprensiva del nodo stesso)
 
     Node(Formula F) {
         this.F = F;
@@ -80,11 +81,17 @@ public class Node implements Tree {
             ris+=n.count();
         return ris;
     }
+    /**************addHP****************+*****/
+    /*****************************************/
+    /*******Metodi per aggiungere ipotesi*****/
+    /*******sotto forma di Hypothesis o di****/
+    /*************Formula*********************/
+    /*****************************************/
 
     public void addHPFormula(List<Formula>List,boolean deleted) {
         loop:for (Formula newHp:List) {
             for (Hypothesis oldHp: NodeHP) {
-                if (oldHp.HP.toString().equals(newHp.toString())) {
+                if (oldHp.HP.toString().equals(newHp.toString())) { //ipotesi già presente: passo alla prossima
                     continue loop;
                 }
             }
@@ -95,7 +102,7 @@ public class Node implements Tree {
     public void addHPList(List<Hypothesis>List) {
         loop:for (Hypothesis newHp:List) {
             for (Hypothesis oldHp: NodeHP) {
-                if (oldHp.HP.toString().equals(newHp.HP.toString())) {
+                if (oldHp.HP.toString().equals(newHp.HP.toString())) { //ipotesi già presente: passo alla prossima
                     continue loop;
                 }
             }
@@ -105,6 +112,11 @@ public class Node implements Tree {
         }
     }
 
+    /*****************************************/
+    /******* Algoritmo di ricerca del ********/
+    /******* focus: restituisce false ********/
+    /******* se la dimostrazione è completa***/
+
     public boolean searchFocus(Node caller)
     {
         if (Children.size()==0) //caso base: controllo se il focus può essere su di me
@@ -137,6 +149,7 @@ public class Node implements Tree {
         N.Father = this;
         Children.add(N);
         Node tmp=Father;
+        //c'è un nuovo nodo nell'albero: tutti i campi dell'algoritmo di disegno sono da ricalcolare per questo ramo
         baseLine=FIELD_UNSET;
         maxWidth=FIELD_UNSET;
         leftOffset=FIELD_UNSET;
@@ -170,20 +183,11 @@ public class Node implements Tree {
             return baseLine;
         else
         {
-            float spaceSize = DrawActivity.spaceSize;
-            if (Children.size() == 0)
-                return (getBaseWidth());
-            int res = 0;
-            for (Node n:Children)
-                res += (n.getMaxWidth()) + spaceSize;
-            res -= spaceSize;
-            res -= Children.get(0).getLeftOffset();
-            res -= Children.get(Children.size() - 1).getRightOffset();
-            baseLine=Math.max(res,getBaseWidth());
+            baseLine=Math.max(getUpLine(),getBaseWidth()); //la baseline è il massimo valore tra la upLine e la baseWidth
             return baseLine;
         }
     }
-    public float getUpLine()
+    public float getUpLine() //calcola la upLine, ovvero la dimensione prevista del sottoalbero assumendo il nodo attuale di lunghezza unitaria
     {
         float spaceSize= DrawActivity.spaceSize;
         if (Children.size()==0)
@@ -192,10 +196,16 @@ public class Node implements Tree {
         for(Node n:Children)
             res+=(n.getMaxWidth())+spaceSize;
         res-=spaceSize;
-        res-=Children.get(0).getLeftOffset();
-        res-=Children.get(Children.size()-1).getRightOffset();
+        res-=Children.get(0).getLeftOffset(); //la linea deve fermarsi all'inizio della formula del primo figlio sinistro
+        res-=Children.get(Children.size()-1).getRightOffset(); //la linea deve finire alla fine della formula dell'ultimo figlio destro
         return res;
     }
+
+    /**Calcolo del leftOffset
+     * esso è uguale al leftOffset del primo figlio, a cui aggiungere la porzione di overline a sinistra della formula del nodo
+     * o rimuovere la mezza differenza tra la baseWidth e la upLine. Se il leftOffset risulterebbe negativo, diventa nullo.
+     */
+
     public float getLeftOffset() {
         if (leftOffset != FIELD_UNSET) {
             return leftOffset;
@@ -209,18 +219,6 @@ public class Node implements Tree {
         }
     }
 
-    public float getMaxHeight()
-    {
-        float baseRes=F.height();
-        float res=baseRes;
-        for (Node n:Children)
-        {
-            float tempH=n.getMaxHeight()+baseRes;
-            if(tempH>res)
-                res=tempH;
-        }
-        return res;
-    }
     public float getRightOffset()
     {
         if (rightOffset!=FIELD_UNSET)
@@ -233,7 +231,21 @@ public class Node implements Tree {
             return rightOffset;
         }
     }
-    void Refactor()
+
+    public float getMaxHeight() //calcolo dell'altezza massima dell'albero attuale.
+    {
+        float baseRes=F.height();
+        float res=baseRes;
+        for (Node n:Children)
+        {
+            float tempH=n.getMaxHeight()+baseRes;
+            if(tempH>res)
+                res=tempH;
+        }
+        return res;
+    }
+
+    void Refactor() //metodo di supporto: svuota i campi dell'intero sottoalbero che verranno ricalcolati dall'algoritmo alla prossima applicazione
     {
         baseLine=FIELD_UNSET;
         leftOffset=FIELD_UNSET;
@@ -243,83 +255,13 @@ public class Node implements Tree {
             n.Refactor();
     }
 
-    void Resize()
-    {
-        int i;
-        float interval=0; //intervallo di spazio da sommare nella creazione dei figli
-        float spaceSize= DrawActivity.spaceSize;
-        int childNo=Children.size();
-        if (childNo!=0)
-        {
-
-            ruleView.setText(ruleName);
-            ruleView.setTextSize(TypedValue.COMPLEX_UNIT_PX, DrawActivity.textSize / 2);
-            RelativeLayout.LayoutParams intlp=new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
-            intlp.addRule(RelativeLayout.RIGHT_OF,view.getId());
-            int sum=0;
-            sum+=F.height();
-            Node tmp=Father;
-            while (tmp!=null)
-            {
-                sum+=tmp.F.height();
-                tmp=tmp.Father;
-            }
-            intlp.setMargins(0,0,0,sum);
-            intlp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
-            ruleView.setLayoutParams(intlp);
-        }
-        for (i=0;i<childNo;i++) {
-            Node newChild=Children.get(i);
-            RelativeLayout.LayoutParams lp=new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
-            TextView childView=Children.get(i).view;
-            lp.addRule(RelativeLayout.ABOVE,view.getId());
-            if (i==0) //first child
-            {
-                float leftPos= view.getLeft()-Math.max((newChild.getLineWidth()-newChild.getBaseWidth())/2,0);
-                if (getLineWidth()>getUpLine())
-                    leftPos+=((getLineWidth()-getUpLine())/2);
-                lp.setMargins(Math.round(leftPos), 0, 0, 0);
-                childView.setLeft(Math.round(leftPos));
-            }
-            else {
-                lp.setMargins(Math.round(view.getLeft() + interval), 0, 0, 0);
-                childView.setLeft(Math.round(view.getLeft() + interval));
-            }
-            childView.setLayoutParams(lp);
-            childView.setTextSize(TypedValue.COMPLEX_UNIT_PX, DrawActivity.textSize);
-
-            if(newChild.status==CANCELED || newChild.status==FAKE_CANCELED)
-                childView.setWidth((int) ((newChild.F.sizeDeleted())));
-            else
-                childView.setWidth(Math.round(newChild.getLineWidth()));
-
-            newChild.Resize();
 
-            if (i!=childNo-1) //l'ultimo figlio non ha intervalli
-            {
-                float leftOverflow=(Children.get(i+1).getLineWidth()-Children.get(i+1).getBaseWidth())/2;
-                interval += (newChild.getBaseWidth()+newChild.getRightOffset()+Children.get(i+1).getLeftOffset()-(leftOverflow));
-                interval+=spaceSize;
-                if (i!=0) //devo sommare anche il leftOverflow del nuovo figlio
-                    interval+=newChild.getLeftOffset();
-            }
-
-        }
-
-    }
-
-    public int treeHeight()
+    public void Clean() //metodo di supporto: rimuove dal layout legato al Node tutte le view presenti
     {
-        int res=0,tmp;
-        for (Node n:Children)
-        {
-            tmp=n.treeHeight();
-            if (tmp>res)
-                res=tmp;
-        }
-        return res+1;
+        global.removeAllViews();
     }
-    public boolean isCorrect()
+
+    public boolean isCorrect() //controlla per l'intero sottoalbero se esso è privo di nodi fake.
     {
         if (status==FAKE || status==FAKE_CANCELED || status==FAKE_CLOSED)
             return false;
@@ -329,25 +271,21 @@ public class Node implements Tree {
         return true;
 
     }
-    public void Clean()
-    {
-        global.removeAllViews();
-    }
 
     public void Draw()
     {
-        int i;
         float interval=0; //intervallo di spazio da sommare nella creazione dei figli
-        float spaceSize= DrawActivity.spaceSize;
-        int childNo=Children.size();
+        float spaceSize= DrawActivity.spaceSize; //dimensione della spaziatura tra i sottoalberi
+        int childNo=Children.size(); //numero di figli del nodo attuale
         if (childNo==0) //foglia: possibile ramo dimostrato
+
         {
             view.setBorders(null); //le foglie non hanno overline
             if (status!=OPEN && status!=FAKE) { //nodo chiuso
                 view.setTextColor(Color.GRAY);
                 if (hasFocus) //avevo il focus: provo a darlo ad uno dei miei fratelli
                 {
-                    if (!(Father.searchFocus(this))) {
+                    if (!(Father.searchFocus(this))) { //focus inapplicabile nell'albero: dimostrazione completata.
                         DrawActivity.finishedTree(view.getContext());
                         return;
                     }
@@ -355,8 +293,12 @@ public class Node implements Tree {
                 }
                 if (status==CANCELED || status==FAKE_CANCELED) { //nodo cancellato
                     view.setWidth((int) F.sizeDeleted());
-                    view.setText("[" + view.getText() + "]");
+                    view.setText(F.toStringDeleted());
                     view.setOnClickListener(null); //rimuove eventuali listener per evitare il proseguimento dell'albero
+                    /**NOTA: è possibile permettere all'utente di proseguire la dimostrazione
+                     * di un ramo chiuso commentando la riga precedente e aggiungendo nel touchnodeHandler
+                     * un'controllo che, in caso di nodo chiuso cliccato, lo riapre e gli riaffida il focus.
+                     */
                 }
                 return;
             }
@@ -371,40 +313,29 @@ public class Node implements Tree {
         ruleView.setTextSize(TypedValue.COMPLEX_UNIT_PX, DrawActivity.textSize / 2);
         RelativeLayout.LayoutParams intlp=new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
         intlp.addRule(RelativeLayout.RIGHT_OF,view.getId());
-        int sum=0;
-        sum+=F.height();
-        Node tmp=Father;
-        while (tmp!=null)
-        {
-            sum+=tmp.F.height();
-            tmp=tmp.Father;
-        }
-        intlp.setMargins(0,0,0,sum);
-        intlp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
+        intlp.addRule(RelativeLayout.ABOVE,view.getId());
         ruleView.setLayoutParams(intlp);
         global.addView(ruleView);
 
-        /////////////////
-
+        hasFocus=false; //se sono arrivato a questo punto il nodo non è una foglia e non può avere il focus di default
 
-        hasFocus=false;
-        for (i=0;i<childNo;i++) {
-            final Node newChild=Children.get(i);
+        for (int i=0;i<childNo;i++) {
+            final Node newChild=Children.get(i); //recupero l'i-esimo figlio
             RelativeLayout.LayoutParams lp=new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
             final BorderedTextView childView=new BorderedTextView(view.getContext());
             childView.setBorders(DrawActivity.b);
             lp.addRule(RelativeLayout.ABOVE, view.getId());
             if (i==0) //first child
             {
-                float leftPos= view.getLeft()-Math.max((newChild.getLineWidth()-newChild.getBaseWidth())/2,0);
-                if (getLineWidth()>getUpLine())
+                float leftPos= view.getLeft()-Math.max((newChild.getLineWidth()-newChild.getBaseWidth())/2,0); //il primo figlio è posizionato a sinistra del padre, con un ulteriore offset
+                                                                                                               // sinistro pari allo scarto della sua overline
+                if (getLineWidth()>getUpLine()) //sono più grande dell'overline prevista: aggiungo un ulteriore offset al figlio
                     leftPos+=((getLineWidth()-getUpLine())/2);
-
-                lp.setMargins(Math.round(leftPos), 0, 0, 0);
+                lp.setMargins(Math.round(leftPos), 0, 0, 0); //leftPos è il margine sinistro del figlio
                 childView.setLeft(Math.round(leftPos));
             }
             else {
-                lp.setMargins(Math.round(view.getLeft() + interval), 0, 0, 0);
+                lp.setMargins(Math.round(view.getLeft() + interval), 0, 0, 0); //figlio intermedio: basta aggiungere l'interval alla posizione sinistra del padre
                 childView.setLeft(Math.round(view.getLeft() + interval));
             }
             childView.setLayoutParams(lp);
@@ -420,7 +351,9 @@ public class Node implements Tree {
                     newChild.setView(childView,global);
                     if(newChild.handler==null)
                         newChild.handler=new touchnodeHandler(newChild);
+                    newChild.longHandler=new longnodeHandler(newChild);
                     newChild.view.setOnClickListener(newChild.handler);
+                    newChild.view.setOnLongClickListener(newChild.longHandler);
                     childView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                     newChild.Draw();
                 }
@@ -428,12 +361,76 @@ public class Node implements Tree {
             if (i!=childNo-1) //l'ultimo figlio non ha intervalli
             {
                 float leftOverflow=Math.max((Children.get(i+1).getLineWidth()-Children.get(i+1).getBaseWidth())/2,0);
+                interval += (newChild.getBaseWidth()+newChild.getRightOffset()+Children.get(i+1).getLeftOffset()-(leftOverflow)); //devo aggiungere all'interval la basewidth del figlio attuale, il rightoffset del figlio attuale e il leftOffset del figlio successivo.
+                interval+=spaceSize;
+                if (i!=0) //devo sommare anche il leftOverflow del nuovo figlio
+                    interval+=newChild.getLeftOffset();
+            }
+        }
+    }
+    void Resize() //metodo per ridisegnare l'albero dopo un pinch zoom: l'algoritmo applicato è uguale a quello del metodo Draw()
+    {
+        int i;
+        float interval=0; //intervallo di spazio da sommare nella creazione dei figli
+        float spaceSize= DrawActivity.spaceSize;
+        int childNo=Children.size();
+        if (childNo!=0)
+        {
+
+            ruleView.setText(ruleName);
+            ruleView.setTextSize(TypedValue.COMPLEX_UNIT_PX, DrawActivity.textSize / 2);
+            RelativeLayout.LayoutParams intlp=new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+            intlp.addRule(RelativeLayout.RIGHT_OF,view.getId());
+            int sum=0;
+            sum+=F.height();
+            Node tmp=Father;
+            while (tmp!=null)
+            {
+                sum+=tmp.F.height();
+                tmp=tmp.Father;
+            }
+            intlp.setMargins(0,0,0,sum);
+            intlp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
+            ruleView.setLayoutParams(intlp);
+        }
+        for (i=0;i<childNo;i++) {
+            Node newChild=Children.get(i);
+            RelativeLayout.LayoutParams lp=new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+            TextView childView=Children.get(i).view;
+            lp.addRule(RelativeLayout.ABOVE,view.getId());
+            if (i==0) //first child
+            {
+                float leftPos= view.getLeft()-Math.max((newChild.getLineWidth()-newChild.getBaseWidth())/2,0);
+                if (getLineWidth()>getUpLine())
+                    leftPos+=((getLineWidth()-getUpLine())/2);
+                lp.setMargins(Math.round(leftPos), 0, 0, 0);
+                childView.setLeft(Math.round(leftPos));
+            }
+            else {
+                lp.setMargins(Math.round(view.getLeft() + interval), 0, 0, 0);
+                childView.setLeft(Math.round(view.getLeft() + interval));
+            }
+            childView.setLayoutParams(lp);
+            childView.setTextSize(TypedValue.COMPLEX_UNIT_PX, DrawActivity.textSize);
+
+            if(newChild.status==CANCELED || newChild.status==FAKE_CANCELED)
+                childView.setWidth((int) ((newChild.F.sizeDeleted())));
+            else
+                childView.setWidth(Math.round(newChild.getLineWidth()));
+
+            newChild.Resize();
+
+            if (i!=childNo-1) //l'ultimo figlio non ha intervalli
+            {
+                float leftOverflow=(Children.get(i+1).getLineWidth()-Children.get(i+1).getBaseWidth())/2;
                 interval += (newChild.getBaseWidth()+newChild.getRightOffset()+Children.get(i+1).getLeftOffset()-(leftOverflow));
                 interval+=spaceSize;
                 if (i!=0) //devo sommare anche il leftOverflow del nuovo figlio
                     interval+=newChild.getLeftOffset();
             }
+
         }
+
     }
 
-}
\ No newline at end of file
+}