-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Resource takes page view * Test app for resource take cards * Added test wav files * Renamed test app * Takes view model * Load test text and takes * Navigate to takes from resources list (load real data) * TakesListView and Play/Pause event handling * Takes page refactor Fix broken Takes Fragment * Support change to Resource * Refactoring to support RecordableItem * Use observable list of Recordables rather than 'title' and 'body' * Better names for Takes fragments * WorkbookViewModel * navigateToTakesPage() uses BookElement * Support change to RecordTake * New take action * Put tab label properties in an enum map * Add sort to tabs * Fixed bug in TakeDao * Proper subscribe handling * Add vgrow to workspace root to fill screen * Dispose takes subscription when Recordable changes * Remove test files to be put in test branch * WorkbookViewModel getters return non-null values or throw error * Remove code dependent on testapp files * Utility function for EnumMap: getNotNull() * Bug fix for TakesTab clear disposables * Restore functionality to TMVM recordContent (sort of) TakeManagementViewModel will be merged with TakesViewModel soon, so these changes will be obsolete when that happens. * PR Comments * PR Comments * PR Comments and applying FileName pattern * Using Recordable Interface and WorkbookFileNamerBuilder * Simplified WorkbookFileNameBuilder * Using simplified FileNamer * Better filenames * Renamed to RecordResourceViewModel Moved recording functionality to TakeManagementViewModel (which needs to be refactored later) * Removed Platform.runLater where it is not necessary * Refactored RecordableTab, added RecordableTabViewModel * Minor improvements * ResourcesViewModel tests and RecordableTab tests * Allow importing OBS markdown files (#461) * Allow importing OBS markdown files. MimeType enum instead of string literals. Ignore creator if unable to match help RCs otherwise. Unhide the Tree generics. More type safety. * Narrow down a few more OtterTree<Any> params. * Test cleanup * Fix broken unit tests * Update travis.yml to include chromeabletabpane * Remove RecordableTabTest until better solution found It used PlatformImpl.startup, which errors on travis
- Loading branch information
Showing
27 changed files
with
877 additions
and
80 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
rootProject.name = 'otter-jvm' | ||
includeBuild '../kotlin-resource-container' | ||
includeBuild '../otter-common' | ||
includeBuild '../chromeabletabpane' | ||
includeBuild '../otter-common' |
1 change: 0 additions & 1 deletion
1
src/main/kotlin/org/wycliffeassociates/otter/jvm/app/ui/mainscreen/view/MainScreenStyles.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
37 changes: 16 additions & 21 deletions
37
.../kotlin/org/wycliffeassociates/otter/jvm/app/ui/resources/viewmodel/ResourcesViewModel.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,43 +1,38 @@ | ||
package org.wycliffeassociates.otter.jvm.app.ui.resources.viewmodel | ||
|
||
import javafx.application.Platform | ||
import javafx.beans.property.SimpleObjectProperty | ||
import javafx.beans.property.SimpleStringProperty | ||
import org.wycliffeassociates.otter.common.data.workbook.* | ||
import org.wycliffeassociates.otter.common.utils.mapNotNull | ||
import org.wycliffeassociates.otter.jvm.app.ui.resourcetakes.viewmodel.RecordResourceViewModel | ||
import org.wycliffeassociates.otter.jvm.app.ui.workbook.viewmodel.WorkbookViewModel | ||
import org.wycliffeassociates.otter.jvm.app.widgets.resourcecard.model.ResourceGroupCardItemList | ||
import org.wycliffeassociates.otter.jvm.app.widgets.resourcecard.model.resourceGroupCardItem | ||
import tornadofx.* | ||
|
||
class ResourcesViewModel : ViewModel() { | ||
val activeWorkbookProperty = SimpleObjectProperty<Workbook>() | ||
val workbook: Workbook | ||
get() = activeWorkbookProperty.value | ||
internal val recordResourceViewModel: RecordResourceViewModel by inject() | ||
private val workbookViewModel: WorkbookViewModel by inject() | ||
|
||
val activeChapterProperty = SimpleObjectProperty<Chapter>() | ||
val chapter: Chapter | ||
get() = activeChapterProperty.value | ||
|
||
val activeResourceSlugProperty = SimpleStringProperty() | ||
val resourceSlug: String | ||
get() = activeResourceSlugProperty.value | ||
|
||
val resourceGroups: ResourceGroupCardItemList = ResourceGroupCardItemList(mutableListOf()) | ||
val resourceGroupCardItemList: ResourceGroupCardItemList = ResourceGroupCardItemList() | ||
|
||
fun loadResourceGroups() { | ||
val chapter = workbookViewModel.chapter | ||
chapter | ||
.children | ||
.startWith(chapter) | ||
.mapNotNull { resourceGroupCardItem(it, resourceSlug, onSelect = this::navigateToTakesPage) } | ||
.mapNotNull { | ||
resourceGroupCardItem(it, workbookViewModel.resourceSlug, onSelect = this::navigateToTakesPage) | ||
} | ||
.buffer(2) // Buffering by 2 prevents the list UI from jumping while groups are loading | ||
.subscribe { | ||
Platform.runLater { | ||
resourceGroups.addAll(it) | ||
} | ||
resourceGroupCardItemList.addAll(it) | ||
} | ||
} | ||
|
||
private fun navigateToTakesPage(resource: Resource) { | ||
// TODO use navigator | ||
internal fun navigateToTakesPage(bookElement: BookElement, resource: Resource) { | ||
// TODO use navigator to navigate to takes page | ||
workbookViewModel.activeChunkProperty.set(bookElement as? Chunk) | ||
recordResourceViewModel.setRecordableListItems( | ||
listOfNotNull(resource.title, resource.body) | ||
) | ||
} | ||
} |
93 changes: 93 additions & 0 deletions
93
...kotlin/org/wycliffeassociates/otter/jvm/app/ui/resourcetakes/view/RecordResourceStyles.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package org.wycliffeassociates.otter.jvm.app.ui.resourcetakes.view | ||
|
||
import javafx.geometry.Pos | ||
import javafx.scene.layout.BorderStrokeStyle | ||
import javafx.scene.paint.Color | ||
import javafx.scene.text.FontPosture | ||
import org.wycliffeassociates.otter.jvm.app.theme.AppTheme | ||
import tornadofx.* | ||
|
||
typealias LinearU = Dimension<Dimension.LinearUnits> | ||
|
||
class RecordResourceStyles : Stylesheet() { | ||
companion object { | ||
val takesTab by cssclass() | ||
val leftRegionContainer by cssclass() | ||
val rightRegion by cssclass() | ||
val dragTarget by cssclass() | ||
val contentText by cssclass() | ||
val newTakeRegion by cssclass() | ||
val contentScrollPane by cssclass() | ||
val takesList by cssclass() | ||
|
||
val takeMaxWidth = 500.px | ||
val takeMinHeight = 80.px | ||
} | ||
|
||
private fun margin(top: LinearU, right: LinearU, bottom: LinearU, left: LinearU) = mixin { | ||
backgroundInsets += box(top, right, bottom, left) | ||
borderInsets += box(top, right, bottom, left) | ||
} | ||
|
||
private val topMargin = 15.px | ||
private val bottomMargin = 15.px | ||
private val leftRegionLeftMargin = 80.px | ||
private val leftRegionRightMargin = 100.px | ||
|
||
init { | ||
takesTab { | ||
backgroundColor += AppTheme.colors.white | ||
} | ||
|
||
leftRegionContainer { | ||
borderColor += box( | ||
Color.TRANSPARENT, | ||
AppTheme.colors.lightBackground, | ||
AppTheme.colors.lightBackground, | ||
Color.TRANSPARENT | ||
) | ||
} | ||
|
||
rightRegion { | ||
padding = box(topMargin, 70.px, 30.px, 30.px) | ||
} | ||
|
||
dragTarget { | ||
+margin(topMargin, leftRegionLeftMargin, 0.px, leftRegionRightMargin) | ||
alignment = Pos.CENTER | ||
backgroundColor += AppTheme.colors.defaultBackground | ||
maxWidth = takeMaxWidth + leftRegionLeftMargin + leftRegionRightMargin | ||
minHeight = takeMinHeight + topMargin | ||
borderStyle += BorderStrokeStyle.DASHED | ||
borderWidth += box(2.px) | ||
fontStyle = FontPosture.ITALIC | ||
} | ||
|
||
contentText { | ||
fontSize = 24.px // If you put this in contentScrollPane, the scroll bar gets very big | ||
} | ||
|
||
newTakeRegion { | ||
alignment = Pos.CENTER | ||
borderColor += box(AppTheme.colors.lightBackground, Color.TRANSPARENT, Color.TRANSPARENT, Color.TRANSPARENT) | ||
borderWidth += box(3.px, 0.px, 0.px, 0.px) | ||
padding = box(topMargin, leftRegionLeftMargin, bottomMargin, leftRegionRightMargin) | ||
} | ||
|
||
contentScrollPane { | ||
padding = box(15.px, leftRegionLeftMargin, 30.px, leftRegionRightMargin) | ||
backgroundColor += Color.TRANSPARENT | ||
viewport { | ||
backgroundColor += Color.TRANSPARENT | ||
} | ||
} | ||
|
||
takesList { | ||
backgroundColor += Color.TRANSPARENT | ||
} | ||
|
||
listCell { | ||
backgroundColor += Color.TRANSPARENT | ||
} | ||
} | ||
} |
31 changes: 31 additions & 0 deletions
31
...n/kotlin/org/wycliffeassociates/otter/jvm/app/ui/resourcetakes/view/RecordResourceView.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package org.wycliffeassociates.otter.jvm.app.ui.resourcetakes.view | ||
|
||
import org.wycliffeassociates.controls.ChromeableTabPane | ||
import org.wycliffeassociates.otter.common.data.model.ContentType | ||
import org.wycliffeassociates.otter.jvm.app.ui.resourcetakes.viewmodel.RecordResourceViewModel | ||
import tornadofx.* | ||
import org.wycliffeassociates.otter.jvm.utils.getNotNull | ||
|
||
class RecordResourceView : View() { | ||
private val viewModel: RecordResourceViewModel by inject() | ||
private val tabPane = ChromeableTabPane() | ||
|
||
override val root = tabPane | ||
|
||
// The tabs will add or remove themselves from the tabPane when their view model's 'recordable' property changes | ||
private val tabs: List<RecordableTab> = listOf( | ||
recordableTab(ContentType.TITLE, 0), | ||
recordableTab(ContentType.BODY, 1) | ||
) | ||
|
||
private fun recordableTab(contentType: ContentType, sort: Int) = RecordableTab( | ||
viewModel.contentTypeToViewModelMap.getNotNull(contentType), | ||
tabPane, | ||
sort, | ||
viewModel::onTabSelect | ||
) | ||
|
||
init { | ||
importStylesheet<RecordResourceStyles>() | ||
} | ||
} |
65 changes: 65 additions & 0 deletions
65
src/main/kotlin/org/wycliffeassociates/otter/jvm/app/ui/resourcetakes/view/RecordableTab.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package org.wycliffeassociates.otter.jvm.app.ui.resourcetakes.view | ||
|
||
import javafx.scene.control.Tab | ||
import javafx.scene.control.TabPane | ||
import org.wycliffeassociates.otter.common.domain.content.Recordable | ||
import org.wycliffeassociates.otter.jvm.app.ui.resourcetakes.viewmodel.RecordableTabViewModel | ||
import tornadofx.* | ||
import kotlin.math.min | ||
|
||
class RecordableTab( | ||
private val viewModel: RecordableTabViewModel, | ||
// tabPaneProperty gets set to null every time the tab gets removed from the tab pane so we need to cache it | ||
private val parent: TabPane, | ||
val sort: Int, | ||
private val onTabSelect: (Recordable) -> Unit | ||
): Tab() { | ||
|
||
init { | ||
textProperty().bind(viewModel.labelProperty) | ||
|
||
RecordableTabContent(viewModel.takesList).apply { | ||
formattedTextProperty.bind(viewModel.getFormattedTextBinding()) | ||
this@RecordableTab.content = this.root | ||
} | ||
|
||
selectedProperty().onChange { selected -> | ||
if (selected) { | ||
callOnTabSelect() | ||
} | ||
} | ||
|
||
viewModel.recordableProperty.onChange { item -> | ||
item?.let { | ||
checkAndAddSelf() | ||
} ?: removeSelf() | ||
} | ||
} | ||
|
||
private fun checkAndAddSelf() { | ||
if (!parent.tabs.contains(this)) { | ||
addSelfToParent() | ||
} | ||
} | ||
|
||
private fun removeSelf() { | ||
parent.tabs.remove(this) | ||
} | ||
|
||
private fun addSelfToParent() { | ||
parent.tabs.add(min(sort, parent.tabs.size), this) | ||
if (parent.tabs.size == 1) { | ||
selectTab() | ||
} | ||
} | ||
|
||
private fun selectTab() { | ||
select() | ||
callOnTabSelect() | ||
} | ||
|
||
private fun callOnTabSelect() { | ||
viewModel.recordable?.let { onTabSelect(it) } | ||
?: throw IllegalStateException("Selected tab's recordable is null") | ||
} | ||
} |
56 changes: 56 additions & 0 deletions
56
...kotlin/org/wycliffeassociates/otter/jvm/app/ui/resourcetakes/view/RecordableTabContent.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package org.wycliffeassociates.otter.jvm.app.ui.resourcetakes.view | ||
|
||
import javafx.beans.property.SimpleStringProperty | ||
import javafx.collections.ObservableList | ||
import javafx.scene.layout.GridPane | ||
import javafx.scene.layout.RowConstraints | ||
import org.wycliffeassociates.otter.common.data.workbook.Take | ||
import org.wycliffeassociates.otter.jvm.app.ui.resourcetakes.viewmodel.RecordResourceViewModel | ||
import org.wycliffeassociates.otter.jvm.app.ui.takemanagement.viewmodel.TakeManagementViewModel | ||
import tornadofx.* | ||
|
||
class RecordableTabContent( | ||
takesList: ObservableList<Take> | ||
) : Fragment() { | ||
|
||
private val takeManagementViewModel: TakeManagementViewModel by inject() | ||
private val recordResourceViewModel: RecordResourceViewModel by inject() | ||
|
||
val formattedTextProperty = SimpleStringProperty() | ||
|
||
init { | ||
importStylesheet<RecordResourceStyles>() | ||
} | ||
|
||
private fun GridPane.setFillHeightSingleRow() { | ||
val rc = RowConstraints() | ||
rc.percentHeight = 100.0 | ||
rowConstraints.addAll(rc) | ||
} | ||
|
||
override val root = gridpane { | ||
addClass(RecordResourceStyles.takesTab) | ||
setFillHeightSingleRow() | ||
|
||
row { | ||
vbox { | ||
gridpaneColumnConstraints { | ||
percentWidth = 50.0 | ||
} | ||
addClass(RecordResourceStyles.leftRegionContainer) | ||
add( | ||
TabContentLeftRegion(formattedTextProperty, recordResourceViewModel::newTakeAction) | ||
) | ||
} | ||
vbox(20.0) { | ||
gridpaneColumnConstraints { | ||
percentWidth = 50.0 | ||
} | ||
addClass(RecordResourceStyles.rightRegion) | ||
add( | ||
TakesListView(takesList, takeManagementViewModel::audioPlayer) | ||
) | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.