diff --git a/Sources/app/src/main/AndroidManifest.xml b/Sources/app/src/main/AndroidManifest.xml index 3c27b6d238eb4a68416007a992f9948229c6cc71..99e601ea60a604d60ad623a8c52eb1de7ebce73f 100644 --- a/Sources/app/src/main/AndroidManifest.xml +++ b/Sources/app/src/main/AndroidManifest.xml @@ -3,6 +3,15 @@ xmlns:tools="http://schemas.android.com/tools" package="com.furwaz.roomview"> + <uses-permission android:name="android.permission.CAMERA" /> + + <uses-feature android:name="android.hardware.camera" /> + + <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> + <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> + + <uses-feature android:name="android.hardware.location.gps" /> + <application android:allowBackup="true" android:dataExtractionRules="@xml/data_extraction_rules" @@ -13,6 +22,15 @@ android:supportsRtl="true" android:theme="@style/Theme.RoomView" tools:targetApi="31"> + <activity + android:name=".BuildingView" + android:exported="false" /> + <activity + android:name=".PhotoActivity" + android:exported="false" /> + <activity + android:name=".ZoneActivity" + android:exported="false" /> <activity android:name=".PathwayActivity" android:exported="false" /> diff --git a/Sources/app/src/main/java/Common/BuildingManager.java b/Sources/app/src/main/java/Common/BuildingManager.java index 9c6e9e0ba6a3d97e59dc1730d3e5c354b6910932..2ba5d9676642fbf12c2d8f8a0e2048c655373dc3 100644 --- a/Sources/app/src/main/java/Common/BuildingManager.java +++ b/Sources/app/src/main/java/Common/BuildingManager.java @@ -28,6 +28,10 @@ public class BuildingManager { save_dir = context.getFilesDir(); } + public static Context getContext() { + return context; + } + public static void removeBuilding(BuildingInfo b) { if (BuildingManager.buildings == null) loadBuildings(); diff --git a/Sources/app/src/main/java/Common/ImageManager.java b/Sources/app/src/main/java/Common/ImageManager.java new file mode 100644 index 0000000000000000000000000000000000000000..3d6db2bd4da336a8fed199631f7327a911ed0e17 --- /dev/null +++ b/Sources/app/src/main/java/Common/ImageManager.java @@ -0,0 +1,63 @@ +package Common; + +import android.content.Context; +import android.widget.Toast; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; + +import Structures.BuildingInfo; +import Structures.PhotoInfo; +import Structures.RoomInfo; +import Structures.ZoneInfo; + +public class ImageManager { + private static File saveDir; + private static Context context = null; + + public static void setContext(Context c) { + context = c; + saveDir = context.getFilesDir(); + } + + public static boolean saveImage(byte[] data, PhotoInfo photo) { + boolean res = true; + File imgFile = getImageFile(photo); + try { + FileOutputStream fos = new FileOutputStream(imgFile); + fos.write(data); + fos.close(); + res = true; + } catch (Exception e) { + res = false; + } + return res; + } + + public static byte[] getImage(PhotoInfo photo) { + byte[] res = new byte[0]; + File imgFile = getImageFile(photo); + try { + FileInputStream fis = new FileInputStream(imgFile); + int length = (int) imgFile.length(); + res = new byte[length]; + fis.read(res, 0, length); + fis.close(); + } catch (Exception ignored) {} + return res; + } + + protected static String getImagePath(PhotoInfo photo) { + ZoneInfo zone = photo.getZone(); + RoomInfo room = zone.getRoom(); + BuildingInfo building = room.getBuilding(); + return "img-"+building.getName()+"-"+room.getName()+"-"+zone.getName()+"-"+photo.getOrientation()+".png"; + } + + protected static File getImageFile(PhotoInfo photo) { + String abs_path = saveDir + getImagePath(photo); + Toast.makeText(context, "saved to "+abs_path, Toast.LENGTH_SHORT).show(); + return new File(abs_path); + } +} diff --git a/Sources/app/src/main/java/Popups/PathviewPopup.java b/Sources/app/src/main/java/Popups/PathviewPopup.java new file mode 100644 index 0000000000000000000000000000000000000000..ba1cbfcc1c4d9183aa1266fa30b16b7aa9236dd2 --- /dev/null +++ b/Sources/app/src/main/java/Popups/PathviewPopup.java @@ -0,0 +1,74 @@ +package Popups; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.Spinner; +import android.widget.TextView; + +import androidx.appcompat.app.AlertDialog; + +import com.furwaz.roomview.R; + +import java.util.ArrayList; +import java.util.List; + +import Common.Callback; +import Structures.Orientation; +import Structures.PathInfo; +import Structures.RoomInfo; +import Structures.ZoneInfo; + +public class PathviewPopup { + public static final int MODE_NEW = 1; + public static final int MODE_EDIT = 2; + + Context context = null; + RoomInfo room = null; + AlertDialog dialog = null; + Spinner p_path = null; + Button validate_btn = null; + Button cancel_btn = null; + + public PathviewPopup(Context context, RoomInfo room, Callback onCreate, Callback onCancel, Callback onValidate, int mode) { + AlertDialog.Builder builder = new AlertDialog.Builder(context); + dialog = builder.create(); + LayoutInflater factory = LayoutInflater.from(context); + View popup = factory.inflate(R.layout.add_pathview_popup, null); + dialog.setView(popup); + + this.context = context; + this.room = room; + + dialog.setOnShowListener(dialogInterface -> { + p_path = popup.findViewById(R.id.pathview_path); + validate_btn = popup.findViewById(R.id.btn_validate_room); + cancel_btn = popup.findViewById(R.id.btn_cancel_room); + + onCreate.call(this); + + String[] str_orients = new String[room.getPaths().size()]; + for (int i = 0; i < str_orients.length; i++) + str_orients[i] = room.getPath(i).getName(); + p_path.setAdapter(new ArrayAdapter<String>(context, android.R.layout.simple_spinner_dropdown_item, str_orients)); + + cancel_btn.setOnClickListener(view -> onCancel.call(this)); + validate_btn.setOnClickListener(view -> onValidate.call(this)); + }); + dialog.show(); + } + + public void dismiss() { + dialog.dismiss(); + } + + public PathInfo getSelectedPath() { + return room.getPath( p_path.getSelectedItemPosition() ); + } + + public void show() { + dialog.show(); + } +} diff --git a/Sources/app/src/main/java/Popups/PathwayPopup.java b/Sources/app/src/main/java/Popups/PathwayPopup.java new file mode 100644 index 0000000000000000000000000000000000000000..ddfd57947b8612e3fe55bd0518a5d9d9d28ad585 --- /dev/null +++ b/Sources/app/src/main/java/Popups/PathwayPopup.java @@ -0,0 +1,148 @@ +package Popups; + +import android.content.Context; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.EditText; +import android.widget.Spinner; +import android.widget.TextView; + +import androidx.appcompat.app.AlertDialog; + +import com.furwaz.roomview.R; + +import java.util.ArrayList; +import java.util.List; + +import Common.Callback; +import Structures.BuildingInfo; +import Structures.PathType; +import Structures.RoomInfo; + +public class PathwayPopup { + public static final int MODE_NEW = 1; + public static final int MODE_EDIT = 2; + static String PATHWAY_DOOR = ""; + static String PATHWAY_STAIRS = ""; + + AlertDialog dialog = null; + TextView p_err = null; + EditText p_name = null; + Button validate_btn = null; + Button cancel_btn = null; + Spinner sp_type = null; + Spinner sp_dest_up = null; + Spinner sp_dest_down = null; + + BuildingInfo building = null; + + public PathwayPopup(Context context, BuildingInfo building, RoomInfo room, Callback onCreate, Callback onCancel, Callback onValidate, int mode) { + AlertDialog.Builder builder = new AlertDialog.Builder(context); + dialog = builder.create(); + LayoutInflater factory = LayoutInflater.from(context); + View popup = factory.inflate(R.layout.add_pathway_popup, null); + dialog.setView(popup); + + this.building = building; + + PATHWAY_DOOR = context.getResources().getString(R.string.door); + PATHWAY_STAIRS = context.getResources().getString(R.string.stairs); + + dialog.setOnShowListener(dialogInterface -> { + p_err = popup.findViewById(R.id.pathway_input_error_msg); + p_name = popup.findViewById(R.id.input_pathway_name); + validate_btn = popup.findViewById(R.id.btn_validate_room); + cancel_btn = popup.findViewById(R.id.btn_cancel_room); + + validate_btn.setEnabled(false); + p_err.setText(""); + p_name.addTextChangedListener(new TextWatcher() { + public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {} + public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {} + public void afterTextChanged(Editable editable) { + validate_btn.setEnabled(false); + p_err.setText(""); + String input = editable.toString(); + if (input.length() == 0) { + p_err.setText(context.getResources().getString(R.string.specify_pathway_name)); + return; + } + if (room.getPath(input) != null) { + p_err.setText(context.getResources().getString(R.string.pathway_exists)); + return; + } + // everything is correct, display the button + validate_btn.setEnabled(true); + } + }); + + sp_type = dialog.findViewById(R.id.pathway_type); + String[] sp_type_items = new String[]{PATHWAY_DOOR, PATHWAY_STAIRS}; + sp_type.setAdapter(new ArrayAdapter<String>(context, android.R.layout.simple_spinner_dropdown_item, sp_type_items)); + + sp_dest_up = dialog.findViewById(R.id.pathway_dest_up); + sp_dest_down = dialog.findViewById(R.id.pathway_dest_down); + + List<String> names = new ArrayList<>(); + names.add("<"+context.getResources().getString(R.string.none)+">"); + for(RoomInfo r : building.getRooms()) names.add(r.getName()); + + String[] sp_dest_items = new String[names.size()]; + for (int i = 0; i < names.size(); i++) sp_dest_items[i] = names.get(i); + + sp_dest_up.setAdapter(new ArrayAdapter<String>(context, android.R.layout.simple_spinner_dropdown_item, sp_dest_items)); + sp_dest_down.setAdapter(new ArrayAdapter<String>(context, android.R.layout.simple_spinner_dropdown_item, sp_dest_items)); + + sp_type.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) { + if (adapterView.getAdapter().getItem(i) == PATHWAY_DOOR) { + dialog.findViewById(R.id.dest_down_layout).setVisibility(View.GONE); + dialog.findViewById(R.id.pathway_dest_down_txt).setVisibility(View.GONE); + ((TextView) dialog.findViewById(R.id.pathway_dest_up_txt)).setText(R.string.pathway_destination); + } else { + dialog.findViewById(R.id.dest_down_layout).setVisibility(View.VISIBLE); + dialog.findViewById(R.id.pathway_dest_down_txt).setVisibility(View.VISIBLE); + ((TextView) dialog.findViewById(R.id.pathway_dest_down_txt)).setText(R.string.pathway_destination_down); + ((TextView) dialog.findViewById(R.id.pathway_dest_up_txt)).setText(R.string.pathway_destination_up); + } + } + public void onNothingSelected(AdapterView<?> adapterView) {} + }); + + cancel_btn.setOnClickListener(view -> onValidate.call(this)); + validate_btn.setOnClickListener(view -> onValidate.call(this)); + }); + dialog.show(); + } + + public void dismiss() { + dialog.dismiss(); + } + + public EditText getInput() { + return p_name; + } + + public PathType getSelectedType() { + return sp_type.getSelectedItemPosition() == 0 ? PathType.DOOR : PathType.STAIRS; + } + + public RoomInfo getUpDestination() { + int index = sp_dest_up.getSelectedItemPosition() - 1; + return index < 0 ? null: building.getRoom(index); + } + + public RoomInfo getDownDestination() { + int index = sp_dest_down.getSelectedItemPosition() - 1; + return index < 0 ? null: building.getRoom(index); + } + + public void show() { + dialog.show(); + } +} diff --git a/Sources/app/src/main/java/Popups/PhotoPopup.java b/Sources/app/src/main/java/Popups/PhotoPopup.java new file mode 100644 index 0000000000000000000000000000000000000000..72cc909db12a115d203965c3e5ab3a17ab8a8bed --- /dev/null +++ b/Sources/app/src/main/java/Popups/PhotoPopup.java @@ -0,0 +1,92 @@ +package Popups; + +import android.content.Context; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.EditText; +import android.widget.Spinner; +import android.widget.TextView; + +import androidx.appcompat.app.AlertDialog; + +import com.furwaz.roomview.R; + +import java.util.ArrayList; +import java.util.List; + +import Common.Callback; +import Structures.BuildingInfo; +import Structures.Orientation; +import Structures.ZoneInfo; + +public class PhotoPopup { + public static final int MODE_NEW = 1; + public static final int MODE_EDIT = 2; + + protected String stringifyOrientation(Orientation orient) { + int stringID = -1; + switch (orient) { + case EST: stringID = R.string.est; break; + case NORTH: stringID = R.string.north; break; + case SOUTH: stringID = R.string.south; break; + case WEST: stringID = R.string.west; break; + } + return context.getResources().getString(stringID); + } + + Context context = null; + AlertDialog dialog = null; + Spinner p_orient = null; + Button validate_btn = null; + Button cancel_btn = null; + TextView room_title = null; + List<Orientation> availableOrientations = new ArrayList<>(); + + public PhotoPopup(Context context, ZoneInfo zone, Callback onCreate, Callback onCancel, Callback onValidate, int mode) { + AlertDialog.Builder builder = new AlertDialog.Builder(context); + dialog = builder.create(); + LayoutInflater factory = LayoutInflater.from(context); + View popup = factory.inflate(R.layout.add_photo_popup, null); + dialog.setView(popup); + + this.context = context; + + availableOrientations.clear(); + Orientation[] orients = {Orientation.NORTH, Orientation.SOUTH, Orientation.EST, Orientation.WEST}; + for (Orientation o: orients) + if (zone.getPhoto(o) == null) availableOrientations.add(o); + + dialog.setOnShowListener(dialogInterface -> { + p_orient = popup.findViewById(R.id.photo_orient); + validate_btn = popup.findViewById(R.id.btn_validate_room); + cancel_btn = popup.findViewById(R.id.btn_cancel_room); + + onCreate.call(this); + + String[] str_orients = new String[availableOrientations.size()]; + for (int i = 0; i < availableOrientations.size(); i++) str_orients[i] = stringifyOrientation(availableOrientations.get(i)); + p_orient.setAdapter(new ArrayAdapter<String>(context, android.R.layout.simple_spinner_dropdown_item, str_orients)); + + cancel_btn.setOnClickListener(view -> onCancel.call(this)); + validate_btn.setOnClickListener(view -> onValidate.call(this)); + }); + dialog.show(); + } + + public void dismiss() { + dialog.dismiss(); + } + + public Orientation getSelectedOrient() { + return availableOrientations.get( p_orient.getSelectedItemPosition() ); + } + + public void show() { + dialog.show(); + } +} diff --git a/Sources/app/src/main/java/Popups/ZonePopup.java b/Sources/app/src/main/java/Popups/ZonePopup.java new file mode 100644 index 0000000000000000000000000000000000000000..919d464d429d5fb96eace4fd955a496d1c660aee --- /dev/null +++ b/Sources/app/src/main/java/Popups/ZonePopup.java @@ -0,0 +1,90 @@ +package Popups; + +import android.content.Context; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.TextView; + +import androidx.appcompat.app.AlertDialog; + +import com.furwaz.roomview.R; + +import Common.Callback; +import Structures.RoomInfo; + +public class ZonePopup { + public static final int MODE_NEW = 1; + public static final int MODE_EDIT = 2; + + AlertDialog dialog = null; + TextView z_err = null; + EditText z_name = null; + Button validate_btn = null; + Button cancel_btn = null; + + public ZonePopup(Context context, RoomInfo room, Callback onCreate, Callback onCancel, Callback onValidate, int mode) { + AlertDialog.Builder builder = new AlertDialog.Builder(context); + dialog = builder.create(); + LayoutInflater factory = LayoutInflater.from(context); + View popup = factory.inflate(R.layout.add_zone_popup, null); + dialog.setView(popup); + + dialog.setOnShowListener(dialogInterface -> { + z_err = popup.findViewById(R.id.zone_input_error_msg); + z_name = popup.findViewById(R.id.input_zone_name); + validate_btn = popup.findViewById(R.id.btn_validate_room); + cancel_btn = popup.findViewById(R.id.btn_cancel_room); + + onCreate.call(this); + + validate_btn.setEnabled(false); + z_err.setText(""); + z_name.addTextChangedListener(new TextWatcher() { + public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {} + public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {} + public void afterTextChanged(Editable editable) { + validate_btn.setEnabled(false); + z_err.setText(""); + String input = editable.toString(); + if (input.length() == 0) { + z_err.setText(context.getResources().getString(R.string.specify_zone_name)); + return; + } + if (room.getZone(input) != null) { + z_err.setText(context.getResources().getString(R.string.zone_exists)); + return; + } + // everything is correct, display the button + validate_btn.setEnabled(true); + } + }); + + cancel_btn.setOnClickListener(view -> onCancel.call(this)); + + validate_btn.setOnClickListener(view -> onValidate.call(this)); + + if (mode == MODE_EDIT) { + TextView title = dialog.findViewById(R.id.zone_popup_title); + title.setText(context.getResources().getString(R.string.edit_zone)); + validate_btn.setText(context.getResources().getString(R.string.edit)); + } + }); + dialog.show(); + } + + public void dismiss() { + dialog.dismiss(); + } + + public EditText getInput() { + return z_name; + } + + public void show() { + dialog.show(); + } +} diff --git a/Sources/app/src/main/java/Structures/BuildingInfo.java b/Sources/app/src/main/java/Structures/BuildingInfo.java index e629efdbfebe5d8720f28c1519f109631b116578..aa576ac3f998ece0fe197998d3aedb0373e79b31 100644 --- a/Sources/app/src/main/java/Structures/BuildingInfo.java +++ b/Sources/app/src/main/java/Structures/BuildingInfo.java @@ -40,13 +40,13 @@ public class BuildingInfo implements Serializable { public void removeRoom(RoomInfo room) { this.rooms.remove(room); - this.save(); + this.askForSave(); } public void addRoom(RoomInfo room) { room.setBuilding(this); this.rooms.add(room); - this.save(); + this.askForSave(); } public Date getDate() { @@ -55,7 +55,7 @@ public class BuildingInfo implements Serializable { public void setDate(Date date) { this.date = date; - BuildingManager.saveBuilding(this); + this.askForSave(); } public String getName() { @@ -65,14 +65,14 @@ public class BuildingInfo implements Serializable { public void setName(String name) { BuildingManager.removeBuilding(this); this.name = name; - BuildingManager.saveBuilding(this); + this.askForSave(); } public int getNbRooms() { return this.rooms.size(); } - public void save() { + public void askForSave() { BuildingManager.saveBuilding(this); } diff --git a/Sources/app/src/main/java/Structures/Orientation.java b/Sources/app/src/main/java/Structures/Orientation.java new file mode 100644 index 0000000000000000000000000000000000000000..4a0ac605581253fd803f1de3afb98103454550f1 --- /dev/null +++ b/Sources/app/src/main/java/Structures/Orientation.java @@ -0,0 +1,8 @@ +package Structures; + +public enum Orientation { + NORTH, + SOUTH, + EST, + WEST +} diff --git a/Sources/app/src/main/java/Structures/PathInfo.java b/Sources/app/src/main/java/Structures/PathInfo.java index 95a4fb14330bd8937cb1bac0fecaa1a1f803f0a5..edcb5073f029e565a6dd9a007e1aae158189a761 100644 --- a/Sources/app/src/main/java/Structures/PathInfo.java +++ b/Sources/app/src/main/java/Structures/PathInfo.java @@ -1,5 +1,7 @@ package Structures; +import android.widget.Toast; + import java.io.Serializable; import java.util.Objects; @@ -7,36 +9,46 @@ public class PathInfo implements Serializable { String name = ""; PathType type = PathType.DOOR; RoomInfo destination; + RoomInfo room; public PathInfo() { - + this.askForSave(); } public PathInfo(String name, RoomInfo destination) { this.name = name; this.destination = destination; + this.askForSave(); } public PathInfo(PathType type) { this.type = type; + this.askForSave(); } public PathInfo(String name, RoomInfo destination, PathType type) { this.name = name; this.destination = destination; this.type = type; + this.askForSave(); } public String getName() { return name; } + public void setName(String name) { + this.name = name; + this.askForSave(); + } + public PathType getType() { return type; } public void setType(PathType type) { this.type = type; + this.askForSave(); } public RoomInfo getDestination() { @@ -45,6 +57,16 @@ public class PathInfo implements Serializable { public void setDestination(RoomInfo destination) { this.destination = destination; + this.askForSave(); + } + + public void setRoom(RoomInfo room) { + this.room = room; + this.askForSave(); + } + + public void askForSave() { + if (this.room != null) this.room.askForSave(); } @Override diff --git a/Sources/app/src/main/java/Structures/PathStairs.java b/Sources/app/src/main/java/Structures/PathStairs.java index 388bd3e8b8ca59c2f19017a82856a8faac80be49..d9d24d13deb836828dd0b5d1998d1657740263a1 100644 --- a/Sources/app/src/main/java/Structures/PathStairs.java +++ b/Sources/app/src/main/java/Structures/PathStairs.java @@ -8,6 +8,7 @@ public class PathStairs extends PathInfo implements Serializable { public PathStairs() { super(PathType.STAIRS); + this.askForSave(); } public PathStairs(String name, RoomInfo roomUp, RoomInfo roomDown) { @@ -15,6 +16,17 @@ public class PathStairs extends PathInfo implements Serializable { this.roomDown = roomDown; this.direction = (roomUp == null)? StairsDirection.DOWN: ( (roomDown == null)? StairsDirection.UP : StairsDirection.BOTH ); + this.askForSave(); + } + + public void setDestination(StairsDirection dir, RoomInfo dest) { + if (dir == StairsDirection.BOTH) { + this.roomDown = dest; + this.destination = dest; + } + else if (dir == StairsDirection.UP) this.destination = dest; + else this.roomDown = dest; + this.askForSave(); } public RoomInfo getDestination(StairsDirection direction) { @@ -29,5 +41,6 @@ public class PathStairs extends PathInfo implements Serializable { public void setDirection(StairsDirection direction) { this.direction = direction; + this.askForSave(); } } diff --git a/Sources/app/src/main/java/Structures/PathView.java b/Sources/app/src/main/java/Structures/PathView.java index 5fae525a36298bfc32468cce6754ddf5dc782ca6..ec79b5a869f13e5154b0f38a5bd8c859b31020b7 100644 --- a/Sources/app/src/main/java/Structures/PathView.java +++ b/Sources/app/src/main/java/Structures/PathView.java @@ -1,44 +1,34 @@ package Structures; +import android.graphics.RectF; + import java.io.Serializable; public class PathView implements Serializable { - int x, y, width, height; + float top, left, bottom, right; PathInfo path; public PathView() { } - public PathView(int x, int y, int width, int height) { - this.x = x; - this.y = y; - this.width = width; - this.height = height; + public PathView(RectF rect) { + this.top = rect.top; + this.left = rect.left; + this.bottom = rect.bottom; + this.right = rect.right; } - public PathView(int x, int y, int width, int height, PathInfo path) { - this.x = x; - this.y = y; - this.width = width; - this.height = height; + public PathView(RectF rect, PathInfo path) { + this.top = rect.top; + this.left = rect.left; + this.bottom = rect.bottom; + this.right = rect.right; this.path = path; } - public int getX() { - return x; - } - - public int getY() { - return y; - } - - public int getWidth() { - return width; - } - - public int getHeight() { - return height; + public RectF getRect() { + return new RectF(this.left, this.top, this.right, this.bottom); } public PathInfo getPath() { diff --git a/Sources/app/src/main/java/Structures/PhotoInfo.java b/Sources/app/src/main/java/Structures/PhotoInfo.java index 76cb2c4bc3b3a1bb2f65d8b175267ebb3bcd7c70..7dc3d0d32042bb05df6765786c1b297a67d903de 100644 --- a/Sources/app/src/main/java/Structures/PhotoInfo.java +++ b/Sources/app/src/main/java/Structures/PhotoInfo.java @@ -1,34 +1,35 @@ package Structures; import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Matrix; import java.io.Serializable; import java.util.ArrayList; import java.util.List; -enum Orientation { - NORTH, - SOUTH, - EST, - WEST -} - public class PhotoInfo implements Serializable { Orientation orientation = Orientation.NORTH; - Bitmap image; + byte[] image = null; + ZoneInfo zone = null; List<PathView> pathViews = new ArrayList<>(); public PhotoInfo() { } - public PhotoInfo(Bitmap im) { + public PhotoInfo(Orientation orient) { + this.orientation = orient; + } + + public PhotoInfo(byte[] im) { this.image = im; } - public PhotoInfo(Bitmap im, Orientation orientation) { + public PhotoInfo(byte[] im, Orientation orientation) { this.image = im; this.orientation = orientation; + this.askForSave(); } public Orientation getOrientation() { @@ -37,14 +38,25 @@ public class PhotoInfo implements Serializable { public void setOrientation(Orientation orientation) { this.orientation = orientation; + this.askForSave(); } - public Bitmap getImage() { + public byte[] getImage() { return image; } - public void setImage(Bitmap image) { - this.image = image; + public Bitmap getBitmap() { + if (this.image == null || this.image.length == 0) + return null; + Bitmap source = BitmapFactory.decodeByteArray(this.image, 0, this.image.length); + Matrix mat = new Matrix(); + mat.postRotate(90); + return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), mat, true); + } + + public void setImage(byte[] data) { + this.image = data; + this.askForSave(); } public List<PathView> getPathViews() { @@ -57,10 +69,25 @@ public class PhotoInfo implements Serializable { public void addPathView(PathView pathView) { this.pathViews.add(pathView); + this.askForSave(); } public void removePathView(PathView pathView) { this.pathViews.remove(pathView); + this.askForSave(); + } + + public void setZone(ZoneInfo zone) { + this.zone = zone; + this.askForSave(); + } + + public ZoneInfo getZone() { + return zone; + } + + public void askForSave() { + if (this.zone != null) this.zone.askForSave(); } @Override diff --git a/Sources/app/src/main/java/Structures/RoomInfo.java b/Sources/app/src/main/java/Structures/RoomInfo.java index 2f5a6d31b2efa154d5b1e1b486ce208c518d415e..aec0cde658df6eef209871a76668f327e5d17a5a 100644 --- a/Sources/app/src/main/java/Structures/RoomInfo.java +++ b/Sources/app/src/main/java/Structures/RoomInfo.java @@ -1,11 +1,15 @@ package Structures; +import com.furwaz.roomview.R; + import java.io.Serializable; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.Objects; +import Common.BuildingManager; + enum RoomType { CORRIDOR, ROOM @@ -24,6 +28,8 @@ public class RoomInfo implements Serializable { public RoomInfo(String name) { this.name = name; + this.addZone(new ZoneInfo(BuildingManager.getContext().getResources().getString(com.furwaz.roomview.R.string.center))); + this.askForSave(); } public RoomType getRoomType() { @@ -32,6 +38,7 @@ public class RoomInfo implements Serializable { public void setRoomType(RoomType type) { this.type = type; + this.askForSave(); } public List<ZoneInfo> getZones() { @@ -50,13 +57,14 @@ public class RoomInfo implements Serializable { } public void addZone(ZoneInfo zone) { + zone.setRoom(this); this.zones.add(zone); - if (this.building != null) this.building.save(); + this.askForSave(); } public void removeZone(ZoneInfo zone) { this.zones.remove(zone); - if (this.building != null) this.building.save(); + this.askForSave(); } public List<PathInfo> getPaths() { @@ -75,13 +83,14 @@ public class RoomInfo implements Serializable { } public void addPath(PathInfo path) { + path.setRoom(this); this.paths.add(path); - if (this.building != null) this.building.save(); + this.askForSave(); } public void removePath(PathInfo path) { this.paths.remove(path); - if (this.building != null) this.building.save(); + this.askForSave(); } public int getNbZones() { return this.zones.size(); } @@ -92,11 +101,19 @@ public class RoomInfo implements Serializable { public void setName(String name) { this.name = name; - if (this.building != null) this.building.save(); + this.askForSave(); } public void setBuilding(BuildingInfo building) { this.building = building; } + public BuildingInfo getBuilding() { + return building; + } + + public void askForSave() { + if (this.building != null) this.building.askForSave(); + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/Sources/app/src/main/java/Structures/ZoneInfo.java b/Sources/app/src/main/java/Structures/ZoneInfo.java index 317096cc40e96ef176646e5d68a8ee2508d5acc1..fd32c5e9ce6b595925f5af7a747951a098d46e03 100644 --- a/Sources/app/src/main/java/Structures/ZoneInfo.java +++ b/Sources/app/src/main/java/Structures/ZoneInfo.java @@ -9,6 +9,7 @@ public class ZoneInfo implements Serializable { String name = "X"; Date date; MeteoInfo meteo; + RoomInfo room = null; List<PhotoInfo> photos = new ArrayList<>(); List<WalkInfo> walks = new ArrayList<>(); @@ -18,12 +19,14 @@ public class ZoneInfo implements Serializable { public ZoneInfo(String name) { this.name = name; + this.askForSave(); } public ZoneInfo(String name, Date date, MeteoInfo meteo) { this.name = name; this.date = date; this.meteo = meteo; + this.askForSave(); } public String getName() { @@ -32,6 +35,7 @@ public class ZoneInfo implements Serializable { public void setName(String name) { this.name = name; + this.askForSave(); } public Date getDate() { @@ -40,6 +44,7 @@ public class ZoneInfo implements Serializable { public void setDate(Date date) { this.date = date; + this.askForSave(); } public List<PhotoInfo> getPhotos() { @@ -63,11 +68,14 @@ public class ZoneInfo implements Serializable { if (existingPhoto != null) { this.removePhoto(existingPhoto); } + photo.setZone(this); this.photos.add(photo); + this.askForSave(); } public void removePhoto(PhotoInfo photo) { this.photos.remove(photo); + this.askForSave(); } public MeteoInfo getMeteo() { @@ -76,6 +84,7 @@ public class ZoneInfo implements Serializable { public void setMeteo(MeteoInfo meteo) { this.meteo = meteo; + this.askForSave(); } public List<WalkInfo> getWalks() { @@ -100,10 +109,25 @@ public class ZoneInfo implements Serializable { this.removeWalk(existingWalk); } this.walks.add(walk); + this.askForSave(); } public void removeWalk(WalkInfo walk) { this.walks.remove(walk); + this.askForSave(); + } + + public void setRoom(RoomInfo room) { + this.room = room; + this.askForSave(); + } + + public RoomInfo getRoom() { + return room; + } + + public void askForSave() { + if (this.room != null) this.room.askForSave(); } @Override diff --git a/Sources/app/src/main/java/Views/CameraPreview.java b/Sources/app/src/main/java/Views/CameraPreview.java new file mode 100644 index 0000000000000000000000000000000000000000..4a8dc4c1cff2d520608a4b1585a1e3c867c22606 --- /dev/null +++ b/Sources/app/src/main/java/Views/CameraPreview.java @@ -0,0 +1,110 @@ +package Views; + +import android.content.Context; +import android.hardware.Camera; +import android.util.Log; +import android.view.SurfaceHolder; +import android.view.SurfaceView; +import android.widget.Toast; + +import java.io.IOException; +import java.util.List; + +/** A basic Camera preview class */ +public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback { + private SurfaceHolder mHolder; + private Camera mCamera; + + public CameraPreview(Context context, Camera camera) { + super(context); + mCamera = camera; + + // Install a SurfaceHolder.Callback so we get notified when the + // underlying surface is created and destroyed. + mHolder = getHolder(); + mHolder.addCallback(this); + // deprecated setting, but required on Android versions prior to 3.0 + mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); + } + + private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) { + final double ASPECT_TOLERANCE = 0.1; + double targetRatio=(double)h / w; + + if (sizes == null) return null; + + Camera.Size optimalSize = null; + double minDiff = Double.MAX_VALUE; + + int targetHeight = h; + + for (Camera.Size size : sizes) { + double ratio = (double) size.width / size.height; + if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue; + if (Math.abs(size.height - targetHeight) < minDiff) { + optimalSize = size; + minDiff = Math.abs(size.height - targetHeight); + } + } + + if (optimalSize == null) { + minDiff = Double.MAX_VALUE; + for (Camera.Size size : sizes) { + if (Math.abs(size.height - targetHeight) < minDiff) { + optimalSize = size; + minDiff = Math.abs(size.height - targetHeight); + } + } + } + return optimalSize; + } + + protected void setCameraPreview(SurfaceHolder holder) { + Camera.Parameters params = mCamera.getParameters(); + params.set("orientation", "portrait"); + + int width = getWidth(); + int height = getHeight(); + Camera.Size size = getOptimalPreviewSize(params.getSupportedPreviewSizes(), width, height); + params.setPreviewSize(size.width, size.height); + mCamera.setParameters(params); + mCamera.setDisplayOrientation(90); + + try { + mCamera.setPreviewDisplay(holder); + mCamera.startPreview(); + } catch (IOException e) { + Log.d("furwaz:error", "Error setting camera preview: " + e.getMessage()); + } + } + + public void surfaceCreated(SurfaceHolder holder) { + setCameraPreview(holder); + } + + public void surfaceDestroyed(SurfaceHolder holder) { + // empty. Take care of releasing the Camera preview in your activity. + } + + public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { + // If your preview can change or rotate, take care of those events here. + // Make sure to stop the preview before resizing or reformatting it. + + if (mHolder.getSurface() == null){ + // preview surface does not exist + return; + } + + // stop preview before making changes + try { + mCamera.stopPreview(); + } catch (Exception e){ + // ignore: tried to stop a non-existent preview + } + + // set preview size and make any resize, rotate or + // reformatting changes here + + setCameraPreview(holder); + } +} diff --git a/Sources/app/src/main/java/Views/DoorsSelector.java b/Sources/app/src/main/java/Views/DoorsSelector.java new file mode 100644 index 0000000000000000000000000000000000000000..d504a4de7e5a15f6240ee98c2e39de7621ad4b6b --- /dev/null +++ b/Sources/app/src/main/java/Views/DoorsSelector.java @@ -0,0 +1,250 @@ +package Views; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.RectF; +import android.util.AttributeSet; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.Toast; + +import com.furwaz.roomview.R; + +import java.sql.Array; +import java.util.ArrayList; +import java.util.List; + +import Popups.PathviewPopup; +import Popups.PhotoPopup; +import Structures.Orientation; +import Structures.PathView; +import Structures.PhotoInfo; +import Structures.RoomInfo; +import Structures.ZoneInfo; + +final class Coord { + private float x, y; + public Coord() { } + public Coord(float x, float y) { this.x = x; this.y = y; } + public float getY() { return y; } + public float getX() { return x; } + public float distance(Coord c) { + return (float) Math.sqrt( Math.pow(c.getX() - this.getX(), 2) + Math.pow(c.getY() - this.getY(), 2) ); + } +} + +public class DoorsSelector extends View { + RoomInfo room = null; + PhotoInfo photo = null; + Coord startTouchPoint = null; + Coord endTouchPoint = null; + RectF editedRect = null; + List<RectF> btns = new ArrayList<>(); + + protected void init() { + setOnTouchListener(this::touchListener); + } + + public DoorsSelector(Context context) { + super(context); + this.init(); + } + + public DoorsSelector(Context context, AttributeSet attrs) { + super(context, attrs); + this.init(); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + + btns.clear(); + for (PathView p : photo.getPathViews()) { + drawDoorZone( + canvas, + p.getRect(), + true, + p.getPath().getName() + ); + } + if (this.editedRect != null) + drawDoorZone( + canvas, + editedRect, + false, + "" + ); + } + + protected void drawDoorZone(Canvas c, RectF rect, boolean showButton, String name) { + Paint p = new Paint(); + int width = getWidth(); + int height = getHeight(); + + RectF r = new RectF(rect.left * width, rect.top * height, rect.right * width, rect.bottom * height); + + int btn_h = 50; + int btn_w = 130; + int btn_x = (int) ((r.left + r.right) / 2 - btn_w / 2); + int btn_y = (int) r.bottom - 30 - btn_h; + RectF btn_rect = new RectF( + btn_x, + btn_y, + btn_x + btn_w, + btn_y + btn_h + ); + + p.setColor(showButton? + Color.parseColor("#60f8fafc") : + getResources().getColor(R.color.blue_500, getContext().getTheme()) + ); + c.drawRect( + r.left, + r.top, + r.right, + r.bottom, + p + ); + p.setColor(getResources().getColor(R.color.slate_50, getContext().getTheme())); + p.setTextSize(36); + p.setTextAlign(Paint.Align.CENTER); + c.drawText(name, (r.left + r.right) / 2, (r.top + r.bottom) / 2, p); + + if (showButton) { + p.setStyle(Paint.Style.STROKE); + p.setStrokeWidth(10); + p.setColor(getResources().getColor(R.color.blue_500, getContext().getTheme())); + c.drawRect( + r.left, + r.top, + r.right, + r.bottom, + p + ); + + btns.add(btn_rect); + p.setStyle(Paint.Style.FILL); + p.setColor(Color.RED); + c.drawRect( + btn_rect.left, + btn_rect.top, + btn_rect.right, + btn_rect.bottom, + p + ); + p.setColor(getResources().getColor(R.color.slate_50, getContext().getTheme())); + p.setTextSize(24); + p.setTextAlign(Paint.Align.CENTER); + c.drawText(getResources().getString(R.string.remove), btn_x+btn_w/2.f, btn_y+btn_h/2.f + 6, p); + } + } + + protected void propagateClick(Coord c) { + for(int i = 0; i < btns.size(); i++) { + RectF r = btns.get(i); + if (r.contains(c.getX(), c.getY())) { + photo.removePathView(photo.getPathView(i)); + btns.remove(i); + invalidate(); + break; + } + } + } + + protected boolean touchListener(View v, MotionEvent ev) { + if (ev.getPointerCount() != 1) return true; + + if (ev.getAction() == MotionEvent.ACTION_DOWN) { + startTouchPoint = getRelativeCoord(new Coord(ev.getX(), ev.getY())); + } + if (ev.getAction() == MotionEvent.ACTION_MOVE) { + endTouchPoint = getRelativeCoord(new Coord(ev.getX(), ev.getY())); + editedRect = new RectF( + startTouchPoint.getX(), + startTouchPoint.getY(), + endTouchPoint.getX(), + endTouchPoint.getY() + ); + } + if (ev.getAction() == MotionEvent.ACTION_UP) { + endTouchPoint = getRelativeCoord(new Coord(ev.getX(), ev.getY())); + int distance = (int) getAbsoluteCoord(startTouchPoint).distance(getAbsoluteCoord(endTouchPoint)); + if (distance > 100) { + boolean isXvalid = Math.abs(getAbsoluteCoord(startTouchPoint).getX() - getAbsoluteCoord(endTouchPoint).getX()) > 150; + boolean isYvalid = Math.abs(getAbsoluteCoord(startTouchPoint).getY() - getAbsoluteCoord(endTouchPoint).getY()) > 80; + if (!isXvalid || !isYvalid) { + Toast.makeText(getContext(), getResources().getString(R.string.door_too_small), Toast.LENGTH_SHORT).show(); + } else if (editedRect != null) { + showAddDoorPopup(); + } + } else { + propagateClick(getAbsoluteCoord(endTouchPoint)); + } + editedRect = null; + endTouchPoint = null; + startTouchPoint = null; + } + this.invalidate(); + return true; + } + + protected Coord getRelativeCoord(Coord c) { + if (c == null) return null; + float width = getWidth(); + float height = getHeight(); + float pos_x = getX(); + float pos_y = getY(); + return new Coord( + (c.getX() - pos_x) / width, + (c.getY() - pos_y) / height + ); + } + + protected Coord getAbsoluteCoord(Coord c) { + if (c == null) return null; + float width = getWidth(); + float height = getHeight(); + return new Coord( + c.getX() * width, + c.getY() * height + ); + } + + public void setRoom(RoomInfo room) { + this.room = room; + } + + public void setPhoto(PhotoInfo photo) { + this.photo = photo; + } + + protected void showAddDoorPopup() { + RectF rect = new RectF(editedRect.left, editedRect.top, editedRect.right, editedRect.bottom); + new PathviewPopup( + getContext(), + room, + param -> null, + param -> { + ((PathviewPopup) param).dismiss(); + return null; + }, + param -> { + PathviewPopup popup = (PathviewPopup) param; + popup.dismiss(); + photo.addPathView(new PathView(new RectF( + Math.min(rect.left, rect.right), + Math.min(rect.top, rect.bottom), + Math.max(rect.left, rect.right), + Math.max(rect.top, rect.bottom) + ), popup.getSelectedPath())); + invalidate(); + return null; + }, + PhotoPopup.MODE_NEW + ).show(); + } +} diff --git a/Sources/app/src/main/java/Views/InfoAdapter.java b/Sources/app/src/main/java/Views/InfoAdapter.java index 3a0e9fcdd9bdb19f43604f9d39f07f2c2962fc02..20bb09ae57c5437ba73e1d55c11582dca2dc72b8 100644 --- a/Sources/app/src/main/java/Views/InfoAdapter.java +++ b/Sources/app/src/main/java/Views/InfoAdapter.java @@ -1,11 +1,13 @@ package Views; import android.content.Context; +import android.graphics.Bitmap; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.Button; +import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; @@ -30,7 +32,7 @@ public class InfoAdapter<A> extends BaseAdapter { private Callback editCallback = null; private Callback viewCallback = null; private Callback removeCallback = null; - private InfoBinding[] bindings = new InfoBinding[0]; + private InfoBinding[] objs = new InfoBinding[0]; private int tile = 0; @@ -82,13 +84,15 @@ public class InfoAdapter<A> extends BaseAdapter { public View getView(int i, View view, ViewGroup viewGroup) { view = LayoutInflater.from(context).inflate(this.tile, viewGroup, false); - A building = queryList.get(i); - if (this.bindings != null) - for (InfoBinding b : this.bindings) { + A obj = queryList.get(i); + if (this.objs != null) + for (InfoBinding b : this.objs) { try { View v = view.findViewById(b.getElement()); if (v instanceof TextView) - ((TextView) v).setText( b.getCallback().call(building).toString() ); + ((TextView) v).setText( b.getCallback().call(obj).toString() ); + if (v instanceof ImageView) + ((ImageView) v).setImageBitmap( (Bitmap) b.getCallback().call(obj) ); } catch (Exception e) { } } @@ -117,8 +121,8 @@ public class InfoAdapter<A> extends BaseAdapter { }); } - public void setBindings(InfoBinding[] bindings) { - this.bindings = bindings; + public void setBindings(InfoBinding[] objs) { + this.objs = objs; } public void setOnEditListener(Callback cb) { diff --git a/Sources/app/src/main/java/Views/LevelCanvas.java b/Sources/app/src/main/java/Views/LevelCanvas.java new file mode 100644 index 0000000000000000000000000000000000000000..682e21b6243cf2d77e7be1dd63a051cf00eff6f4 --- /dev/null +++ b/Sources/app/src/main/java/Views/LevelCanvas.java @@ -0,0 +1,72 @@ +package Views; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Rect; +import android.util.AttributeSet; +import android.util.Log; +import android.view.View; + +import com.furwaz.roomview.R; + +public class LevelCanvas extends View { + Paint p; + Rect dims = new Rect(0, 0, 10, 10); + float r; + + public LevelCanvas(Context context, AttributeSet attrs) { + super(context, attrs); + p = new Paint(Paint.ANTI_ALIAS_FLAG); + p.setColor(Color.BLACK); + } + + @Override + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); + dims = new Rect(0, 0, w, h); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + int width = dims.width(); + int height = dims.height(); + int radius = width / 2; + int color_blue = getResources().getColor(R.color.blue_500, getContext().getTheme()); + int color_red = getResources().getColor(R.color.red_500, getContext().getTheme()); + int color_white = getResources().getColor(R.color.slate_50, getContext().getTheme()); + + p.setColor(Color.TRANSPARENT); + canvas.drawRect(0, 0, width, height, p); + + p.setColor(color_white); + p.setStyle(Paint.Style.STROKE); + p.setStrokeWidth(10); + canvas.drawCircle(width/2.f, height/2.f, radius - 10, p); + + float rot_l = this.r + (float) Math.PI / 2.f; + float rot_r = this.r - (float) Math.PI / 2.f; + int l_x = (int) (Math.cos(rot_l) * (radius - 18)) + radius; + int l_y = (int) (Math.sin(rot_l) * (radius - 18)) + radius; + int r_x = (int) (Math.cos(rot_r) * (radius - 18)) + radius; + int r_y = (int) (Math.sin(rot_r) * (radius - 18)) + radius; + int p_x = (int) (Math.cos(r) * 25) + radius; + int p_y = (int) (Math.sin(r) * 25) + radius; + + int orientation = (int) (r * 180 / 3.141593f) + 90; + int tolerance = 5; + p.setStyle(Paint.Style.FILL); + p.setStrokeWidth(15); + p.setColor( (orientation > tolerance || orientation < -tolerance)? color_red: color_blue ); + canvas.drawLine(l_x, l_y, r_x, r_y, p); + canvas.drawLine(radius, radius, p_x, p_y, p); + } + + public void askForDraw(float rot) { + float newRot = - rot; + this.r += (newRot - this.r) / 4; // to smooth it a little bit + this.invalidate(); + } +} \ No newline at end of file diff --git a/Sources/app/src/main/java/com/furwaz/roomview/BuildingView.java b/Sources/app/src/main/java/com/furwaz/roomview/BuildingView.java new file mode 100644 index 0000000000000000000000000000000000000000..8548589d2bbdb89326d5868c5777cc3cedda1449 --- /dev/null +++ b/Sources/app/src/main/java/com/furwaz/roomview/BuildingView.java @@ -0,0 +1,25 @@ +package com.furwaz.roomview; + +import androidx.appcompat.app.AppCompatActivity; + +import android.os.Bundle; +import android.widget.TextView; + +import Common.BuildingManager; +import Structures.BuildingInfo; + +public class BuildingView extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_building_view); + + Bundle extras = getIntent().getExtras(); + int building_index = extras.getInt("building"); + BuildingInfo building = BuildingManager.getBuilding(building_index); + + TextView b_name = findViewById(R.id.building_name); + b_name.setText(building.getName()); + } +} \ No newline at end of file diff --git a/Sources/app/src/main/java/com/furwaz/roomview/MainActivity.java b/Sources/app/src/main/java/com/furwaz/roomview/MainActivity.java index 8df82b250cd2f9cc5b9cf5874f6e0c18dc8b2894..aaecc6417fbc21f15b14e7b8ecef7ed780f55bf4 100644 --- a/Sources/app/src/main/java/com/furwaz/roomview/MainActivity.java +++ b/Sources/app/src/main/java/com/furwaz/roomview/MainActivity.java @@ -29,6 +29,7 @@ import java.util.Date; import java.util.List; import Common.BuildingManager; +import Common.ImageManager; import Common.InfoBinding; import Popups.BuildingPopup; import Structures.BuildingInfo; @@ -43,6 +44,7 @@ public class MainActivity extends AppCompatActivity { setContentView(R.layout.activity_main); BuildingManager.setContext(getBaseContext()); + ImageManager.setContext(getBaseContext()); ListView building_lv = findViewById(R.id.building_list); LinearLayout noDataLayout = findViewById(R.id.no_building_layout); @@ -56,7 +58,9 @@ public class MainActivity extends AppCompatActivity { }); building_adapter.setOnViewListener(param -> { - Toast.makeText(this, "Viewing building named "+((BuildingInfo) param).getName(), Toast.LENGTH_SHORT).show(); + Intent intent = new Intent(this, BuildingView.class); + intent.putExtra("building", BuildingManager.getBuildings().indexOf(param)); + startActivity(intent); return null; }); diff --git a/Sources/app/src/main/java/com/furwaz/roomview/PathwayActivity.java b/Sources/app/src/main/java/com/furwaz/roomview/PathwayActivity.java index 3048dca75ec077f0a5b004157a8e0da7d68c18d6..b2f8244ee184b85e3f59845cec1aabd4e0e2bbf5 100644 --- a/Sources/app/src/main/java/com/furwaz/roomview/PathwayActivity.java +++ b/Sources/app/src/main/java/com/furwaz/roomview/PathwayActivity.java @@ -3,16 +3,30 @@ package com.furwaz.roomview; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; +import android.view.View; +import android.widget.ArrayAdapter; import android.widget.Button; +import android.widget.EditText; +import android.widget.LinearLayout; +import android.widget.Spinner; import android.widget.TextView; import android.widget.Toast; +import java.util.ArrayList; +import java.util.List; + import Common.BuildingManager; import Structures.BuildingInfo; import Structures.PathInfo; +import Structures.PathStairs; +import Structures.PathType; import Structures.RoomInfo; +import Structures.StairsDirection; public class PathwayActivity extends AppCompatActivity { + BuildingInfo building = null; + RoomInfo room = null; + PathInfo path = null; @Override protected void onCreate(Bundle savedInstanceState) { @@ -24,12 +38,11 @@ public class PathwayActivity extends AppCompatActivity { int roomIndex = extras.getInt("room"); int pathIndex = extras.getInt("path"); - BuildingInfo building = BuildingManager.getBuilding(buildingIndex); - RoomInfo room = building.getRoom(roomIndex); - PathInfo path = room.getPath(pathIndex); + building = BuildingManager.getBuilding(buildingIndex); + room = building.getRoom(roomIndex); + path = room.getPath(pathIndex); - TextView path_tv = findViewById(R.id.pathway_name); - path_tv.setText(path.getName()); + setPathInfos(); Button btn_cancel = findViewById(R.id.btn_cancel); btn_cancel.setOnClickListener(view -> { @@ -37,9 +50,75 @@ public class PathwayActivity extends AppCompatActivity { }); Button btn_edit = findViewById(R.id.btn_edit); - btn_edit.setEnabled(false); btn_edit.setOnClickListener(view -> { - + this.savePathInfos(); + this.finish(); }); } + + protected void setPathInfos() { + TextView path_tv = findViewById(R.id.pathway_name); + path_tv.setText(path.getName()); + + EditText input_name = findViewById(R.id.input_pathway_name); + input_name.setText(path.getName()); + + String PATHWAY_DOOR = getResources().getString(R.string.door); + String PATHWAY_STAIRS = getResources().getString(R.string.stairs); + + Spinner path_type = findViewById(R.id.pathway_type); + String[] sp_type_items = new String[]{PATHWAY_DOOR, PATHWAY_STAIRS}; + path_type.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item, sp_type_items)); + path_type.setSelection(path.getType() == PathType.DOOR? 0 : 1); + path_type.setEnabled(false); + + Spinner path_dest_up = findViewById(R.id.pathway_dest_up); + Spinner path_dest_down = findViewById(R.id.pathway_dest_down); + TextView tv_dest_up = findViewById(R.id.pathway_dest_up_txt); + TextView tv_dest_down = findViewById(R.id.pathway_dest_down_txt); + LinearLayout ll_dest_down = findViewById(R.id.dest_down_layout); + + List<String> names = new ArrayList<>(); + names.add("<"+getResources().getString(R.string.none)+">"); + for(RoomInfo r : building.getRooms()) names.add(r.getName()); + String[] sp_dest_items = new String[names.size()]; + for (int i = 0; i < names.size(); i++) sp_dest_items[i] = names.get(i); + + path_dest_up.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item, sp_dest_items)); + path_dest_down.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item, sp_dest_items)); + + int path_up_index = building.getRooms().indexOf(path.getDestination()); + path_dest_up.setSelection(path_up_index + 1); + + if (path.getType() == PathType.STAIRS) { + ll_dest_down.setVisibility(View.VISIBLE); + tv_dest_down.setVisibility(View.VISIBLE); + + int path_down_index = building.getRooms().indexOf(((PathStairs) path).getDestination(StairsDirection.DOWN)); + path_dest_down.setSelection(path_down_index + 1); + } else { + tv_dest_up.setText(getResources().getString(R.string.pathway_destination)); + } + } + + protected void savePathInfos() { + EditText input_name = findViewById(R.id.input_pathway_name); + + Spinner path_dest_up = findViewById(R.id.pathway_dest_up); + Spinner path_dest_down = findViewById(R.id.pathway_dest_down); + + // save zone + path.setName(input_name.getText().toString()); + + // save dest up + int room_up_index = path_dest_up.getSelectedItemPosition() - 1; + RoomInfo room_up = room_up_index < 0 ? null: building.getRoom( room_up_index ); + path.setDestination(room_up); + + if (path.getType() == PathType.STAIRS) { + int room_down_index = path_dest_down.getSelectedItemPosition() - 1; + RoomInfo room_down = room_down_index < 0 ? null : building.getRoom( room_down_index ); + ((PathStairs) path).setDestination(StairsDirection.DOWN, room_down); + } + } } \ No newline at end of file diff --git a/Sources/app/src/main/java/com/furwaz/roomview/PhotoActivity.java b/Sources/app/src/main/java/com/furwaz/roomview/PhotoActivity.java new file mode 100644 index 0000000000000000000000000000000000000000..5b0dc238c5c14ddf93fc8513676abeee819b9c1b --- /dev/null +++ b/Sources/app/src/main/java/com/furwaz/roomview/PhotoActivity.java @@ -0,0 +1,194 @@ +package com.furwaz.roomview; + +import androidx.appcompat.app.AppCompatActivity; + +import android.content.pm.ActivityInfo; +import android.content.pm.PackageManager; +import android.hardware.Camera; +import android.hardware.Sensor; +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.Button; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.RelativeLayout; +import android.widget.Toast; + +import java.io.File; + +import Common.BuildingManager; +import Common.ImageManager; +import Structures.BuildingInfo; +import Structures.PhotoInfo; +import Structures.RoomInfo; +import Structures.ZoneInfo; +import Views.CameraPreview; +import Views.DoorsSelector; +import Views.LevelCanvas; + +public class PhotoActivity extends AppCompatActivity implements SensorEventListener { + protected static final int MODE_EDIT = 1; + protected static final int MODE_PHOTO = 2; + + SensorManager sm = null; + Sensor accelerometer = null; + LevelCanvas levelView = null; + + BuildingInfo building = null; + RoomInfo room = null; + ZoneInfo zone = null; + PhotoInfo photo = null; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_photo); + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + + Bundle extras = getIntent().getExtras(); + int building_index = extras.getInt("building"); + int room_index = extras.getInt("room"); + int zone_index = extras.getInt("zone"); + int photo_index = extras.getInt("photo"); + boolean new_photo = extras.getBoolean("new_photo"); + building = BuildingManager.getBuilding(building_index); + room = building.getRoom(room_index); + zone = room.getZone(zone_index); + photo = zone.getPhoto(photo_index); + + if (new_photo) { + this.setViewMode(MODE_PHOTO); + } else { + this.setViewMode(MODE_EDIT); + } + } + + protected void setViewMode(int mode) { + FrameLayout cam_prev = findViewById(R.id.camera_preview); + LinearLayout cam_hud = findViewById(R.id.camera_hud); + FrameLayout edit_prev = findViewById(R.id.edit_preview); + LinearLayout edit_hud = findViewById(R.id.edit_hud); + + cam_prev.setVisibility( mode == MODE_EDIT ? View.GONE : View.VISIBLE ); + cam_hud.setVisibility( mode == MODE_EDIT ? View.GONE : View.VISIBLE ); + edit_prev.setVisibility( mode == MODE_PHOTO ? View.GONE : View.VISIBLE ); + edit_hud.setVisibility( mode == MODE_PHOTO ? View.GONE : View.VISIBLE ); + + if (mode == MODE_EDIT) { + setupEditMode(); + } else { + setupPhotoMode(); + } + } + + protected void setupPhotoMode() { + if (!checkCameraHardware()) { + Toast.makeText(this, "Error : no camera detected on this device", Toast.LENGTH_SHORT).show(); + this.finish(); + } + Camera c = getCamera(); + FrameLayout cam_prev = findViewById(R.id.camera_preview); + + CameraPreview camPrev = new CameraPreview(this, c); + cam_prev.addView(camPrev); + + Button btn_nope = findViewById(R.id.btn_nope); + Button btn_foto = findViewById(R.id.btn_foto); + + btn_nope.setOnClickListener(view -> { + this.finish(); + }); + btn_foto.setOnClickListener(view -> { + c.takePicture(null, null, (bytes, camera) -> { + photo.setImage(bytes); + setViewMode(MODE_EDIT); + }); + }); + + levelView = findViewById(R.id.level_view); + sm = (SensorManager) getSystemService(SENSOR_SERVICE); + if (sm != null) { + accelerometer = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); + register(); + } + } + + protected void setupEditMode() { + ImageView photo_prev = findViewById(R.id.photo_preview); + photo_prev.setImageBitmap( photo.getBitmap() ); + + Button btn_done = findViewById(R.id.btn_done); + btn_done.setOnClickListener(view -> { + finish(); + }); + + Button btn_photo = findViewById(R.id.btn_photo); + btn_photo.setOnClickListener(view -> { + setViewMode(MODE_PHOTO); + }); + + DoorsSelector selector = findViewById(R.id.door_selector); + selector.setRoom(room); + selector.setPhoto(photo); + } + + @Override + protected void onPause() { + super.onPause(); + unregister(); + } + + @Override + protected void onResume() { + super.onResume(); + register(); + } + + protected void register() { + if (sm != null && accelerometer != null) + sm.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_GAME); + } + + protected void unregister() { + if (sm != null && accelerometer != null) + sm.unregisterListener(this, accelerometer); + } + + @Override + public void onAccuracyChanged(Sensor sensor, int i) {} + + @Override + public void onSensorChanged(SensorEvent sensorEvent) { + if (sensorEvent.sensor == accelerometer) { + float x_val = sensorEvent.values[0]; + float y_val = sensorEvent.values[1]; + float z_val = sensorEvent.values[2]; + float orient = (float) Math.atan2(y_val, x_val); + if (levelView != null) + levelView.askForDraw(orient); + } + } + + protected Camera getCamera() { + Camera c = null; + try { + c = Camera.open(); + } catch (Exception e) { + Toast.makeText(this, "Error opening camera: "+e, Toast.LENGTH_SHORT).show(); + } + return c; + } + + private boolean checkCameraHardware() { + if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)){ + return true; + } else { + return false; + } + } +} \ No newline at end of file diff --git a/Sources/app/src/main/java/com/furwaz/roomview/RoomActivity.java b/Sources/app/src/main/java/com/furwaz/roomview/RoomActivity.java index 7e21d1dac98a85dbad2ebe7c01b29d0b880420e1..3bb08feb40fecfcfdfafe4b31f0e4f3ea82b051c 100644 --- a/Sources/app/src/main/java/com/furwaz/roomview/RoomActivity.java +++ b/Sources/app/src/main/java/com/furwaz/roomview/RoomActivity.java @@ -29,7 +29,9 @@ import java.util.Locale; import Common.BuildingManager; import Common.InfoBinding; +import Popups.PathwayPopup; import Popups.RoomPopup; +import Popups.ZonePopup; import Structures.BuildingInfo; import Structures.PathDoor; import Structures.PathInfo; @@ -47,9 +49,6 @@ public class RoomActivity extends AppCompatActivity { InfoAdapter<PathInfo> pathways_adapter = null; boolean isViewInPathwaysMode = false; - static String PATHWAY_DOOR = ""; - static String PATHWAY_STAIRS = ""; - protected String beautifyString(String str) { return str.substring(0, 1).toUpperCase(Locale.ROOT) + str.substring(1, str.length()).toLowerCase(Locale.ROOT); @@ -60,9 +59,6 @@ public class RoomActivity extends AppCompatActivity { super.onCreate(savedInstanceState); setContentView(R.layout.activity_room); - PATHWAY_DOOR = getResources().getString(R.string.door); - PATHWAY_STAIRS = getResources().getString(R.string.stairs); - int buildingIndex = getIntent().getExtras().getInt("building"); int roomIndex = getIntent().getExtras().getInt("room"); building = BuildingManager.getBuilding(buildingIndex); @@ -85,7 +81,14 @@ public class RoomActivity extends AppCompatActivity { room_lv.setAdapter(zone_adapter); zone_adapter.setOnRemoveListener(param -> { room.removeZone((ZoneInfo) param); return null; }); - zone_adapter.setOnEditListener(param -> null); + zone_adapter.setOnEditListener(param -> { + Intent intent = new Intent(this, ZoneActivity.class); + intent.putExtra("building", BuildingManager.getBuildings().indexOf(building)); + intent.putExtra("room", building.getRooms().indexOf(room)); + intent.putExtra("zone", room.getZones().indexOf(param)); + this.startActivity(intent); + return null; + }); zone_adapter.setOnViewListener(param -> null); zone_adapter.setBindings(new InfoBinding[]{ @@ -111,7 +114,11 @@ public class RoomActivity extends AppCompatActivity { pathways_adapter.setBindings(new InfoBinding[]{ new InfoBinding(param -> ((PathInfo) param).getName(), R.id.pathway_name), - new InfoBinding(param -> beautifyString(((PathInfo) param).getType().toString()), R.id.pathway_type), + new InfoBinding(param -> { + PathInfo path = ((PathInfo) param); + String type = getResources().getString( path.getType() == PathType.DOOR? R.string.door : R.string.stairs ); + return beautifyString(type); + }, R.id.pathway_type), new InfoBinding(param -> { PathInfo path = ((PathInfo) param); if (path.getType() == PathType.DOOR) { @@ -230,139 +237,55 @@ public class RoomActivity extends AppCompatActivity { } protected void showAddZonePopup(View v) { - AlertDialog.Builder builder = new AlertDialog.Builder(RoomActivity.this); - AlertDialog dialog = builder.create(); - LayoutInflater factory = LayoutInflater.from(RoomActivity.this); - View popup = factory.inflate(R.layout.add_zone_popup, null); - dialog.setView(popup); - - dialog.setOnShowListener(dialogInterface -> { - TextView z_err = popup.findViewById(R.id.zone_input_error_msg); - EditText z_name = popup.findViewById(R.id.input_zone_name); - Button validate_btn = popup.findViewById(R.id.btn_validate_room); - Button cancel_btn = popup.findViewById(R.id.btn_cancel_room); - - validate_btn.setEnabled(false); - z_err.setText(""); - z_name.addTextChangedListener(new TextWatcher() { - public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {} - public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {} - public void afterTextChanged(Editable editable) { - validate_btn.setEnabled(false); - z_err.setText(""); - String input = editable.toString(); - if (input.length() == 0) { - z_err.setText(getResources().getString(R.string.specify_zone_name)); - return; - } - if (room.getZone(input) != null) { - z_err.setText(getResources().getString(R.string.zone_exists)); - return; - } - // everything is correct, display the button - validate_btn.setEnabled(true); - } - }); - - cancel_btn.setOnClickListener(view -> { - dialog.dismiss(); - }); - - validate_btn.setOnClickListener(view -> { - room.addZone(new ZoneInfo(z_name.getText().toString())); - zone_adapter.setData(room.getZones()); - dialog.dismiss(); - }); - }); - dialog.show(); + new ZonePopup( + this, + room, + param -> { + ((ZonePopup) param).getInput().setText(""); + return null; + }, + param -> { + ((ZonePopup) param).dismiss(); + return null; + }, + param -> { + ZonePopup popup = ((ZonePopup) param); + String name = popup.getInput().getText().toString(); + room.addZone(new ZoneInfo(name)); + zone_adapter.setData(room.getZones()); + popup.dismiss(); + return null; + }, + ZonePopup.MODE_NEW + ).show(); } protected void showAddPathwayPopup(View v) { - AlertDialog.Builder builder = new AlertDialog.Builder(RoomActivity.this); - AlertDialog dialog = builder.create(); - LayoutInflater factory = LayoutInflater.from(RoomActivity.this); - View popup = factory.inflate(R.layout.add_pathway_popup, null); - dialog.setView(popup); - - dialog.setOnShowListener(dialogInterface -> { - TextView p_err = popup.findViewById(R.id.pathway_input_error_msg); - EditText p_name = popup.findViewById(R.id.input_pathway_name); - Button validate_btn = popup.findViewById(R.id.btn_validate_room); - Button cancel_btn = popup.findViewById(R.id.btn_cancel_room); - - validate_btn.setEnabled(false); - p_err.setText(""); - p_name.addTextChangedListener(new TextWatcher() { - public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {} - public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {} - public void afterTextChanged(Editable editable) { - validate_btn.setEnabled(false); - p_err.setText(""); - String input = editable.toString(); - if (input.length() == 0) { - p_err.setText(getResources().getString(R.string.specify_pathway_name)); - return; - } - if (room.getPath(input) != null) { - p_err.setText(getResources().getString(R.string.pathway_exists)); - return; - } - // everything is correct, display the button - validate_btn.setEnabled(true); - } - }); - - Spinner sp_type = dialog.findViewById(R.id.pathway_type); - String[] sp_type_items = new String[]{PATHWAY_DOOR, PATHWAY_STAIRS}; - sp_type.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item, sp_type_items)); - - Spinner sp_dest_up = dialog.findViewById(R.id.pathway_dest_up); - Spinner sp_dest_down = dialog.findViewById(R.id.pathway_dest_down); - - List<String> names = new ArrayList<>(); - names.add("<"+getResources().getString(R.string.none)+">"); - for(RoomInfo r : building.getRooms()) names.add(r.getName()); - - String[] sp_dest_items = new String[names.size()]; - for (int i = 0; i < names.size(); i++) sp_dest_items[i] = names.get(i); - - sp_dest_up.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item, sp_dest_items)); - sp_dest_down.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item, sp_dest_items)); - - sp_type.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) { - if (adapterView.getAdapter().getItem(i) == PATHWAY_DOOR) { - dialog.findViewById(R.id.dest_down_layout).setVisibility(View.GONE); - dialog.findViewById(R.id.pathway_dest_down_txt).setVisibility(View.GONE); - ((TextView) dialog.findViewById(R.id.pathway_dest_up_txt)).setText(R.string.pathway_destination); + new PathwayPopup( + this, + building, + room, + param -> { + ((PathwayPopup) param).getInput().setText(""); + return null; + }, + param -> { + ((PathwayPopup) param).dismiss(); + return null; + }, + param -> { + PathwayPopup popup = ((PathwayPopup) param); + String name = popup.getInput().getText().toString(); + if (popup.getSelectedType() == PathType.DOOR) { + room.addPath(new PathDoor(name, popup.getUpDestination())); } else { - dialog.findViewById(R.id.dest_down_layout).setVisibility(View.VISIBLE); - dialog.findViewById(R.id.pathway_dest_down_txt).setVisibility(View.VISIBLE); - ((TextView) dialog.findViewById(R.id.pathway_dest_down_txt)).setText(R.string.pathway_destination_down); - ((TextView) dialog.findViewById(R.id.pathway_dest_up_txt)).setText(R.string.pathway_destination_up); + room.addPath(new PathStairs(name, popup.getUpDestination(), popup.getDownDestination())); } - } - public void onNothingSelected(AdapterView<?> adapterView) {} - }); - - cancel_btn.setOnClickListener(view -> { - dialog.dismiss(); - }); - - validate_btn.setOnClickListener(view -> { - RoomInfo dest_up = building.getRoom(sp_dest_up.getSelectedItem().toString()); - RoomInfo dest_down = building.getRoom(sp_dest_down.getSelectedItem().toString()); - - if (sp_type.getSelectedItem() == PATHWAY_DOOR) { // door - room.addPath(new PathDoor(p_name.getText().toString(), dest_up)); - } else { // stairs - room.addPath(new PathStairs(p_name.getText().toString(), dest_up, dest_down)); - } - zone_adapter.setData(room.getZones()); - pathways_adapter.setData(room.getPaths()); - dialog.dismiss(); - }); - }); - dialog.show(); + pathways_adapter.setData(room.getPaths()); + popup.dismiss(); + return null; + }, + ZonePopup.MODE_NEW + ).show(); } } \ No newline at end of file diff --git a/Sources/app/src/main/java/com/furwaz/roomview/ZoneActivity.java b/Sources/app/src/main/java/com/furwaz/roomview/ZoneActivity.java new file mode 100644 index 0000000000000000000000000000000000000000..5a934f43e096fad4dc32dafa1364641fd7a0bb36 --- /dev/null +++ b/Sources/app/src/main/java/com/furwaz/roomview/ZoneActivity.java @@ -0,0 +1,169 @@ +package com.furwaz.roomview; + +import androidx.appcompat.app.AppCompatActivity; + +import android.content.Intent; +import android.os.Bundle; +import android.view.View; +import android.widget.ImageButton; +import android.widget.LinearLayout; +import android.widget.ListView; +import android.widget.SearchView; +import android.widget.TextView; +import android.widget.Toast; + +import Common.BuildingManager; +import Common.InfoBinding; +import Popups.PhotoPopup; +import Popups.ZonePopup; +import Structures.BuildingInfo; +import Structures.Orientation; +import Structures.PhotoInfo; +import Structures.RoomInfo; +import Structures.ZoneInfo; +import Views.InfoAdapter; + +public class ZoneActivity extends AppCompatActivity { + InfoAdapter<PhotoInfo> photo_adapter = null; + BuildingInfo building = null; + RoomInfo room = null; + ZoneInfo zone = null; + ImageButton add_btn = null; + ListView photo_lv = null; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_zone); + + Bundle extras = getIntent().getExtras(); + int building_index = extras.getInt("building"); + int room_index = extras.getInt("room"); + int zone_index = extras.getInt("zone"); + building = BuildingManager.getBuilding(building_index); + room = building.getRoom(room_index); + zone = room.getZone(zone_index); + + photo_lv = findViewById(R.id.photo_list); + LinearLayout noDataLayout = findViewById(R.id.no_photo_layout); + + photo_adapter = new InfoAdapter<PhotoInfo>(this, zone.getPhotos(), noDataLayout, R.layout.photo_tile); + photo_lv.setAdapter(photo_adapter); + + photo_adapter.setOnRemoveListener(param -> { + zone.removePhoto((PhotoInfo) param); + checkForAddButton(); + return null; + }); + photo_adapter.setOnEditListener(param -> { + Intent intent = new Intent(this, PhotoActivity.class); + intent.putExtra("building", BuildingManager.getBuildings().indexOf(building)); + intent.putExtra("room", building.getRooms().indexOf(room)); + intent.putExtra("zone", room.getZones().indexOf(zone)); + intent.putExtra("photo", zone.getPhotos().indexOf(param)); + intent.putExtra("new_photo", ((PhotoInfo) param).getBitmap() == null); + startActivity(intent); + return null; + }); + photo_adapter.setOnViewListener(param -> null); + + photo_adapter.setBindings(new InfoBinding[]{ + new InfoBinding(param -> ((PhotoInfo) param).getPathViews().size(), R.id.photo_pathways), + new InfoBinding(param -> stringifyOrientation(((PhotoInfo) param).getOrientation()), R.id.photo_orientation), + new InfoBinding(param -> ((PhotoInfo) param).getBitmap(), R.id.photo_bitmap) + }); + + SearchView photo_sv = findViewById(R.id.photo_search); + photo_sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() { + public boolean onQueryTextSubmit(String s) { return true; } + + public boolean onQueryTextChange(String s) { + photo_adapter.setSearchQuery(s); + photo_lv.setAdapter(photo_adapter); + return true; + } + }); + + add_btn = findViewById(R.id.add_photo_btn); + add_btn.setOnClickListener(this::showAddPhotoPopup); + + checkForAddButton(); + + ImageButton edit_btn = findViewById(R.id.edit_zone_name); + edit_btn.setOnClickListener(view -> showEditPopup()); + + TextView zone_tv_name = findViewById(R.id.zone_name); + zone_tv_name.setText(zone.getName()); + } + + @Override + protected void onResume() { + super.onResume(); + photo_lv.setAdapter(photo_adapter); + } + + protected String stringifyOrientation(Orientation orient) { + int stringID = -1; + switch (orient) { + case EST: stringID = R.string.est; break; + case NORTH: stringID = R.string.north; break; + case SOUTH: stringID = R.string.south; break; + case WEST: stringID = R.string.west; break; + } + return getResources().getString(R.string.photo) + " (" + getResources().getString(stringID) + ")"; + } + + protected void showEditPopup() { + new ZonePopup( + this, + room, + param -> { + ((ZonePopup) param).getInput().setText(zone.getName()); + return null; + }, + param -> { + ((ZonePopup) param).dismiss(); + return null; + }, + param -> { + ZonePopup popup = ((ZonePopup) param); + String name = popup.getInput().getText().toString(); + zone.setName(name); + ((TextView) findViewById(R.id.zone_name)).setText(zone.getName()); + popup.dismiss(); + return null; + }, + ZonePopup.MODE_EDIT + ).show(); + } + + protected void showAddPhotoPopup(View v) { + new PhotoPopup( + this, + zone, + param -> null, + param -> { + ((PhotoPopup) param).dismiss(); + return null; + }, + param -> { + PhotoPopup popup = ((PhotoPopup) param); + Orientation orient = popup.getSelectedOrient(); + zone.addPhoto(new PhotoInfo(orient)); + photo_adapter.setData(zone.getPhotos()); + checkForAddButton(); + popup.dismiss(); + return null; + }, + PhotoPopup.MODE_NEW + ).show(); + } + + protected void checkForAddButton() { + if (zone.getPhotos().size() < 4) { + add_btn.setVisibility(View.VISIBLE); + } else { + add_btn.setVisibility(View.GONE); + } + } +} \ No newline at end of file diff --git a/Sources/app/src/main/res/drawable/action_bg.xml b/Sources/app/src/main/res/drawable/action_bg.xml new file mode 100644 index 0000000000000000000000000000000000000000..fafb5db66acfaecc1dc279607b5fef8970d512ac --- /dev/null +++ b/Sources/app/src/main/res/drawable/action_bg.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8"?> +<shape xmlns:android="http://schemas.android.com/apk/res/android"> + <solid android:color="@color/blue_500"/> + <stroke android:width="2dp" android:color="@color/blue_600" /> + <corners android:radius="8dp"/> + <padding android:left="0dp" android:top="0dp" android:right="0dp" android:bottom="0dp" /> +</shape> \ No newline at end of file diff --git a/Sources/app/src/main/res/drawable/action_tile.xml b/Sources/app/src/main/res/drawable/action_tile.xml new file mode 100644 index 0000000000000000000000000000000000000000..74c4e5b5815464f1ec4115352014b83897a2aabd --- /dev/null +++ b/Sources/app/src/main/res/drawable/action_tile.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8"?> +<shape xmlns:android="http://schemas.android.com/apk/res/android"> + <solid android:color="@color/slate_200"/> + <stroke android:width="2dp" android:color="@color/slate_300" /> + <corners android:radius="4dp"/> + <padding android:left="0dp" android:top="0dp" android:right="0dp" android:bottom="0dp" /> +</shape> \ No newline at end of file diff --git a/Sources/app/src/main/res/drawable/ic_baseline_directions_24.xml b/Sources/app/src/main/res/drawable/ic_baseline_directions_24.xml new file mode 100644 index 0000000000000000000000000000000000000000..ac19d4784c524aacc1c87de73a4f4b5203b90145 --- /dev/null +++ b/Sources/app/src/main/res/drawable/ic_baseline_directions_24.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="#FFFFFF" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M21.71,11.29l-9,-9c-0.39,-0.39 -1.02,-0.39 -1.41,0l-9,9c-0.39,0.39 -0.39,1.02 0,1.41l9,9c0.39,0.39 1.02,0.39 1.41,0l9,-9c0.39,-0.38 0.39,-1.01 0,-1.41zM14,14.5V12h-4v3H8v-4c0,-0.55 0.45,-1 1,-1h5V7.5l3.5,3.5 -3.5,3.5z"/> +</vector> diff --git a/Sources/app/src/main/res/drawable/ic_baseline_directions_walk_24.xml b/Sources/app/src/main/res/drawable/ic_baseline_directions_walk_24.xml new file mode 100644 index 0000000000000000000000000000000000000000..ded01eb4cedf14b78cf833b3e5b5ed3b0cdc859b --- /dev/null +++ b/Sources/app/src/main/res/drawable/ic_baseline_directions_walk_24.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="#FFFFFF" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M13.5,5.5c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM9.8,8.9L7,23h2.1l1.8,-8 2.1,2v6h2v-7.5l-2.1,-2 0.6,-3C14.8,12 16.8,13 19,13v-2c-1.9,0 -3.5,-1 -4.3,-2.4l-1,-1.6c-0.4,-0.6 -1,-1 -1.7,-1 -0.3,0 -0.5,0.1 -0.8,0.1L6,8.3V13h2V9.6l1.8,-0.7"/> +</vector> diff --git a/Sources/app/src/main/res/drawable/ic_baseline_location_on_24.xml b/Sources/app/src/main/res/drawable/ic_baseline_location_on_24.xml new file mode 100644 index 0000000000000000000000000000000000000000..e5383d72a6ad6813ce78d283e78b77b61d7969ab --- /dev/null +++ b/Sources/app/src/main/res/drawable/ic_baseline_location_on_24.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="#FFFFFF" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13c0,-3.87 -3.13,-7 -7,-7zM12,11.5c-1.38,0 -2.5,-1.12 -2.5,-2.5s1.12,-2.5 2.5,-2.5 2.5,1.12 2.5,2.5 -1.12,2.5 -2.5,2.5z"/> +</vector> diff --git a/Sources/app/src/main/res/drawable/icon_background.xml b/Sources/app/src/main/res/drawable/icon_background.xml index ca3826a46ce070f906d0d3fbe6987df882134381..334eee14f3c7ea56620a0579c69fee10606f98b7 100644 --- a/Sources/app/src/main/res/drawable/icon_background.xml +++ b/Sources/app/src/main/res/drawable/icon_background.xml @@ -1,74 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> -<vector - android:height="108dp" - android:width="108dp" - android:viewportHeight="108" - android:viewportWidth="108" - xmlns:android="http://schemas.android.com/apk/res/android"> - <path android:fillColor="#3DDC84" - android:pathData="M0,0h108v108h-108z"/> - <path android:fillColor="#00000000" android:pathData="M9,0L9,108" - android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> - <path android:fillColor="#00000000" android:pathData="M19,0L19,108" - android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> - <path android:fillColor="#00000000" android:pathData="M29,0L29,108" - android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> - <path android:fillColor="#00000000" android:pathData="M39,0L39,108" - android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> - <path android:fillColor="#00000000" android:pathData="M49,0L49,108" - android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> - <path android:fillColor="#00000000" android:pathData="M59,0L59,108" - android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> - <path android:fillColor="#00000000" android:pathData="M69,0L69,108" - android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> - <path android:fillColor="#00000000" android:pathData="M79,0L79,108" - android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> - <path android:fillColor="#00000000" android:pathData="M89,0L89,108" - android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> - <path android:fillColor="#00000000" android:pathData="M99,0L99,108" - android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> - <path android:fillColor="#00000000" android:pathData="M0,9L108,9" - android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> - <path android:fillColor="#00000000" android:pathData="M0,19L108,19" - android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> - <path android:fillColor="#00000000" android:pathData="M0,29L108,29" - android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> - <path android:fillColor="#00000000" android:pathData="M0,39L108,39" - android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> - <path android:fillColor="#00000000" android:pathData="M0,49L108,49" - android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> - <path android:fillColor="#00000000" android:pathData="M0,59L108,59" - android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> - <path android:fillColor="#00000000" android:pathData="M0,69L108,69" - android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> - <path android:fillColor="#00000000" android:pathData="M0,79L108,79" - android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> - <path android:fillColor="#00000000" android:pathData="M0,89L108,89" - android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> - <path android:fillColor="#00000000" android:pathData="M0,99L108,99" - android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> - <path android:fillColor="#00000000" android:pathData="M19,29L89,29" - android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> - <path android:fillColor="#00000000" android:pathData="M19,39L89,39" - android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> - <path android:fillColor="#00000000" android:pathData="M19,49L89,49" - android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> - <path android:fillColor="#00000000" android:pathData="M19,59L89,59" - android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> - <path android:fillColor="#00000000" android:pathData="M19,69L89,69" - android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> - <path android:fillColor="#00000000" android:pathData="M19,79L89,79" - android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> - <path android:fillColor="#00000000" android:pathData="M29,19L29,89" - android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> - <path android:fillColor="#00000000" android:pathData="M39,19L39,89" - android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> - <path android:fillColor="#00000000" android:pathData="M49,19L49,89" - android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> - <path android:fillColor="#00000000" android:pathData="M59,19L59,89" - android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> - <path android:fillColor="#00000000" android:pathData="M69,19L69,89" - android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> - <path android:fillColor="#00000000" android:pathData="M79,19L79,89" - android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> -</vector> +<shape xmlns:android="http://schemas.android.com/apk/res/android"> + <stroke android:width="4dp" android:color="@color/blue_500" /> + <corners android:radius="8dp"/> + <padding android:left="0dp" android:top="0dp" android:right="0dp" android:bottom="0dp" /> +</shape> \ No newline at end of file diff --git a/Sources/app/src/main/res/layout/activity_building.xml b/Sources/app/src/main/res/layout/activity_building.xml index 62ba0eebf7b4bab5d83bf79574dcc6e0f2e246b2..b6be48938b61f3fbff771fceb43ccf4a956cdb5f 100644 --- a/Sources/app/src/main/res/layout/activity_building.xml +++ b/Sources/app/src/main/res/layout/activity_building.xml @@ -14,6 +14,10 @@ <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content"> + <TextView + android:layout_width="0dp" + android:layout_weight="1" + android:layout_height="wrap_content"/> <TextView android:id="@+id/building_name" android:layout_width="0dp" diff --git a/Sources/app/src/main/res/layout/activity_building_view.xml b/Sources/app/src/main/res/layout/activity_building_view.xml new file mode 100644 index 0000000000000000000000000000000000000000..a8cb70983455506bcebbb8b8cc964d2770a1c2d5 --- /dev/null +++ b/Sources/app/src/main/res/layout/activity_building_view.xml @@ -0,0 +1,117 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + tools:context=".BuildingActivity"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + android:background="@color/slate_50"> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content"> + <TextView + android:id="@+id/building_name" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center" + android:paddingBottom="20dp" + android:paddingTop="20dp" + android:textSize="40sp" + android:text="" + android:maxLines="1" + android:ellipsize="end" + android:scrollHorizontally="true" + android:textStyle="bold" + android:textColor="@color/blue_500"/> + </LinearLayout> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@color/blue_500" + android:orientation="vertical"> + <LinearLayout + android:id="@+id/no_room_layout" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + android:visibility="visible" + android:background="@color/slate_50" + android:layout_marginTop="5dp" + android:padding="10dp"> + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textColor="@color/slate_500" + android:textStyle="bold" + android:textSize="18sp" + android:padding="8dp" + android:text="@string/actions" /> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:padding="4dp" + android:orientation="horizontal"> + <LinearLayout + android:layout_width="0dp" + android:layout_weight="1" + android:gravity="center" + android:layout_height="wrap_content" + android:orientation="vertical"> + <LinearLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="center" + android:background="@drawable/action_tile" + android:padding="8dp" + android:orientation="vertical"> + <ImageButton + android:layout_width="60dp" + android:layout_height="60dp" + android:src="@drawable/ic_baseline_directions_24" + android:background="@drawable/action_bg"/> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textStyle="bold" + android:paddingTop="8dp" + android:textColor="@color/blue_500" + android:text="@string/directions" /> + </LinearLayout> + </LinearLayout> + <LinearLayout + android:layout_width="0dp" + android:layout_weight="1" + android:gravity="center" + android:layout_height="wrap_content" + android:orientation="vertical"> + <LinearLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="center" + android:background="@drawable/action_tile" + android:padding="8dp" + android:orientation="vertical"> + <ImageButton + android:layout_width="60dp" + android:layout_height="60dp" + android:src="@drawable/ic_baseline_location_on_24" + android:background="@drawable/action_bg"/> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textStyle="bold" + android:textColor="@color/blue_500" + android:paddingTop="8dp" + android:text="@string/go_to" /> + </LinearLayout> + </LinearLayout> + </LinearLayout> + </LinearLayout> + </LinearLayout> + </LinearLayout> +</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/Sources/app/src/main/res/layout/activity_pathway.xml b/Sources/app/src/main/res/layout/activity_pathway.xml index fda8e4457b0aaebab1aaa6ea2ea186653c860675..5472ee1634ebd888604c36d3690232eccb2fb5d1 100644 --- a/Sources/app/src/main/res/layout/activity_pathway.xml +++ b/Sources/app/src/main/res/layout/activity_pathway.xml @@ -59,13 +59,127 @@ android:text="@string/edit_pathway" /> </LinearLayout> <LinearLayout - android:id="@+id/no_room_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:visibility="visible" - android:gravity="center" + android:gravity="top" + android:padding="4dp" android:background="@color/slate_50" > + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textColor="@color/slate_700" + android:textSize="16sp" + android:textStyle="normal" + android:text="@string/pathway_name" + android:paddingTop="20dp" + android:paddingBottom="4dp"/> + <EditText + android:id="@+id/input_pathway_name" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:inputType="text" + android:hint="@string/pathway_name" + android:textColorHint="@color/slate_300" + android:textColor="@color/slate_500" + android:backgroundTint="@color/blue_500" + android:textSize="20sp" + android:textStyle="bold"/> + <TextView + android:id="@+id/pathway_input_error_msg" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="start" + android:textColor="@color/red_500" + android:textSize="12sp" + android:textStyle="normal" + android:text="" + android:layout_marginStart="4dp" + android:layout_marginEnd="4dp"/> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textColor="@color/slate_700" + android:textSize="16sp" + android:textStyle="normal" + android:text="@string/pathway_type" + android:paddingTop="20dp" + android:paddingBottom="4dp"/> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:background="@color/blue_500" + android:paddingBottom="4dp"> + <Spinner + android:id="@+id/pathway_type" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="@color/slate_100" + android:textColor="@color/slate_800" + android:textSize="20sp" + android:textStyle="bold"/> + </LinearLayout> + + <TextView + android:id="@+id/pathway_dest_up_txt" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textColor="@color/slate_700" + android:textSize="16sp" + android:textStyle="normal" + android:text="@string/pathway_destination_up" + android:paddingTop="20dp" + android:paddingBottom="4dp"/> + <LinearLayout + android:id="@+id/dest_up_layout" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:background="@color/blue_500" + android:paddingBottom="4dp"> + <Spinner + android:id="@+id/pathway_dest_up" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="@color/slate_100" + android:text="@string/new_pathway" + android:textColor="@color/slate_800" + android:textSize="20sp" + android:textStyle="bold"/> + </LinearLayout> + + <TextView + android:visibility="gone" + android:id="@+id/pathway_dest_down_txt" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textColor="@color/slate_700" + android:textSize="16sp" + android:textStyle="normal" + android:text="@string/pathway_destination_down" + android:paddingTop="20dp" + android:paddingBottom="4dp"/> + <LinearLayout + android:visibility="gone" + android:id="@+id/dest_down_layout" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:background="@color/blue_500" + android:paddingBottom="4dp"> + <Spinner + android:id="@+id/pathway_dest_down" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="@color/slate_100" + android:text="@string/new_pathway" + android:textColor="@color/slate_800" + android:textSize="20sp" + android:textStyle="bold"/> + </LinearLayout> </LinearLayout> </LinearLayout> <LinearLayout diff --git a/Sources/app/src/main/res/layout/activity_photo.xml b/Sources/app/src/main/res/layout/activity_photo.xml new file mode 100644 index 0000000000000000000000000000000000000000..66cd22d809b7e0d792c6ea1d74a906bd373147b7 --- /dev/null +++ b/Sources/app/src/main/res/layout/activity_photo.xml @@ -0,0 +1,196 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@color/slate_50" + tools:context=".PhotoActivity"> + <FrameLayout + android:id="@+id/camera_preview" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:foregroundGravity="center"/> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="1"/> + <FrameLayout + android:id="@+id/edit_preview" + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="10" + android:foregroundGravity="center"> + <ImageView + android:id="@+id/photo_preview" + android:layout_width="match_parent" + android:layout_height="match_parent"/> + </FrameLayout> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="3"/> + </LinearLayout> + + <LinearLayout + android:id="@+id/camera_hud" + android:visibility="gone" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + <Views.LevelCanvas + android:id="@+id/level_view" + android:layout_width="60dp" + android:layout_height="60dp" + android:layout_gravity="center"/> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:gravity="center" + android:text="@string/keep_phone_straight" + android:textSize="18sp" + android:textStyle="bold" + android:textColor="@color/blue_500"/> + </LinearLayout> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="horizontal" + android:layout_marginBottom="20dp" + android:gravity="bottom|center"> + + <LinearLayout + android:layout_width="0dp" + android:layout_weight="1" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:gravity="center"> + <Button + android:id="@+id/btn_nope" + android:text="@string/cancel" + android:backgroundTint="@color/red_500" + android:layout_width="wrap_content" + android:layout_height="wrap_content"/> + </LinearLayout> + + <LinearLayout + android:layout_width="0dp" + android:layout_weight="1" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:gravity="center"> + <Button + android:id="@+id/btn_foto" + android:text="@string/done" + android:layout_width="wrap_content" + android:layout_height="wrap_content"/> + </LinearLayout> + + <LinearLayout + android:layout_width="0dp" + android:layout_weight="1" + android:layout_height="wrap_content" + android:orientation="horizontal" /> + </LinearLayout> + </LinearLayout> + + <LinearLayout + android:id="@+id/edit_hud" + android:visibility="visible" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="8" + android:orientation="vertical"> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/select_doors" + android:layout_gravity="center" + android:gravity="center" + android:textAlignment="center" + android:textColor="@color/blue_500" + android:textStyle="bold" + android:textSize="18sp" + android:layout_marginTop="15dp"/> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="8" + android:orientation="horizontal"> + <Views.DoorsSelector + android:id="@+id/door_selector" + android:layout_width="match_parent" + android:layout_height="match_parent"/> + </LinearLayout> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="1" + android:orientation="horizontal" + android:gravity="center"> + <LinearLayout + android:id="@+id/walk_btn" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:background="@drawable/icon_background" + android:orientation="horizontal" + android:padding="8dp"> + <ImageView + android:layout_width="40dp" + android:layout_height="40dp" + android:src="@drawable/ic_baseline_directions_walk_24"/> + </LinearLayout> + </LinearLayout> + </LinearLayout> + </LinearLayout> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="1" + android:orientation="horizontal" + android:gravity="center"> + <LinearLayout + android:layout_width="0dp" + android:layout_weight="1" + android:layout_height="wrap_content" + android:gravity="center" + android:orientation="horizontal"> + <Button + android:id="@+id/btn_photo" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/change_photo"/> + </LinearLayout> + <LinearLayout + android:layout_width="0dp" + android:layout_weight="1" + android:layout_height="wrap_content" + android:gravity="center" + android:orientation="horizontal"> + <Button + android:id="@+id/btn_done" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/done"/> + </LinearLayout> + </LinearLayout> + </LinearLayout> +</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/Sources/app/src/main/res/layout/activity_room.xml b/Sources/app/src/main/res/layout/activity_room.xml index 06753c24c7dcc0a76f75faf32c6083f20391cb53..4b4b46f5e14cf1661679abb68a32046fe80c6b70 100644 --- a/Sources/app/src/main/res/layout/activity_room.xml +++ b/Sources/app/src/main/res/layout/activity_room.xml @@ -15,6 +15,10 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> + <TextView + android:layout_width="0dp" + android:layout_weight="1" + android:layout_height="wrap_content"/> <TextView android:id="@+id/room_name" android:layout_width="0dp" diff --git a/Sources/app/src/main/res/layout/activity_zone.xml b/Sources/app/src/main/res/layout/activity_zone.xml new file mode 100644 index 0000000000000000000000000000000000000000..f361e90a5a444e3ee4345d3c3f0cda8ca1cff1b6 --- /dev/null +++ b/Sources/app/src/main/res/layout/activity_zone.xml @@ -0,0 +1,133 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + tools:context=".MainActivity"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + android:background="@color/slate_50"> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal"> + <TextView + android:layout_width="0dp" + android:layout_weight="1" + android:layout_height="wrap_content"/> + <TextView + android:id="@+id/zone_name" + android:layout_width="0dp" + android:layout_weight="6" + android:layout_height="wrap_content" + android:gravity="center" + android:paddingBottom="20dp" + android:paddingTop="20dp" + android:textSize="40sp" + android:text="" + android:maxLines="1" + android:ellipsize="end" + android:scrollHorizontally="true" + android:textStyle="bold" + android:textColor="@color/blue_500"/> + <ImageButton + android:id="@+id/edit_zone_name" + android:layout_width="0dp" + android:layout_weight="1" + android:layout_height="wrap_content" + android:background="#00000000" + android:src="@drawable/ic_baseline_edit_24" + android:layout_gravity="center"/> + </LinearLayout> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@color/blue_500" + android:orientation="vertical"> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:background="@color/slate_200" + android:layout_marginBottom="6dp" + android:paddingLeft="10dp" + android:paddingRight="10dp"> + <TextView + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:gravity="center" + android:textSize="20sp" + android:textStyle="bold" + android:textColor="@color/slate_800" + android:text="@string/photos" /> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:gravity="end"> + <SearchView + android:id="@+id/photo_search" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="end" + android:searchIcon="@drawable/ic_search_black" /> + </LinearLayout> + </LinearLayout> + <LinearLayout + android:id="@+id/no_photo_layout" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + android:visibility="visible" + android:gravity="center" + android:background="@color/slate_50" > + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/no_photos" + android:textColor="@color/slate_400" + android:textStyle="bold" + android:textAlignment="center" + android:layout_marginStart="20dp" + android:layout_marginEnd="20dp" + android:textSize="24sp"/> + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/no_photos_desc" + android:textColor="@color/slate_300" + android:textStyle="normal" + android:textAlignment="center" + android:layout_marginStart="20dp" + android:layout_marginEnd="20dp" + android:textSize="20sp"/> + </LinearLayout> + <ListView + android:id="@+id/photo_list" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@color/slate_50" + android:divider="@null" + android:dividerHeight="0dp" + android:padding="10dp"/> + </LinearLayout> + </LinearLayout> + + <RelativeLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + android:gravity="bottom|end"> + + <ImageButton + android:id="@+id/add_photo_btn" + android:layout_width="80dp" + android:layout_height="80dp" + android:layout_marginEnd="20dp" + android:layout_marginBottom="20dp" + android:src="@drawable/ic_baseline_add_circle_24" + android:backgroundTint="#00FFFFFF"/> + </RelativeLayout> +</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/Sources/app/src/main/res/layout/add_pathview_popup.xml b/Sources/app/src/main/res/layout/add_pathview_popup.xml new file mode 100644 index 0000000000000000000000000000000000000000..d412a39f5b30612e620c5cdd456d81e40e608db3 --- /dev/null +++ b/Sources/app/src/main/res/layout/add_pathview_popup.xml @@ -0,0 +1,90 @@ +<?xml version="1.0" encoding="utf-8"?> +<RelativeLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="wrap_content" + android:layout_height="wrap_content"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + android:background="@color/slate_50"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:background="@color/blue_500" + android:layout_marginBottom="20dp"> + + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="@color/slate_200" + android:text="@string/new_pathview" + android:textColor="@color/blue_500" + android:textSize="20sp" + android:layout_marginBottom="4dp" + android:textStyle="bold" + android:padding="10dp" + /> + </LinearLayout> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textColor="@color/slate_700" + android:textSize="16sp" + android:textStyle="normal" + android:text="@string/pathview_path" + android:layout_marginStart="10dp" + android:layout_marginEnd="10dp" + android:paddingTop="10dp" + android:paddingBottom="4dp"/> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:background="@color/blue_500" + android:layout_marginStart="10dp" + android:layout_marginEnd="10dp" + android:paddingBottom="4dp"> + <Spinner + android:id="@+id/pathview_path" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="@color/slate_100" + android:textColor="@color/slate_800" + android:textSize="20sp" + android:textStyle="bold"/> + </LinearLayout> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:layout_marginTop="20dp" + android:padding="8dp"> + + <Button + android:id="@+id/btn_cancel_room" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textColor="@color/red_500" + style="@style/Widget.AppCompat.Button.Borderless" + android:text="@string/cancel"/> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:gravity="right"> + <Button + android:id="@+id/btn_validate_room" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:backgroundTint="@color/blue_500" + android:text="@string/add"/> + </LinearLayout> + </LinearLayout> + </LinearLayout> +</RelativeLayout> \ No newline at end of file diff --git a/Sources/app/src/main/res/layout/add_photo_popup.xml b/Sources/app/src/main/res/layout/add_photo_popup.xml new file mode 100644 index 0000000000000000000000000000000000000000..1875ff69d7c1d26890309e3613ed8257d3e9878b --- /dev/null +++ b/Sources/app/src/main/res/layout/add_photo_popup.xml @@ -0,0 +1,90 @@ +<?xml version="1.0" encoding="utf-8"?> +<RelativeLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="wrap_content" + android:layout_height="wrap_content"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + android:background="@color/slate_50"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:background="@color/blue_500" + android:layout_marginBottom="20dp"> + + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="@color/slate_200" + android:text="@string/new_photo" + android:textColor="@color/blue_500" + android:textSize="20sp" + android:layout_marginBottom="4dp" + android:textStyle="bold" + android:padding="10dp" + /> + </LinearLayout> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textColor="@color/slate_700" + android:textSize="16sp" + android:textStyle="normal" + android:text="@string/photo_orientation" + android:layout_marginStart="10dp" + android:layout_marginEnd="10dp" + android:paddingTop="10dp" + android:paddingBottom="4dp"/> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:background="@color/blue_500" + android:layout_marginStart="10dp" + android:layout_marginEnd="10dp" + android:paddingBottom="4dp"> + <Spinner + android:id="@+id/photo_orient" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="@color/slate_100" + android:textColor="@color/slate_800" + android:textSize="20sp" + android:textStyle="bold"/> + </LinearLayout> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:layout_marginTop="20dp" + android:padding="8dp"> + + <Button + android:id="@+id/btn_cancel_room" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textColor="@color/red_500" + style="@style/Widget.AppCompat.Button.Borderless" + android:text="@string/cancel"/> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:gravity="right"> + <Button + android:id="@+id/btn_validate_room" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:backgroundTint="@color/blue_500" + android:text="@string/create"/> + </LinearLayout> + </LinearLayout> + </LinearLayout> +</RelativeLayout> \ No newline at end of file diff --git a/Sources/app/src/main/res/layout/add_zone_popup.xml b/Sources/app/src/main/res/layout/add_zone_popup.xml index 420e6dcf847c40aa959fac763126a236fe3c6db1..6463f391c153666b9f29b8d9f99097e044a53d54 100644 --- a/Sources/app/src/main/res/layout/add_zone_popup.xml +++ b/Sources/app/src/main/res/layout/add_zone_popup.xml @@ -18,6 +18,7 @@ android:layout_marginBottom="20dp"> <TextView + android:id="@+id/zone_popup_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/slate_200" diff --git a/Sources/app/src/main/res/layout/photo_tile.xml b/Sources/app/src/main/res/layout/photo_tile.xml new file mode 100644 index 0000000000000000000000000000000000000000..95114890205898b1227b3673a58764748d023496 --- /dev/null +++ b/Sources/app/src/main/res/layout/photo_tile.xml @@ -0,0 +1,107 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:paddingBottom="10dp"> + <LinearLayout + android:id="@+id/tile_box" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + android:padding="10dp" + android:background="@drawable/round_bg" + tools:ignore="MissingConstraints"> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal"> + <LinearLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="vertical"> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal"> + <TextView + android:id="@+id/photo_orientation" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textStyle="bold" + android:text="Orientation" + android:maxLines="1" + android:ellipsize="end" + android:scrollHorizontally="true" + android:textSize="20sp" + android:textColor="@color/blue_500" /> + </LinearLayout> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal"> + <TextView + android:id="@+id/photo_pathways" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textStyle="normal" + android:text="X" + android:layout_marginEnd="4dp" + android:textSize="16sp" + android:textColor="@color/slate_500" /> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textStyle="normal" + android:text="@string/pathways" + android:layout_marginEnd="20dp" + android:textSize="16sp" + android:textColor="@color/slate_500" /> + </LinearLayout> + </LinearLayout> + <LinearLayout + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:orientation="horizontal"> + <ImageView + android:id="@+id/photo_bitmap" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_gravity="end" + android:foregroundGravity="right" + android:contentDescription="@string/photo_preview"> + </ImageView> + </LinearLayout> + </LinearLayout> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:layout_marginTop="10dp"> + <Button + android:id="@+id/tile_remove" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:backgroundTint="@color/red_500" + android:text="@string/remove" + android:textSize="16sp" + android:textColor="@color/slate_50" + android:textStyle="normal"/> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:gravity="end"> + <Button + android:id="@+id/tile_edit" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:backgroundTint="@color/blue_500" + android:text="@string/edit" + android:textSize="16sp" + android:textColor="@color/slate_50" + android:textStyle="normal" /> + </LinearLayout> + </LinearLayout> + </LinearLayout> +</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/Sources/app/src/main/res/values-fr/strings.xml b/Sources/app/src/main/res/values-fr/strings.xml index 0560ca472106ecc5603306d0bf960f70edd59ccd..ee7daf9bc9fe1ec44cfb8a9f2f6c8a3916c7b281 100644 --- a/Sources/app/src/main/res/values-fr/strings.xml +++ b/Sources/app/src/main/res/values-fr/strings.xml @@ -12,7 +12,7 @@ <string name="no_rooms">Pas de pièces</string> <string name="no_rooms_desc">Appuyez sur l\'icône + pour ajouter une pièce</string> <string name="new_building">Nouveau bâtiment</string> - <string name="building_name">Nom du bâtiment ...</string> + <string name="building_name">Nom du bâtiment</string> <string name="create">Créer</string> <string name="new_room">Nouvelle pièce</string> <string name="room_name">Nom de la pièce ...</string> @@ -20,10 +20,10 @@ <string name="no_zones_desc">Appuyez sur l\'icône + pour ajouter une zone</string> <string name="doors">Portes</string> <string name="new_zone">Nouvelle zone</string> - <string name="zone_name">Nom de la zone ...</string> + <string name="zone_name">Nom de la zone</string> <string name="no_pathways">Pas de chemins</string> <string name="no_pathways_desc">Appuyez sur l\'icône + pour ajouter un chemin</string> - <string name="pathway_name">Nom du chemin ...</string> + <string name="pathway_name">Nom du chemin</string> <string name="new_pathway">Nouveau chemin</string> <string name="pathway_destination_down">Destination du chemin (haut)</string> <string name="pathway_destination_up">Destination du chemin (bas)</string> @@ -40,9 +40,33 @@ <string name="specify_zone_name">Spécifiez un nom de zone</string> <string name="zone_exists">La zone existe déjà</string> <string name="specify_pathway_name">Spécifiez un nom de chemin</string> - <string name="pathway_exists">le chemin existe déjà</string> + <string name="pathway_exists">Le chemin existe déjà</string> <string name="edit_building">Modifier le bâtiment</string> <string name="building_invalid">Nom de bâtiment invalide</string> <string name="edit_room">Modifier la pièce</string> <string name="edit_pathway">Modifier le chemin</string> + <string name="no_photos_desc">Appuyez sur l\'icône + pour ajouter une photo</string> + <string name="no_photos">Pas de photos</string> + <string name="photos">Photos</string> + <string name="est">Est</string> + <string name="north">Nord</string> + <string name="south">Sud</string> + <string name="west">Ouest</string> + <string name="photo_orientation">Orientation de photo</string> + <string name="edit_zone">Modifier la zone</string> + <string name="new_photo">Nouvelle photo</string> + <string name="photo">Photo</string> + <string name="center">Centre</string> + <string name="done">Terminé</string> + <string name="select_doors">Sélectionnez toutes les portes</string> + <string name="photo_preview">Previsualisation de la photo</string> + <string name="keep_phone_straight">Gardez votre téléphone droit</string> + <string name="change_photo">Changer la photo</string> + <string name="door_too_small">La zone de porte est trop petite !</string> + <string name="new_pathview">Nouvelle zone de porte</string> + <string name="pathview_path">Porte correspondante</string> + <string name="add">Ajouter</string> + <string name="actions">Actions</string> + <string name="directions">Directions</string> + <string name="go_to">Aller à</string> </resources> \ No newline at end of file diff --git a/Sources/app/src/main/res/values/strings.xml b/Sources/app/src/main/res/values/strings.xml index 74b3706c6e3383f5476b10cbba1e321edf4aa281..8effd5602e59f76dbf50b40810386d90c8f83521 100644 --- a/Sources/app/src/main/res/values/strings.xml +++ b/Sources/app/src/main/res/values/strings.xml @@ -12,7 +12,7 @@ <string name="no_rooms_desc">Click on the + icon to add a room</string> <string name="no_rooms">No rooms</string> <string name="new_building">New building</string> - <string name="building_name">Building name ...</string> + <string name="building_name">Building name</string> <string name="create">Create</string> <string name="new_room">New room</string> <string name="room_name">Room name ...</string> @@ -20,10 +20,10 @@ <string name="no_zones_desc">Click on the + icon to add a zone</string> <string name="doors">Doors</string> <string name="new_zone">New zone</string> - <string name="zone_name">Zone name ...</string> + <string name="zone_name">Zone name</string> <string name="no_pathways">No pathways</string> <string name="no_pathways_desc">Click on the + icon to add a pathway</string> - <string name="pathway_name">Pathway name ...</string> + <string name="pathway_name">Pathway name</string> <string name="new_pathway">New pathway</string> <string name="pathway_destination_down">Pathway destination (down):</string> <string name="pathway_destination_up">Pathway destination (up):</string> @@ -45,4 +45,28 @@ <string name="building_invalid">Invalid building name</string> <string name="edit_room">Edit room</string> <string name="edit_pathway">Edit pathway</string> + <string name="photos">Photos</string> + <string name="no_photos">No photos</string> + <string name="no_photos_desc">Click on the + icon to add a photo</string> + <string name="est">Est</string> + <string name="north">North</string> + <string name="south">South</string> + <string name="west">West</string> + <string name="photo_orientation">Photo orientation</string> + <string name="edit_zone">Edit zone</string> + <string name="new_photo">New photo</string> + <string name="photo">Photo</string> + <string name="center">Center</string> + <string name="photo_preview">Photo preview</string> + <string name="done">Done</string> + <string name="select_doors">Select all the doors</string> + <string name="keep_phone_straight">Keep your phone straight</string> + <string name="change_photo">Change photo</string> + <string name="door_too_small">Door zone is too small !</string> + <string name="new_pathview">New door zone</string> + <string name="pathview_path">Corresponding door</string> + <string name="add">Add</string> + <string name="actions">Actions</string> + <string name="directions">Directions</string> + <string name="go_to">Go to</string> </resources> \ No newline at end of file