Skip to content

Commit 1a46593

Browse files
committed
feat: Added front and back navigation buttons
1 parent 251e781 commit 1a46593

2 files changed

Lines changed: 145 additions & 32 deletions

File tree

harbor/engine/src/render/mod.rs

Lines changed: 71 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,50 @@ impl ApplicationHandler<AppEvent> for App {
261261
state.address_bar_active = true;
262262
}
263263
} else {
264+
if elem_state == ElementState::Pressed {
265+
let item_pressed = (state.cursor_position.0
266+
/ (address_bar_address_offset.0 / 3.0))
267+
.floor() as usize;
268+
269+
let tab_data = state.tab_datas.get_mut(state.active_tab).unwrap();
270+
271+
match item_pressed {
272+
0 => {
273+
let prev_url = tab_data.prev_urls.pop();
274+
if prev_url.is_none() {
275+
return;
276+
}
277+
278+
let prev_url = prev_url.unwrap();
279+
let curr_url = tab_data.url.clone();
280+
281+
tab_data.next_urls.push(curr_url);
282+
283+
if let Some(callbacks) = &self.callbacks {
284+
(callbacks.link_callback)(&prev_url);
285+
}
286+
}
287+
1 => {
288+
println!("Refresh button pressed");
289+
}
290+
2 => {
291+
let next_url = tab_data.next_urls.pop();
292+
if next_url.is_none() {
293+
return;
294+
}
295+
296+
let next_url = next_url.unwrap();
297+
let curr_url = tab_data.url.clone();
298+
299+
tab_data.prev_urls.push(curr_url);
300+
301+
if let Some(callbacks) = &self.callbacks {
302+
(callbacks.link_callback)(&next_url);
303+
}
304+
}
305+
_ => unreachable!(),
306+
}
307+
}
264308
}
265309
} else {
266310
if let Some(root) = layout.root_box.as_ref() {
@@ -429,42 +473,38 @@ impl ApplicationHandler<AppEvent> for App {
429473
let state = self.state.as_mut().unwrap();
430474
let agent = self.agent.as_ref().unwrap();
431475

432-
if state.tab_datas[state.active_tab].url != url {
433-
state.tab_datas[state.active_tab].url = url.clone();
434-
state.tab_datas[state.active_tab].scroll_x = 0.0;
435-
state.tab_datas[state.active_tab].scroll_y = 0.0;
436-
state.tab_datas[state.active_tab].document = None;
437-
state.tab_datas[state.active_tab].layout = None;
476+
let tab_data = state.tab_datas.get_mut(state.active_tab).unwrap();
477+
478+
if tab_data.url != url {
479+
tab_data.prev_urls.push(tab_data.url.clone());
480+
481+
tab_data.url = url.clone();
482+
tab_data.scroll_x = 0.0;
483+
tab_data.scroll_y = 0.0;
484+
tab_data.document = None;
485+
tab_data.layout = None;
438486
}
439487

440-
self.document = Some(
441-
state.tab_datas[state.active_tab]
442-
.document
443-
.clone()
444-
.unwrap_or_else(|| {
445-
let doc = agent.borrow_mut().open(&url).unwrap();
446-
state.tab_datas[state.active_tab].document = Some(Rc::clone(&doc));
447-
doc
448-
}),
449-
);
488+
self.document = Some(tab_data.document.clone().unwrap_or_else(|| {
489+
let doc = agent.borrow_mut().open(&url).unwrap();
490+
tab_data.document = Some(Rc::clone(&doc));
491+
doc
492+
}));
450493

451-
let layout = state.tab_datas[state.active_tab]
452-
.layout
453-
.clone()
454-
.unwrap_or_else(|| {
455-
let layout = Layout::make_layout(
456-
self.document.as_ref().unwrap().clone(),
457-
(
458-
state.window.inner_size().width as f64,
459-
state.window.inner_size().height as f64,
460-
),
461-
);
494+
let layout = tab_data.layout.clone().unwrap_or_else(|| {
495+
let layout = Layout::make_layout(
496+
self.document.as_ref().unwrap().clone(),
497+
(
498+
state.window.inner_size().width as f64,
499+
state.window.inner_size().height as f64,
500+
),
501+
);
462502

463-
let rc = Rc::new(RefCell::new(layout));
503+
let rc = Rc::new(RefCell::new(layout));
464504

465-
state.tab_datas[state.active_tab].layout = Some(rc.clone());
466-
rc
467-
});
505+
tab_data.layout = Some(rc.clone());
506+
rc
507+
});
468508

469509
state.viewport_height = layout
470510
.borrow()

harbor/engine/src/render/state.rs

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ pub struct TabData {
3131

3232
pub document: Option<Rc<RefCell<Document>>>,
3333
pub layout: Option<Rc<RefCell<Layout>>>,
34+
35+
pub prev_urls: Vec<String>,
36+
pub next_urls: Vec<String>,
3437
}
3538

3639
impl Default for TabData {
@@ -41,6 +44,8 @@ impl Default for TabData {
4144
scroll_y: 0.0,
4245
document: None,
4346
layout: None,
47+
prev_urls: vec![],
48+
next_urls: vec![],
4449
}
4550
}
4651
}
@@ -351,7 +356,75 @@ impl WindowState {
351356
self.address_bar_input.clone(),
352357
);
353358

354-
for (key, instances) in glyph_instances {
359+
let padding = 10.0;
360+
let w = (address_bar_address_offset.0 - 4.0 * padding) / 3.0;
361+
362+
let back_position = (padding, adj_position.1);
363+
let refresh_position = (w + 2.0 * padding, adj_position.1);
364+
let front_position = (2.0 * w + 3.0 * padding, adj_position.1);
365+
366+
let glyph_instances_back = WindowState::get_char_instances(
367+
back_position,
368+
&self.device,
369+
renderer,
370+
address_bar_offset.1 as f32 * 0.5,
371+
TAB_TEXT_COLOR,
372+
String::from("←"),
373+
);
374+
375+
let glyph_instances_refresh = WindowState::get_char_instances(
376+
refresh_position,
377+
&self.device,
378+
renderer,
379+
address_bar_offset.1 as f32 * 0.5,
380+
TAB_TEXT_COLOR,
381+
String::from("R"),
382+
);
383+
384+
let glyph_instances_front = WindowState::get_char_instances(
385+
front_position,
386+
&self.device,
387+
renderer,
388+
address_bar_offset.1 as f32 * 0.5,
389+
TAB_TEXT_COLOR,
390+
String::from("→"),
391+
);
392+
393+
for (key, instances) in glyph_instances
394+
.iter()
395+
.chain(glyph_instances_back.iter())
396+
.chain(glyph_instances_refresh.iter())
397+
.chain(glyph_instances_front.iter())
398+
{
399+
let glyph = renderer.get_from_char(key.0, key.1, &self.device).unwrap();
400+
401+
let instance_buffer =
402+
self.device
403+
.create_buffer_init(&wgpu::util::BufferInitDescriptor {
404+
label: Some("Glyph Instance Buffer"),
405+
contents: bytemuck::cast_slice(&instances),
406+
usage: wgpu::BufferUsages::VERTEX,
407+
});
408+
409+
render_pass.set_pipeline(&self.glyph_stencil_render_pipeline);
410+
render_pass.set_vertex_buffer(0, glyph.fill_vertex_buffer.slice(..));
411+
render_pass.set_vertex_buffer(1, instance_buffer.slice(..));
412+
render_pass.draw(0..glyph.fill_vertex_count, 0..instances.len() as u32);
413+
414+
render_pass.set_pipeline(&self.glyph_fill_render_pipeline);
415+
render_pass.set_stencil_reference(0);
416+
417+
render_pass.set_vertex_buffer(0, glyph.fill_vertex_buffer.slice(..));
418+
render_pass.set_vertex_buffer(1, instance_buffer.slice(..));
419+
render_pass.draw(0..glyph.fill_vertex_count, 0..instances.len() as u32);
420+
}
421+
422+
let merged = glyph_instances_back
423+
.into_iter()
424+
.chain(glyph_instances_refresh)
425+
.chain(glyph_instances_front);
426+
427+
for (key, instances) in merged {
355428
let glyph = renderer.get_from_char(key.0, key.1, &self.device).unwrap();
356429

357430
let instance_buffer =

0 commit comments

Comments
 (0)