Hecho algún cambio en clases del modelo y dejado anotaciones sobre cosas para…

Hecho algún cambio en clases del modelo y dejado anotaciones sobre cosas para aclarar. Hay que hablar del sistema de calidad y perfiles
parent 7f744b7b
......@@ -2,16 +2,17 @@ import 'dart:io';
import 'convertible.dart';
import 'formato.dart';
class Archivo extends Convertible{
// TODO: QUE PASA SI NO RECONOCEMOS EL FORMATO?
class Archivo extends Convertible {
final File _file;
List<String> metadatos = [];
File get file => _file;
Archivo({required String id, required File file}):
Archivo({required super.id, required File file}):
_file = file,
super(id: id,
nombre: file.path.split('/').last,
formatoOriginal: ClaseFormato.fromExtension(file.path.split('/').last.split('.').last),
icon: ClaseFormato.fromExtension(file.path.split('/').last.split('.').last).tipoMultimedia.icono);
super(nombre: file.path.split('/').last,
// TODO: POR AHORA USAMOS (!) PERO HAY QUE TENERLO EN CUENTA
formatoOriginal: Formato.fromExtension(file.path.split('.').last)!,
icon: Formato.fromExtension(file.path.split('.').last)!.tipoMultimedia.icono);
}
\ No newline at end of file
......@@ -7,15 +7,15 @@ import 'formato.dart';
class Carpeta extends ElementoSeleccionable{
final Directory _directory;
bool _incluirSubcarpetas = false;
final bool _incluirSubcarpetas = false;
final List<InfoFormato> _formatos;
Directory get directory => _directory;
List<InfoFormato> get formatos => List.unmodifiable(_formatos);
Carpeta({required String id, required Directory directory}):
Carpeta({required super.id, required Directory directory}):
_directory = directory, _formatos = [],
super(id: id, nombre: directory.path.split('/').last, icon: const Icon(Icons.folder_outlined));
super(nombre: directory.path.split('/').last, icon: const Icon(Icons.folder_outlined));
@override
void convertir() {
......@@ -32,20 +32,20 @@ class InfoFormato {
bool get subcarpeta => _subcarpeta;
bool get seleccionado => _seleccionado;
Convertible get conversion => _conversion;
ClaseFormato get formatoOriginal => _conversion.formatoOriginal;
Formato get formatoOriginal => _conversion.formatoOriginal;
Formato? get formatoDestino => _conversion.formatoDestino;
List<Archivo> get archivos => List.unmodifiable(_archivos);
set seleccionado(bool value) => _seleccionado = value;
set formato(Formato? destino) => _conversion.formatoDestino = destino;
InfoFormato({required ClaseFormato formato,
InfoFormato({required Formato formato,
required String nombreCarpeta,
required bool subCarpeta,
bool? seleccionado,
required List<File> archivos}):
_subcarpeta = subCarpeta, _seleccionado = seleccionado ?? !subCarpeta, _archivos = archivos,
_conversion = Convertible(id: "null", nombre: '${nombreCarpeta} > ${formato.name}',
_conversion = Convertible(id: "null", nombre: '$nombreCarpeta > ${formato.name}',
icon: Icon(Icons.find_in_page_outlined), formatoOriginal: formato);
void convertir(){
......
import 'elemento_seleccionable.dart';
import 'formato.dart';
// TODO: QUE PASA SI NO RECONOCEMOS EL FORMATO?
class Convertible extends ElementoSeleccionable{
final ClaseFormato _formatoOriginal;
Formato? _formatoDestino;
final Formato _formatoOriginal;
Formato? formatoDestino;
ClaseFormato get formatoOriginal => _formatoOriginal;
Formato? get formatoDestino => _formatoDestino;
set formatoDestino(Formato? siguiente) => _formatoDestino = siguiente;
Formato get formatoOriginal => _formatoOriginal;
Convertible({required super.id, required super.nombre, required super.icon,
required ClaseFormato formatoOriginal, Formato? formatoDestino = null}):
_formatoOriginal = formatoOriginal,
_formatoDestino = formatoDestino;
required Formato formatoOriginal, this.formatoDestino}):
_formatoOriginal = formatoOriginal;
@override
void convertir(){
// TODO: <implement>
}
......
......@@ -5,11 +5,11 @@ abstract class ElementoSeleccionable{
final String _nombre;
final Icon _icono;
String get id => this._id;
String get nombre => this._nombre;
Icon get icono => this._icono;
String get id => _id;
String get nombre => _nombre;
Icon get icono => _icono;
ElementoSeleccionable({required String id,
ElementoSeleccionable({required id,
required String nombre,
required Icon icon}):
_id = id, _nombre = nombre, _icono = icon;
......
......@@ -2,17 +2,18 @@ import 'package:flutter/material.dart';
import 'convertible.dart';
import 'formato.dart';
// TODO: QUE PASA SI NO RECONOCEMOS EL FORMATO?
class Enlace extends Convertible{
final String _direccion;
final RedSocial _redSocial;
List<String> metadatos = [];
Enlace({required String id, required String direccion}):
Enlace({required String super.id, required String direccion}):
_direccion = direccion,
_redSocial = RedSocial.FACEBOOK,
super(id: id,
nombre: direccion.split('/').last,
formatoOriginal: ClaseFormato.fromExtension('png'),
super(nombre: direccion.split('/').last,
// TODO: POR AHORA USAMOS (!) PERO HAY QUE TENERLO EN CUENTA
formatoOriginal: Formato.fromExtension('png')!,
icon: Icon(Icons.insert_drive_file_outlined));
@override
......
import 'package:flutter/material.dart';
class Formato{
final ClaseFormato _extension;
Calidad _calidad;
ClaseFormato get claseFormato => _extension;
Calidad get calidad => _calidad;
set calidad(Calidad calidad) => _calidad = calidad;
bool get isVideo => _extension.tipoMultimedia == TipoMultimedia.VIDEO;
Formato({required ClaseFormato extension, Calidad calidad = Calidad.Media}):
_extension = extension, _calidad = calidad;
Formato copiaSiNulo({ClaseFormato? formato, Calidad? calidad}){
return Formato(
extension: formato ?? this.claseFormato,
calidad: calidad ?? this._calidad
);
}
}
enum ClaseFormato{
PNG('png',
'Portable Network Graphics',
TipoMultimedia.IMAGEN,
'Calidad',
[],
'Formato gráfico basado en un algoritmo de compresión sin pérdida para bitmaps no sujeto a patentes. Fue desarrollado en buena parte para solventar las deficiencias del formato GIF y permite almacenar imágenes con una mayor profundidad de contraste y otros datos importantes.'
// TODO: AÑADIR CALIDAD
enum Formato {
png('Portable Network Graphics', TipoMultimedia.imagen, Clasificacion.calidad, [],
'ClaseFormato gráfico basado en un algoritmo de compresión sin pérdida para bitmaps no sujeto a patentes. Fue desarrollado en buena parte para solventar las deficiencias del formato GIF y permite almacenar imágenes con una mayor profundidad de contraste y otros datos importantes.'
),
JPG('jpg',
'Joint Photographic Experts Group',
TipoMultimedia.IMAGEN,
'Ligero',
[],
jpg('Joint Photographic Experts Group', TipoMultimedia.imagen, Clasificacion.ligero, [],
'A pesar de ser un método de compresión, es a menudo considerado como un formato de archivo. Es el formato de imagen más común, utilizado por las cámaras fotográficas digitales y otros dispositivos de captura de imagen'
),
TIF('tif',
'Tagged Image File Format',
TipoMultimedia.IMAGEN,
'Calidad',
[],
tif('Tagged Image File Format', TipoMultimedia.imagen, Clasificacion.calidad, [],
'Un formato de archivo informático para almacenar imágenes de mapa de bits. Es prevalente en la industria gráfica y en la fotografía profesional por su versatilidad y compresión no destructiva.'
),
MP3('mp3',
'MPEG-1 Layer III',
TipoMultimedia.AUDIO,
'Calidad',
[ Metadato('Título', 'title'),
Metadato('Artista', 'artist'),
Metadato('Álbum', 'album'),
Metadato('Género', 'genre'),
Metadato('Compositor', 'composer'),
Metadato('Número de pista', 'track', true),
Metadato('Idioma', 'language')],
mp3('MPEG-1 Layer III', TipoMultimedia.audio, Clasificacion.calidad,
[ Metadato.title, Metadato.artist, Metadato.album, Metadato.genre,
Metadato.composer, Metadato.track, Metadato.language],
'Un formato de compresión de audio digital que usa un algoritmo con pérdida para conseguir un menor tamaño de archivo. Es un formato de audio común utilizado para música tanto en computadoras como en reproductores de audio portátil.'
),
OGG('ogg',
'Xiph.org Ogg',
TipoMultimedia.AUDIO,
'Versátil',
[],
ogg('Xiph.org Ogg', TipoMultimedia.audio, Clasificacion.versatil, [],
'Un formato contenedor libre y abierto, desarrollado y mantenido por la Fundación Xiph.Org que no está restringido por las patentes de software, y está diseñado para proporcionar una difusión de flujo eficiente y manipulación de multimedios digitales de alta calidad.'
),
WAV('wav',
'Waveform Audio File Format',
TipoMultimedia.AUDIO,
'Calidad',
[],
wav('Waveform Audio File Format', TipoMultimedia.audio, Clasificacion.calidad, [],
'Un formato de audio digital con o sin compresión de datos desarrollado por Microsoft e IBM que se utiliza para almacenar flujos digitales de audio en el PC, mono y estéreo a diversas resoluciones y velocidades de muestreo.'
),
MP4('mp4',
'MPEG-4 Parte 14',
TipoMultimedia.VIDEO,
'Calidad',
[ Metadato('Título', 'title'),
Metadato('Autor', 'author'),
Metadato('Álbum', 'album'),
Metadato('Año', 'year', true),
Metadato('Género', 'genre'),
Metadato('Compositor', 'composer'),
Metadato('Número de pista', 'track', true),
Metadato('Descripción', 'description'),
Metadato('Comentario', 'comment')],
mp4('MPEG-4 Parte 14', TipoMultimedia.video, Clasificacion.calidad,
[ Metadato.title, Metadato.author, Metadato.album, Metadato.year,
Metadato.genre, Metadato.composer, Metadato.track,
Metadato.description, Metadato.comment],
'Un formato contenedor especificado como parte del estándar internacional MPEG-4 de ISO/IEC. Es utilizado para almacenar los formatos audiovisuales especificados por ISO/IEC y el grupo MPEG (Moving Picture Experts Group) al igual que otros formatos audiovisuales disponibles.'
),
MKV('mkv',
'Matroshka',
TipoMultimedia.VIDEO,
'Calidad',
[ Metadato('Título', 'title'),
Metadato('Descripción', 'description'),
Metadato('Idioma', 'language')],
mkv('Matroshka', TipoMultimedia.video, Clasificacion.calidad,
[ Metadato.title, Metadato.description, Metadato.language ],
'Un formato contenedor abierto que puede almacenar una cantidad muy grande de vídeo, audio, imagen o pistas de subtítulos dentro de un solo archivo. Su finalidad es la de servir como formato universal para el almacenamiento de contenidos audiovisuales y multimedia, como películas o programas de televisión, imágenes y textos.'
),
WMV('wmv',
'Windows Media Video',
TipoMultimedia.VIDEO,
'Calidad',
[ Metadato('Título', 'title'),
Metadato('Autor', 'author'),
Metadato('Valoración', 'rating'),
Metadato('Comentario', 'comment')],
wmv('Windows Media Video', TipoMultimedia.video, Clasificacion.calidad,
[ Metadato.title, Metadato.author, Metadato.rating, Metadato.comment ],
'Un formato de vídeo desarrollado por Microsoft, que forma parte del framework Windows Media. No está contruida solo con tecnología interna de Microsoft. Desde la versión 7 (WMV1), Microsoft ha utilizado su propia versión no estandarizada de MPEG-4. El vídeo a menudo se combina con sonido en formato Windows Media Audio.'
);
final String _extension;
final String _nombre;
final String _nombreCompleto;
final TipoMultimedia _tipoMultimedia;
final String _descripcion;
final String _clasificacion;
final Clasificacion _clasificacion;
final List<Metadato> _metadatos;
String get extension => _extension;
String get nombre => _nombre;
String get descripcion => _descripcion;
final String _descripcion;
String get extension => name;
String get nombre => _nombreCompleto;
Clasificacion get clasificacion => _clasificacion;
TipoMultimedia get tipoMultimedia => _tipoMultimedia;
List<Metadato> get metadatos => _metadatos;
String get descripcion => _descripcion;
const ClaseFormato(this._extension, this._nombre, this._tipoMultimedia, this._clasificacion, this._metadatos, this._descripcion);
static List<ClaseFormato> listadoFormatos({required TipoMultimedia tipo, ClaseFormato? excepcion}){
final toRet = <ClaseFormato>[];
const Formato(this._nombreCompleto, this._tipoMultimedia, this._clasificacion,
this._metadatos, this._descripcion);
for(var formato in ClaseFormato.values){
/// Devuelve aquellos formatos de TipoMultimedia que no sean excepcion
static List<Formato> listadoFormatos({required TipoMultimedia tipo, Formato? excepcion}){
final toRet = <Formato>[];
for(var formato in Formato.values){
if(formato._tipoMultimedia == tipo && formato != excepcion) {
toRet.add(formato);
}
}
return toRet;
}
static ClaseFormato fromExtension(String extension){
for(ClaseFormato f in ClaseFormato.values){
if(f._extension == extension){
/// Si la extensión no es valida devuelve nulo
static Formato? fromExtension(String extension){
for(Formato f in Formato.values) {
if(f.name == extension){
return f;
}
}
return ClaseFormato.PNG;
return null;
}
}
enum TipoMultimedia{
VIDEO(Icon(Icons.movie_creation_outlined)),
AUDIO(Icon(Icons.music_note_outlined)),
IMAGEN(Icon(Icons.image_outlined));
enum TipoMultimedia {
video(Icon(Icons.movie_creation_outlined)),
audio(Icon(Icons.music_note_outlined)),
imagen(Icon(Icons.image_outlined));
final Icon icono;
const TipoMultimedia(this.icono);
}
enum Calidad{
Baja,
Media,
Alta,
Muy_alta;
enum Clasificacion {
calidad("Calidad"), ligero("Ligero"), versatil("Versátil");
final String nombre;
const Clasificacion(this.nombre);
}
class Metadato{
enum Calidad {
baja("Baja"), media("Media"), alta("Alta"), muyAlta("Muy Alta");
final String texto;
const Calidad(this.texto);
}
enum Metadato {
title("Título"),
artist("Artista"),
author("Autor"),
album("Álbum"),
genre("Género"),
composer("Compositor"),
track("Número de pista", true),
language("Idioma"),
year("Año", true),
description("Descripción"),
comment("Comentario"),
rating("Valoración", true);
final String _nombreMostrado;
final String _nombreInterno;
final bool _numerico;
final bool _esNumerico;
String get nombreMostrado => _nombreMostrado;
String get nombreInterno => _nombreInterno;
bool get numerico => _numerico;
bool get numerico => _esNumerico;
const Metadato(String nombreMostrado, String nombreInterno, [bool numerico = false]):
_nombreMostrado = nombreMostrado, _nombreInterno = nombreInterno, _numerico = numerico;
const Metadato(this._nombreMostrado, [this._esNumerico = false]);
}
\ No newline at end of file
import 'formato.dart';
enum Perfil {
IMAGEN_ALTA_CALIDAD('Alta calidad', ClaseFormato.PNG, ClaseFormato.WAV, ClaseFormato.MKV ,Calidad.Muy_alta),
IMAGEN_COMPARTIR('Para compartir', ClaseFormato.JPG, ClaseFormato.MP3, ClaseFormato.MP4, Calidad.Baja);
IMAGEN_ALTA_CALIDAD('Alta calidad', Formato.png, Formato.wav, Formato.mkv, Calidad.muyAlta),
IMAGEN_COMPARTIR('Para compartir', Formato.jpg, Formato.mp3, Formato.mp4, Calidad.baja);
final String nombre;
final ClaseFormato? extensionImagen;
final ClaseFormato? extensionMusica;
final ClaseFormato? extensionVideo;
final Formato? extensionImagen;
final Formato? extensionMusica;
final Formato? extensionVideo;
final Calidad calidad;
const Perfil(this.nombre, this.extensionImagen, this.extensionMusica,
......
......@@ -68,7 +68,7 @@ class _PaginaConfiguracionState extends State<PaginaConfiguracion> {
return PaginaMetadatos(formato: arch.formatoOriginal);
}
else{
if(arch.formatoOriginal.tipoMultimedia == TipoMultimedia.VIDEO){
if(arch.formatoOriginal.tipoMultimedia == TipoMultimedia.video){
return PaginaFotograma();
}
// Página de metadatos
......@@ -79,19 +79,19 @@ class _PaginaConfiguracionState extends State<PaginaConfiguracion> {
// Páginas de carpetas y formato de archivo para carpeta
// TODO: Carpeta de ejemplo, cargar carpetas de verdad
return PaginaConfiguracionCarpeta(formatosCarpeta: [
InfoFormato(formato: ClaseFormato.JPG,
InfoFormato(formato: Formato.jpg,
nombreCarpeta: widget._elementoAsociado.nombre,
subCarpeta: false,
archivos: []),
InfoFormato(formato: ClaseFormato.MP4,
InfoFormato(formato: Formato.mp4,
nombreCarpeta: widget._elementoAsociado.nombre,
subCarpeta: false,
archivos: []),
InfoFormato(formato: ClaseFormato.TIF,
InfoFormato(formato: Formato.tif,
nombreCarpeta: widget._elementoAsociado.nombre,
subCarpeta: true,
archivos: []),
InfoFormato(formato: ClaseFormato.PNG,
InfoFormato(formato: Formato.png,
nombreCarpeta: widget._elementoAsociado.nombre,
subCarpeta: true,
archivos: [])
......@@ -118,7 +118,7 @@ class _PaginaConfiguracionState extends State<PaginaConfiguracion> {
bool isVideo = false;
if(widget._elementoAsociado is Archivo){
final arch = widget._elementoAsociado as Archivo;
if(arch.formatoOriginal.tipoMultimedia == TipoMultimedia.VIDEO){
if(arch.formatoOriginal.tipoMultimedia == TipoMultimedia.video){
isVideo = true;
}
}
......
......@@ -13,9 +13,9 @@ class PaginaConfiguracionCarpeta extends StatefulWidget {
}
class _PaginaConfiguracionCarpetaState extends State<PaginaConfiguracionCarpeta> {
final Map<TipoMultimedia, List<ClaseFormato>> _formatos = {};
final Map<TipoMultimedia, List<Formato>> _formatos = {};
final Map<TipoMultimedia, bool?> _allOfType = {};
final Map<ClaseFormato, bool> _seleccionados = {};
final Map<Formato, bool> _seleccionados = {};
late bool _incluirSubcarpetas;
@override
......@@ -99,9 +99,9 @@ class _PaginaConfiguracionCarpetaState extends State<PaginaConfiguracionCarpeta>
Widget _buildCheckboxTodos(BuildContext context){
const Map<TipoMultimedia, String> textos = {
TipoMultimedia.IMAGEN : 'Todas las imágenes',
TipoMultimedia.AUDIO : 'Todos los audios',
TipoMultimedia.VIDEO : 'Todos los vídeos'
TipoMultimedia.imagen : 'Todas las imágenes',
TipoMultimedia.audio : 'Todos los audios',
TipoMultimedia.video : 'Todos los vídeos'
};
final lista = <Widget>[];
......@@ -204,8 +204,11 @@ class _PaginaConfiguracionCarpetaState extends State<PaginaConfiguracionCarpeta>
],
);
if(i.subcarpeta) listaSubcarpeta.add(fila);
else listaCarpeta.add(fila);
if(i.subcarpeta) {
listaSubcarpeta.add(fila);
} else {
listaCarpeta.add(fila);
}
}
return Padding(
......
......@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:prueba_multimedia/modelo/modelo.dart';
class PaginaConversion extends StatefulWidget {
final ClaseFormato _formatoOriginal;
final Formato _formatoOriginal;
const PaginaConversion({
super.key,
......@@ -15,11 +15,13 @@ class PaginaConversion extends StatefulWidget {
class _PaginaConversionState extends State<PaginaConversion>
with SingleTickerProviderStateMixin {
// Podríamos hacer que en vez de poder haber nulos sea el mismo formato
// que el de origen de manera predeterminada ?
Formato? _formatoConvertido;
Calidad calidadActual = Calidad.media;
bool _showProfiles = true;
late final _tabController;
int _tabElegida = 0;
late final TabController _tabController;
@override
void initState() {
......@@ -82,12 +84,10 @@ class _PaginaConversionState extends State<PaginaConversion>
_createConversionFormatBox() {
final String nombreFormato;
if(_formatoConvertido == null){
nombreFormato = ' ';
}
else{
nombreFormato = _formatoConvertido!.claseFormato.name.toUpperCase();
} else {
nombreFormato = _formatoConvertido!.name.toUpperCase();
}
return DecoratedBox(
......@@ -109,18 +109,22 @@ class _PaginaConversionState extends State<PaginaConversion>
);
}
// TODO: A QUÉ SE REFIERE LA CALIDAD ?
/*
Un formato puede tener una calidad predeterminada?
De que sirve cambiar la calidad de un formato?
Hay formatos lossless para los que no hay ajustes de calidad/compresión
*/
// TODO: IMPLEMENTAR SISTEMA CALIDAD FORMATOS
/// Comportamiento temporal: Mostrar todas las calidades
Widget _createCalidadSelectionPanel() {
final listaChips = Calidad.values.map((elemento) {
return ChoiceChip(
selected: (_formatoConvertido != null)? _formatoConvertido!.calidad == elemento : false,
selected: elemento == calidadActual,
shape: StadiumBorder(),
label: Text(
elemento.name.replaceAll(RegExp(r'_'), ' ')
),
onSelected: (_formatoConvertido == null)? null : (selection) {
setState(() { if(_formatoConvertido != null) _formatoConvertido!.calidad = elemento; });
},
label: Text(elemento.texto),
// TODO: CAMBIAR CALIDAD FORMATO
onSelected: (selected) { setState((){calidadActual = elemento;}); },
);
}).toList();
......@@ -131,7 +135,7 @@ class _PaginaConversionState extends State<PaginaConversion>
'Calidad:',
style: Theme.of(context).textTheme.titleSmall
),
SizedBox(height: 8.0),
const SizedBox(height: 8.0),
Wrap(
spacing: 10.0,
children: listaChips,
......@@ -141,7 +145,7 @@ class _PaginaConversionState extends State<PaginaConversion>
}
Widget _createConversionSelectionPanel(){
if(widget._formatoOriginal.tipoMultimedia == TipoMultimedia.VIDEO && !_showProfiles){
if(widget._formatoOriginal.tipoMultimedia == TipoMultimedia.video && !_showProfiles){
return _createTabVideos();
}
else{
......@@ -171,7 +175,7 @@ class _PaginaConversionState extends State<PaginaConversion>
child: Column(
children: [
_createBotonesPerfilFormato(),
Container(
SizedBox(
height: MediaQuery.of(context).size.height - 460,
child: Padding(
padding: const EdgeInsets.only(top: 16.0),
......@@ -213,52 +217,40 @@ class _PaginaConversionState extends State<PaginaConversion>
child: Column(
children: [
_createBotonesPerfilFormato(),
Container(
SizedBox(
height: 68,
child: TabBar(
controller: _tabController,
tabs: <Widget>[
Tab(
icon: TipoMultimedia.VIDEO.icono,
icon: TipoMultimedia.video.icono,
text: 'Vídeo',
),
Tab(
icon: TipoMultimedia.AUDIO.icono,
icon: TipoMultimedia.audio.icono,
text: 'Audio',
),
Tab(
icon: TipoMultimedia.IMAGEN.icono,
icon: TipoMultimedia.imagen.icono,
text: 'Imagen',
)
]
),
),
Container(
SizedBox(
height: MediaQuery.of(context).size.height - 528,
child: Padding(
padding: const EdgeInsets.only(top: 16.0),
child: TabBarView(
controller: _tabController,
children: [
GridView.count(
children: TipoMultimedia.values.map((tipo) {
return GridView.count(
crossAxisCount: 3,
crossAxisSpacing: 12,
mainAxisSpacing: 12,
children: _createGridBotonesConversion(tipo: TipoMultimedia.VIDEO)
),
GridView.count(
crossAxisCount: 3,
crossAxisSpacing: 12,
mainAxisSpacing: 12,
children: _createGridBotonesConversion(tipo: TipoMultimedia.AUDIO)
),
GridView.count(
crossAxisCount: 3,
crossAxisSpacing: 12,
mainAxisSpacing: 12,
children: _createGridBotonesConversion(tipo: TipoMultimedia.IMAGEN)
),
]
children: _createGridBotonesConversion(tipo: tipo)
);
}).toList()
),
),
),
......@@ -318,31 +310,57 @@ class _PaginaConversionState extends State<PaginaConversion>
);
}
// TODO: HABLAR SOBRE CÓMO HACER LOS PERFILES
List<Widget> _createListPerfiles(){
final toRet = <Widget>[];
for(Perfil elemento in Perfil.values){
ClaseFormato? extension = elemento.extensionImagen;
if(widget._formatoOriginal.tipoMultimedia == TipoMultimedia.VIDEO){
extension = elemento.extensionVideo;
for(Perfil perfil in Perfil.values){
// Averigua de que formato y tipo multimedia es el perfil
Formato? formatoPerfil = perfil.extensionImagen;
if(widget._formatoOriginal.tipoMultimedia == TipoMultimedia.video){
formatoPerfil = perfil.extensionVideo;
}
if(widget._formatoOriginal.tipoMultimedia == TipoMultimedia.AUDIO){
extension = elemento.extensionMusica;
if(widget._formatoOriginal.tipoMultimedia == TipoMultimedia.audio){
formatoPerfil = perfil.extensionMusica;
}
//
if(extension != null && extension != widget._formatoOriginal){
if(formatoPerfil != null && formatoPerfil != widget._formatoOriginal){
/**
* Entiendo que si el archivo ya se encuentra en un formato que
* es el mismo que se usa para un cierto perfil entonces ese perfil
* esté desabilitado, pero podría llegar a ser confuso ya que no
* se especifica por ningún sitio al usuario el por qué esa opción
* no está disponible.
*
* Además, no se como compaginar esto con que cada formato pueda
* tener un nivel de calidad diferente, porque podríamos tener
* hipotéticamente un formato como jpg (que es de baja calidad) pero con
* un valor de calidad alto
*
* En aplicaciones como gimp por ejemplo se puede especificar el nivel
* de compresión (inverso a la calidad) de formatos como jpg
bool desabilitado = (_formatoConvertido == formatoPerfil) &&
(_formatoConvertido?.calidad == perfil.calidad);
**/
toRet.add(Material(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
color: (_formatoConvertido?.claseFormato == extension &&
_formatoConvertido?.calidad == elemento.calidad)?
Theme.of(context).disabledColor : Theme.of(context).cardColor,
// TODO: ANALIZAR SI DESABILITAR PERFILES O NO
// color: desabilitado ? Theme.of(context).disabledColor : Theme.of(context).cardColor,
color: Theme.of(context).cardColor,
child: InkWell(
onTap: () {
setState(() {
_formatoConvertido = Formato(extension: extension!, calidad: elemento.calidad);
});
if (_formatoConvertido != formatoPerfil) {
setState(() {
// TODO: IMPLEMENTAR SISTEMA CALIDAD FORMATOS
// _formatoConvertido = Formato(formato: formatoPerfil!, calidad: perfil.calidad);
_formatoConvertido = formatoPerfil;
});
}
},
child: Container(
decoration: BoxDecoration(
......@@ -353,7 +371,7 @@ class _PaginaConversionState extends State<PaginaConversion>
),
child: Center(
child: Text(
elemento.nombre,
perfil.nombre,
style: Theme.of(context).textTheme.headlineMedium,
),
),
......@@ -368,7 +386,7 @@ class _PaginaConversionState extends State<PaginaConversion>
List<Widget> _createGridBotonesConversion({TipoMultimedia? tipo}){
tipo ??= widget._formatoOriginal.tipoMultimedia;
final listaFormatos = ClaseFormato.listadoFormatos(
final listaFormatos = Formato.listadoFormatos(
tipo: tipo,
excepcion: widget._formatoOriginal
);
......@@ -378,21 +396,16 @@ class _PaginaConversionState extends State<PaginaConversion>
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
color: (_formatoConvertido?.claseFormato == elemento)?
Theme.of(context).disabledColor : Theme.of(context).cardColor,
color: _formatoConvertido == elemento ? Theme.of(context).disabledColor
: Theme.of(context).cardColor,
child: InkWell(
onTap: (_formatoConvertido?.claseFormato == elemento)? () {
/*
TODO: COMPORTAMIENTO DE LOS BOTONES
onTap: _formatoConvertido == elemento ? () {
setState(() { _formatoConvertido = null; });
} : () {
setState(() {
if(_formatoConvertido == null){
_formatoConvertido = Formato(extension: elemento, calidad: Calidad.Media);
}
else{
_formatoConvertido = _formatoConvertido!.copiaSiNulo(formato: elemento);
}
});
},
} :
*/
onTap: () { setState((){_formatoConvertido = elemento;}); },
onLongPress: () {
showDialog<void>(
context: context,
......@@ -421,11 +434,11 @@ class _PaginaConversionState extends State<PaginaConversion>
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
elemento.name,
elemento.name.toUpperCase(),
style: Theme.of(context).textTheme.titleLarge,
textScaler: TextScaler.linear(1.5),
),
Container(
const SizedBox(
height: 15.0,
child: Icon(Icons.airplanemode_active),
)
......
......@@ -10,7 +10,7 @@ class PaginaFotograma extends StatefulWidget {
class _PaginaFotogramaState extends State<PaginaFotograma> {
int _fotogramaSeleccionado = 0;
int _ultimoFotograma = 1200;
final int _ultimoFotograma = 1200;
final _buttons = _IconButtons.values;
Timer? timer;
......
......@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:prueba_multimedia/modelo/modelo.dart';
class PaginaMetadatos extends StatefulWidget {
final ClaseFormato _formato;
final Formato _formato;
const PaginaMetadatos({super.key, required formato}): _formato = formato;
......@@ -54,7 +54,7 @@ class _PaginaMetadatosState extends State<PaginaMetadatos> {
@override
Widget build(BuildContext context) {
if(_metadatos.length > 0){
if(_metadatos.isNotEmpty){
return SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(15.0),
......
......@@ -5,7 +5,7 @@ class ActionButton extends StatelessWidget {
final VoidCallback? onPressed;
ActionButton({super.key, required this.tipoBoton, required this.onPressed});
const ActionButton({super.key, required this.tipoBoton, required this.onPressed});
@override
Widget build(BuildContext context) {
......
......@@ -76,7 +76,7 @@ class ExpandableFabState extends State<ExpandableFab>
@override
Widget build(BuildContext context) {
return Container(
return SizedBox(
width: _computeWidth(),
height: _open? 56 + (widget.distance*widget.children.length) : 56,
child: SizedBox.expand(
......@@ -198,7 +198,6 @@ class _ExpandingActionButton extends StatelessWidget {
final Widget child;
const _ExpandingActionButton({
super.key,
this.invert = false,
required this.directionInDegrees,
required this.maxDistance,
......
......@@ -5,8 +5,10 @@
import FlutterMacOS
import Foundation
import ffmpeg_kit_flutter
import file_picker
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FFmpegKitFlutterPlugin.register(with: registry.registrar(forPlugin: "FFmpegKitFlutterPlugin"))
FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin"))
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment