Skip to content

Commit 81671be

Browse files
committed
Add map legend
1 parent 8485d57 commit 81671be

File tree

6 files changed

+173
-21
lines changed

6 files changed

+173
-21
lines changed
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/**
2+
* DepNav -- department navigator.
3+
* Copyright (C) 2023 Timofey Pushkin
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
17+
*/
18+
19+
package ru.spbu.depnav.ui.map
20+
21+
import androidx.annotation.StringRes
22+
import androidx.compose.foundation.layout.Arrangement
23+
import androidx.compose.foundation.lazy.LazyColumn
24+
import androidx.compose.foundation.text.InlineTextContent
25+
import androidx.compose.foundation.text.appendInlineContent
26+
import androidx.compose.material3.AlertDialog
27+
import androidx.compose.material3.LocalTextStyle
28+
import androidx.compose.material3.Text
29+
import androidx.compose.material3.TextButton
30+
import androidx.compose.runtime.Composable
31+
import androidx.compose.ui.res.stringResource
32+
import androidx.compose.ui.text.Placeholder
33+
import androidx.compose.ui.text.PlaceholderVerticalAlign
34+
import androidx.compose.ui.text.buildAnnotatedString
35+
import ru.spbu.depnav.R
36+
import ru.spbu.depnav.data.model.Marker
37+
import ru.spbu.depnav.ui.theme.DEFAULT_PADDING
38+
39+
/** Dialog with the map legend. **/
40+
@Composable
41+
fun MapLegendDialog(onDismiss: () -> Unit) {
42+
AlertDialog(
43+
onDismissRequest = onDismiss,
44+
confirmButton = {
45+
TextButton(onClick = onDismiss) {
46+
Text(stringResource(R.string.ok))
47+
}
48+
},
49+
title = { Text(stringResource(R.string.map_legend)) },
50+
text = {
51+
LazyColumn(verticalArrangement = Arrangement.spacedBy(DEFAULT_PADDING)) {
52+
item { LegendItem(Marker.MarkerType.ENTRANCE, R.string.entrance_descr) }
53+
item { LegendItem(Marker.MarkerType.STAIRS_UP, R.string.stairs_up_descr) }
54+
item { LegendItem(Marker.MarkerType.STAIRS_DOWN, R.string.stairs_down_descr) }
55+
item { LegendItem(Marker.MarkerType.STAIRS_BOTH, R.string.stairs_both_descr) }
56+
item { LegendItem(Marker.MarkerType.ELEVATOR, R.string.elevator_descr) }
57+
item { LegendItem(Marker.MarkerType.WC_MAN, R.string.wc_man_descr) }
58+
item { LegendItem(Marker.MarkerType.WC_WOMAN, R.string.wc_woman_descr) }
59+
item { LegendItem(Marker.MarkerType.WC, R.string.wc_descr) }
60+
item { LegendItem(Marker.MarkerType.OTHER, R.string.other_descr) }
61+
}
62+
}
63+
)
64+
}
65+
66+
private const val INLINE_ICON_ID = "icon"
67+
68+
@Composable
69+
private fun LegendItem(markerType: Marker.MarkerType, @StringRes descriptionId: Int) {
70+
Text(
71+
text = buildAnnotatedString {
72+
appendInlineContent(INLINE_ICON_ID)
73+
append("${stringResource(descriptionId)}")
74+
},
75+
inlineContent = mapOf(INLINE_ICON_ID to getInlineMarkerView(markerType))
76+
)
77+
}
78+
79+
@Composable
80+
private fun getInlineMarkerView(type: Marker.MarkerType) = InlineTextContent(
81+
Placeholder(
82+
width = LocalTextStyle.current.lineHeight,
83+
height = LocalTextStyle.current.lineHeight,
84+
PlaceholderVerticalAlign.TextCenter
85+
)
86+
) {
87+
MarkerView(title = type.name, type = type, isClosed = false)
88+
}

app/src/main/java/ru/spbu/depnav/ui/map/MapScreen.kt

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,16 @@ fun MapScreen(vm: MapScreenViewModel = hiltViewModel(), onStartSearch: () -> Uni
8080
return
8181
}
8282

