mirror of
https://github.com/maxkratz/lectureStudio.git
synced 2024-09-08 00:03:48 +00:00
editor: added configurable actions unite threshold #898
This commit is contained in:
parent
1972952701
commit
20773b5165
20 changed files with 438 additions and 67 deletions
|
@ -42,6 +42,7 @@ public class DefaultConfiguration extends EditorConfiguration {
|
|||
setAdvancedUIMode(false);
|
||||
setExtendedFullscreen(false);
|
||||
setVideoExportPath(new File(System.getProperty("user.home"), "Desktop").getAbsolutePath());
|
||||
setActionsUniteThreshold(700);
|
||||
|
||||
getWhiteboardConfig().setBackgroundColor(Color.WHITE);
|
||||
getWhiteboardConfig().setVerticalLinesVisible(false);
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
package org.lecturestudio.editor.api.config;
|
||||
|
||||
import org.lecturestudio.core.app.configuration.Configuration;
|
||||
import org.lecturestudio.core.beans.IntegerProperty;
|
||||
import org.lecturestudio.core.beans.StringProperty;
|
||||
|
||||
public class EditorConfiguration extends Configuration {
|
||||
|
@ -26,6 +27,9 @@ public class EditorConfiguration extends Configuration {
|
|||
/** The path where the video export files are stored at. */
|
||||
private final StringProperty videoExportPath = new StringProperty();
|
||||
|
||||
/** The threshold value in milliseconds for merging annotations. */
|
||||
private final IntegerProperty actionsUniteThreshold = new IntegerProperty(700);
|
||||
|
||||
|
||||
/**
|
||||
* Get the path where the video export files are stored at.
|
||||
|
@ -53,4 +57,31 @@ public class EditorConfiguration extends Configuration {
|
|||
public StringProperty videoExportPathProperty() {
|
||||
return videoExportPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the actions unite threshold in milliseconds.
|
||||
*
|
||||
* @return the unite threshold.
|
||||
*/
|
||||
public int getActionsUniteThreshold() {
|
||||
return actionsUniteThreshold.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the actions unite threshold in milliseconds.
|
||||
*
|
||||
* @param threshold the unite threshold.
|
||||
*/
|
||||
public void setActionsUniteThreshold(int threshold) {
|
||||
this.actionsUniteThreshold.set(threshold);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the actions unite threshold property.
|
||||
*
|
||||
* @return the unite threshold property.
|
||||
*/
|
||||
public IntegerProperty actionsUniteThresholdProperty() {
|
||||
return actionsUniteThreshold;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* Copyright (C) 2020 TU Darmstadt, Department of Computer Science,
|
||||
* Embedded Systems and Applications Group.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.lecturestudio.editor.api.edit;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
|
||||
import org.lecturestudio.core.recording.RecordedEvents;
|
||||
import org.lecturestudio.core.recording.RecordedPage;
|
||||
import org.lecturestudio.core.recording.RecordingEditException;
|
||||
import org.lecturestudio.core.recording.action.ActionType;
|
||||
import org.lecturestudio.core.recording.action.PlaybackAction;
|
||||
import org.lecturestudio.core.recording.action.ZoomAction;
|
||||
import org.lecturestudio.core.recording.edit.RecordedObjectAction;
|
||||
|
||||
public class DeleteCompositeEventsAction extends RecordedObjectAction<RecordedEvents> {
|
||||
|
||||
private final List<PlaybackAction> actions;
|
||||
|
||||
private final int pageNumber;
|
||||
|
||||
private List<PlaybackAction> savedActions;
|
||||
|
||||
|
||||
public DeleteCompositeEventsAction(RecordedEvents lectureObject,
|
||||
List<PlaybackAction> actions, int pageNumber) {
|
||||
super(lectureObject);
|
||||
|
||||
this.actions = actions;
|
||||
this.pageNumber = pageNumber;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws RecordingEditException {
|
||||
List<PlaybackAction> pageActions = getPageActions();
|
||||
|
||||
savedActions = new ArrayList<>(pageActions);
|
||||
|
||||
for (PlaybackAction action : actions) {
|
||||
int actionIndex = pageActions.indexOf(action);
|
||||
if (actionIndex < 0) {
|
||||
throw new RecordingEditException("RecordedPage does not contain any action to delete");
|
||||
}
|
||||
|
||||
ListIterator<PlaybackAction> iterator = pageActions.listIterator(actionIndex);
|
||||
|
||||
deleteAction(action, iterator);
|
||||
|
||||
if (action instanceof ZoomAction) {
|
||||
deleteZoomAction(iterator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void undo() {
|
||||
List<PlaybackAction> actions = getPageActions();
|
||||
|
||||
actions.clear();
|
||||
actions.addAll(savedActions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void redo() throws RecordingEditException {
|
||||
execute();
|
||||
}
|
||||
|
||||
private List<PlaybackAction> getPageActions() {
|
||||
RecordedEvents lecturePages = getRecordedObject();
|
||||
RecordedPage recordedPage = lecturePages.getRecordedPage(pageNumber);
|
||||
|
||||
return recordedPage.getPlaybackActions();
|
||||
}
|
||||
|
||||
private void deleteAction(PlaybackAction action,
|
||||
ListIterator<PlaybackAction> iterator) {
|
||||
while (iterator.hasNext()) {
|
||||
var iterAction = iterator.next();
|
||||
var actionType = iterAction.getType();
|
||||
|
||||
if (!iterAction.equals(action)
|
||||
&& iterAction.hasHandle()
|
||||
&& action.hasHandle()
|
||||
&& iterAction.getHandle() != action.getHandle()) {
|
||||
// End the deletion, if and only if both actions contain handles,
|
||||
// which do not match.
|
||||
break;
|
||||
}
|
||||
|
||||
iterator.remove();
|
||||
|
||||
if (actionType == ActionType.TOOL_END || actionType == ActionType.ZOOM_OUT) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteZoomAction(ListIterator<PlaybackAction> iterator) {
|
||||
while (iterator.hasNext()) {
|
||||
var action = iterator.next();
|
||||
var actionType = action.getType();
|
||||
|
||||
switch (actionType) {
|
||||
case ZOOM -> {
|
||||
// Ran into a separate zoom action, keep it intact.
|
||||
return;
|
||||
}
|
||||
case ZOOM_OUT -> {
|
||||
// Done here removing connected actions.
|
||||
iterator.remove();
|
||||
return;
|
||||
}
|
||||
case PANNING -> {
|
||||
// Remove pan action belonging to the zoomed state action.
|
||||
iterator.remove();
|
||||
deleteAction(action, iterator);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
package org.lecturestudio.editor.api.edit;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.lecturestudio.core.model.Interval;
|
||||
|
@ -54,14 +53,7 @@ public class DeletePageActions extends RecordingAction {
|
|||
List<PlaybackAction> actions, int pageNumber) {
|
||||
RecordedEvents lectureEvents = recording.getRecordedEvents();
|
||||
|
||||
List<EditAction> deletions = new ArrayList<>();
|
||||
|
||||
for (var action : actions) {
|
||||
deletions.add(new DeleteEventAction(lectureEvents, action,
|
||||
pageNumber));
|
||||
}
|
||||
|
||||
return deletions;
|
||||
return List.of(new DeleteCompositeEventsAction(lectureEvents, actions, pageNumber));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (C) 2020 TU Darmstadt, Department of Computer Science,
|
||||
* Embedded Systems and Applications Group.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.lecturestudio.editor.api.presenter;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.lecturestudio.core.app.ApplicationContext;
|
||||
import org.lecturestudio.core.presenter.Presenter;
|
||||
import org.lecturestudio.editor.api.config.DefaultConfiguration;
|
||||
import org.lecturestudio.editor.api.config.EditorConfiguration;
|
||||
import org.lecturestudio.editor.api.view.ActionsSettingsView;
|
||||
|
||||
public class ActionsSettingsPresenter extends Presenter<ActionsSettingsView> {
|
||||
|
||||
@Inject
|
||||
ActionsSettingsPresenter(ApplicationContext context, ActionsSettingsView view) {
|
||||
super(context, view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() throws IOException {
|
||||
EditorConfiguration config = (EditorConfiguration) context.getConfiguration();
|
||||
|
||||
view.bindUniteThreshold(config.actionsUniteThresholdProperty());
|
||||
view.setOnReset(this::reset);
|
||||
}
|
||||
|
||||
private void reset() {
|
||||
EditorConfiguration config = (EditorConfiguration) context.getConfiguration();
|
||||
DefaultConfiguration defaultConfig = new DefaultConfiguration();
|
||||
|
||||
config.setActionsUniteThreshold(defaultConfig.getActionsUniteThreshold());
|
||||
}
|
||||
}
|
|
@ -45,6 +45,7 @@ import org.lecturestudio.core.recording.action.ActionType;
|
|||
import org.lecturestudio.core.recording.action.PlaybackAction;
|
||||
import org.lecturestudio.core.recording.edit.EditAction;
|
||||
import org.lecturestudio.core.service.DocumentService;
|
||||
import org.lecturestudio.editor.api.config.EditorConfiguration;
|
||||
import org.lecturestudio.editor.api.context.EditorContext;
|
||||
import org.lecturestudio.editor.api.edit.DeletePageActions;
|
||||
import org.lecturestudio.editor.api.service.RecordingFileService;
|
||||
|
@ -176,6 +177,11 @@ public class PageEventsPresenter extends Presenter<PageEventsView> {
|
|||
PlaybackAction previousAction = null;
|
||||
Integer previousEndTs = null;
|
||||
|
||||
EditorConfiguration config = (EditorConfiguration) context.getConfiguration();
|
||||
int uniteThreshold = config.getActionsUniteThreshold();
|
||||
// Fail-safe if the value is not configured and/or is not present.
|
||||
uniteThreshold = uniteThreshold == 0 ? Integer.MIN_VALUE : uniteThreshold;
|
||||
|
||||
for (var action : recordedPage.getPlaybackActions()) {
|
||||
ActionType actionType = action.getType();
|
||||
|
||||
|
@ -200,7 +206,7 @@ public class PageEventsPresenter extends Presenter<PageEventsView> {
|
|||
|| !previousAction.hasHandle()
|
||||
|| action.getHandle() != previousAction.getHandle()) {
|
||||
if (nonNull(previousAction) && nonNull(previousEndTs)
|
||||
&& Math.abs(action.getTimestamp() - previousEndTs) < -1000
|
||||
&& Math.abs(action.getTimestamp() - previousEndTs) < uniteThreshold
|
||||
&& action.getClass().equals(previousAction.getClass())) {
|
||||
// This is a composite action.
|
||||
PageEvent initEvent = eventList.get(eventList.size() - 1);
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (C) 2020 TU Darmstadt, Department of Computer Science,
|
||||
* Embedded Systems and Applications Group.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.lecturestudio.editor.api.view;
|
||||
|
||||
import org.lecturestudio.core.beans.IntegerProperty;
|
||||
|
||||
public interface ActionsSettingsView extends SettingsBaseView {
|
||||
|
||||
void bindUniteThreshold(IntegerProperty property);
|
||||
|
||||
}
|
|
@ -26,10 +26,10 @@ import javafx.scene.control.TableCell;
|
|||
import javafx.scene.control.TableColumn;
|
||||
import javafx.util.Callback;
|
||||
|
||||
import org.lecturestudio.core.recording.action.ActionType;
|
||||
import org.lecturestudio.editor.api.view.model.PageEvent;
|
||||
import org.lecturestudio.javafx.control.SvgIcon;
|
||||
|
||||
public class EventTypeCellFactory implements Callback<TableColumn<Object, ActionType>, TableCell<Object, ActionType>> {
|
||||
public class EventTypeCellFactory implements Callback<TableColumn<Object, PageEvent>, TableCell<Object, PageEvent>> {
|
||||
|
||||
private final ResourceBundle resources;
|
||||
|
||||
|
@ -40,20 +40,20 @@ public class EventTypeCellFactory implements Callback<TableColumn<Object, Action
|
|||
}
|
||||
|
||||
@Override
|
||||
public TableCell<Object, ActionType> call(TableColumn<Object, ActionType> param) {
|
||||
public TableCell<Object, PageEvent> call(TableColumn<Object, PageEvent> param) {
|
||||
return new EventTypeCell();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private class EventTypeCell extends TableCell<Object, ActionType> {
|
||||
private class EventTypeCell extends TableCell<Object, PageEvent> {
|
||||
|
||||
@Override
|
||||
protected void updateItem(ActionType item, boolean empty) {
|
||||
protected void updateItem(PageEvent item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
|
||||
if (!empty) {
|
||||
String typeName = item.toString().toLowerCase();
|
||||
String typeName = item.getActionType().toString().toLowerCase();
|
||||
String eventName = "page.events." + typeName.replace("_", ".");
|
||||
String iconName = typeName.replace("_", "-") + "-icon";
|
||||
|
||||
|
@ -61,7 +61,14 @@ public class EventTypeCellFactory implements Callback<TableColumn<Object, Action
|
|||
SvgIcon icon = new SvgIcon();
|
||||
icon.getStyleClass().add(iconName);
|
||||
|
||||
setText(resources.getString(eventName));
|
||||
int compositeCount = item.getCompositeActions().size();
|
||||
if (compositeCount > 1) {
|
||||
setText(resources.getString(eventName) + String.format(" (%d)", compositeCount));
|
||||
}
|
||||
else {
|
||||
setText(resources.getString(eventName));
|
||||
}
|
||||
|
||||
setGraphic(icon);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (C) 2020 TU Darmstadt, Department of Computer Science,
|
||||
* Embedded Systems and Applications Group.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.lecturestudio.editor.javafx.factory;
|
||||
|
||||
import javafx.beans.property.ReadOnlyObjectWrapper;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.util.Callback;
|
||||
|
||||
import org.lecturestudio.editor.api.view.model.PageEvent;
|
||||
|
||||
public class EventTypeCellValueFactory implements Callback<TableColumn.CellDataFeatures<PageEvent, PageEvent>, ObservableValue<PageEvent>> {
|
||||
|
||||
@Override
|
||||
public ObservableValue<PageEvent> call(TableColumn.CellDataFeatures<PageEvent, PageEvent> pageEventStringCellDataFeatures) {
|
||||
return new ReadOnlyObjectWrapper<>(pageEventStringCellDataFeatures.getValue());
|
||||
}
|
||||
|
||||
}
|
|
@ -43,55 +43,8 @@ import org.lecturestudio.core.view.ProgressDialogView;
|
|||
import org.lecturestudio.core.view.ProgressView;
|
||||
import org.lecturestudio.core.view.TextBoxView;
|
||||
import org.lecturestudio.core.view.ViewContextFactory;
|
||||
import org.lecturestudio.editor.api.view.AudioEffectsView;
|
||||
import org.lecturestudio.editor.api.view.GeneralSettingsView;
|
||||
import org.lecturestudio.editor.api.view.ImportRecordingView;
|
||||
import org.lecturestudio.editor.api.view.LoudnessNormalizeView;
|
||||
import org.lecturestudio.editor.api.view.MainView;
|
||||
import org.lecturestudio.editor.api.view.MediaControlsView;
|
||||
import org.lecturestudio.editor.api.view.MediaTrackControlsView;
|
||||
import org.lecturestudio.editor.api.view.MediaTracksView;
|
||||
import org.lecturestudio.editor.api.view.MenuView;
|
||||
import org.lecturestudio.editor.api.view.NoiseReductionProgressView;
|
||||
import org.lecturestudio.editor.api.view.NoiseReductionSettingsView;
|
||||
import org.lecturestudio.editor.api.view.PageEventsView;
|
||||
import org.lecturestudio.editor.api.view.QuitSaveRecordingView;
|
||||
import org.lecturestudio.editor.api.view.ReplacePageView;
|
||||
import org.lecturestudio.editor.api.view.SettingsView;
|
||||
import org.lecturestudio.editor.api.view.SlidesView;
|
||||
import org.lecturestudio.editor.api.view.SoundSettingsView;
|
||||
import org.lecturestudio.editor.api.view.SplitRecordingView;
|
||||
import org.lecturestudio.editor.api.view.StartView;
|
||||
import org.lecturestudio.editor.api.view.ToolbarView;
|
||||
import org.lecturestudio.editor.api.view.VideoExportProgressView;
|
||||
import org.lecturestudio.editor.api.view.VideoExportSettingsView;
|
||||
import org.lecturestudio.editor.api.view.VideoExportView;
|
||||
import org.lecturestudio.editor.api.view.VideoSettingsView;
|
||||
import org.lecturestudio.editor.javafx.view.FxAboutView;
|
||||
import org.lecturestudio.editor.javafx.view.FxAudioEffectsView;
|
||||
import org.lecturestudio.editor.javafx.view.FxGeneralSettingsView;
|
||||
import org.lecturestudio.editor.javafx.view.FxImportRecordingView;
|
||||
import org.lecturestudio.editor.javafx.view.FxLoudnessNormalizeView;
|
||||
import org.lecturestudio.editor.javafx.view.FxMainView;
|
||||
import org.lecturestudio.editor.javafx.view.FxMediaControlsView;
|
||||
import org.lecturestudio.editor.javafx.view.FxMediaTrackControlsView;
|
||||
import org.lecturestudio.editor.javafx.view.FxMediaTracksView;
|
||||
import org.lecturestudio.editor.javafx.view.FxMenuView;
|
||||
import org.lecturestudio.editor.javafx.view.FxNoiseReductionProgressView;
|
||||
import org.lecturestudio.editor.javafx.view.FxNoiseReductionSettingsView;
|
||||
import org.lecturestudio.editor.javafx.view.FxPageEventsView;
|
||||
import org.lecturestudio.editor.javafx.view.FxQuitSaveRecordingView;
|
||||
import org.lecturestudio.editor.javafx.view.FxReplacePageView;
|
||||
import org.lecturestudio.editor.javafx.view.FxSettingsView;
|
||||
import org.lecturestudio.editor.javafx.view.FxSlidesView;
|
||||
import org.lecturestudio.editor.javafx.view.FxSoundSettingsView;
|
||||
import org.lecturestudio.editor.javafx.view.FxSplitRecordingView;
|
||||
import org.lecturestudio.editor.javafx.view.FxStartView;
|
||||
import org.lecturestudio.editor.javafx.view.FxToolbarView;
|
||||
import org.lecturestudio.editor.javafx.view.FxVideoExportProgressView;
|
||||
import org.lecturestudio.editor.javafx.view.FxVideoExportSettingsView;
|
||||
import org.lecturestudio.editor.javafx.view.FxVideoExportView;
|
||||
import org.lecturestudio.editor.javafx.view.FxVideoSettingsView;
|
||||
import org.lecturestudio.editor.api.view.*;
|
||||
import org.lecturestudio.editor.javafx.view.*;
|
||||
import org.lecturestudio.javafx.control.TextBox;
|
||||
import org.lecturestudio.javafx.guice.FxmlViewLoader;
|
||||
import org.lecturestudio.javafx.guice.FxmlViewMatcher;
|
||||
|
@ -128,6 +81,7 @@ public class ViewModule extends AbstractModule {
|
|||
bind(NotificationPopupManager.class).to(FxNotificationPopupManager.class);
|
||||
|
||||
bind(AboutView.class).to(FxAboutView.class);
|
||||
bind(ActionsSettingsView.class).to(FxActionsSettingsView.class);
|
||||
bind(AudioEffectsView.class).to(FxAudioEffectsView.class);
|
||||
bind(GeneralSettingsView.class).to(FxGeneralSettingsView.class);
|
||||
bind(ImportRecordingView.class).to(FxImportRecordingView.class);
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (C) 2020 TU Darmstadt, Department of Computer Science,
|
||||
* Embedded Systems and Applications Group.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.lecturestudio.editor.javafx.view;
|
||||
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.util.converter.NumberStringConverter;
|
||||
|
||||
import org.lecturestudio.core.beans.IntegerProperty;
|
||||
import org.lecturestudio.core.view.Action;
|
||||
import org.lecturestudio.editor.api.view.ActionsSettingsView;
|
||||
import org.lecturestudio.javafx.beans.LectIntegerProperty;
|
||||
import org.lecturestudio.javafx.util.FxUtils;
|
||||
import org.lecturestudio.javafx.view.FxmlView;
|
||||
|
||||
@FxmlView(name = "actions-settings", presenter = org.lecturestudio.editor.api.presenter.ActionsSettingsPresenter.class)
|
||||
public class FxActionsSettingsView extends GridPane implements ActionsSettingsView {
|
||||
|
||||
@FXML
|
||||
private ResourceBundle resources;
|
||||
|
||||
@FXML
|
||||
private TextField uniteThresholdField;
|
||||
|
||||
@FXML
|
||||
private Button closeButton;
|
||||
|
||||
@FXML
|
||||
private Button resetButton;
|
||||
|
||||
|
||||
public FxActionsSettingsView() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOnClose(Action action) {
|
||||
FxUtils.bindAction(closeButton, action);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOnReset(Action action) {
|
||||
FxUtils.bindAction(resetButton, action);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindUniteThreshold(IntegerProperty property) {
|
||||
uniteThresholdField.textProperty().bindBidirectional(new LectIntegerProperty(property),
|
||||
new NumberStringConverter());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
.actions-settings {
|
||||
-fx-hgap: 10;
|
||||
-fx-padding: 2em;
|
||||
}
|
||||
.actions-settings > .label {
|
||||
-fx-padding: 0 0 0.425em 0;
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.*?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import org.lecturestudio.javafx.util.TextIntegerFormatter?>
|
||||
|
||||
<fx:root styleClass="actions-settings" type="GridPane" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="ALWAYS" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints />
|
||||
<RowConstraints />
|
||||
<RowConstraints vgrow="ALWAYS" />
|
||||
</rowConstraints>
|
||||
|
||||
<Label text="%actions.settings.unite.threshold" />
|
||||
<HBox alignment="CENTER_LEFT" spacing="5.0" GridPane.rowIndex="1" GridPane.hgrow="NEVER">
|
||||
<TextField fx:id="uniteThresholdField" prefColumnCount="5" maxWidth="-Infinity">
|
||||
<GridPane.margin>
|
||||
<Insets />
|
||||
</GridPane.margin>
|
||||
<textFormatter>
|
||||
<TextIntegerFormatter />
|
||||
</textFormatter>
|
||||
</TextField>
|
||||
<Label text="%actions.settings.unite.threshold.ms" />
|
||||
</HBox>
|
||||
|
||||
<HBox alignment="BOTTOM_RIGHT" spacing="5" GridPane.rowIndex="2">
|
||||
<Button fx:id="resetButton" text="%button.reset" />
|
||||
<Button fx:id="closeButton" text="%button.close" />
|
||||
</HBox>
|
||||
</fx:root>
|
|
@ -0,0 +1,2 @@
|
|||
actions.settings.unite.threshold = Schwellwert in Millisekunden für das Zusammenf\u00fchren von Annotationen
|
||||
actions.settings.unite.threshold.ms = ms
|
|
@ -0,0 +1,2 @@
|
|||
actions.settings.unite.threshold = Threshold value in milliseconds for merging annotations
|
||||
actions.settings.unite.threshold.ms = ms
|
|
@ -60,6 +60,9 @@
|
|||
* *
|
||||
******************************************************************************/
|
||||
|
||||
.settings-actions-icon {
|
||||
-fx-icon-content: "M992 896q13 0 22.5 9.25t9.5 22.75q0 12-8.5 22-15 17.5-34.5 31.25t-41.5 23.25-45.5 14.5-46 5q-49.5 0-91.5-19.25t-76-54.75q-24.5-25.5-54.5-39.75t-66-14.25q-35 0-65.75 14.25t-54.75 39.75l-4.75 4.5-11.5 11.25-14.75 14.75-15.25 15-12.5 12.5-6.25 6.5q-9.5 9.5-22.5 9.5t-22.5-9.5-9.5-22.5 9.5-22.5q27-27 51-52t50-44 57-30.25 72.5-11.25q49.5 0 91.5 19.25t76 54.75q24.5 25.5 54.5 39.75t66 14.25q38 0 66-14.25t54.5-39.75q5.5-5 10.75-7.5t12.75-2.5zm-374.5-751q7 4 11.5 11.5t4.5 16q0 4-1 7.5t-2.5 7l-353.5 707.5q-4.5 9.5-14 14l-86.5 43.5q-16 8-34.5 8h-4.75l-4.75-.5-23.5 47q-4 8-11.75 12.75t-16.75 4.75q-13 0-22.5-9.5t-9.5-22.5q0-6 3.5-15t8.25-18.75 9.75-18.25 7.5-14q-13-20-13-43.5v-82.5q0-8 3.5-14.5l288-576-32.5-16-118.5 237q-4 8-11.75 12.75t-16.75 4.75q-13 0-22.5-9.5t-9.5-22.5q0-6.5 3.5-14.5l119.5-239q8-16 21.5-25.25t31.5-9.25q17.5 0 33.25 8.5t30.75 16l35.5-71q4-8.5 11.75-13t16.75-4.5q6.5 0 11 2 6-12 11.75-23.75t13-21.25 17.75-15.25 26.5-5.75 30.5 7.5l47 23.5q16 8 25.25 21.25t9.25 31.75q0 17-7.75 31.75t-14.75 29.25zm-101-50.5l43.5 21.5 14.5-29-43.5-21.5zm42 92.5l-96-48-334.5 668.5v75q0 5.5 4 9.5t9.5 4q2 0 8.25-2.5t14.5-6.5 17.5-8.75 17.75-9.25 15-8 9.5-5z";
|
||||
}
|
||||
.settings-general-icon {
|
||||
-fx-icon-content: "M32,376h283.35c6.186-14.112,20.281-24,36.65-24s30.465,9.888,36.65,24H480v32h-91.35c-6.186,14.112-20.281,24-36.65,24 s-30.465-9.888-36.65-24H32 M32,240h91.35c6.186-14.112,20.281-24,36.65-24s30.465,9.888,36.65,24H480v32H196.65c-6.186,14.112-20.281,24-36.65,24 s-30.465-9.888-36.65-24H32 M32,104h283.35c6.186-14.112,20.281-24,36.65-24s30.465,9.888,36.65,24H480v32h-91.35c-6.186,14.112-20.281,24-36.65,24 s-30.465-9.888-36.65-24H32";
|
||||
}
|
||||
|
|
|
@ -11,6 +11,12 @@
|
|||
<SvgIcon styleClass="settings-general-icon" />
|
||||
</graphic>
|
||||
</Tab>
|
||||
<Tab id="actions" text="%settings.actions">
|
||||
<FxActionsSettingsView />
|
||||
<graphic>
|
||||
<SvgIcon styleClass="settings-actions-icon" />
|
||||
</graphic>
|
||||
</Tab>
|
||||
<Tab id="video" text="%settings.sound">
|
||||
<FxSoundSettingsView />
|
||||
<graphic>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
settings.actions = Annotationen
|
||||
settings.general = Allgemein
|
||||
settings.sound = Sound
|
||||
settings.video = Video
|
|
@ -1,3 +1,4 @@
|
|||
settings.actions = Annotations
|
||||
settings.general = General
|
||||
settings.sound = Sound
|
||||
settings.video = Video
|
|
@ -27,7 +27,7 @@
|
|||
<EventTypeCellFactory />
|
||||
</cellFactory>
|
||||
<cellValueFactory>
|
||||
<PropertyValueFactory property="actionType"/>
|
||||
<EventTypeCellValueFactory />
|
||||
</cellValueFactory>
|
||||
</TableColumn>
|
||||
<TableColumn text="%page.events.time">
|
||||
|
|
Loading…
Reference in a new issue