Flutter fileimage not appearing in page flip animation widget - pdf
I want to create a book app like google's play book application
my books are in pdf, Im getting them from Firebase storage, then im converting that pdf to image, page by page, its working fine
but when I try to put the file inside the PageFlip widget, it doesn't work as intended... it starts converting pdf to images, all good, then shows blank screen, when I press ctrl+s to refresh, then it does the conversion again, then it works
when I restart the app, again first time shows blank screen, after refresh it works fine
I can swipe through the images and animation works fine on them, but some pages are still blank, they're not rendered as image
for example, im on page 1 I swipe, page 2 (shows fine), again, page 3 (shows fine).... page 22(is blank/not rendered), page 23(shows fine)
the animation is a bit laggy too, not as smooth as playbooks application,
can someone help please?
My code
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:internet_file/internet_file.dart';
import 'package:path_provider/path_provider.dart';
import 'package:pdfx/pdfx.dart';
import 'package:show_up_animation/show_up_animation.dart';
import '../helpers/ui_control.dart';
import '../models/book.dart';
import '../providers/book.dart';
import '../providers/loading.dart';
import '../providers/user.dart';
import '../widgets/featured_book.dart';
import '../widgets/page_flip.dart';
import '../widgets/slide_route.dart';
class BookView extends StatefulWidget {
const BookView({Key? key, required this.book, required this.currentPage})
: super(key: key);
final BookModel book;
final int currentPage;
#override
_BookViewState createState() => _BookViewState();
}
class _BookViewState extends State<BookView> {
late int page;
bool show = true;
Future<List<File>> pdfToImages(Future<PdfDocument> pdf) async {
final pdfDoc = await pdf;
List<File> images = [];
print('converting pdf to image');
for (int i = 1; i <= pdfDoc.pagesCount; i++) {
final tempDir = await getTemporaryDirectory();
File file =
File('${tempDir.path}/${widget.book.id}-${widget.book.title}-$i.png');
if (!file.existsSync()) {
final page = await pdfDoc.getPage(i);
final image = await page.render(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
backgroundColor: "#EFEADD",
);
Uint8List imageInUnit8List = image!.bytes;
file.writeAsBytesSync(imageInUnit8List);
page.close();
}
images.add(file);
}
return images;
}
#override
void initState() {
super.initState();
page = widget.currentPage;
}
void _onTap() {
setState(() {
show = !show;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
body: FutureBuilder<List<File>>(
future: pdfToImages(
PdfDocument.openData(InternetFile.get(widget.book.path))),
builder: (context, snapshot) {
if (snapshot.hasError) {
return Center(child: Text(snapshot.error.toString()));
}
if (!snapshot.hasData) {
return const Center(child: CircularProgressIndicator());
}
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: _onTap,
child: InteractiveViewer(
child: PageFlipWidget(
backgroundColor: const Color(0xFFEFEADD),
lastPage: Image.file(
snapshot.data!.elementAt(widget.book.pageCount - 1)),
onMiddleTap: _onTap,
children: List.generate(widget.book.pageCount, (index) {
return Image.file(
snapshot.data!.elementAt(index),
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
);
}),
),
),
);
}),
);
}
}
Page flip animation widget
import 'package:flutter/material.dart';
import 'dart:math' as math;
import 'dart:ui' as ui;
import 'package:flutter/rendering.dart';
class PageFlipWidget extends StatefulWidget {
const PageFlipWidget({
Key? key,
this.duration = const Duration(milliseconds: 450),
this.cutoff = 0.6,
this.backgroundColor = const Color(0xFFFFFFFF),
required this.children,
this.initialIndex = 0,
this.lastPage,
this.showDragCutoff = false,
required this.onMiddleTap,
}) : super(key: key);
final Color backgroundColor;
final List\<Widget\> children;
final Duration duration;
final int initialIndex;
final Widget? lastPage;
final bool showDragCutoff;
final double cutoff;
final VoidCallback onMiddleTap;
#override
PageFlipWidgetState createState() =\> PageFlipWidgetState();
}
class PageFlipWidgetState extends State\<PageFlipWidget\>
with TickerProviderStateMixin {
int pageNumber = 0;
List\<Widget\>? pages = \[\];
final List\<AnimationController\> \_controllers = \[\];
bool? \_isForward;
#override
void didUpdateWidget(PageFlipWidget oldWidget) {
if (oldWidget.children != widget.children) {
\_setUp();
}
if (oldWidget.duration != widget.duration) {
\_setUp();
}
if (oldWidget.backgroundColor != widget.backgroundColor) {
\_setUp();
}
super.didUpdateWidget(oldWidget);
}
#override
void dispose() {
for (var c in \_controllers) {
c.dispose();
}
super.dispose();
}
#override
void initState() {
super.initState();
\_setUp();
}
void \_setUp() {
\_controllers.clear();
pages?.clear();
for (var i = 0; i < widget.children.length; i++) {
final controller = AnimationController(
value: 1,
duration: widget.duration,
vsync: this,
);
_controllers.add(controller);
final child = PageFlipBuilder(
backgroundColor: widget.backgroundColor,
amount: controller,
child: widget.children[i],
);
pages?.add(child);
}
pages = pages?.reversed.toList();
pageNumber = widget.initialIndex;
}
bool get \_isLastPage =\>
pages != null && (pages?.length ?? 0 - 1) == pageNumber;
bool get \_isFirstPage =\> pageNumber == 0;
void \_flipPage(DragUpdateDetails details, BoxConstraints dimens) {
final ratio = details.delta.dx / dimens.maxWidth;
if (\_isForward == null) {
if (details.delta.dx \> 0) {
\_isForward = false;
} else {
\_isForward = true;
}
}
if (\_isForward! || pageNumber == 0) {
\_isLastPage ? null : \_controllers\[pageNumber\].value += ratio;
} else {
\_controllers\[pageNumber - 1\].value += ratio;
}
}
Future \_onDragFinish() async {
if (\_isForward != null) {
if (\_isForward!) {
if (!\_isLastPage &&
\_controllers\[pageNumber\].value \<= (widget.cutoff + 0.15)) {
await nextPage();
} else {
\_isLastPage ? null : await \_controllers\[pageNumber\].forward();
}
} else {
if (!\_isFirstPage &&
\_controllers\[pageNumber - 1\].value \>= widget.cutoff) {
await previousPage();
} else {
if (\_isFirstPage) {
await \_controllers\[pageNumber\].forward();
} else {
\_isFirstPage ? null : await \_controllers\[pageNumber - 1\].reverse();
}
}
}
}
\_isForward = null;
}
Future nextPage() async {
await \_controllers\[pageNumber\].reverse();
if (mounted) {
setState(() {
pageNumber++;
});
}
}
Future previousPage() async {
await \_controllers\[pageNumber - 1\].forward();
if (mounted) {
setState(() {
pageNumber--;
});
}
}
Future goToPage(int index) async {
if (mounted) {
setState(() {
pageNumber = index;
});
}
for (var i = 0; i \< \_controllers.length; i++) {
if (i == index) {
\_controllers\[i\].forward();
} else if (i \< index) {
// \_controllers\[i\].value = 0;
\_controllers\[i\].reverse();
} else {
if (\_controllers\[i\].status == AnimationStatus.reverse) {
\_controllers\[i\].value = 1;
}
}
}
}
#override
Widget build(BuildContext context) {
return Material(
child: LayoutBuilder(
builder: (context, dimens) =\> GestureDetector(
behavior: HitTestBehavior.opaque,
onHorizontalDragCancel: () =\> \_isForward = null,
onHorizontalDragUpdate: (details) =\> \_flipPage(details, dimens),
onHorizontalDragEnd: (details) =\> \_onDragFinish(),
child: Stack(
fit: StackFit.expand,
children: \<Widget\>\[
if (widget.lastPage != null) ...\[
widget.lastPage!,
\],
...pages!,
Positioned.fill(
child: Flex(
direction: Axis.horizontal,
children: \<Widget\>\[
Flexible(
flex: (widget.cutoff \* 0.75 \* 10).round(),
child: Container(
color: widget.showDragCutoff
? Colors.blue.withAlpha(100)
: null,
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: \_isFirstPage ? null : previousPage,
),
),
),
Flexible(
flex: 10,
child: Container(
color: widget.showDragCutoff
? Colors.orange.withAlpha(100)
: null,
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: widget.onMiddleTap,
),
),
),
Flexible(
flex: (widget.cutoff \* 0.75 \* 10).round(),
child: Container(
color: widget.showDragCutoff
? Colors.red.withAlpha(100)
: null,
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: \_isLastPage ? null : nextPage,
),
),
),
\],
),
),
\],
),
),
),
);
}
}
class PageFlipEffect extends CustomPainter {
PageFlipEffect({
required this.amount,
required this.image,
this.backgroundColor,
this.radius = 0.18,
}) : super(repaint: amount);
final Animation\<double\> amount;
final ui.Image image;
final Color? backgroundColor;
final double radius;
#override
void paint(ui.Canvas canvas, ui.Size size) {
final pos = amount.value;
final movX = (1.0 - pos) \* 0.85;
final calcR = (movX \< 0.20) ? radius \* movX \* 5 : radius;
final wHRatio = 1 - calcR;
final hWRatio = image.height / image.width;
final hWCorrection = (hWRatio - 1.0) / 2.0;
final w = size.width.toDouble();
final h = size.height.toDouble();
final c = canvas;
final shadowXf = (wHRatio - movX);
final shadowSigma =
Shadow.convertRadiusToSigma(8.0 + (32.0 * (1.0 - shadowXf)));
final pageRect = Rect.fromLTRB(0.0, 0.0, w * shadowXf, h);
if (backgroundColor != null) {
c.drawRect(pageRect, Paint()..color = backgroundColor!);
}
if (pos != 0) {
c.drawRect(
pageRect,
Paint()
..color = Colors.black54
..maskFilter = MaskFilter.blur(BlurStyle.outer, shadowSigma),
);
}
final ip = Paint();
for (double x = 0; x < size.width; x++) {
final xf = (x / w);
final v = (calcR * (math.sin(math.pi / 0.5 * (xf - (1.0 - pos)))) +
(calcR * 1.1));
final xv = (xf * wHRatio) - movX;
final sx = (xf * image.width);
final sr = Rect.fromLTRB(sx, 0.0, sx + 1.0, image.height.toDouble());
final yv = ((h * calcR * movX) * hWRatio) - hWCorrection;
final ds = (yv * v);
final dr = Rect.fromLTRB(xv * w, 0.0 - ds, xv * w + 1.0, h + ds);
c.drawImageRect(image, sr, dr, ip);
}
}
#override
bool shouldRepaint(PageFlipEffect oldDelegate) {
return oldDelegate.image != image ||
oldDelegate.amount.value != amount.value;
}
}
class PageFlipBuilder extends StatefulWidget {
const PageFlipBuilder({
Key? key,
required this.amount,
this.backgroundColor = const Color(0xFFFFFFCC),
this.child,
}) : super(key: key);
final Animation\<double\> amount;
final Color backgroundColor;
final Widget? child;
#override
State\<PageFlipBuilder\> createState() =\> \_PageFlipBuilderState();
}
class \_PageFlipBuilderState extends State\<PageFlipBuilder\> {
final \_boundaryKey = GlobalKey();
ui.Image? \_image;
#override
void didUpdateWidget(PageFlipBuilder oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.child != widget.child) {
\_image = null;
}
}
void \_captureImage(Duration timeStamp) async {
final pixelRatio = MediaQuery.of(context).devicePixelRatio;
final boundary = \_boundaryKey.currentContext?.findRenderObject()
as RenderRepaintBoundary;
if (boundary.debugNeedsPaint) {
await Future.delayed(const Duration(milliseconds: 20));
return \_captureImage(timeStamp);
}
final image = await boundary.toImage(pixelRatio: pixelRatio);
setState(() =\> \_image = image);
}
#override
Widget build(BuildContext context) {
if (\_image != null) {
return CustomPaint(
painter: PageFlipEffect(
amount: widget.amount,
image: \_image!,
backgroundColor: widget.backgroundColor,
),
size: Size.infinite,
);
} else {
WidgetsBinding.instance.addPostFrameCallback(\_captureImage);
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
final size = constraints.biggest;
return Stack(
clipBehavior: Clip.hardEdge,
children: \<Widget\>\[
Positioned(
left: 1 + size.width,
top: 1 + size.height,
width: size.width,
height: size.height,
child: RepaintBoundary(
key: \_boundaryKey,
child: widget.child,
),
),
\],
);
},
);
}
}
}
class PageFlipImage extends StatefulWidget {
const PageFlipImage({
Key? key,
required this.amount,
this.image,
this.backgroundColor = const Color(0xFFFFFFCC),
}) : super(key: key);
final Animation\<double\> amount;
final ImageProvider? image;
final Color? backgroundColor;
#override
State\<PageFlipImage\> createState() =\> \_PageFlipImageState();
}
class \_PageFlipImageState extends State\<PageFlipImage\> {
ImageStream? \_imageStream;
ImageInfo? \_imageInfo;
bool \_isListeningToStream = false;
late ImageStreamListener \_imageListener;
#override
void initState() {
super.initState();
\_imageListener = ImageStreamListener(\_handleImageFrame);
}
#override
void dispose() {
\_stopListeningToStream();
super.dispose();
}
#override
void didChangeDependencies() {
\_resolveImage();
if (TickerMode.of(context)) {
\_listenToStream();
} else {
\_stopListeningToStream();
}
super.didChangeDependencies();
}
#override
void didUpdateWidget(PageFlipImage oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.image != oldWidget.image) {
\_resolveImage();
}
}
#override
void reassemble() {
\_resolveImage(); // in case the image cache was flushed
super.reassemble();
}
void \_resolveImage() {
final ImageStream newStream =
widget.image!.resolve(createLocalImageConfiguration(context));
\_updateSourceStream(newStream);
}
void \_handleImageFrame(ImageInfo imageInfo, bool synchronousCall) {
setState(() =\> \_imageInfo = imageInfo);
}
// Updates \_imageStream to newStream, and moves the stream listener
// registration from the old stream to the new stream (if a listener was
// registered).
void \_updateSourceStream(ImageStream newStream) {
if (\_imageStream?.key == newStream.key) return;
if (_isListeningToStream) _imageStream?.removeListener(_imageListener);
_imageStream = newStream;
if (_isListeningToStream) _imageStream?.addListener(_imageListener);
}
void \_listenToStream() {
if (\_isListeningToStream) return;
\_imageStream?.addListener(\_imageListener);
\_isListeningToStream = true;
}
void \_stopListeningToStream() {
if (!\_isListeningToStream) return;
\_imageStream?.removeListener(\_imageListener);
\_isListeningToStream = false;
}
#override
Widget build(BuildContext context) {
if (\_imageInfo != null) {
return CustomPaint(
painter: PageFlipEffect(
amount: widget.amount,
image: \_imageInfo!.image,
backgroundColor: widget.backgroundColor,
),
size: Size.infinite,
);
} else {
return const SizedBox();
}
}
}
in the beginning I was converting the pdf page to uint8list and using the image.memory widget, and it was not working swell, so I converted the uint8list bytes into file and then using image.file, it started getting this issue where it first it blank then after ctrl+s it starts rendering but some pages still not rendered
I think image.asset works well, but idk if that's helpful, I need my files on firebase storage.
Related
How to put different limit for multi chekbox in recyclerview item
I can choose 2 items from the first group and choose 1 item from the second group. Now there should be a certain limit for each group and the whole choice as well. How can I apply it? #Override public void onBindViewHolder(#NonNull Holder holder, int position) { holder.txt_ingredient.setText(ingredients.get(position).getName()); ArrayList<HomeList.Ingredient> sizeArrayList = new ArrayList<>(); sizeArrayList.addAll(ingredients); for (int i = 0; i < ingredients.get(position).getIngredients().size(); i++) { indi.add(ingredients.get(position).getIngredients().get(i).getId()); } for (int i = 0; i < sizeArrayList.get(position).getIngredients().size(); i++) { LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); final View rowView = inflater.inflate(R.layout.checkbox_feild, null); holder.parentLinearSize.addView(rowView, holder.parentLinearSize.getChildCount() - 1); } for (int itemPos = 0; itemPos < holder.parentLinearSize.getChildCount(); itemPos++) { View view1 = holder.parentLinearSize.getChildAt(itemPos); CheckBox ch = (CheckBox) view1.findViewById(R.id.chkSpe); TextView cat_value = (TextView) view1.findViewById(R.id.cat_value); String c = String.valueOf(sizeArrayList.get(position).getIngredients().size()); ch.setText(sizeArrayList.get(position).getIngredients().get(itemPos).getTitle()); ch.setOnCheckedChangeListener(null); int finalItemPos = itemPos; ch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { #Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { int limit = Integer.parseInt(sizeArrayList.get(position).getSelectionLimit()); int globalInc = 0; if (globalInc == limit && isChecked) { ch.setChecked(false); Toast.makeText(context, "Limit reached!!!", Toast.LENGTH_SHORT).show(); } else if (isChecked) { globalInc++; Toast.makeText(context, globalInc + " checked!", Toast.LENGTH_SHORT) .show(); ch.setSelected(isChecked); if (ch.isChecked()) { for (int i = 0; i < ingredients.get(position).getIngredients().size(); i++) { if (i == finalItemPos) { ingredients.get(position).getIngredients().get(i).setQty("1"); } else ingredients.get(position).getIngredients().get(i).setQty("0"); } ingredients.get(position).setIsOpenSection("1"); onItemCheckListener.onItemCheck(sizeArrayList.get(position).getIngredients(), sizeArrayList.get(position)); Toast.makeText(context, sizeArrayList.get(position).getIngredients().get(finalItemPos).getPrice(), Toast.LENGTH_SHORT).show(); onRecycleItemClickListenerExtra.onItemClickListener(holder, position, "selectExtra", sizeArrayList.get(position).getIngredients().get(finalItemPos).getPrice(), "trextra"); } else { onItemCheckListener.onItemUncheck(sizeArrayList.get(position).getIngredients().get(position)); onRecycleItemClickListenerExtra.onItemClickListener(holder, position, "DeselectExtra", sizeArrayList.get(position).getIngredients().get(finalItemPos).getPrice(), "trextra"); sizeArrayList.get(position).getIngredients().get(finalItemPos).setQty("0"); } } else if (!isChecked) { globalInc--; } } }); cat_value.setText(sizeArrayList.get(position).getIngredients().get(itemPos).getPrice()); holder.maximum_amt.setText(sizeArrayList.get(position).getMaximumAmount()); holder.select_limit.setText(sizeArrayList.get(position).getSelectionLimit()); String count = String.valueOf(getItemCount()); holder.total_itm_count.setText(c); String eql_les_grt = sizeArrayList.get(position).getEqualGraterLess(); if (eql_les_grt.equalsIgnoreCase("1")) { if (lan.equals("English")) { String eql_ls_status = "Greater"; holder.euql_grt_les.setText(eql_ls_status); } if (lan.equals("Español")) { String eql_ls_status = "Máximo"; holder.euql_grt_les.setText(eql_ls_status); } } if (eql_les_grt.equalsIgnoreCase("2")) { if (lan.equals("English")) { String eql_ls_status = "Exactly"; holder.euql_grt_les.setText(eql_ls_status); } if (lan.equals("Español")) { String eql_ls_status = "solo"; holder.euql_grt_les.setText(eql_ls_status); } } if (eql_les_grt.equalsIgnoreCase("3")) { if (lan.equals("English")) { String eql_ls_status = "Less"; holder.euql_grt_les.setText(eql_ls_status); } if (lan.equals("Español")) { String eql_ls_status = "Mínimo"; holder.euql_grt_les.setText(eql_ls_status); } } holder.img_arrow.setOnClickListener(new View.OnClickListener() { #Override public void onClick(View v) { holder.rl_details.setVisibility(View.VISIBLE); holder.img_dwn_arrow.setVisibility(View.VISIBLE); holder.img_dwn_arrow.setVisibility(View.VISIBLE); holder.img_arrow.setVisibility(View.GONE); holder.parentLinearSize.setVisibility(View.VISIBLE); } }); holder.img_dwn_arrow.setOnClickListener(new View.OnClickListener() { #Override public void onClick(View v) { holder.rl_details.setVisibility(View.GONE); holder.img_dwn_arrow.setVisibility(View.GONE); holder.img_dwn_arrow.setVisibility(View.GONE); holder.img_arrow.setVisibility(View.VISIBLE); holder.parentLinearSize.setVisibility(View.GONE); } }); }
Can Uncrustify be configured to align braces in one-line functions in header files?
Scenario: C++, a bunch of one-line setters and getters inlined in the header file, as follows: bool hasVoices(int staffIdx) const { return m_mstaves[staffIdx]->hasVoices(); } void setHasVoices(int staffIdx, bool v) { return m_mstaves[staffIdx]->setHasVoices(v); } StaffLines* staffLines(int staffIdx) { return m_mstaves[staffIdx]->lines(); } Spacer* vspacerDown(int staffIdx) const { return m_mstaves[staffIdx]->vspacerDown(); } Spacer* vspacerUp(int staffIdx) const { return m_mstaves[staffIdx]->vspacerUp(); } void setStaffVisible(int staffIdx, bool visible) { m_mstaves[staffIdx]->setVisible(visible); } void setStaffStemless(int staffIdx, bool stemless) { m_mstaves[staffIdx]->setStemless(stemless); } bool corrupted(int staffIdx) const { return m_mstaves[staffIdx]->corrupted(); } void setCorrupted(int staffIdx, bool val) { m_mstaves[staffIdx]->setCorrupted(val); } MeasureNumber* noText(int staffIdx) const { return m_mstaves[staffIdx]->noText(); } void setNoText(int staffIdx, MeasureNumber* t) { m_mstaves[staffIdx]->setNoText(t); } MeasureNumberMode measureNumberMode() const { return m_noMode; } void setMeasureNumberMode(MeasureNumberMode v) { m_noMode = v; } Fraction timesig() const { return m_timesig; } void setTimesig(const Fraction& f) { m_timesig = f; } bool isIrregular() const { return m_timesig != _len; } int size() const { return m_segments.size(); } Segment* first() const { return m_segments.first(); } Segment* first(SegmentType t) const { return m_segments.first(t); } Segment* firstEnabled() const { return m_segments.first(ElementFlag::ENABLED); } Segment* last() const { return m_segments.last(); } SegmentList& segments() { return m_segments; } const SegmentList& segments() const { return m_segments; } void setUserStretch(qreal v) { m_userStretch = v; } The function bodies are aligned for the sake of readability. The repository I'm contributing to has just begun using Uncrustify and added a test to enforce the code style for new pull requests. Uncrustify as currently configured wants this changed to: bool hasVoices(int staffIdx) const { return m_mstaves[staffIdx]->hasVoices(); } void setHasVoices(int staffIdx, bool v) { return m_mstaves[staffIdx]->setHasVoices(v); } StaffLines* staffLines(int staffIdx) { return m_mstaves[staffIdx]->lines(); } Spacer* vspacerDown(int staffIdx) const { return m_mstaves[staffIdx]->vspacerDown(); } Spacer* vspacerUp(int staffIdx) const { return m_mstaves[staffIdx]->vspacerUp(); } void setStaffVisible(int staffIdx, bool visible) { m_mstaves[staffIdx]->setVisible(visible); } void setStaffStemless(int staffIdx, bool stemless) { m_mstaves[staffIdx]->setStemless(stemless); } bool corrupted(int staffIdx) const { return m_mstaves[staffIdx]->corrupted(); } void setCorrupted(int staffIdx, bool val) { m_mstaves[staffIdx]->setCorrupted(val); } MeasureNumber* noText(int staffIdx) const { return m_mstaves[staffIdx]->noText(); } void setNoText(int staffIdx, MeasureNumber* t) { m_mstaves[staffIdx]->setNoText(t); } MeasureNumberMode measureNumberMode() const { return m_noMode; } void setMeasureNumberMode(MeasureNumberMode v) { m_noMode = v; } Fraction timesig() const { return m_timesig; } void setTimesig(const Fraction& f) { m_timesig = f; } bool isIrregular() const { return m_timesig != _len; } int size() const { return m_segments.size(); } Segment* first() const { return m_segments.first(); } Segment* first(SegmentType t) const { return m_segments.first(t); } Segment* firstEnabled() const { return m_segments.first(ElementFlag::ENABLED); } Segment* last() const { return m_segments.last(); } SegmentList& segments() { return m_segments; } const SegmentList& segments() const { return m_segments; } void setUserStretch(qreal v) { m_userStretch = v; } Can Uncrustify be configured to produce something more like the first example instead?
You can use: # Don't split one-line function definitions, as in 'int foo() { return 0; }'. # might modify nl_func_type_name nl_func_leave_one_liners = true # true/false But that won't help you with the spacing for cases where you have a const in your member function. Open up a bug ticket and well see what we can do about that / point you in the directions to create a PR for that.
How to move the snap position from center to left of RecycleView using SnapHelper?
I have an RecycleView that contains ImageViews and my question is how can i move the snap to be on the left side of the RecycleView instead of the center? When i move the ImageViews they get snapped in the center and I can move them to the left or right inside that "snap window" by overriding the CalculateDistanceToFinalSnap method. I think I would now need to move that "snap window" to the left side of the RecycleView but I don't know how, or maybe there is another way, please help. Here is a image of my problem, maybe it will help you to understand more clearly: image
#Jessie Zhang -MSFT's solution works for me. The code was a little oddly formatted and I had some difficulty bringing it over. Here is the same solution (for a horizontal snap only) in Kotlin. class StartSnapHelper: LinearSnapHelper() { override fun calculateDistanceToFinalSnap(layoutManager: RecyclerView.LayoutManager, targetView: View): IntArray? { return if (layoutManager.canScrollHorizontally()) { val outer = mutableListOf<Int>() outer.add(distanceToStart(targetView, getHorizontalHelper(layoutManager))) outer.add(0) outer.toIntArray() } else { super.calculateDistanceToFinalSnap(layoutManager, targetView) } } override fun findSnapView(layoutManager: RecyclerView.LayoutManager?): View? { return if (layoutManager is LinearLayoutManager) { if (layoutManager.canScrollHorizontally()) { getStartView(layoutManager, getHorizontalHelper(layoutManager)) } else { super.findSnapView(layoutManager) } } else { super.findSnapView(layoutManager) } } private fun distanceToStart(targetView: View, helper: OrientationHelper): Int { return helper.getDecoratedStart(targetView) - helper.startAfterPadding } private fun getStartView(layoutManager: RecyclerView.LayoutManager, orientationHelper: OrientationHelper): View? { val firstChild = (layoutManager as LinearLayoutManager).findFirstVisibleItemPosition() val isLastItem = (layoutManager.findLastCompletelyVisibleItemPosition() == layoutManager.itemCount - 1) if (firstChild == RecyclerView.NO_POSITION || isLastItem) { return null } val child = layoutManager.findViewByPosition(firstChild) return if (orientationHelper.getDecoratedEnd(child) >= orientationHelper.getDecoratedMeasurement(child) / 2 && orientationHelper.getDecoratedEnd(child) > 0) { child; } else { if (layoutManager.findFirstCompletelyVisibleItemPosition() == layoutManager.itemCount -1) { null } else { layoutManager.findViewByPosition(firstChild + 1) } } } private fun getHorizontalHelper(layoutManager: RecyclerView.LayoutManager): OrientationHelper { return OrientationHelper.createHorizontalHelper(layoutManager) } }
I have achieved this function ,we juse need to create a class and extent class LinearSnapHelper and override method CalculateDistanceToFinalSnap and FindSnapView. You can check out the full demo here . The main code is as follows: public class StartSnapHelper: LinearSnapHelper { private OrientationHelper mVerticalHelper, mHorizontalHelper; public StartSnapHelper() { } public override void AttachToRecyclerView(RecyclerView recyclerView) { base.AttachToRecyclerView(recyclerView); } public override int[] CalculateDistanceToFinalSnap(RecyclerView.LayoutManager layoutManager, View targetView) { //return base.CalculateDistanceToFinalSnap(layoutManager, targetView); int[] outer = new int[2]; if (layoutManager.CanScrollHorizontally()) { outer[0] = distanceToStart(targetView, getHorizontalHelper(layoutManager)); } else { outer[0] = 0; } if (layoutManager.CanScrollVertically()) { outer[1] = distanceToStart(targetView, getVerticalHelper(layoutManager)); } else { outer[1] = 0; } return outer; } private int distanceToStart(View targetView, OrientationHelper helper) { return helper.GetDecoratedStart(targetView) - helper.StartAfterPadding; } public override View FindSnapView(RecyclerView.LayoutManager layoutManager) { if (layoutManager is LinearLayoutManager) { if (layoutManager.CanScrollHorizontally()) { return getStartView(layoutManager, getHorizontalHelper(layoutManager)); } else { return getStartView(layoutManager, getVerticalHelper(layoutManager)); } } return base.FindSnapView(layoutManager); } private View getStartView(RecyclerView.LayoutManager layoutManager, OrientationHelper helper) { if (layoutManager is LinearLayoutManager) { int firstChild = ((LinearLayoutManager)layoutManager).FindFirstVisibleItemPosition(); bool isLastItem = ((LinearLayoutManager)layoutManager) .FindLastCompletelyVisibleItemPosition() == layoutManager.ItemCount - 1; if (firstChild == RecyclerView.NoPosition || isLastItem) { return null; } View child = layoutManager.FindViewByPosition(firstChild); if (helper.GetDecoratedEnd(child) >= helper.GetDecoratedMeasurement(child) / 2 && helper.GetDecoratedEnd(child) > 0) { return child; } else { if (((LinearLayoutManager)layoutManager).FindLastCompletelyVisibleItemPosition() == layoutManager.ItemCount - 1) { return null; } else { return layoutManager.FindViewByPosition(firstChild + 1); } } } return base.FindSnapView(layoutManager); } private OrientationHelper getVerticalHelper(RecyclerView.LayoutManager layoutManager) { if (mVerticalHelper == null) { mVerticalHelper = OrientationHelper.CreateVerticalHelper(layoutManager); } return mVerticalHelper; } private OrientationHelper getHorizontalHelper(RecyclerView.LayoutManager layoutManager) { if (mHorizontalHelper == null) { mHorizontalHelper = OrientationHelper.CreateHorizontalHelper(layoutManager); } return mHorizontalHelper; } } And use like this: SnapHelper snapHelperStart = new StartSnapHelper(); snapHelperStart.AttachToRecyclerView(recyclerView);
ColorSpace Issues Migrating to PDFBox 2.0.x
Our department has inherited code that uses Apache PDFBox 1.8.x or earlier and we are in the process of trying to migrate it to Apache PDFBox 2.0.x. I have resolved a lot of the various issues in this migration, but I'm still having problems migrating some of the ColorSpace related code. Below are some examples that I haven't figured out how to resolve. I've used the missing methods as the headings for each code snippet. getColorSpaces() and setColorSpace() public class ColorSpaceSetter extends OperatorProcessor { private static final Logger logger = LogManager.getLogger(ColorSpaceSetter.class.getName()); public void process(Operator operator, List<COSBase> arguments) throws IOException { try { COSName arg = (COSName)arguments.get(0); String argString = arg.getName(); if (context.getColorSpaces().containsKey(argString)) { PDColorSpace colorSpace = context.getColorSpaces().get(argString); if (colorSpace.getName().equals(COSName.SEPARATION.getName())) { PDSeparation separation = (PDSeparation)colorSpace; PDColor color; //Non-stroking if (StringUtils.isAllLowerCase(operator.getName())) { color = context.getGraphicsState().getNonStrokingColor(); //Stroking } else { color = context.getGraphicsState().getStrokingColor(); } color.setColorSpace(separation); } } } catch (Exception e) { logger.error("Unexpected argument array for operator " + operator.getName(), e); } } } getColorSpace() public boolean determineStroking(PDColor color) { for ( Float val : color.getColorSpace()) { if (val != 1) { return true; } } return false; } setColorSpace() and setColorSpaceValue() public class StrokeSetter extends OperatorProcessor { public void process(Operator operator, List<COSBase> arguments) throws IOException { //Supported operators are: g, rg, k, sc, and scn //g = device gray (black or white) //rg = rgb (000 is black, 111 is white, other is some other color) //k = cmyk (0 is black, 1 is white, other is some other color) //sc and scn = could be anything, but 0 is black, 1 is white) boolean blackSeparation = false; //Lowercase is non-stroking (fill) color PDColor color; if (StringUtils.isAllLowerCase(operator.getName())) { color = context.getGraphicsState().getNonStrokingColor(); //Uppercase is stroking color } else { color = context.getGraphicsState().getStrokingColor(); } //Treat separations differently - see section 4.5.5 of PDF Reference Documentation PDColorSpace colorSpace = color.getColorSpace(); if (colorSpace.getName().equals(COSName.SEPARATION.getName())) { PDSeparation separation = (PDSeparation)color.getColorSpace(); if (separation.getColorantName().equals("Black")) { blackSeparation = true; } } //Black and White if (operator.getName().equalsIgnoreCase("g")) { color.setColorSpace( new PDDeviceGray() ); float[] values = new float[1]; if ( arguments.size() >= 1 ) { values[0] = ((COSNumber)arguments.get( 0 )).floatValue(); } else { throw new IOException( "Error: Expected at least one argument when setting gray color"); } color.setColorSpaceValue( values ); //RGB colors } else if (operator.getName().equalsIgnoreCase("rg")) { color.setColorSpace(PDDeviceRGB.INSTANCE); float[] values = new float[3]; for ( int i = 0; i < arguments.size(); i++) { values[i] = ((COSNumber)arguments.get( i )).floatValue(); } color.setColorSpaceValue(values); //CMYK colors } else if (operator.getName().equalsIgnoreCase("k")) { color.setColorSpace( PDDeviceCMYK.INSTANCE ); float[] values = new float[4]; for( int i=0; i<arguments.size(); i++ ) { values[i] = ((COSNumber)arguments.get( i )).floatValue(); } color.setColorSpaceValue(values); // Unspecified ColorSpace } else if (operator.getName().equalsIgnoreCase("sc") || operator.getName().equalsIgnoreCase("scn")) { int size = arguments.size(); if ( size == 1) { color.setColorSpace(new PDDeviceGray()); } else if ( size == 3) { color.setColorSpace(PDDeviceRGB.INSTANCE); } else if ( size == 4) { color.setColorSpace(PDDeviceCMYK.INSTANCE); } else { color.setColorSpace(new PDDeviceN()); } float[] values = new float[size]; for( int i=0; i<arguments.size(); i++ ) { //Flip values when blackSeparation for PDDeviceGray if (blackSeparation & size == 1) { float val = ((COSNumber)arguments.get( i )).floatValue(); values[i] = Math.abs(val - 1); } else { values[i] = ((COSNumber)arguments.get( i )).floatValue(); } } color.setColorSpaceValue(values); } } }
Photo doesn't show in browser
I am making a web application in asp.net with MVC 4 and i'm trying to show the user twitter home feed. To get the user home feed i'm using twitterizer2. Everything work fine and i have the user home feed and the feed photo link but it doesn't display in the browser. If i open the picture link from the browser address bar it is displayed and also if i use another photo link not related with twitter everything works fine. So i'm guessing it has something to do with twitter. My view is this: <div class="NoBullets" style="font-size:#Model.TextSize"> <ul style="list-style-type:none"> #foreach (var status in Model.TStatusCollection) { <li> <img src=#status.User.ProfileImageLocation style="float:left" width="48" height="48" align="bottom"> #status.Text<br /> #string.Format("{0:dd MMMM yyyy} {0:H:mm}", status.CreatedDate) </li> } </ul> </div> And the model: public class PortletMyTwitter : PortletBase { private int noOfTweets = 15; private string textSize = "medium"; private string userExtAppID; private TwitterStatusCollection tStatusCollection; private IList<object> noOfTweetsList = new List<object>() { new {value = 5}, new {value = 10}, new {value = 15}, new {value = 20}, new {value = 25} }; private IList<object> textSizeList = new List<object>() { new {value = "small"}, new {value = "medium"}, new {value = "large"} }; public string UserExtAppID { get { return userExtAppID; } set { userExtAppID = value; } } public IList<object> NoOfTweetsList { get { return noOfTweetsList; } } public int NoOfTweets { get { return noOfTweets; } set { noOfTweets = value; } } public IList<object> TextSizeList { get { return textSizeList; } } public string TextSize { get { return textSize; } set { textSize = value; } } public TwitterStatusCollection TStatusCollection { get { return tStatusCollection; } } public void GetSettings(XmlDocument xmlPortletState) { if (xmlPortletState.GetElementsByTagName("UserExtAppID").Count > 0) { if (xmlPortletState.GetElementsByTagName("UserExtAppID")[0].FirstChild != null) UserExtAppID = ((System.Xml.XmlText)(xmlPortletState.GetElementsByTagName("UserExtAppID")[0]).FirstChild).Value; } if (xmlPortletState.GetElementsByTagName("HideHeader").Count > 0) { if (xmlPortletState.GetElementsByTagName("HideHeader")[0].FirstChild != null) HideHeader = bool.Parse(((System.Xml.XmlText)(xmlPortletState.GetElementsByTagName("HideHeader")[0]).FirstChild).Value); } if (xmlPortletState.GetElementsByTagName("TextSize").Count > 0) { if (xmlPortletState.GetElementsByTagName("TextSize")[0].FirstChild != null) try { TextSize = ((System.Xml.XmlText)(xmlPortletState.GetElementsByTagName("TextSize")[0]).FirstChild).Value; } catch { TextSize = "medium"; } } if (xmlPortletState.GetElementsByTagName("NoOfTweets").Count > 0) { if (xmlPortletState.GetElementsByTagName("NoOfTweets")[0].FirstChild != null) try { NoOfTweets = Convert.ToInt32(((System.Xml.XmlText)(xmlPortletState.GetElementsByTagName("NoOfTweets")[0]).FirstChild).Value); } catch { NoOfTweets = 10; } } UpdateFeed(); } protected void UpdateFeed() { try { OAuthTokens oauthTokens = new OAuthTokens() { AccessToken = "", AccessTokenSecret = "", ConsumerKey = "", ConsumerSecret = "" }; TimelineOptions myOptions = new TimelineOptions(); myOptions.IncludeRetweets = false; myOptions.UseSSL = true; myOptions.APIBaseAddress = "https://api.twitter.com/1.1/"; myOptions.Count = NoOfTweets; TwitterResponse<TwitterStatusCollection> twitterDataSource = TwitterTimeline.HomeTimeline(oauthTokens, myOptions); tStatusCollection = twitterDataSource.ResponseObject; } catch (Exception) { } } }