mirror of
https://codeberg.org/unspeaker/tek.git
synced 2026-09-18 04:46:43 +02:00
This commit is contained in:
parent
f57ca9af84
commit
f743d9fb4d
7 changed files with 104 additions and 98 deletions
|
|
@ -610,7 +610,7 @@ impl Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_view (&self, name: impl AsRef<str>) -> Option<Arc<View<Tui, App>>> {
|
pub fn get_view (&self, name: impl AsRef<str>) -> Option<Arc<View<Tui, App>>> {
|
||||||
self.views.try_read().unwrap().get(name.as_ref()).cloned()
|
self.views.try_read().map(|views|views.get(name.as_ref()).cloned()).flatten()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ impl HasClipsSize for Arrangement {
|
||||||
impl<T: TracksView + ScenesView + Send + Sync> ClipsView for T {}
|
impl<T: TracksView + ScenesView + Send + Sync> ClipsView for T {}
|
||||||
|
|
||||||
pub trait ClipsView: TracksView + ScenesView {
|
pub trait ClipsView: TracksView + ScenesView {
|
||||||
|
|
||||||
/// Draw clips per scene
|
/// Draw clips per scene
|
||||||
fn view_scenes_clips (&self) -> impl Draw<Tui> {
|
fn view_scenes_clips (&self) -> impl Draw<Tui> {
|
||||||
let select = self.selection();
|
let select = self.selection();
|
||||||
|
|
@ -73,10 +74,10 @@ pub trait ClipsView: TracksView + ScenesView {
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.full_h()
|
|
||||||
.exact_w(track.width as u16))
|
.exact_w(track.width as u16))
|
||||||
)).align_c()
|
)).align_c()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn view_scene_name_theme (scene: &Scene, track_index: usize) -> (Arc<str>, ItemTheme) {
|
fn view_scene_name_theme (scene: &Scene, track_index: usize) -> (Arc<str>, ItemTheme) {
|
||||||
|
|
@ -89,12 +90,10 @@ fn view_scene_name_theme (scene: &Scene, track_index: usize) -> (Arc<str>, ItemT
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_clips_size (show: bool, size: &Sizer, content: impl Draw<Tui>) -> impl Draw<Tui> {
|
fn with_clips_size (show: bool, size: &Sizer, content: impl Draw<Tui>) -> impl Draw<Tui> {
|
||||||
size.of(above(
|
above(
|
||||||
when(show, fg(Green, east!(
|
when(show, fg(Green, east!(size.w() as usize, "x", size.h() as usize)).align_se()),
|
||||||
size.w() as usize, "x", size.h() as usize
|
size.of(content.align_c().full_wh())
|
||||||
)).align_se()),
|
)
|
||||||
content.align_c().full_wh()
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn view_scene_bg (
|
fn view_scene_bg (
|
||||||
|
|
|
||||||
|
|
@ -304,7 +304,7 @@ pub fn view_scene_name <'a> (
|
||||||
} else {
|
} else {
|
||||||
scene.color.base.term
|
scene.color.base.term
|
||||||
};
|
};
|
||||||
bg(c, south(a, b).align_nw()).exact_wh(20, h)
|
bg(c, south(a, b).align_nw().exact_h(h))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait HasSceneScroll: HasScenes {
|
pub trait HasSceneScroll: HasScenes {
|
||||||
|
|
|
||||||
|
|
@ -369,26 +369,16 @@ pub trait TracksView: HasTracks + ScenesView + HasMidiIns + HasMidiOuts + HasTra
|
||||||
|
|
||||||
/// Draw name of each track
|
/// Draw name of each track
|
||||||
fn view_track_names (&self, theme: ItemTheme) -> impl Draw<Tui> {
|
fn view_track_names (&self, theme: ItemTheme) -> impl Draw<Tui> {
|
||||||
let selected = self.selection();
|
let btn1t = self.view_track_count();
|
||||||
let btn1t = button_3("t", "rack ", east(
|
let btn1s = self.view_scene_count();
|
||||||
selected.track().map(|track|east(track, "/")),
|
|
||||||
self.tracks().len()
|
|
||||||
), false);
|
|
||||||
let btn1s = button_3("s", "cene ", east(
|
|
||||||
selected.scene().map(|scene|east(scene, "/")),
|
|
||||||
self.scenes().len()
|
|
||||||
), false);
|
|
||||||
let btns1 = south(btn1t, btn1s);
|
let btns1 = south(btn1t, btn1s);
|
||||||
let btns2 = south(
|
let btns2 = south(self.view_track_add(), self.view_scene_add());
|
||||||
button_2("T", "+", false),
|
|
||||||
button_2("S", "+", false),
|
|
||||||
);
|
|
||||||
view_track_row_section(theme,
|
view_track_row_section(theme,
|
||||||
btns1,
|
btns1,
|
||||||
btns2,
|
btns2,
|
||||||
bg(theme.darker.term,
|
bg(theme.darker.term,
|
||||||
iter_east(||self.tracks_with_sizes().map(|(index, track, _x1, _x2)|{
|
iter_east(||self.tracks_with_sizes().map(|(index, track, _x1, _x2)|{
|
||||||
let b = if selected.track() == Some(index) {
|
let b = if self.selection().track() == Some(index) {
|
||||||
track.color.light.term
|
track.color.light.term
|
||||||
} else {
|
} else {
|
||||||
track.color.base.term
|
track.color.base.term
|
||||||
|
|
@ -409,20 +399,6 @@ pub trait TracksView: HasTracks + ScenesView + HasMidiIns + HasMidiOuts + HasTra
|
||||||
}))))
|
}))))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn view_track_output_count (&self) -> impl Draw<Tui> {
|
|
||||||
south(button_2("o", "utput", false).align_w().full_w(),
|
|
||||||
draw(|to: &mut Tui|{
|
|
||||||
for port in self.midi_outs().iter() {
|
|
||||||
let _ = port.port_name().align_w().full_w().draw(to)?;
|
|
||||||
}
|
|
||||||
Ok(Some(XYWH(0, 0, 0, 0)))
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn view_track_output_add (&self) -> impl Draw<Tui> {
|
|
||||||
button_2("O", "+", false)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Draw outputs per track
|
/// Draw outputs per track
|
||||||
fn view_track_outputs <'a> (&'a self, theme: ItemTheme, _h: u16) -> impl Draw<Tui> {
|
fn view_track_outputs <'a> (&'a self, theme: ItemTheme, _h: u16) -> impl Draw<Tui> {
|
||||||
view_track_row_section(theme,
|
view_track_row_section(theme,
|
||||||
|
|
@ -441,14 +417,6 @@ pub trait TracksView: HasTracks + ScenesView + HasMidiIns + HasMidiOuts + HasTra
|
||||||
}))))
|
}))))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn view_track_input_count (&self) -> impl Draw<Tui> {
|
|
||||||
button_2("i", "nput", false)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn view_track_input_add (&self) -> impl Draw<Tui> {
|
|
||||||
button_2("I", "+", false)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Draw inputs per track
|
/// Draw inputs per track
|
||||||
fn view_track_inputs <'a> (&'a self, theme: ItemTheme) -> impl Draw<Tui> {
|
fn view_track_inputs <'a> (&'a self, theme: ItemTheme) -> impl Draw<Tui> {
|
||||||
let mut height = 0u16;
|
let mut height = 0u16;
|
||||||
|
|
@ -479,8 +447,8 @@ pub trait TracksView: HasTracks + ScenesView + HasMidiIns + HasMidiOuts + HasTra
|
||||||
|
|
||||||
fn view_track_devices (&self, theme: ItemTheme) -> impl Draw<Tui> {
|
fn view_track_devices (&self, theme: ItemTheme) -> impl Draw<Tui> {
|
||||||
let height = self.tracks_devices_height();
|
let height = self.tracks_devices_height();
|
||||||
let btn1 = button_3("d", "evice", self.track().map(|t|t.devices.len()).unwrap_or(0), false);
|
let btn1 = button_3("d", "evice", self.track().map(|t|t.devices.len()).unwrap_or(0), false).min_h(2);
|
||||||
let btn2 = button_2("D", "+", false);
|
let btn2 = self.view_track_device_add();
|
||||||
view_track_row_section(theme, btn1, btn2, iter_east(move||self.tracks_with_sizes()
|
view_track_row_section(theme, btn1, btn2, iter_east(move||self.tracks_with_sizes()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(move|(index, (_, track, _x1, _x2))|bg(
|
.map(move|(index, (_, track, _x1, _x2))|bg(
|
||||||
|
|
@ -508,7 +476,7 @@ pub trait TracksView: HasTracks + ScenesView + HasMidiIns + HasMidiOuts + HasTra
|
||||||
|
|
||||||
fn view_inputs (&self, _theme: ItemTheme) -> impl Draw<Tui> + '_ {
|
fn view_inputs (&self, _theme: ItemTheme) -> impl Draw<Tui> + '_ {
|
||||||
let title_1 = button_3("i", "nput ", self.midi_ins().len(), false).align_w().exact_wh(20, 1);
|
let title_1 = button_3("i", "nput ", self.midi_ins().len(), false).align_w().exact_wh(20, 1);
|
||||||
let title_2 = button_2("I", "+", false).exact_wh(4, 1);
|
let title_2 = self.view_track_input_add().exact_wh(4, 1);
|
||||||
east(title_1, west(title_2, draw(move|to: &mut Tui|{
|
east(title_1, west(title_2, draw(move|to: &mut Tui|{
|
||||||
for (_index, track, x1, _x2) in self.tracks_with_sizes() {
|
for (_index, track, x1, _x2) in self.tracks_with_sizes() {
|
||||||
let _ = south(
|
let _ = south(
|
||||||
|
|
@ -553,10 +521,8 @@ pub trait TracksView: HasTracks + ScenesView + HasMidiIns + HasMidiOuts + HasTra
|
||||||
fn view_outputs (&self, theme: ItemTheme) -> impl Draw<Tui> {
|
fn view_outputs (&self, theme: ItemTheme) -> impl Draw<Tui> {
|
||||||
let height = self.outputs_height();
|
let height = self.outputs_height();
|
||||||
let list = south(
|
let list = south(
|
||||||
button_3(
|
button_3("o", "utput", self.midi_outs().len(), false).align_w().full_w().exact_h(1),
|
||||||
"o", "utput", self.midi_outs().len(), false
|
bg(Color::Rgb(0, 0, 0), draw(|to: &mut Tui|{
|
||||||
).align_w().full_w().exact_h(1),
|
|
||||||
draw(|to: &mut Tui|{
|
|
||||||
for (_index, port) in self.midi_outs().iter().enumerate() {
|
for (_index, port) in self.midi_outs().iter().enumerate() {
|
||||||
east(
|
east(
|
||||||
east(
|
east(
|
||||||
|
|
@ -578,9 +544,9 @@ pub trait TracksView: HasTracks + ScenesView + HasMidiIns + HasMidiOuts + HasTra
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
todo!();
|
todo!();
|
||||||
}).align_nw().full_wh().exact_h(height - 1)
|
})).align_nw().full_wh().exact_h(height - 1).min_h(1)
|
||||||
);
|
);
|
||||||
view_track_row_section(theme, list, button_2("O", "+", false),
|
view_track_row_section(theme, list, self.view_track_output_add(),
|
||||||
bg(theme.darker.term, draw(|to: &mut Tui|{
|
bg(theme.darker.term, draw(|to: &mut Tui|{
|
||||||
for (index, track, _x1, _x2) in self.tracks_with_sizes() {
|
for (index, track, _x1, _x2) in self.tracks_with_sizes() {
|
||||||
let _ = draw(|to: &mut Tui|{
|
let _ = draw(|to: &mut Tui|{
|
||||||
|
|
@ -604,6 +570,54 @@ pub trait TracksView: HasTracks + ScenesView + HasMidiIns + HasMidiOuts + HasTra
|
||||||
}).align_w().full_w())).exact_h(height)
|
}).align_w().full_w())).exact_h(height)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn view_track_count (&self) -> impl Draw<Tui> {
|
||||||
|
button_3("t", "rack ", east(
|
||||||
|
self.selection().track().map(|track|east(track, "/")),
|
||||||
|
self.tracks().len()
|
||||||
|
), false)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn view_scene_count (&self) -> impl Draw<Tui> {
|
||||||
|
button_3("s", "cene ", east(
|
||||||
|
self.selection().scene().map(|scene|east(scene, "/")),
|
||||||
|
self.scenes().len()
|
||||||
|
), false)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn view_track_add (&self) -> impl Draw<Tui> {
|
||||||
|
button_2("T", "+", false)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn view_scene_add (&self) -> impl Draw<Tui> {
|
||||||
|
button_2("S", "+", false)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn view_track_input_count (&self) -> impl Draw<Tui> {
|
||||||
|
button_2("i", "nput", false)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn view_track_output_count (&self) -> impl Draw<Tui> {
|
||||||
|
button_3("o", "utput", 0, false)
|
||||||
|
//draw(|to: &mut Tui|{
|
||||||
|
//for port in self.midi_outs().iter() {
|
||||||
|
//let _ = port.port_name().align_w().full_w().draw(to)?;
|
||||||
|
//}
|
||||||
|
//Ok(Some(XYWH(0, 0, 0, 0)))
|
||||||
|
//})),
|
||||||
|
}
|
||||||
|
|
||||||
|
fn view_track_output_add (&self) -> impl Draw<Tui> {
|
||||||
|
button_2("O", "+", false)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn view_track_input_add (&self) -> impl Draw<Tui> {
|
||||||
|
button_2("I", "+", false)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn view_track_device_add (&self) -> impl Draw<Tui> {
|
||||||
|
button_2("D", "+", false)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait HasTrackScroll {
|
pub trait HasTrackScroll {
|
||||||
|
|
@ -654,10 +668,14 @@ fn view_track_row_section <'a> (
|
||||||
button_add: impl Draw<Tui>,
|
button_add: impl Draw<Tui>,
|
||||||
content: impl Draw<Tui>,
|
content: impl Draw<Tui>,
|
||||||
) -> impl Draw<Tui> {
|
) -> impl Draw<Tui> {
|
||||||
west(
|
bar(
|
||||||
button_add.align_nw().exact_w(4).full_h(),
|
Split::West,
|
||||||
east(
|
4u16,
|
||||||
button.align_nw().full_h().exact_w(16),
|
button_add.align_ne().full_wh(),
|
||||||
|
bar(
|
||||||
|
Split::East,
|
||||||
|
20u16,
|
||||||
|
button.full_wh().align_nw(),
|
||||||
content.align_c().full_wh()
|
content.align_c().full_wh()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -4,30 +4,17 @@ pub fn draw_dialog <'a, I: Debug + Iterator<Item = &'a str>> (to: &mut Tui, mut
|
||||||
-> Drawn<u16>
|
-> Drawn<u16>
|
||||||
{
|
{
|
||||||
match frags.next() {
|
match frags.next() {
|
||||||
|
|
||||||
Some("menu") => if let Dialog::Menu(selected, items) = &state.dialog {
|
Some("menu") => if let Dialog::Menu(selected, items) = &state.dialog {
|
||||||
//Some(iter_south(move||items.0.iter().enumerate().map(move|(index, MenuItem(item, _))|{
|
|
||||||
//let f = if *selected == index { Rgb(240,200,180) } else { Rgb(200, 200, 200) };
|
|
||||||
//let b = if *selected == index { Rgb(80, 80, 50) } else { Rgb(30, 30, 30) };
|
|
||||||
//fg_bg(f, b, item.full_w().align_x().exact_h(2)).push_y(index as u16 * 4)
|
|
||||||
//})).full_wh())
|
|
||||||
//let items = items.clone();
|
|
||||||
//let selected = selected;
|
|
||||||
//Some(draw(move|to: &mut Tui|{
|
|
||||||
//for (index, MenuItem(item, _)) in items.0.iter().enumerate() {
|
|
||||||
//let f = if *selected == index { Rgb(240,200,180) } else { Rgb(200, 200, 200) };
|
|
||||||
//let b = if *selected == index { Rgb(80, 80, 50) } else { Rgb(30, 30, 30) };
|
|
||||||
//fg_bg(f, b, item.exact_h(2).full_w().align_x()).draw(to)?;
|
|
||||||
//}
|
|
||||||
//Ok(Some(to.area().into()))
|
|
||||||
//}))
|
|
||||||
Some(iter_south(move||items.0.iter().enumerate().map(move|(index, MenuItem(item, _))|{
|
Some(iter_south(move||items.0.iter().enumerate().map(move|(index, MenuItem(item, _))|{
|
||||||
let f = if *selected == index { Rgb(240,200,180) } else { Rgb(200, 200, 200) };
|
let f = if *selected == index { Rgb(240,200,180) } else { Rgb(200, 200, 200) };
|
||||||
let b = if *selected == index { Rgb(80, 80, 50) } else { Rgb(30, 30, 30) };
|
let b = if *selected == index { Rgb(80, 80, 50) } else { Rgb(30, 30, 30) };
|
||||||
fg_bg(f, b, item).align_x()//.exact_wh(20, 3)//.exact_wh(20, 3).align_x()//.push_y(index as u16 * 4).
|
fg_bg(f, b, item).exact_h(2).align_x()
|
||||||
})).exact_w(20).align_x())
|
})).exact_w(20).align_x())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}.draw(to),
|
}.draw(to),
|
||||||
|
|
||||||
_ => unimplemented!("draw_dialog: ({frags:?})"),
|
_ => unimplemented!("draw_dialog: ({frags:?})"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -119,20 +106,20 @@ impl Dialog {
|
||||||
pub fn welcome () -> Self {
|
pub fn welcome () -> Self {
|
||||||
Self::Menu(1, MenuItems([
|
Self::Menu(1, MenuItems([
|
||||||
|
|
||||||
MenuItem(" Resume session \n".into(), Arc::new(Box::new(|_app|{
|
MenuItem(" Resume session ".into(), Arc::new(Box::new(|_app|{
|
||||||
Ok(())
|
Ok(())
|
||||||
}))),
|
}))),
|
||||||
|
|
||||||
MenuItem(" Create session \n".into(), Arc::new(Box::new(|app|Ok({
|
MenuItem(" Create session ".into(), Arc::new(Box::new(|app|Ok({
|
||||||
app.dialog = Dialog::None;
|
app.dialog = Dialog::None;
|
||||||
app.mode = Some(":arranger".into());
|
app.mode = Some(":arranger".into());
|
||||||
})))),
|
})))),
|
||||||
|
|
||||||
MenuItem(" Load session \n".into(), Arc::new(Box::new(|_|{
|
MenuItem(" Load session ".into(), Arc::new(Box::new(|_|{
|
||||||
Ok(())
|
Ok(())
|
||||||
}))),
|
}))),
|
||||||
|
|
||||||
MenuItem(" Exit \n".into(), Arc::new(Box::new(|app|Ok({
|
MenuItem(" Exit ".into(), Arc::new(Box::new(|app|Ok({
|
||||||
app.exit.exit();
|
app.exit.exit();
|
||||||
println!("Exited cleanly.")
|
println!("Exited cleanly.")
|
||||||
})))),
|
})))),
|
||||||
|
|
|
||||||
30
src/tek.edn
30
src/tek.edn
|
|
@ -1,4 +1,4 @@
|
||||||
(view :logo (text tek))
|
(view :logo (text tek ))
|
||||||
|
|
||||||
(view :browse (bsp/s
|
(view :browse (bsp/s
|
||||||
(pad/xy 3 1 :browse-title)
|
(pad/xy 3 1 :browse-title)
|
||||||
|
|
@ -10,10 +10,15 @@
|
||||||
(keys :clock :global)
|
(keys :clock :global)
|
||||||
:transport)
|
:transport)
|
||||||
|
|
||||||
(mode :menu (name Menu) (info Mode selector.) (keys :axis/y :confirm)
|
(mode :menu
|
||||||
(view (bsp/s
|
(name Menu)
|
||||||
(align/s (bsp/e :ports/out (bsp/e :transport :ports/in)))
|
(info Mode selector.)
|
||||||
(align/c (bsp/s (align/x (bg (g 36) :logo)) (bg (g 24) :dialog/menu))))))
|
(keys :axis/y :confirm)
|
||||||
|
(view
|
||||||
|
(bar/n 2 (bsp/e :transport :status)
|
||||||
|
(align/c
|
||||||
|
(bar/s 2 (align/x (bg (g 12) :logo))
|
||||||
|
:dialog/menu)))))
|
||||||
|
|
||||||
(keys :back (@escape (back)))
|
(keys :back (@escape (back)))
|
||||||
(keys :confirm (@enter (dialog confirm)))
|
(keys :confirm (@enter (dialog confirm)))
|
||||||
|
|
@ -35,23 +40,20 @@
|
||||||
(mode :mix (keys :mix))
|
(mode :mix (keys :mix))
|
||||||
(view
|
(view
|
||||||
(bar/n 2 (bsp/e :transport :status)
|
(bar/n 2 (bsp/e :transport :status)
|
||||||
(bar/w 2 (align/ne :meters/output)
|
|
||||||
(bar/e 2 (align/nw :meters/input)
|
|
||||||
(full/xy (pad/xy 2 1 (align/c
|
|
||||||
(bar/s 2 :tracks/outputs
|
(bar/s 2 :tracks/outputs
|
||||||
(bar/s 2 :tracks/devices
|
(bar/s 2 :tracks/devices
|
||||||
(bar/s 2 :tracks/names
|
(bar/s 2 :tracks/names
|
||||||
(bar/n 2 :tracks/inputs
|
(bar/n 2 :tracks/inputs
|
||||||
(bar/e 12 (bg (g 50) :scenes/names)
|
(bar/e 16 :scenes/names :scenes/clips))))))))
|
||||||
(align/c :scenes/clips))))))))))))))
|
|
||||||
|
|
||||||
(keys :global (see :history :saveload)
|
(keys :global (see :history :saveload)
|
||||||
(@f8 dialog :options)
|
(@f1 (dialog :help))
|
||||||
(@f10 dialog :quit))
|
(@f8 (dialog :options))
|
||||||
|
(@f10 (dialog :quit)))
|
||||||
|
|
||||||
(keys :clock
|
(keys :clock
|
||||||
(@space clock/toggle 0)
|
(@space (clock/toggle 0))
|
||||||
(@shift/space clock/toggle 0))
|
(@shift/space (clock/toggle 0)))
|
||||||
|
|
||||||
(keys :color
|
(keys :color
|
||||||
(@c color))
|
(@c color))
|
||||||
|
|
|
||||||
2
tengri
2
tengri
|
|
@ -1 +1 @@
|
||||||
Subproject commit 48aaa3933aadd2d795b6652a244fce179d7072bf
|
Subproject commit 5272b8ec55e48d135c88cbc840eab530afa1ae73
|
||||||
Loading…
Add table
Add a link
Reference in a new issue