83-
var openMenu by rememberSaveable { mutableStateOf(false) }
84-
if (openMenu) {
83+
var openMapLegend by rememberSaveable { mutableStateOf(false) }
84+
if (openMapLegend) {
85+
MapLegendDialog(onDismiss = { openMapLegend = false })
86+
}
87+
88+
var openSettings by rememberSaveable { mutableStateOf(false) }
89+
if (openSettings) {
8590
SettingsDialog(
8691
prefs = vm.prefs,
87-
onDismiss = { openMenu = false }
92+
onDismiss = { openSettings = false }
8893
)
8994
}
9095

@@ -97,7 +102,8 @@ fun MapScreen(vm: MapScreenViewModel = hiltViewModel(), onStartSearch: () -> Uni
97102
visible = vm.showUI,
98103
currentFloor = vm.currentFloor,
99104
maxFloor = vm.floorsNum,
100-
onOpenMenuClick = { openMenu = true },
105+
onOpenMapLegendClick = { openMapLegend = true },
106+
onOpenSettingsClick = { openSettings = true },
101107
onStartSearchClick = onStartSearch,
102108
onSwitchFloorClick = { vm.viewModelScope.launch { vm.setFloor(it) } }
103109
)
@@ -127,7 +133,8 @@ private fun BoxScope.TopUi(
127133
visible: Boolean,
128134
currentFloor: Int,
129135
maxFloor: Int,
130-
onOpenMenuClick: () -> Unit,
136+
onOpenMapLegendClick: () -> Unit,
137+
onOpenSettingsClick: () -> Unit,
131138
onStartSearchClick: () -> Unit,
132139
onSwitchFloorClick: (Int) -> Unit
133140
) {
@@ -149,7 +156,8 @@ private fun BoxScope.TopUi(
149156
) {
150157
TopButton(
151158
text = stringResource(R.string.search_markers),
152-
onSettingsClick = onOpenMenuClick,
159+
onInfoClick = onOpenMapLegendClick,
160+
onSettingsClick = onOpenSettingsClick,
153161
onSurfaceClick = onStartSearchClick,
154162
modifier = Modifier.fillMaxWidth(0.9f)
155163
)

app/src/main/java/ru/spbu/depnav/ui/map/SettingsDialog.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import androidx.compose.material3.MaterialTheme
3333
import androidx.compose.material3.RadioButton
3434
import androidx.compose.material3.Switch
3535
import androidx.compose.material3.Text
36+
import androidx.compose.material3.TextButton
3637
import androidx.compose.runtime.Composable
3738
import androidx.compose.ui.Alignment
3839
import androidx.compose.ui.Modifier
@@ -50,10 +51,13 @@ private val ADDITIONAL_START_PADDING = 4.dp
5051
/** Dialog with app settings. */
5152
@Composable
5253
fun SettingsDialog(prefs: PreferencesManager, onDismiss: () -> Unit) {
53-
// TODO: replace with a custom dialog
5454
AlertDialog(
5555
onDismissRequest = onDismiss,
56-
confirmButton = {},
56+
confirmButton = {
57+
TextButton(onClick = onDismiss) {
58+
Text(stringResource(R.string.ok))
59+
}
60+
},
5761
title = { Text(stringResource(R.string.settings)) },
5862
text = {
5963
LazyColumn(

app/src/main/java/ru/spbu/depnav/ui/map/TopButton.kt

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,16 @@
1818

1919
package ru.spbu.depnav.ui.map
2020

21+
import androidx.compose.foundation.ExperimentalFoundationApi
22+
import androidx.compose.foundation.basicMarquee
2123
import androidx.compose.foundation.layout.Box
2224
import androidx.compose.foundation.layout.Row
2325
import androidx.compose.foundation.layout.size
2426
import androidx.compose.foundation.shape.CircleShape
2527
import androidx.compose.material.icons.Icons
28+
import androidx.compose.material.icons.rounded.Info
2629
import androidx.compose.material.icons.rounded.Search
2730
import androidx.compose.material.icons.rounded.Settings
28-
import androidx.compose.material3.ExperimentalMaterial3Api
2931
import androidx.compose.material3.Icon
3032
import androidx.compose.material3.IconButton
3133
import androidx.compose.material3.LocalContentColor
@@ -40,11 +42,12 @@ import androidx.compose.ui.platform.LocalViewConfiguration
4042
import androidx.compose.ui.tooling.preview.Preview
4143
import ru.spbu.depnav.ui.theme.DepNavTheme
4244

43-
/** Button with a search icon and text. */
44-
@OptIn(ExperimentalMaterial3Api::class)
45+
/** Button with a search icon, text, and additional nested buttons. */
46+
@OptIn(ExperimentalFoundationApi::class)
4547
@Composable
4648
fun TopButton(
4749
text: String,
50+
onInfoClick: () -> Unit,
4851
onSettingsClick: () -> Unit,
4952
onSurfaceClick: () -> Unit,
5053
modifier: Modifier = Modifier
@@ -59,19 +62,25 @@ fun TopButton(
5962
modifier = Modifier.size(LocalViewConfiguration.current.minimumTouchTargetSize),
6063
contentAlignment = Alignment.Center
6164
) {
62-
Icon(Icons.Rounded.Search, contentDescription = "Open menu")
65+
Icon(Icons.Rounded.Search, contentDescription = "Search")
6366
}
6467

6568
CompositionLocalProvider(
6669
LocalContentColor provides MaterialTheme.colorScheme.onSurfaceVariant
6770
) {
6871
Text(
6972
text = text,
70-
modifier = Modifier.weight(1f),
73+
modifier = Modifier
74+
.weight(1f)
75+
.basicMarquee(),
7176
maxLines = 1,
7277
)
7378
}
7479

80+
IconButton(onClick = onInfoClick) {
81+
Icon(Icons.Rounded.Info, contentDescription = "Open map info")
82+
}
83+
7584
IconButton(onClick = onSettingsClick) {
7685
Icon(Icons.Rounded.Settings, contentDescription = "Open settings")
7786
}
@@ -86,6 +95,7 @@ private fun TopButtonPreview() {
8695
DepNavTheme {
8796
TopButton(
8897
text = "Search markers",
98+
onInfoClick = {},
8999
onSettingsClick = {},
90100
onSurfaceClick = {}
91101
)
Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,34 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<resources>
3+
<!-- Markers -->
34
<string name="no_title">Без названия</string>
4-
<string name="search_markers">Поиск меток</string>
55
<string name="closed">Закрыто</string>
6+
7+
<!-- Search -->
8+
<string name="search_markers">Поиск меток</string>
9+
<string name="nothing_found">Ничего не найдено</string>
10+
11+
<!-- Map legend -->
12+
<string name="map_legend">Условные обозначения</string>
13+
<string name="entrance_descr">вход в здание</string>
14+
<string name="stairs_up_descr">лестница вверх</string>
15+
<string name="stairs_down_descr">лестница вниз</string>
16+
<string name="stairs_both_descr">лестница в оба направления</string>
17+
<string name="elevator_descr">лифт</string>
18+
<string name="wc_man_descr">мужской туалет</string>
19+
<string name="wc_woman_descr">женский туалет</string>
20+
<string name="wc_descr">общий туалет</string>
21+
<string name="other_descr">прочее</string>
22+
23+
<!-- Settings -->
624
<string name="settings">Настройки</string>
725
<string name="theme">Тема</string>
826
<string name="dark_theme">Тёмная</string>
927
<string name="light_theme">Светлая</string>
1028
<string name="system_theme">Как в системе</string>
11-
<string name="zoom_in_to_see_markers">Приблизьте, чтобы увидеть маркеры</string>
12-
<string name="nothing_found">Ничего не найдено</string>
13-
<string name="rotation_gesture">Жест поворота</string>
1429
<string name="map">Карта</string>
30+
<string name="rotation_gesture">Жест поворота</string>
31+
32+
<!-- Etc -->
33+
<string name="zoom_in_to_see_markers">Приблизьте, чтобы увидеть метки</string>
1534
</resources>

app/src/main/res/values/strings.xml

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,38 @@
11
<resources>
22
<string name="app_name" translatable="false">DepNav</string>
3+
4+
<!-- General -->
5+
<string name="ok" translatable="false">OK</string>
6+
7+
<!-- Markers -->
38
<string name="no_title">No title</string>
4-
<string name="search_markers">Search markers</string>
59
<string name="closed">Closed</string>
10+
11+
<!-- Search -->
12+
<string name="search_markers">Search markers</string>
13+
<string name="nothing_found">Nothing was found</string>
14+
15+
<!-- Map legend -->
16+
<string name="map_legend">Map legend</string>
17+
<string name="entrance_descr">building entrance</string>
18+
<string name="stairs_up_descr">stairs to the floor above</string>
19+
<string name="stairs_down_descr">stairs to the floor below</string>
20+
<string name="stairs_both_descr">stairs in both directions</string>
21+
<string name="elevator_descr">elevator</string>
22+
<string name="wc_man_descr">men\'s restroom</string>
23+
<string name="wc_woman_descr">women\'s restroom</string>
24+
<string name="wc_descr">unisex restroom</string>
25+
<string name="other_descr">miscellaneous</string>
26+
27+
<!-- Settings -->
628
<string name="settings">Settings</string>
729
<string name="theme">Theme</string>
830
<string name="dark_theme">Dark</string>
931
<string name="light_theme">Light</string>
1032
<string name="system_theme">Match system</string>
11-
<string name="zoom_in_to_see_markers">Zoom in to see markers</string>
12-
<string name="nothing_found">Nothing was found</string>
13-
<string name="rotation_gesture">Rotation gesture</string>
1433
<string name="map">Map</string>
34+
<string name="rotation_gesture">Rotation gesture</string>
35+
36+
<!-- Etc -->
37+
<string name="zoom_in_to_see_markers">Zoom in to see markers</string>
1538
</resources>

0 commit comments

Comments
 (0)